|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2004 - 2009 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing a dialog showing a pixmap. |
|
8 """ |
|
9 |
|
10 from PyQt4.QtCore import * |
|
11 from PyQt4.QtGui import * |
|
12 |
|
13 from ZoomDialog import ZoomDialog |
|
14 |
|
15 import UI.Config |
|
16 |
|
17 import Preferences |
|
18 |
|
19 class PixmapDiagram(QMainWindow): |
|
20 """ |
|
21 Class implementing a dialog showing a pixmap. |
|
22 """ |
|
23 def __init__(self, pixmap, parent = None, name = None): |
|
24 """ |
|
25 Constructor |
|
26 |
|
27 @param pixmap filename of a graphics file to show (string) |
|
28 @param parent parent widget of the view (QWidget) |
|
29 @param name name of the view widget (string) |
|
30 """ |
|
31 QMainWindow.__init__(self, parent) |
|
32 if name: |
|
33 self.setObjectName(name) |
|
34 else: |
|
35 self.setObjectName("PixmapDiagram") |
|
36 self.setWindowTitle(self.trUtf8("Pixmap-Viewer")) |
|
37 |
|
38 self.pixmapLabel = QLabel() |
|
39 self.pixmapLabel.setObjectName("pixmapLabel") |
|
40 self.pixmapLabel.setBackgroundRole(QPalette.Base) |
|
41 self.pixmapLabel.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) |
|
42 self.pixmapLabel.setScaledContents(True) |
|
43 |
|
44 self.pixmapView = QScrollArea() |
|
45 self.pixmapView.setObjectName("pixmapView") |
|
46 self.pixmapView.setBackgroundRole(QPalette.Dark) |
|
47 self.pixmapView.setWidget(self.pixmapLabel) |
|
48 |
|
49 self.setCentralWidget(self.pixmapView) |
|
50 |
|
51 # polish up the dialog |
|
52 self.resize(QSize(800, 600).expandedTo(self.minimumSizeHint())) |
|
53 |
|
54 self.zoom = 1.0 |
|
55 self.pixmapfile = pixmap |
|
56 self.status = self.__showPixmap(self.pixmapfile) |
|
57 |
|
58 self.__initActions() |
|
59 self.__initContextMenu() |
|
60 self.__initToolBars() |
|
61 |
|
62 def __initActions(self): |
|
63 """ |
|
64 Private method to initialize the view actions. |
|
65 """ |
|
66 self.closeAct = \ |
|
67 QAction(UI.PixmapCache.getIcon("close.png"), |
|
68 self.trUtf8("Close"), self) |
|
69 self.connect(self.closeAct, SIGNAL("triggered()"), self.close) |
|
70 |
|
71 self.printAct = \ |
|
72 QAction(UI.PixmapCache.getIcon("print.png"), |
|
73 self.trUtf8("Print"), self) |
|
74 self.connect(self.printAct, SIGNAL("triggered()"), self.__printDiagram) |
|
75 |
|
76 self.printPreviewAct = \ |
|
77 QAction(UI.PixmapCache.getIcon("printPreview.png"), |
|
78 self.trUtf8("Print Preview"), self) |
|
79 self.connect(self.printPreviewAct, SIGNAL("triggered()"), |
|
80 self.__printPreviewDiagram) |
|
81 |
|
82 self.zoomInAct = \ |
|
83 QAction(UI.PixmapCache.getIcon("zoomIn.png"), |
|
84 self.trUtf8("Zoom in"), self) |
|
85 self.connect(self.zoomInAct, SIGNAL("triggered()"), self.__zoomIn) |
|
86 |
|
87 self.zoomOutAct = \ |
|
88 QAction(UI.PixmapCache.getIcon("zoomOut.png"), |
|
89 self.trUtf8("Zoom out"), self) |
|
90 self.connect(self.zoomOutAct, SIGNAL("triggered()"), self.__zoomOut) |
|
91 |
|
92 self.zoomAct = \ |
|
93 QAction(UI.PixmapCache.getIcon("zoomTo.png"), |
|
94 self.trUtf8("Zoom..."), self) |
|
95 self.connect(self.zoomAct, SIGNAL("triggered()"), self.__zoom) |
|
96 |
|
97 self.zoomResetAct = \ |
|
98 QAction(UI.PixmapCache.getIcon("zoomReset.png"), |
|
99 self.trUtf8("Zoom reset"), self) |
|
100 self.connect(self.zoomResetAct, SIGNAL("triggered()"), self.__zoomReset) |
|
101 |
|
102 def __initContextMenu(self): |
|
103 """ |
|
104 Private method to initialize the context menu. |
|
105 """ |
|
106 self.__menu = QMenu(self) |
|
107 self.__menu.addAction(self.closeAct) |
|
108 self.__menu.addSeparator() |
|
109 self.__menu.addAction(self.printPreviewAct) |
|
110 self.__menu.addAction(self.printAct) |
|
111 self.__menu.addSeparator() |
|
112 self.__menu.addAction(self.zoomInAct) |
|
113 self.__menu.addAction(self.zoomOutAct) |
|
114 self.__menu.addAction(self.zoomAct) |
|
115 self.__menu.addAction(self.zoomResetAct) |
|
116 |
|
117 self.setContextMenuPolicy(Qt.CustomContextMenu) |
|
118 self.connect(self, SIGNAL('customContextMenuRequested(const QPoint &)'), |
|
119 self.__showContextMenu) |
|
120 |
|
121 def __showContextMenu(self, coord): |
|
122 """ |
|
123 Private slot to show the context menu of the listview. |
|
124 |
|
125 @param coord the position of the mouse pointer (QPoint) |
|
126 """ |
|
127 self.__menu.popup(self.mapToGlobal(coord)) |
|
128 |
|
129 def __initToolBars(self): |
|
130 """ |
|
131 Private method to populate the toolbars with our actions. |
|
132 """ |
|
133 self.windowToolBar = QToolBar(self.trUtf8("Window"), self) |
|
134 self.windowToolBar.setIconSize(UI.Config.ToolBarIconSize) |
|
135 self.windowToolBar.addAction(self.closeAct) |
|
136 |
|
137 self.graphicsToolBar = QToolBar(self.trUtf8("Graphics"), self) |
|
138 self.graphicsToolBar.setIconSize(UI.Config.ToolBarIconSize) |
|
139 self.graphicsToolBar.addAction(self.printPreviewAct) |
|
140 self.graphicsToolBar.addAction(self.printAct) |
|
141 self.graphicsToolBar.addSeparator() |
|
142 self.graphicsToolBar.addAction(self.zoomInAct) |
|
143 self.graphicsToolBar.addAction(self.zoomOutAct) |
|
144 self.graphicsToolBar.addAction(self.zoomAct) |
|
145 self.graphicsToolBar.addAction(self.zoomResetAct) |
|
146 |
|
147 self.addToolBar(Qt.TopToolBarArea, self.windowToolBar) |
|
148 self.addToolBar(Qt.TopToolBarArea, self.graphicsToolBar) |
|
149 |
|
150 def __showPixmap(self, filename): |
|
151 """ |
|
152 Private method to show a file. |
|
153 |
|
154 @param filename name of the file to be shown (string) |
|
155 @return flag indicating success (boolean) |
|
156 """ |
|
157 image = QImage(filename) |
|
158 if image.isNull(): |
|
159 QMessageBox.warning(self, |
|
160 self.trUtf8("Pixmap-Viewer"), |
|
161 self.trUtf8("""<p>The file <b>{0}</b> cannot be displayed.""" |
|
162 """ The format is not supported.</p>""").format(filename)) |
|
163 return False |
|
164 |
|
165 self.pixmapLabel.setPixmap(QPixmap.fromImage(image)) |
|
166 self.pixmapLabel.adjustSize() |
|
167 return True |
|
168 |
|
169 def getDiagramName(self): |
|
170 """ |
|
171 Method to retrieve a name for the diagram. |
|
172 |
|
173 @return name for the diagram |
|
174 """ |
|
175 return self.pixmapfile |
|
176 |
|
177 def getStatus(self): |
|
178 """ |
|
179 Method to retrieve the status of the canvas. |
|
180 |
|
181 @return flag indicating a successful pixmap loading (boolean) |
|
182 """ |
|
183 return self.status |
|
184 |
|
185 ############################################################################ |
|
186 ## Private menu handling methods below. |
|
187 ############################################################################ |
|
188 |
|
189 def __adjustScrollBar(self, scrollBar, factor): |
|
190 """ |
|
191 Private method to adjust a scrollbar by a certain factor. |
|
192 |
|
193 @param scrollBar reference to the scrollbar object (QScrollBar) |
|
194 @param factor factor to adjust by (float) |
|
195 """ |
|
196 scrollBar.setValue(int(factor * scrollBar.value() |
|
197 + ((factor - 1) * scrollBar.pageStep()/2))) |
|
198 |
|
199 def __doZoom(self, factor): |
|
200 """ |
|
201 Private method to perform the zooming. |
|
202 |
|
203 @param factor zoom factor (float) |
|
204 """ |
|
205 self.zoom *= factor |
|
206 self.pixmapLabel.resize(self.zoom * self.pixmapLabel.pixmap().size()) |
|
207 |
|
208 self.__adjustScrollBar(self.pixmapView.horizontalScrollBar(), factor) |
|
209 self.__adjustScrollBar(self.pixmapView.verticalScrollBar(), factor) |
|
210 |
|
211 def __zoomIn(self): |
|
212 """ |
|
213 Private method to handle the zoom in context menu entry. |
|
214 """ |
|
215 self.__doZoom(1.25) |
|
216 |
|
217 def __zoomOut(self): |
|
218 """ |
|
219 Private method to handle the zoom out context menu entry. |
|
220 """ |
|
221 self.__doZoom(0.8) |
|
222 |
|
223 def __zoomReset(self): |
|
224 """ |
|
225 Private method to handle the reset zoom context menu entry. |
|
226 """ |
|
227 self.zoom = 1.0 |
|
228 self.pixmapLabel.adjustSize() |
|
229 |
|
230 def __zoom(self): |
|
231 """ |
|
232 Private method to handle the zoom context menu action. |
|
233 """ |
|
234 dlg = ZoomDialog(self.zoom, self) |
|
235 if dlg.exec_() == QDialog.Accepted: |
|
236 zoom = dlg.getZoomSize() |
|
237 factor = zoom / self.zoom |
|
238 self.__doZoom(factor) |
|
239 |
|
240 def __printDiagram(self): |
|
241 """ |
|
242 Private slot called to print the diagram. |
|
243 """ |
|
244 printer = QPrinter(mode = QPrinter.ScreenResolution) |
|
245 printer.setFullPage(True) |
|
246 if Preferences.getPrinter("ColorMode"): |
|
247 printer.setColorMode(QPrinter.Color) |
|
248 else: |
|
249 printer.setColorMode(QPrinter.GrayScale) |
|
250 if Preferences.getPrinter("FirstPageFirst"): |
|
251 printer.setPageOrder(QPrinter.FirstPageFirst) |
|
252 else: |
|
253 printer.setPageOrder(QPrinter.LastPageFirst) |
|
254 printer.setPrinterName(Preferences.getPrinter("PrinterName")) |
|
255 |
|
256 printDialog = QPrintDialog(printer, self) |
|
257 if printDialog.exec_(): |
|
258 self.__print(printer) |
|
259 |
|
260 def __printPreviewDiagram(self): |
|
261 """ |
|
262 Private slot called to show a print preview of the diagram. |
|
263 """ |
|
264 from PyQt4.QtGui import QPrintPreviewDialog |
|
265 |
|
266 printer = QPrinter(mode = QPrinter.ScreenResolution) |
|
267 printer.setFullPage(True) |
|
268 if Preferences.getPrinter("ColorMode"): |
|
269 printer.setColorMode(QPrinter.Color) |
|
270 else: |
|
271 printer.setColorMode(QPrinter.GrayScale) |
|
272 if Preferences.getPrinter("FirstPageFirst"): |
|
273 printer.setPageOrder(QPrinter.FirstPageFirst) |
|
274 else: |
|
275 printer.setPageOrder(QPrinter.LastPageFirst) |
|
276 printer.setPrinterName(Preferences.getPrinter("PrinterName")) |
|
277 |
|
278 preview = QPrintPreviewDialog(printer, self) |
|
279 self.connect(preview, SIGNAL("paintRequested(QPrinter*)"), self.__print) |
|
280 preview.exec_() |
|
281 |
|
282 def __print(self, printer): |
|
283 """ |
|
284 Private slot to the actual printing. |
|
285 |
|
286 @param printer reference to the printer object (QPrinter) |
|
287 """ |
|
288 painter = QPainter() |
|
289 painter.begin(printer) |
|
290 |
|
291 # calculate margin and width of printout |
|
292 font = QFont("times", 10) |
|
293 painter.setFont(font) |
|
294 fm = painter.fontMetrics() |
|
295 fontHeight = fm.lineSpacing() |
|
296 marginX = printer.pageRect().x() - printer.paperRect().x() |
|
297 marginX = \ |
|
298 Preferences.getPrinter("LeftMargin") * int(printer.resolution() / 2.54) \ |
|
299 - marginX |
|
300 marginY = printer.pageRect().y() - printer.paperRect().y() |
|
301 marginY = \ |
|
302 Preferences.getPrinter("TopMargin") * int(printer.resolution() / 2.54) \ |
|
303 - marginY |
|
304 |
|
305 width = printer.width() - marginX \ |
|
306 - Preferences.getPrinter("RightMargin") * int(printer.resolution() / 2.54) |
|
307 height = printer.height() - fontHeight - 4 - marginY \ |
|
308 - Preferences.getPrinter("BottomMargin") * int(printer.resolution() / 2.54) |
|
309 |
|
310 # write a foot note |
|
311 s = self.trUtf8("Diagram: {0}").format(self.getDiagramName()) |
|
312 tc = QColor(50, 50, 50) |
|
313 painter.setPen(tc) |
|
314 painter.drawRect(marginX, marginY, width, height) |
|
315 painter.drawLine(marginX, marginY + height + 2, |
|
316 marginX + width, marginY + height + 2) |
|
317 painter.setFont(font) |
|
318 painter.drawText(marginX, marginY + height + 4, width, |
|
319 fontHeight, Qt.AlignRight, s) |
|
320 |
|
321 # render the diagram |
|
322 size = self.pixmapLabel.pixmap().size() |
|
323 size.scale(QSize(width - 10, height - 10), # 5 px inner margin |
|
324 Qt.KeepAspectRatio) |
|
325 painter.setViewport(marginX + 5, marginY + 5, size.width(), size.height()) |
|
326 painter.setWindow(self.pixmapLabel.pixmap().rect()) |
|
327 painter.drawPixmap(0, 0, self.pixmapLabel.pixmap()) |
|
328 painter.end() |