Snapshot/SnapWidget.py

changeset 6926
519145f2ba79
parent 6913
be170600edcd
parent 6921
4783b00711d5
equal deleted inserted replaced
6922:b5d830bdea12 6926:519145f2ba79
14 # 14 #
15 15
16 import os 16 import os
17 17
18 from PyQt5.QtCore import pyqtSlot, QFile, QFileInfo, QTimer, QPoint, \ 18 from PyQt5.QtCore import pyqtSlot, QFile, QFileInfo, QTimer, QPoint, \
19 QMimeData, Qt, QEvent, QRegExp, QLocale, PYQT_VERSION_STR 19 QMimeData, Qt, QRegExp, QLocale, PYQT_VERSION_STR
20 from PyQt5.QtGui import QImageWriter, QPixmap, QCursor, QDrag, QKeySequence 20 from PyQt5.QtGui import QImageWriter, QPixmap, QDrag, QKeySequence
21 from PyQt5.QtWidgets import QWidget, QApplication, QShortcut 21 from PyQt5.QtWidgets import QWidget, QApplication, QShortcut
22 22
23 from E5Gui import E5FileDialog, E5MessageBox 23 from E5Gui import E5FileDialog, E5MessageBox
24 24
25 from .Ui_SnapWidget import Ui_SnapWidget 25 from .Ui_SnapWidget import Ui_SnapWidget
26 26
27 import UI.PixmapCache 27 import UI.PixmapCache
28 import Preferences 28 import Preferences
29 import Globals 29 import Globals
30 from Globals import qVersionTuple 30
31 from .SnapshotModes import SnapshotModes
31 32
32 33
33 class SnapWidget(QWidget, Ui_SnapWidget): 34 class SnapWidget(QWidget, Ui_SnapWidget):
34 """ 35 """
35 Class implementing the snapshot widget. 36 Class implementing the snapshot widget.
36 """ 37 """
37 ModeFullscreen = 0
38 ModeScreen = 1
39 ModeRectangle = 2
40 ModeFreehand = 3
41 ModeEllipse = 4
42
43 def __init__(self, parent=None): 38 def __init__(self, parent=None):
44 """ 39 """
45 Constructor 40 Constructor
46 41
47 @param parent reference to the parent widget (QWidget) 42 @param parent reference to the parent widget (QWidget)
53 self.takeButton.setIcon(UI.PixmapCache.getIcon("cameraPhoto.png")) 48 self.takeButton.setIcon(UI.PixmapCache.getIcon("cameraPhoto.png"))
54 self.copyButton.setIcon(UI.PixmapCache.getIcon("editCopy.png")) 49 self.copyButton.setIcon(UI.PixmapCache.getIcon("editCopy.png"))
55 self.copyPreviewButton.setIcon(UI.PixmapCache.getIcon("editCopy.png")) 50 self.copyPreviewButton.setIcon(UI.PixmapCache.getIcon("editCopy.png"))
56 self.setWindowIcon(UI.PixmapCache.getIcon("ericSnap.png")) 51 self.setWindowIcon(UI.PixmapCache.getIcon("ericSnap.png"))
57 52
58 self.modeCombo.addItem(self.tr("Fullscreen"), 53 if Globals.isWaylandSession():
59 SnapWidget.ModeFullscreen) 54 from .SnapshotWaylandGrabber import SnapshotWaylandGrabber
60 if qVersionTuple() >= (5, 10, 0): 55 self.__grabber = SnapshotWaylandGrabber(self)
61 if len(QApplication.screens()) > 1:
62 self.modeCombo.addItem(self.tr("Select Screen"),
63 SnapWidget.ModeScreen)
64 else: 56 else:
65 if QApplication.desktop().screenCount() > 1: 57 from .SnapshotDefaultGrabber import SnapshotDefaultGrabber
66 self.modeCombo.addItem(self.tr("Select Screen"), 58 self.__grabber = SnapshotDefaultGrabber(self)
67 SnapWidget.ModeScreen) 59 self.decorationsCheckBox.hide()
68 self.modeCombo.addItem(self.tr("Rectangular Selection"), 60 self.mouseCursorCheckBox.hide()
69 SnapWidget.ModeRectangle) 61 self.__grabber.grabbed.connect(self.__captured)
70 self.modeCombo.addItem(self.tr("Elliptical Selection"), 62 supportedModes = self.__grabber.supportedModes()
71 SnapWidget.ModeEllipse) 63
72 self.modeCombo.addItem(self.tr("Freehand Selection"), 64 if SnapshotModes.Fullscreen in supportedModes:
73 SnapWidget.ModeFreehand) 65 self.modeCombo.addItem(self.tr("Fullscreen"),
74 self.__mode = int(Preferences.Prefs.settings.value("Snapshot/Mode", 0)) 66 SnapshotModes.Fullscreen)
75 index = self.modeCombo.findData(self.__mode) 67 if SnapshotModes.SelectedScreen in supportedModes:
68 if Globals.qVersionTuple() >= (5, 10, 0):
69 if len(QApplication.screens()) > 1:
70 self.modeCombo.addItem(self.tr("Select Screen"),
71 SnapshotModes.SelectedScreen)
72 else:
73 if QApplication.desktop().screenCount() > 1:
74 self.modeCombo.addItem(self.tr("Select Screen"),
75 SnapshotModes.SelectedScreen)
76 if SnapshotModes.SelectedWindow in supportedModes:
77 self.modeCombo.addItem(self.tr("Select Window"),
78 SnapshotModes.SelectedWindow)
79 if SnapshotModes.Rectangle in supportedModes:
80 self.modeCombo.addItem(self.tr("Rectangular Selection"),
81 SnapshotModes.Rectangle)
82 if SnapshotModes.Ellipse in supportedModes:
83 self.modeCombo.addItem(self.tr("Elliptical Selection"),
84 SnapshotModes.Ellipse)
85 if SnapshotModes.Freehand in supportedModes:
86 self.modeCombo.addItem(self.tr("Freehand Selection"),
87 SnapshotModes.Freehand)
88 mode = int(Preferences.Prefs.settings.value("Snapshot/Mode", 0))
89 index = self.modeCombo.findData(SnapshotModes(mode))
76 if index == -1: 90 if index == -1:
77 index = 0 91 index = 0
78 self.modeCombo.setCurrentIndex(index) 92 self.modeCombo.setCurrentIndex(index)
79 93
80 self.__delay = int( 94 delay = int(Preferences.Prefs.settings.value("Snapshot/Delay", 0))
81 Preferences.Prefs.settings.value("Snapshot/Delay", 0)) 95 self.delaySpin.setValue(delay)
82 self.delaySpin.setValue(self.__delay)
83 96
84 if PYQT_VERSION_STR >= "5.0.0": 97 if PYQT_VERSION_STR >= "5.0.0":
85 from PyQt5.QtCore import QStandardPaths 98 from PyQt5.QtCore import QStandardPaths
86 picturesLocation = QStandardPaths.writableLocation( 99 picturesLocation = QStandardPaths.writableLocation(
87 QStandardPaths.PicturesLocation) 100 QStandardPaths.PicturesLocation)
92 self.__filename = Preferences.Prefs.settings.value( 105 self.__filename = Preferences.Prefs.settings.value(
93 "Snapshot/Filename", 106 "Snapshot/Filename",
94 os.path.join(picturesLocation, 107 os.path.join(picturesLocation,
95 self.tr("snapshot") + "1.png")) 108 self.tr("snapshot") + "1.png"))
96 109
97 self.__grabber = None
98 self.__snapshot = QPixmap() 110 self.__snapshot = QPixmap()
99 self.__savedPosition = QPoint() 111 self.__savedPosition = QPoint()
100 self.__modified = False 112 self.__modified = False
101 self.__locale = QLocale() 113 self.__locale = QLocale()
102 114
103 self.__grabberWidget = QWidget(None, Qt.X11BypassWindowManagerHint)
104 self.__grabberWidget.move(-10000, -10000)
105 self.__grabberWidget.installEventFilter(self)
106
107 self.__initFileFilters() 115 self.__initFileFilters()
108
109 self.__initShortcuts() 116 self.__initShortcuts()
110 117
111 self.preview.startDrag.connect(self.__dragSnapshot) 118 self.preview.startDrag.connect(self.__dragSnapshot)
112 119
113 from .SnapshotTimer import SnapshotTimer
114 self.__grabTimer = SnapshotTimer()
115 self.__grabTimer.timeout.connect(self.__grabTimerTimeout)
116 self.__updateTimer = QTimer() 120 self.__updateTimer = QTimer()
117 self.__updateTimer.setSingleShot(True) 121 self.__updateTimer.setSingleShot(True)
118 self.__updateTimer.timeout.connect(self.__updatePreview) 122 self.__updateTimer.timeout.connect(self.__updatePreview)
119 123
120 self.__updateCaption() 124 self.__updateCaption()
299 @pyqtSlot() 303 @pyqtSlot()
300 def on_takeButton_clicked(self): 304 def on_takeButton_clicked(self):
301 """ 305 """
302 Private slot to take a snapshot. 306 Private slot to take a snapshot.
303 """ 307 """
304 self.__mode = self.modeCombo.itemData(self.modeCombo.currentIndex())
305 self.__delay = self.delaySpin.value()
306
307 self.__savedPosition = self.pos() 308 self.__savedPosition = self.pos()
308 self.hide() 309 self.hide()
309 310
310 if self.__delay: 311 self.__grabber.grab(
311 self.__grabTimer.start(self.__delay) 312 self.modeCombo.itemData(self.modeCombo.currentIndex()),
312 else: 313 self.delaySpin.value(),
313 QTimer.singleShot(200, self.__startUndelayedGrab) 314 self.mouseCursorCheckBox.isChecked(),
314 315 self.decorationsCheckBox.isChecked(),
315 def __grabTimerTimeout(self): 316 )
316 """
317 Private slot to perform a delayed grab operation.
318 """
319 if self.__mode == SnapWidget.ModeRectangle:
320 self.__grabRectangle()
321 elif self.__mode == SnapWidget.ModeEllipse:
322 self.__grabEllipse()
323 elif self.__mode == SnapWidget.ModeFreehand:
324 self.__grabFreehand()
325 else:
326 self.__performGrab()
327
328 def __startUndelayedGrab(self):
329 """
330 Private slot to perform an undelayed grab operation.
331 """
332 if self.__mode == SnapWidget.ModeRectangle:
333 self.__grabRectangle()
334 elif self.__mode == SnapWidget.ModeEllipse:
335 self.__grabEllipse()
336 elif self.__mode == SnapWidget.ModeFreehand:
337 self.__grabFreehand()
338 else:
339 if Globals.isMacPlatform():
340 self.__performGrab()
341 else:
342 self.__grabberWidget.show()
343 self.__grabberWidget.grabMouse(Qt.CrossCursor)
344
345 def __grabRectangle(self):
346 """
347 Private method to grab a rectangular screen region.
348 """
349 from .SnapshotRegionGrabber import SnapshotRegionGrabber
350 self.__grabber = SnapshotRegionGrabber(
351 mode=SnapshotRegionGrabber.Rectangle)
352 self.__grabber.grabbed.connect(self.__captured)
353
354 def __grabEllipse(self):
355 """
356 Private method to grab an elliptical screen region.
357 """
358 from .SnapshotRegionGrabber import SnapshotRegionGrabber
359 self.__grabber = SnapshotRegionGrabber(
360 mode=SnapshotRegionGrabber.Ellipse)
361 self.__grabber.grabbed.connect(self.__captured)
362
363 def __grabFreehand(self):
364 """
365 Private method to grab a non-rectangular screen region.
366 """
367 from .SnapshotFreehandGrabber import SnapshotFreehandGrabber
368 self.__grabber = SnapshotFreehandGrabber()
369 self.__grabber.grabbed.connect(self.__captured)
370
371 def __performGrab(self):
372 """
373 Private method to perform a screen grab other than a selected region.
374 """
375 self.__grabberWidget.releaseMouse()
376 self.__grabberWidget.hide()
377 self.__grabTimer.stop()
378
379 if self.__mode == SnapWidget.ModeFullscreen:
380 desktop = QApplication.desktop()
381 if qVersionTuple() >= (5, 0, 0):
382 self.__snapshot = QApplication.screens()[0].grabWindow(
383 desktop.winId(), desktop.x(), desktop.y(),
384 desktop.width(), desktop.height())
385 else:
386 self.__snapshot = QPixmap.grabWindow(
387 desktop.winId(), desktop.x(), desktop.y(),
388 desktop.width(), desktop.height())
389 elif self.__mode == SnapWidget.ModeScreen:
390 desktop = QApplication.desktop()
391 if qVersionTuple() >= (5, 10, 0):
392 screen = QApplication.screenAt(QCursor.pos())
393 geom = screen.geometry()
394 else:
395 screenId = desktop.screenNumber(QCursor.pos())
396 geom = desktop.screenGeometry(screenId)
397 x = geom.x()
398 y = geom.y()
399 if qVersionTuple() >= (5, 0, 0):
400 self.__snapshot = QApplication.screens()[0].grabWindow(
401 desktop.winId(), x, y, geom.width(), geom.height())
402 else:
403 self.__snapshot = QPixmap.grabWindow(
404 desktop.winId(), x, y, geom.width(), geom.height())
405 else:
406 self.__snapshot = QPixmap()
407
408 self.__redisplay()
409 self.__modified = True
410 self.__updateCaption()
411 317
412 def __redisplay(self): 318 def __redisplay(self):
413 """ 319 """
414 Private method to redisplay the window. 320 Private method to redisplay the window.
415 """ 321 """
443 """ 349 """
444 Private slot to show a preview of the snapshot. 350 Private slot to show a preview of the snapshot.
445 351
446 @param pixmap pixmap of the snapshot (QPixmap) 352 @param pixmap pixmap of the snapshot (QPixmap)
447 """ 353 """
448 self.__grabber.close()
449 self.__snapshot = QPixmap(pixmap) 354 self.__snapshot = QPixmap(pixmap)
450 355
451 self.__grabber.grabbed.disconnect(self.__captured)
452 self.__grabber = None
453
454 self.__redisplay() 356 self.__redisplay()
455 self.__modified = True 357 self.__modified = not pixmap.isNull()
456 self.__updateCaption() 358 self.__updateCaption()
457 359
458 def __updatePreview(self): 360 def __updatePreview(self):
459 """ 361 """
460 Private slot to update the preview picture. 362 Private slot to update the preview picture.
483 mimeData = QMimeData() 385 mimeData = QMimeData()
484 mimeData.setImageData(self.__snapshot) 386 mimeData.setImageData(self.__snapshot)
485 drag.setMimeData(mimeData) 387 drag.setMimeData(mimeData)
486 drag.setPixmap(self.preview.pixmap()) 388 drag.setPixmap(self.preview.pixmap())
487 drag.exec_(Qt.CopyAction) 389 drag.exec_(Qt.CopyAction)
488
489 def eventFilter(self, obj, evt):
490 """
491 Public method to handle event for other objects.
492
493 @param obj reference to the object (QObject)
494 @param evt reference to the event (QEvent)
495 @return flag indicating that the event should be filtered out (boolean)
496 """
497 if obj == self.__grabberWidget and \
498 evt.type() == QEvent.MouseButtonPress:
499 if QWidget.mouseGrabber() != self.__grabberWidget:
500 return False
501 if evt.button() == Qt.LeftButton:
502 self.__performGrab()
503
504 return False
505 390
506 def closeEvent(self, evt): 391 def closeEvent(self, evt):
507 """ 392 """
508 Protected method handling the close event. 393 Protected method handling the close event.
509 394
525 elif res == E5MessageBox.Save: 410 elif res == E5MessageBox.Save:
526 self.on_saveButton_clicked() 411 self.on_saveButton_clicked()
527 412
528 Preferences.Prefs.settings.setValue( 413 Preferences.Prefs.settings.setValue(
529 "Snapshot/Delay", self.delaySpin.value()) 414 "Snapshot/Delay", self.delaySpin.value())
530 Preferences.Prefs.settings.setValue( 415 modeData = self.modeCombo.itemData(self.modeCombo.currentIndex())
531 "Snapshot/Mode", 416 if modeData is not None:
532 self.modeCombo.itemData(self.modeCombo.currentIndex())) 417 Preferences.Prefs.settings.setValue(
418 "Snapshot/Mode",
419 modeData.value)
533 Preferences.Prefs.settings.setValue( 420 Preferences.Prefs.settings.setValue(
534 "Snapshot/Filename", self.__filename) 421 "Snapshot/Filename", self.__filename)
535 Preferences.Prefs.settings.sync() 422 Preferences.Prefs.settings.sync()
536 423
537 def __updateCaption(self): 424 def __updateCaption(self):
541 self.setWindowTitle("{0}[*] - {1}".format( 428 self.setWindowTitle("{0}[*] - {1}".format(
542 os.path.basename(self.__filename), 429 os.path.basename(self.__filename),
543 self.tr("eric6 Snapshot"))) 430 self.tr("eric6 Snapshot")))
544 self.setWindowModified(self.__modified) 431 self.setWindowModified(self.__modified)
545 self.pathNameEdit.setText(os.path.dirname(self.__filename)) 432 self.pathNameEdit.setText(os.path.dirname(self.__filename))
433
434 @pyqtSlot(int)
435 def on_modeCombo_currentIndexChanged(self, index):
436 """
437 Private slot handling the selection of a screenshot mode.
438
439 @param index index of the selection
440 @type int
441 """
442 isWindowMode = False
443 if index >= 0:
444 mode = self.modeCombo.itemData(index)
445 isWindowMode = (mode == SnapshotModes.SelectedWindow)
446
447 self.decorationsCheckBox.setEnabled(isWindowMode)
448 self.decorationsCheckBox.setChecked(isWindowMode)

eric ide

mercurial