Tools/TRPreviewer.py

changeset 0
de9c2efb9d02
child 7
c679fb30c8f3
equal deleted inserted replaced
-1:000000000000 0:de9c2efb9d02
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2004 - 2009 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing the TR Previewer main window.
8 """
9
10 import sys
11 import os
12
13 from PyQt4.QtCore import *
14 from PyQt4.QtGui import *
15 from PyQt4 import uic
16
17 from TRSingleApplication import TRSingleApplicationServer
18
19 import Preferences
20 import UI.PixmapCache
21 import UI.Config
22
23
24 noTranslationName = QApplication.translate("TRPreviewer", "<No translation>")
25
26 class TRPreviewer(QMainWindow):
27 """
28 Class implementing the UI Previewer main window.
29 """
30 def __init__(self, filenames = [], parent = None, name = None):
31 """
32 Constructor
33
34 @param filenames filenames of form and/or translation files to load
35 @param parent parent widget of this window (QWidget)
36 @param name name of this window (string)
37 """
38 self.mainWidget = None
39 self.currentFile = QDir.currentPath()
40
41 QMainWindow.__init__(self, parent)
42 if not name:
43 self.setObjectName("TRPreviewer")
44 else:
45 self.setObjectName(name)
46 self.resize(QSize(800, 600).expandedTo(self.minimumSizeHint()))
47 self.setAttribute(Qt.WA_DeleteOnClose)
48 self.statusBar()
49
50 self.setWindowIcon(UI.PixmapCache.getIcon("eric.png"))
51 self.setWindowTitle(self.trUtf8("Translations Previewer"))
52
53 self.cw = QWidget(self)
54 self.cw.setObjectName("qt_central_widget")
55
56 self.TRPreviewerLayout = QVBoxLayout(self.cw)
57 self.TRPreviewerLayout.setMargin(6)
58 self.TRPreviewerLayout.setSpacing(6)
59 self.TRPreviewerLayout.setObjectName("TRPreviewerLayout")
60
61 self.languageLayout = QHBoxLayout()
62 self.languageLayout.setMargin(0)
63 self.languageLayout.setSpacing(6)
64 self.languageLayout.setObjectName("languageLayout")
65
66 self.languageLabel = QLabel(self.trUtf8("Select language file"), self.cw)
67 self.languageLabel.setObjectName("languageLabel")
68 self.languageLayout.addWidget(self.languageLabel)
69
70 self.languageCombo = QComboBox(self.cw)
71 self.languageCombo.setObjectName("languageCombo")
72 self.languageCombo.setEditable(False)
73 self.languageCombo.setToolTip(self.trUtf8("Select language file"))
74 self.languageCombo.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
75 self.languageLayout.addWidget(self.languageCombo)
76
77 languageSpacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
78 self.languageLayout.addItem(languageSpacer)
79 self.TRPreviewerLayout.addLayout(self.languageLayout)
80
81 self.preview = WidgetWorkspace(self.cw)
82 self.preview.setObjectName("preview")
83 self.TRPreviewerLayout.addWidget(self.preview)
84 self.connect(self.preview, SIGNAL('lastWidgetClosed'), self.__updateActions)
85
86 self.setCentralWidget(self.cw)
87
88 self.connect(self.languageCombo,SIGNAL("activated(const QString&)"),
89 self.setTranslation)
90
91 self.translations = TranslationsDict(self.languageCombo, self)
92 self.connect(self.translations, SIGNAL('translationChanged'),
93 self.preview, SIGNAL('rebuildWidgets'))
94
95 self.__initActions()
96 self.__initMenus()
97 self.__initToolbars()
98
99 self.__updateActions()
100
101 # fire up the single application server
102 self.SAServer = TRSingleApplicationServer(self)
103 self.connect(self.SAServer, SIGNAL('loadForm'), self.preview.loadWidget)
104 self.connect(self.SAServer, SIGNAL('loadTranslation'), self.translations.add)
105
106 # defere loading of a UI file until we are shown
107 self.filesToLoad = filenames[:]
108
109 def show(self):
110 """
111 Public slot to show this dialog.
112
113 This overloaded slot loads a UI file to be previewed after
114 the main window has been shown. This way, previewing a dialog
115 doesn't interfere with showing the main window.
116 """
117 QMainWindow.show(self)
118 if self.filesToLoad:
119 filenames, self.filesToLoad = (self.filesToLoad[:], [])
120 first = True
121 for fn in filenames:
122 fi = QFileInfo(fn)
123 if fi.suffix().lower() == 'ui':
124 self.preview.loadWidget(fn)
125 elif fi.suffix().lower()== 'qm':
126 self.translations.add(fn, first)
127 first = False
128
129 self.__updateActions()
130
131 def closeEvent(self, event):
132 """
133 Private event handler for the close event.
134
135 @param event close event (QCloseEvent)
136 """
137 if self.SAServer is not None:
138 self.SAServer.shutdown()
139 self.SAServer = None
140 event.accept()
141
142 def __initActions(self):
143 """
144 Private method to define the user interface actions.
145 """
146 self.openUIAct = QAction(UI.PixmapCache.getIcon("openUI.png"),
147 self.trUtf8('&Open UI Files...'), self)
148 self.openUIAct.setStatusTip(self.trUtf8('Open UI files for display'))
149 self.openUIAct.setWhatsThis(self.trUtf8(
150 """<b>Open UI Files</b>"""
151 """<p>This opens some UI files for display.</p>"""
152 ))
153 self.connect(self.openUIAct, SIGNAL('triggered()'), self.__openWidget)
154
155 self.openQMAct = QAction(UI.PixmapCache.getIcon("openQM.png"),
156 self.trUtf8('Open &Translation Files...'), self)
157 self.openQMAct.setStatusTip(self.trUtf8('Open Translation files for display'))
158 self.openQMAct.setWhatsThis(self.trUtf8(
159 """<b>Open Translation Files</b>"""
160 """<p>This opens some translation files for display.</p>"""
161 ))
162 self.connect(self.openQMAct, SIGNAL('triggered()'), self.__openTranslation)
163
164 self.reloadAct = QAction(UI.PixmapCache.getIcon("reload.png"),
165 self.trUtf8('&Reload Translations'), self)
166 self.reloadAct.setStatusTip(self.trUtf8('Reload the loaded translations'))
167 self.reloadAct.setWhatsThis(self.trUtf8(
168 """<b>Reload Translations</b>"""
169 """<p>This reloads the translations for the loaded languages.</p>"""
170 ))
171 self.connect(self.reloadAct, SIGNAL('triggered()'), self.translations.reload)
172
173 self.exitAct = QAction(UI.PixmapCache.getIcon("exit.png"),
174 self.trUtf8('&Quit'), self)
175 self.exitAct.setShortcut(QKeySequence(self.trUtf8("Ctrl+Q","File|Quit")))
176 self.exitAct.setStatusTip(self.trUtf8('Quit the application'))
177 self.exitAct.setWhatsThis(self.trUtf8(
178 """<b>Quit</b>"""
179 """<p>Quit the application.</p>"""
180 ))
181 self.connect(self.exitAct, SIGNAL('triggered()'),
182 qApp, SLOT('closeAllWindows()'))
183
184 self.whatsThisAct = QAction(UI.PixmapCache.getIcon("whatsThis.png"),
185 self.trUtf8('&What\'s This?'), self)
186 self.whatsThisAct.setShortcut(QKeySequence(self.trUtf8("Shift+F1")))
187 self.whatsThisAct.setStatusTip(self.trUtf8('Context sensitive help'))
188 self.whatsThisAct.setWhatsThis(self.trUtf8(
189 """<b>Display context sensitive help</b>"""
190 """<p>In What's This? mode, the mouse cursor shows an arrow with a"""
191 """ question mark, and you can click on the interface elements to get"""
192 """ a short description of what they do and how to use them. In"""
193 """ dialogs, this feature can be accessed using the context help"""
194 """ button in the titlebar.</p>"""
195 ))
196 self.connect(self.whatsThisAct,SIGNAL('triggered()'),self.__whatsThis)
197
198 self.aboutAct = QAction(self.trUtf8('&About'), self)
199 self.aboutAct.setStatusTip(self.trUtf8('Display information about this software'))
200 self.aboutAct.setWhatsThis(self.trUtf8(
201 """<b>About</b>"""
202 """<p>Display some information about this software.</p>"""
203 ))
204 self.connect(self.aboutAct,SIGNAL('triggered()'),self.__about)
205
206 self.aboutQtAct = QAction(self.trUtf8('About &Qt'), self)
207 self.aboutQtAct.setStatusTip(\
208 self.trUtf8('Display information about the Qt toolkit'))
209 self.aboutQtAct.setWhatsThis(self.trUtf8(
210 """<b>About Qt</b>"""
211 """<p>Display some information about the Qt toolkit.</p>"""
212 ))
213 self.connect(self.aboutQtAct,SIGNAL('triggered()'),self.__aboutQt)
214
215 self.tileAct = QAction(self.trUtf8('&Tile'), self)
216 self.tileAct.setStatusTip(self.trUtf8('Tile the windows'))
217 self.tileAct.setWhatsThis(self.trUtf8(
218 """<b>Tile the windows</b>"""
219 """<p>Rearrange and resize the windows so that they are tiled.</p>"""
220 ))
221 self.connect(self.tileAct, SIGNAL('triggered()'),self.preview.tile)
222
223 self.cascadeAct = QAction(self.trUtf8('&Cascade'), self)
224 self.cascadeAct.setStatusTip(self.trUtf8('Cascade the windows'))
225 self.cascadeAct.setWhatsThis(self.trUtf8(
226 """<b>Cascade the windows</b>"""
227 """<p>Rearrange and resize the windows so that they are cascaded.</p>"""
228 ))
229 self.connect(self.cascadeAct, SIGNAL('triggered()'),self.preview.cascade)
230
231 self.closeAct = QAction(UI.PixmapCache.getIcon("close.png"),
232 self.trUtf8('&Close'), self)
233 self.closeAct.setShortcut(QKeySequence(self.trUtf8("Ctrl+W","File|Close")))
234 self.closeAct.setStatusTip(self.trUtf8('Close the current window'))
235 self.closeAct.setWhatsThis(self.trUtf8(
236 """<b>Close Window</b>"""
237 """<p>Close the current window.</p>"""
238 ))
239 self.connect(self.closeAct, SIGNAL('triggered()'),self.preview.closeWidget)
240
241 self.closeAllAct = QAction(self.trUtf8('Clos&e All'), self)
242 self.closeAllAct.setStatusTip(self.trUtf8('Close all windows'))
243 self.closeAllAct.setWhatsThis(self.trUtf8(
244 """<b>Close All Windows</b>"""
245 """<p>Close all windows.</p>"""
246 ))
247 self.connect(self.closeAllAct, SIGNAL('triggered()'),
248 self.preview.closeAllWidgets)
249
250 def __initMenus(self):
251 """
252 Private method to create the menus.
253 """
254 mb = self.menuBar()
255
256 menu = mb.addMenu(self.trUtf8('&File'))
257 menu.setTearOffEnabled(True)
258 menu.addAction(self.openUIAct)
259 menu.addAction(self.openQMAct)
260 menu.addAction(self.reloadAct)
261 menu.addSeparator()
262 menu.addAction(self.closeAct)
263 menu.addAction(self.closeAllAct)
264 menu.addSeparator()
265 menu.addAction(self.exitAct)
266
267 self.windowMenu = mb.addMenu(self.trUtf8('&Window'))
268 self.windowMenu.setTearOffEnabled(True)
269 self.connect(self.windowMenu, SIGNAL('aboutToShow()'), self.__showWindowMenu)
270 self.connect(self.windowMenu, SIGNAL('triggered(QAction *)'),
271 self.preview.toggleSelectedWidget)
272
273 mb.addSeparator()
274
275 menu = mb.addMenu(self.trUtf8('&Help'))
276 menu.setTearOffEnabled(True)
277 menu.addAction(self.aboutAct)
278 menu.addAction(self.aboutQtAct)
279 menu.addSeparator()
280 menu.addAction(self.whatsThisAct)
281
282 def __initToolbars(self):
283 """
284 Private method to create the toolbars.
285 """
286 filetb = self.addToolBar(self.trUtf8("File"))
287 filetb.setIconSize(UI.Config.ToolBarIconSize)
288 filetb.addAction(self.openUIAct)
289 filetb.addAction(self.openQMAct)
290 filetb.addAction(self.reloadAct)
291 filetb.addSeparator()
292 filetb.addAction(self.closeAct)
293 filetb.addSeparator()
294 filetb.addAction(self.exitAct)
295
296 helptb = self.addToolBar(self.trUtf8("Help"))
297 helptb.setIconSize(UI.Config.ToolBarIconSize)
298 helptb.addAction(self.whatsThisAct)
299
300 def __whatsThis(self):
301 """
302 Private slot called in to enter Whats This mode.
303 """
304 QWhatsThis.enterWhatsThisMode()
305
306 def __updateActions(self):
307 """
308 Private slot to update the actions state.
309 """
310 if self.preview.hasWidgets():
311 self.closeAct.setEnabled(True)
312 self.closeAllAct.setEnabled(True)
313 self.tileAct.setEnabled(True)
314 self.cascadeAct.setEnabled(True)
315 else:
316 self.closeAct.setEnabled(False)
317 self.closeAllAct.setEnabled(False)
318 self.tileAct.setEnabled(False)
319 self.cascadeAct.setEnabled(False)
320
321 if self.translations.hasTranslations():
322 self.reloadAct.setEnabled(True)
323 else:
324 self.reloadAct.setEnabled(False)
325
326 def __about(self):
327 """
328 Private slot to show the about information.
329 """
330 QMessageBox.about(self, self.trUtf8("TR Previewer"), self.trUtf8(
331 """<h3> About TR Previewer </h3>"""
332 """<p>The TR Previewer loads and displays Qt User-Interface files"""
333 """ and translation files and shows dialogs for a selected language.</p>"""
334 ))
335
336 def __aboutQt(self):
337 """
338 Private slot to show info about Qt.
339 """
340 QMessageBox.aboutQt(self, self.trUtf8("TR Previewer"))
341
342 def __openWidget(self):
343 """
344 Private slot to handle the Open Dialog action.
345 """
346 fileNameList = QFileDialog.getOpenFileNames(
347 None,
348 self.trUtf8("Select UI files"),
349 "",
350 self.trUtf8("Qt User-Interface Files (*.ui)"))
351
352 for fileName in fileNameList:
353 self.preview.loadWidget(fileName)
354
355 self.__updateActions()
356
357 def __openTranslation(self):
358 """
359 Private slot to handle the Open Translation action.
360 """
361 fileNameList = QFileDialog.getOpenFileNames(
362 None,
363 self.trUtf8("Select translation files"),
364 "",
365 self.trUtf8("Qt Translation Files (*.qm)"))
366
367 first = True
368 for fileName in fileNameList:
369 self.translations.add(fileName, first)
370 first = False
371
372 self.__updateActions()
373
374 def setTranslation(self, name):
375 """
376 Public slot to activate a translation.
377
378 @param name name (language) of the translation (string or QString)
379 """
380 self.translations.set(name)
381
382 def __showWindowMenu(self):
383 """
384 Private slot to handle the aboutToShow signal of the window menu.
385 """
386 self.windowMenu.clear()
387 self.windowMenu.addAction(self.tileAct)
388 self.windowMenu.addAction(self.cascadeAct)
389 self.windowMenu.addSeparator()
390
391 self.preview.showWindowMenu(self.windowMenu)
392
393 def reloadTranslations(self):
394 """
395 Public slot to reload all translations.
396 """
397 self.translations.reload()
398
399 class Translation(object):
400 """
401 Class to store the properties of a translation
402 """
403 def __init__(self):
404 """
405 Constructor
406 """
407 self.fileName = None
408 self.name = None
409 self.translator = None
410
411 class TranslationsDict(QObject):
412 """
413 Class to store all loaded translations.
414
415 @signal translationChanged() emit after a translator was set
416 """
417 def __init__(self, selector, parent):
418 """
419 Constructor
420
421 @param selector reference to the QComboBox used to show the
422 available languages (QComboBox)
423 @param parent parent widget (QWidget)
424 """
425 QObject.__init__(self, parent)
426
427 self.selector = selector
428 self.currentTranslator = None
429 self.selector.addItem(noTranslationName)
430 self.translations = [] # list of Translation objects
431
432 def add(self, fileName, setTranslation = True):
433 """
434 Public method to add a translation to the list.
435
436 If the translation file (*.qm) has not been loaded yet, it will
437 be loaded automatically.
438
439 @param fileName name of the translation file to be added (string)
440 @param setTranslation flag indicating, if this should be set as the active
441 translation (boolean)
442 """
443 if not self.__haveFileName(fileName):
444 ntr = Translation()
445 ntr.fileName = fileName
446 ntr.name = self.__uniqueName(fileName)
447 if ntr.name is None:
448 QMessageBox.warning(None,
449 self.trUtf8("Set Translator"),
450 self.trUtf8("""<p>The translation filename <b>{0}</b>"""
451 """ is invalid.</p>""").format(fileName))
452 return
453
454 ntr.translator = self.loadTransFile(fileName)
455 if ntr.translator is None:
456 return
457
458 self.selector.addItem(ntr.name)
459 self.translations.append(ntr)
460
461 if setTranslation:
462 tr = self.__findFileName(fileName)
463 self.set(tr.name)
464
465 def set(self, name):
466 """
467 Public slot to set a translator by name.
468
469 @param name name (language) of the translator to set (string)
470 """
471 nTranslator = None
472
473 if name != noTranslationName:
474 trans = self.__findName(name)
475 if trans is None:
476 QMessageBox.warning(None,
477 self.trUtf8("Set Translator"),
478 self.trUtf8("""<p>The translator <b>{0}</b> is not known.</p>""")\
479 .format(name))
480 return
481
482 nTranslator = trans.translator
483
484 if nTranslator == self.currentTranslator:
485 return
486
487 if self.currentTranslator is not None:
488 QApplication.removeTranslator(self.currentTranslator)
489 if nTranslator is not None:
490 QApplication.installTranslator(nTranslator)
491 self.currentTranslator = nTranslator
492
493 self.selector.blockSignals(True)
494 self.selector.setCurrentIndex(self.selector.findText(name))
495 self.selector.blockSignals(False)
496
497 self.emit(SIGNAL('translationChanged'))
498
499 def reload(self):
500 """
501 Public method to reload all translators.
502 """
503 cname = self.selector.currentText()
504 if self.currentTranslator is not None:
505 QApplication.removeTranslator(self.currentTranslator)
506 self.currentTranslator = None
507
508 fileNames = []
509 for trans in self.translations:
510 trans.translator = None
511 fileNames.append(trans.fileName)
512 self.translations = []
513 self.selector.clear()
514
515 self.selector.addItem(noTranslationName)
516
517 for fileName in fileNames:
518 self.add(fileName, False)
519
520 if self.__haveName(cname):
521 self.set(cname)
522 else:
523 self.set(noTranslationName)
524
525 def __findFileName(self, transFileName):
526 """
527 Private method to find a translation by file name.
528
529 @param transFileName file name of the translation file (string)
530 @return reference to a translation object or None
531 """
532 for trans in self.translations:
533 if trans.fileName == transFileName:
534 return trans
535 return None
536
537 def __findName(self, name):
538 """
539 Private method to find a translation by name.
540
541 @param name name (language) of the translation (string)
542 @return reference to a translation object or None
543 """
544 for trans in self.translations:
545 if trans.name == name:
546 return trans
547 return None
548
549 def __haveFileName(self, transFileName):
550 """
551 Private method to check for the presence of a translation.
552
553 @param transFileName file name of the translation file (string)
554 @return flag indicating the presence of the translation (boolean)
555 """
556 return self.__findFileName(transFileName) is not None
557
558 def __haveName(self, name):
559 """
560 Private method to check for the presence of a named translation.
561
562 @param name name (language) of the translation (string)
563 @return flag indicating the presence of the translation (boolean)
564 """
565 return self.__findName(name) is not None
566
567 def __uniqueName(self, transFileName):
568 """
569 Private method to generate a unique name.
570
571 @param transFileName file name of the translation file (string)
572 @return unique name (string or None)
573 """
574 name = os.path.basename(transFileName)
575 if not name:
576 return None
577
578 uname = name
579 cnt = 1
580 while self.__haveName(uname):
581 cnt += 1
582 uname = "{0} <{1}>".format(name, cnt)
583
584 return uname
585
586 def __del(self, name):
587 """
588 Private method to delete a translator from the list of available translators.
589
590 @param name name of the translator to delete (string or QString)
591 """
592 if name == noTranslationName:
593 return
594
595 trans = self.__findName(name)
596 if trans is None:
597 return
598
599 if self.selector().currentText() == name:
600 self.set(noTranslationName)
601
602 self.translations.remove(trans)
603 del trans
604
605 def loadTransFile(self, transFileName):
606 """
607 Public slot to load a translation file.
608
609 @param transFileName file name of the translation file (string)
610 @return reference to the new translator object (QTranslator)
611 """
612 tr = QTranslator()
613 if tr.load(transFileName):
614 return tr
615
616 QMessageBox.warning(None,
617 self.trUtf8("Load Translator"),
618 self.trUtf8("""<p>The translation file <b>{0}</b> could not be loaded.</p>""")\
619 .format(transFileName))
620 return None
621
622 def hasTranslations(self):
623 """
624 Public method to check for loaded translations.
625
626 @return flag signaling if any translation was loaded (boolean)
627 """
628 return len(self.translations) > 0
629
630 class WidgetView(QWidget):
631 """
632 Class to show a dynamically loaded widget (or dialog).
633 """
634 def __init__(self, uiFileName, parent = None, name = None):
635 """
636 Constructor
637
638 @param uiFileName name of the UI file to load (string)
639 @param parent parent widget (QWidget)
640 @param name name of this widget (string)
641 """
642 QWidget.__init__(self, parent)
643 if name:
644 self.setObjectName(name)
645 self.setWindowTitle(name)
646 self.setAttribute(Qt.WA_DeleteOnClose)
647
648 self.__widget = None
649 self.__uiFileName = uiFileName
650 self.__layout = QHBoxLayout(self)
651 self.__valid = False
652 self.__timer = QTimer(self)
653 self.__timer.setSingleShot(True)
654 self.connect(self.__timer, SIGNAL('timeout()'), self.buildWidget)
655
656 def isValid(self):
657 """
658 Public method to return the validity of this widget view.
659
660 @return flag indicating the validity (boolean)
661 """
662 return self.__valid
663
664 def uiFileName(self):
665 """
666 Public method to retrieve the name of the UI file.
667
668 @return filename of the loaded UI file (string)
669 """
670 return self.__uiFileName
671
672 def buildWidget(self):
673 """
674 Public slot to load a UI file.
675 """
676 if self.__widget:
677 self.__widget.close()
678 self.__layout.removeWidget(self.__widget)
679 del self.__widget
680 self.__widget = None
681
682 try:
683 self.__widget = uic.loadUi(self.__uiFileName)
684 except:
685 pass
686
687 if not self.__widget:
688 QMessageBox.warning(None,
689 self.trUtf8("Load UI File"),
690 self.trUtf8("""<p>The file <b>{0}</b> could not be loaded.</p>""")\
691 .format(self.__uiFileName))
692 self.__valid = False
693 return
694
695 self.__widget.setParent(self)
696 self.__layout.addWidget(self.__widget)
697 self.__widget.show()
698 self.__valid = True
699 self.adjustSize()
700
701 self.__timer.stop()
702
703 def __rebuildWidget(self):
704 """
705 Private method to schedule a rebuild of the widget.
706 """
707 self.__timer.start(0)
708
709 class WidgetWorkspace(QWorkspace):
710 """
711 Specialized workspace to show the loaded widgets.
712
713 @signal lastWidgetClosed() emitted after last widget was closed
714 """
715 def __init__(self, parent = None):
716 """
717 Constructor
718
719 @param parent parent widget (QWidget)
720 """
721 QWorkspace.__init__(self, parent)
722
723 self.setScrollBarsEnabled(True)
724
725 self.widgets = []
726
727 def loadWidget(self, uiFileName):
728 """
729 Public slot to load a UI file.
730
731 @param uiFileName name of the UI file to load (string)
732 """
733 widget = self.__findWidget(uiFileName)
734 if widget is None:
735 name = os.path.basename(uiFileName)
736 if not name:
737 QMessageBox.warning(None,
738 self.trUtf8("Load UI File"),
739 self.trUtf8("""<p>The file <b>{0}</b> could not be loaded.</p>""")\
740 .format(uiFileName))
741 return
742
743 uname = name
744 cnt = 1
745 while self.findChild(WidgetView, uname) is not None:
746 cnt += 1
747 uname = "{0} <{1}>".format(name, cnt)
748 name = uname
749
750 wview = WidgetView(uiFileName, self, name)
751 wview.buildWidget()
752 if not wview.isValid():
753 del wview
754 return
755
756 self.connect(self, SIGNAL("rebuildWidgets"), wview.buildWidget)
757 wview.installEventFilter(self)
758
759 self.addWindow(wview)
760 self.widgets.append(wview)
761
762 wview.showNormal()
763
764 def eventFilter(self, obj, ev):
765 """
766 Protected method called to filter an event.
767
768 @param object object, that generated the event (QObject)
769 @param event the event, that was generated by object (QEvent)
770 @return flag indicating if event was filtered out
771 """
772 if not isinstance(obj, QWidget):
773 return False
774
775 if not obj in self.widgets:
776 return False
777
778 if ev.type() == QEvent.Close:
779 try:
780 self.widgets.remove(obj)
781 if len(self.widgets) == 0:
782 self.emit(SIGNAL('lastWidgetClosed'))
783 except ValueError:
784 pass
785
786 return False
787
788 def __findWidget(self, uiFileName):
789 """
790 Private method to find a specific widget view.
791
792 @param uiFileName filename of the loaded UI file (string)
793 @return reference to the widget (WidgetView) or None
794 """
795 wviewList = self.findChildren(WidgetView)
796 if wviewList is None:
797 return None
798
799 for wview in wviewList:
800 if wview.uiFileName() == uiFileName:
801 return wview
802
803 return None
804
805 def closeWidget(self):
806 """
807 Public slot to close the active window.
808 """
809 aw = self.activeWindow()
810 if aw is not None:
811 aw.close()
812
813 def closeAllWidgets(self):
814 """
815 Public slot to close all windows.
816 """
817 for w in self.widgets[:]:
818 w.close()
819
820 def showWindowMenu(self, windowMenu):
821 """
822 Public method to set up the widgets part of the Window menu.
823
824 @param windowMenu reference to the window menu
825 """
826 idx = 0
827 for wid in self.widgets:
828 act = windowMenu.addAction(wid.windowTitle())
829 act.setData(QVariant(idx))
830 act.setCheckable(True)
831 act.setChecked(not wid.isHidden())
832 idx = idx + 1
833
834 def toggleSelectedWidget(self, act):
835 """
836 Public method to handle the toggle of a window.
837
838 @param act reference to the action that triggered (QAction)
839 """
840 idx, ok = act.data().toInt()
841 if ok:
842 self.__toggleWidget(self.widgets[idx])
843
844 def __toggleWidget(self, w):
845 """
846 Private method to toggle a workspace window.
847
848 @param w window to be toggled
849 """
850 if w.isHidden():
851 w.show()
852 else:
853 w.hide()
854
855 def hasWidgets(self):
856 """
857 Public method to check for loaded widgets.
858
859 @return flag signaling if any widget was loaded (boolean)
860 """
861 return len(self.widgets) > 0

eric ide

mercurial