Tools/UIPreviewer.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 UI Previewer main window.
8 """
9
10 import sys
11
12 from PyQt4.QtCore import *
13 from PyQt4.QtGui import *
14 from PyQt4 import uic
15
16 import Preferences
17 import UI.PixmapCache
18 import UI.Config
19
20
21 class UIPreviewer(QMainWindow):
22 """
23 Class implementing the UI Previewer main window.
24 """
25 def __init__(self, filename = None, parent = None, name = None):
26 """
27 Constructor
28
29 @param filename name of a UI file to load
30 @param parent parent widget of this window (QWidget)
31 @param name name of this window (string)
32 """
33 self.mainWidget = None
34 self.currentFile = QDir.currentPath()
35
36 QMainWindow.__init__(self, parent)
37 if not name:
38 self.setObjectName("UIPreviewer")
39 else:
40 self.setObjectName(name)
41 self.resize(QSize(600, 480).expandedTo(self.minimumSizeHint()))
42 self.setAttribute(Qt.WA_DeleteOnClose)
43 self.statusBar()
44
45 self.setWindowIcon(UI.PixmapCache.getIcon("eric.png"))
46 self.setWindowTitle(self.trUtf8("UI Previewer"))
47
48 self.cw = QWidget(self)
49 self.cw.setObjectName("centralWidget")
50
51 self.UIPreviewerLayout = QVBoxLayout(self.cw)
52 self.UIPreviewerLayout.setMargin(6)
53 self.UIPreviewerLayout.setSpacing(6)
54 self.UIPreviewerLayout.setObjectName("UIPreviewerLayout")
55
56 self.styleLayout = QHBoxLayout()
57 self.styleLayout.setMargin(0)
58 self.styleLayout.setSpacing(6)
59 self.styleLayout.setObjectName("styleLayout")
60
61 self.styleLabel = QLabel(self.trUtf8("Select GUI Theme"), self.cw)
62 self.styleLabel.setObjectName("styleLabel")
63 self.styleLayout.addWidget(self.styleLabel)
64
65 self.styleCombo = QComboBox(self.cw)
66 self.styleCombo.setObjectName("styleCombo")
67 self.styleCombo.setEditable(False)
68 self.styleCombo.setToolTip(self.trUtf8("Select the GUI Theme"))
69 self.styleLayout.addWidget(self.styleCombo)
70 self.styleCombo.addItems(QStyleFactory().keys())
71 self.styleCombo.setCurrentIndex(\
72 Preferences.Prefs.settings.value('UIPreviewer/style').toInt()[0])
73
74 styleSpacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
75 self.styleLayout.addItem(styleSpacer)
76 self.UIPreviewerLayout.addLayout(self.styleLayout)
77
78 self.previewSV = QScrollArea(self.cw)
79 self.previewSV.setObjectName("preview")
80 self.previewSV.setFrameShape(QFrame.NoFrame)
81 self.previewSV.setFrameShadow(QFrame.Plain)
82 self.previewSV.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
83 self.UIPreviewerLayout.addWidget(self.previewSV)
84
85 self.setCentralWidget(self.cw)
86
87 self.connect(self.styleCombo,SIGNAL("activated(const QString&)"),
88 self.__guiStyleSelected)
89
90 self.__initActions()
91 self.__initMenus()
92 self.__initToolbars()
93
94 self.__updateActions()
95
96 # defere loading of a UI file until we are shown
97 self.fileToLoad = filename
98
99 def show(self):
100 """
101 Public slot to show this dialog.
102
103 This overloaded slot loads a UI file to be previewed after
104 the main window has been shown. This way, previewing a dialog
105 doesn't interfere with showing the main window.
106 """
107 QMainWindow.show(self)
108 if self.fileToLoad is not None:
109 fn, self.fileToLoad = (self.fileToLoad, None)
110 self.__loadFile(fn)
111
112 def __initActions(self):
113 """
114 Private method to define the user interface actions.
115 """
116 self.openAct = QAction(UI.PixmapCache.getIcon("openUI.png"),
117 self.trUtf8('&Open File'), self)
118 self.openAct.setShortcut(QKeySequence(self.trUtf8("Ctrl+O", "File|Open")))
119 self.openAct.setStatusTip(self.trUtf8('Open a UI file for display'))
120 self.openAct.setWhatsThis(self.trUtf8(
121 """<b>Open File</b>"""
122 """<p>This opens a new UI file for display.</p>"""
123 ))
124 self.connect(self.openAct, SIGNAL('triggered()'), self.__openFile)
125
126 self.printAct = QAction(UI.PixmapCache.getIcon("print.png"),
127 self.trUtf8('&Print'), self)
128 self.printAct.setShortcut(QKeySequence(self.trUtf8("Ctrl+P", "File|Print")))
129 self.printAct.setStatusTip(self.trUtf8('Print a screen capture'))
130 self.printAct.setWhatsThis(self.trUtf8(
131 """<b>Print</b>"""
132 """<p>Print a screen capture.</p>"""
133 ))
134 self.connect(self.printAct, SIGNAL('triggered()'), self.__printImage)
135
136 self.printPreviewAct = QAction(UI.PixmapCache.getIcon("printPreview.png"),
137 self.trUtf8('Print Preview'), self)
138 self.printPreviewAct.setStatusTip(self.trUtf8(
139 'Print preview a screen capture'))
140 self.printPreviewAct.setWhatsThis(self.trUtf8(
141 """<b>Print Preview</b>"""
142 """<p>Print preview a screen capture.</p>"""
143 ))
144 self.connect(self.printPreviewAct, SIGNAL('triggered()'),
145 self.__printPreviewImage)
146
147 self.imageAct = QAction(UI.PixmapCache.getIcon("screenCapture.png"),
148 self.trUtf8('&Screen Capture'), self)
149 self.imageAct.setShortcut(\
150 QKeySequence(self.trUtf8("Ctrl+S", "File|Screen Capture")))
151 self.imageAct.setStatusTip(self.trUtf8('Save a screen capture to an image file'))
152 self.imageAct.setWhatsThis(self.trUtf8(
153 """<b>Screen Capture</b>"""
154 """<p>Save a screen capture to an image file.</p>"""
155 ))
156 self.connect(self.imageAct, SIGNAL('triggered()'), self.__saveImage)
157
158 self.exitAct = QAction(UI.PixmapCache.getIcon("exit.png"),
159 self.trUtf8('&Quit'), self)
160 self.exitAct.setShortcut(QKeySequence(self.trUtf8("Ctrl+Q", "File|Quit")))
161 self.exitAct.setStatusTip(self.trUtf8('Quit the application'))
162 self.exitAct.setWhatsThis(self.trUtf8(
163 """<b>Quit</b>"""
164 """<p>Quit the application.</p>"""
165 ))
166 self.connect(self.exitAct, SIGNAL('triggered()'),
167 qApp, SLOT('closeAllWindows()'))
168
169 self.copyAct = QAction(UI.PixmapCache.getIcon("editCopy.png"),
170 self.trUtf8('&Copy'), self)
171 self.copyAct.setShortcut(QKeySequence(self.trUtf8("Ctrl+C", "Edit|Copy")))
172 self.copyAct.setStatusTip(self.trUtf8('Copy screen capture to clipboard'))
173 self.copyAct.setWhatsThis(self.trUtf8(
174 """<b>Copy</b>"""
175 """<p>Copy screen capture to clipboard.</p>"""
176 ))
177 self.connect(self.copyAct,SIGNAL('triggered()'),self.__copyImageToClipboard)
178
179 self.whatsThisAct = QAction(UI.PixmapCache.getIcon("whatsThis.png"),
180 self.trUtf8('&What\'s This?'), self)
181 self.whatsThisAct.setShortcut(QKeySequence(self.trUtf8("Shift+F1")))
182 self.whatsThisAct.setStatusTip(self.trUtf8('Context sensitive help'))
183 self.whatsThisAct.setWhatsThis(self.trUtf8(
184 """<b>Display context sensitive help</b>"""
185 """<p>In What's This? mode, the mouse cursor shows an arrow with a"""
186 """ question mark, and you can click on the interface elements to get"""
187 """ a short description of what they do and how to use them. In"""
188 """ dialogs, this feature can be accessed using the context help"""
189 """ button in the titlebar.</p>"""
190 ))
191 self.connect(self.whatsThisAct,SIGNAL('triggered()'),self.__whatsThis)
192
193 self.aboutAct = QAction(self.trUtf8('&About'), self)
194 self.aboutAct.setStatusTip(self.trUtf8('Display information about this software'))
195 self.aboutAct.setWhatsThis(self.trUtf8(
196 """<b>About</b>"""
197 """<p>Display some information about this software.</p>"""
198 ))
199 self.connect(self.aboutAct,SIGNAL('triggered()'),self.__about)
200
201 self.aboutQtAct = QAction(self.trUtf8('About &Qt'), self)
202 self.aboutQtAct.setStatusTip(\
203 self.trUtf8('Display information about the Qt toolkit'))
204 self.aboutQtAct.setWhatsThis(self.trUtf8(
205 """<b>About Qt</b>"""
206 """<p>Display some information about the Qt toolkit.</p>"""
207 ))
208 self.connect(self.aboutQtAct,SIGNAL('triggered()'),self.__aboutQt)
209
210 def __initMenus(self):
211 """
212 Private method to create the menus.
213 """
214 mb = self.menuBar()
215
216 menu = mb.addMenu(self.trUtf8('&File'))
217 menu.setTearOffEnabled(True)
218 menu.addAction(self.openAct)
219 menu.addAction(self.imageAct)
220 menu.addSeparator()
221 menu.addAction(self.printPreviewAct)
222 menu.addAction(self.printAct)
223 menu.addSeparator()
224 menu.addAction(self.exitAct)
225
226 menu = mb.addMenu(self.trUtf8("&Edit"))
227 menu.setTearOffEnabled(True)
228 menu.addAction(self.copyAct)
229
230 mb.addSeparator()
231
232 menu = mb.addMenu(self.trUtf8('&Help'))
233 menu.setTearOffEnabled(True)
234 menu.addAction(self.aboutAct)
235 menu.addAction(self.aboutQtAct)
236 menu.addSeparator()
237 menu.addAction(self.whatsThisAct)
238
239 def __initToolbars(self):
240 """
241 Private method to create the toolbars.
242 """
243 filetb = self.addToolBar(self.trUtf8("File"))
244 filetb.setIconSize(UI.Config.ToolBarIconSize)
245 filetb.addAction(self.openAct)
246 filetb.addAction(self.imageAct)
247 filetb.addSeparator()
248 filetb.addAction(self.printPreviewAct)
249 filetb.addAction(self.printAct)
250 filetb.addSeparator()
251 filetb.addAction(self.exitAct)
252
253 edittb = self.addToolBar(self.trUtf8("Edit"))
254 edittb.setIconSize(UI.Config.ToolBarIconSize)
255 edittb.addAction(self.copyAct)
256
257 helptb = self.addToolBar(self.trUtf8("Help"))
258 helptb.setIconSize(UI.Config.ToolBarIconSize)
259 helptb.addAction(self.whatsThisAct)
260
261 def __whatsThis(self):
262 """
263 Private slot called in to enter Whats This mode.
264 """
265 QWhatsThis.enterWhatsThisMode()
266
267 def __guiStyleSelected(self, selectedStyle):
268 """
269 Private slot to handle the selection of a GUI style.
270
271 @param selectedStyle name of the selected style (string)
272 """
273 if self.mainWidget:
274 self.__updateChildren(selectedStyle)
275
276 def __about(self):
277 """
278 Private slot to show the about information.
279 """
280 QMessageBox.about(self, self.trUtf8("UI Previewer"), self.trUtf8(
281 """<h3> About UI Previewer </h3>"""
282 """<p>The UI Previewer loads and displays Qt User-Interface files"""
283 """ with various styles, which are selectable via a selection list.</p>"""
284 ))
285
286 def __aboutQt(self):
287 """
288 Private slot to show info about Qt.
289 """
290 QMessageBox.aboutQt(self, self.trUtf8("UI Previewer"))
291
292 def __openFile(self):
293 """
294 Private slot to load a new file.
295 """
296 fn = QFileDialog.getOpenFileName(
297 self,
298 self.trUtf8("Select UI file"),
299 self.currentFile,
300 self.trUtf8("Qt User-Interface Files (*.ui)"))
301 if fn:
302 self.__loadFile(fn)
303
304 def __loadFile(self, fn):
305 """
306 Private slot to load a ui file.
307
308 @param fn name of the ui file to be laoded (string)
309 """
310 if self.mainWidget:
311 self.mainWidget.close()
312 self.previewSV.takeWidget()
313 del self.mainWidget
314 self.mainWidget = None
315
316 # load the file
317 try:
318 self.mainWidget = uic.loadUi(fn)
319 except:
320 pass
321
322 if self.mainWidget:
323 self.currentFile = fn
324 self.__updateChildren(self.styleCombo.currentText())
325 if isinstance(self.mainWidget, QDialog) or \
326 isinstance(self.mainWidget, QMainWindow):
327 self.mainWidget.show()
328 self.mainWidget.installEventFilter(self)
329 else:
330 self.previewSV.setWidget(self.mainWidget)
331 self.mainWidget.show()
332 else:
333 QMessageBox.warning(self,
334 self.trUtf8("Load UI File"),
335 self.trUtf8("""<p>The file <b>{0}</b> could not be loaded.</p>""")\
336 .format(fn))
337 self.__updateActions()
338
339 def __updateChildren(self, sstyle):
340 """
341 Private slot to change the style of the show UI.
342
343 @param sstyle name of the selected style (string)
344 """
345 QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
346 qstyle = QStyleFactory.create(sstyle)
347 self.mainWidget.setStyle(qstyle)
348
349 lst = self.mainWidget.findChildren(QWidget)
350 for obj in lst:
351 try:
352 obj.setStyle(qstyle)
353 except AttributeError:
354 pass
355 del lst
356
357 self.mainWidget.hide()
358 self.mainWidget.show()
359
360 self.lastQStyle = qstyle
361 self.lastStyle = sstyle
362 Preferences.Prefs.settings.setValue('UIPreviewer/style',
363 QVariant(self.styleCombo.currentIndex()))
364 QApplication.restoreOverrideCursor()
365
366 def __updateActions(self):
367 """
368 Private slot to update the actions state.
369 """
370 if self.mainWidget:
371 self.imageAct.setEnabled(True)
372 self.printAct.setEnabled(True)
373 if self.printPreviewAct:
374 self.printPreviewAct.setEnabled(True)
375 self.copyAct.setEnabled(True)
376 self.styleCombo.setEnabled(True)
377 else:
378 self.imageAct.setEnabled(False)
379 self.printAct.setEnabled(False)
380 if self.printPreviewAct:
381 self.printPreviewAct.setEnabled(False)
382 self.copyAct.setEnabled(False)
383 self.styleCombo.setEnabled(False)
384
385 def __handleCloseEvent(self):
386 """
387 Private slot to handle the close event of a viewed QMainWidget.
388 """
389 if self.mainWidget:
390 self.mainWidget.removeEventFilter(self)
391 del self.mainWidget
392 self.mainWidget = None
393 self.__updateActions()
394
395 def eventFilter(self, obj, ev):
396 """
397 Protected method called to filter an event.
398
399 @param object object, that generated the event (QObject)
400 @param event the event, that was generated by object (QEvent)
401 @return flag indicating if event was filtered out
402 """
403 if obj == self.mainWidget:
404 if ev.type() == QEvent.Close:
405 self.__handleCloseEvent()
406 return True
407 else:
408 if isinstance(self.mainWidget, QDialog):
409 return QDialog.eventFilter(self, obj, ev)
410 elif isinstance(self.mainWidget, QMainWindow):
411 return QMainWindow.eventFilter(self, obj, ev)
412 else:
413 return False
414
415 def __saveImage(self):
416 """
417 Private slot to handle the Save Image menu action.
418 """
419 if self.mainWidget is None:
420 QMessageBox.critical(self,
421 self.trUtf8("Save Image"),
422 self.trUtf8("""There is no UI file loaded."""))
423 return
424
425 defaultExt = "PNG"
426 filters = ""
427 formats = QImageWriter.supportedImageFormats()
428 for format in formats:
429 filters = "%s*.%s " % (filters, unicode(format).lower())
430 filter = self.trUtf8("Images ({0})").format(filters[:-1])
431
432 fname = QFileDialog.getSaveFileName(\
433 self,
434 self.trUtf8("Save Image"),
435 "",
436 filter)
437 if not fname:
438 return
439
440 ext = QFileInfo(fname).suffix().upper()
441 if not ext:
442 ext = defaultExt
443 fname.append(".%s" % defaultExt.lower())
444
445 pix = QPixmap.grabWidget(self.mainWidget)
446 self.__updateChildren(self.lastStyle)
447 if not pix.save(fname, str(ext)):
448 QMessageBox.critical(None,
449 self.trUtf8("Save Image"),
450 self.trUtf8("""<p>The file <b>{0}</b> could not be saved.</p>""")
451 .format(fname))
452
453 def __copyImageToClipboard(self):
454 """
455 Private slot to handle the Copy Image menu action.
456 """
457 if self.mainWidget is None:
458 QMessageBox.critical(None,
459 self.trUtf8("Save Image"),
460 self.trUtf8("""There is no UI file loaded."""))
461 return
462
463 cb = QApplication.clipboard()
464 cb.setPixmap(QPixmap.grabWidget(self.mainWidget))
465 self.__updateChildren(self.lastStyle)
466
467 def __printImage(self):
468 """
469 Private slot to handle the Print Image menu action.
470 """
471 if self.mainWidget is None:
472 QMessageBox.critical(None,
473 self.trUtf8("Print Image"),
474 self.trUtf8("""There is no UI file loaded."""))
475 return
476
477 settings = Preferences.Prefs.settings
478 printer = QPrinter(QPrinter.HighResolution)
479 printer.setFullPage(True)
480
481 printer.setPrinterName(settings.value("UIPreviewer/printername").toString())
482 printer.setPageSize(
483 QPrinter.PageSize(settings.value("UIPreviewer/pagesize").toInt()[0]))
484 printer.setPageOrder(
485 QPrinter.PageOrder(settings.value("UIPreviewer/pageorder").toInt()[0]))
486 printer.setOrientation(
487 QPrinter.Orientation(settings.value("UIPreviewer/orientation").toInt()[0]))
488 printer.setColorMode(
489 QPrinter.ColorMode(settings.value("UIPreviewer/colormode").toInt()[0]))
490
491 printDialog = QPrintDialog(printer, self)
492 if printDialog.exec_() == QDialog.Accepted:
493 self.statusBar().showMessage(self.trUtf8("Printing the image..."))
494 self.__print(printer)
495
496 settings.setValue("UIPreviewer/printername",
497 QVariant(printer.printerName()))
498 settings.setValue("UIPreviewer/pagesize", QVariant(printer.pageSize()))
499 settings.setValue("UIPreviewer/pageorder", QVariant(printer.pageOrder()))
500 settings.setValue("UIPreviewer/orientation",
501 QVariant(printer.orientation()))
502 settings.setValue("UIPreviewer/colormode", QVariant(printer.colorMode()))
503
504 self.statusBar().showMessage(self.trUtf8("Image sent to printer..."), 2000)
505
506 def __printPreviewImage(self):
507 """
508 Private slot to handle the Print Preview menu action.
509 """
510 from PyQt4.QtGui import QPrintPreviewDialog
511
512 if self.mainWidget is None:
513 QMessageBox.critical(None,
514 self.trUtf8("Print Preview"),
515 self.trUtf8("""There is no UI file loaded."""))
516 return
517
518 settings = Preferences.Prefs.settings
519 printer = QPrinter(QPrinter.HighResolution)
520 printer.setFullPage(True)
521
522 printer.setPrinterName(settings.value("UIPreviewer/printername").toString())
523 printer.setPageSize(
524 QPrinter.PageSize(settings.value("UIPreviewer/pagesize").toInt()[0]))
525 printer.setPageOrder(
526 QPrinter.PageOrder(settings.value("UIPreviewer/pageorder").toInt()[0]))
527 printer.setOrientation(
528 QPrinter.Orientation(settings.value("UIPreviewer/orientation").toInt()[0]))
529 printer.setColorMode(
530 QPrinter.ColorMode(settings.value("UIPreviewer/colormode").toInt()[0]))
531
532 preview = QPrintPreviewDialog(printer, self)
533 self.connect(preview, SIGNAL("paintRequested(QPrinter*)"), self.__print)
534 preview.exec_()
535
536 def __print(self, printer):
537 """
538 Private slot to the actual printing.
539
540 @param printer reference to the printer object (QPrinter)
541 """
542 p = QPainter(printer)
543 marginX = (printer.pageRect().x() - printer.paperRect().x()) / 2
544 marginY = (printer.pageRect().y() - printer.paperRect().y()) / 2
545
546 # double the margin on bottom of page
547 if printer.orientation() == QPrinter.Portrait:
548 width = printer.width() - marginX * 2
549 height = printer.height() - marginY * 3
550 else:
551 marginX *= 2
552 width = printer.width() - marginX * 2
553 height = printer.height() - marginY * 2
554 img = QPixmap.grabWidget(self.mainWidget).toImage()
555 self.__updateChildren(self.lastStyle)
556 p.drawImage(marginX, marginY,
557 img.scaled(width, height,
558 Qt.KeepAspectRatio, Qt.SmoothTransformation))
559 p.end()

eric ide

mercurial