QScintilla/MarkupProviders/ImageMarkupDialog.py

changeset 5407
f833f89571b8
child 5412
db5a520f69d3
equal deleted inserted replaced
5406:8d09a23a8fdd 5407:f833f89571b8
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2017 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a dialog to enter data for an image markup.
8 """
9
10 from __future__ import unicode_literals
11
12 from PyQt5.QtCore import pyqtSlot, QSize
13 from PyQt5.QtGui import QImage, QImageReader
14 from PyQt5.QtWidgets import QDialog, QDialogButtonBox
15
16 from E5Gui.E5PathPicker import E5PathPickerModes
17
18 from .Ui_ImageMarkupDialog import Ui_ImageMarkupDialog
19
20
21 class ImageMarkupDialog(QDialog, Ui_ImageMarkupDialog):
22 """
23 Class implementing a dialog to enter data for an image markup.
24 """
25 HtmlMode = 0
26 MarkDownMode = 1
27 RestMode = 2
28
29 def __init__(self, mode, parent=None):
30 """
31 Constructor
32
33 @param parent reference to the parent widget
34 @type QWidget
35 """
36 super(ImageMarkupDialog, self).__init__(parent)
37 self.setupUi(self)
38
39 if mode == ImageMarkupDialog.MarkDownMode:
40 self.sizeCheckBox.setEnabled(False)
41 self.aspectRatioCheckBox.setEnabled(False)
42 self.widthSpinBox.setEnabled(False)
43 self.heightSpinBox.setEnabled(False)
44 elif mode == ImageMarkupDialog.RestMode:
45 self.titleEdit.setEnabled(False)
46
47 self.__mode = mode
48 self.__originalImageSize = QSize()
49
50 filters = {
51 'bmp': self.tr("Windows Bitmap File (*.bmp)"),
52 'cur': self.tr("Windows Cursor File (*.cur)"),
53 'dds': self.tr("DirectDraw-Surface File (*.dds)"),
54 'gif': self.tr("Graphic Interchange Format File (*.gif)"),
55 'icns': self.tr("Apple Icon File (*.icns)"),
56 'ico': self.tr("Windows Icon File (*.ico)"),
57 'jp2': self.tr("JPEG2000 File (*.jp2)"),
58 'jpg': self.tr("JPEG File (*.jpg)"),
59 'jpeg': self.tr("JPEG File (*.jpeg)"),
60 'mng': self.tr("Multiple-Image Network Graphics File (*.mng)"),
61 'pbm': self.tr("Portable Bitmap File (*.pbm)"),
62 'pcx': self.tr("Paintbrush Bitmap File (*.pcx)"),
63 'pgm': self.tr("Portable Graymap File (*.pgm)"),
64 'png': self.tr("Portable Network Graphics File (*.png)"),
65 'ppm': self.tr("Portable Pixmap File (*.ppm)"),
66 'sgi': self.tr("Silicon Graphics Image File (*.sgi)"),
67 'svg': self.tr("Scalable Vector Graphics File (*.svg)"),
68 'svgz': self.tr("Compressed Scalable Vector Graphics File"
69 " (*.svgz)"),
70 'tga': self.tr("Targa Graphic File (*.tga)"),
71 'tif': self.tr("TIFF File (*.tif)"),
72 'tiff': self.tr("TIFF File (*.tiff)"),
73 'wbmp': self.tr("WAP Bitmap File (*.wbmp)"),
74 'webp': self.tr("WebP Image File (*.webp)"),
75 'xbm': self.tr("X11 Bitmap File (*.xbm)"),
76 'xpm': self.tr("X11 Pixmap File (*.xpm)"),
77 }
78
79 inputFormats = []
80 readFormats = QImageReader.supportedImageFormats()
81 for readFormat in readFormats:
82 try:
83 inputFormats.append(filters[bytes(readFormat).decode()])
84 except KeyError:
85 pass
86 inputFormats.sort()
87 inputFormats.append(self.tr("All Files (*)"))
88 if filters["png"] in inputFormats:
89 inputFormats.remove(filters["png"])
90 inputFormats.insert(0, filters["png"])
91 self.imagePicker.setFilters(';;'.join(inputFormats))
92 self.imagePicker.setMode(E5PathPickerModes.OpenFileMode)
93
94 self.sizeCheckBox.setChecked(True)
95 self.aspectRatioCheckBox.setChecked(True)
96
97 msh = self.minimumSizeHint()
98 self.resize(max(self.width(), msh.width()), msh.height())
99
100 self.__updateOkButton()
101
102 def __updateOkButton(self):
103 """
104 Private slot to set the state of the OK button.
105 """
106 enable = bool(self.imagePicker.text())
107 if self.__mode == ImageMarkupDialog.MarkDownMode:
108 enable = enable and bool(self.altTextEdit.text())
109
110 self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enable)
111
112 @pyqtSlot(str)
113 def on_imagePicker_textChanged(self, address):
114 """
115 Private slot handling changes of the image path.
116
117 @param address image address (URL or local path)
118 @type str
119 """
120 if address and "://" not in address:
121 image = QImage(address)
122 # load the file to set the size spin boxes
123 if image.isNull():
124 self.widthSpinBox.setValue(0)
125 self.heightSpinBox.setValue(0)
126 self.__originalImageSize = QSize()
127 self.__aspectRatio = 1
128 else:
129 self.widthSpinBox.setValue(image.width())
130 self.heightSpinBox.setValue(image.height())
131 self.__originalImageSize = image.size()
132 self.__aspectRatio = \
133 float(self.__originalImageSize.height()) / \
134 self.__originalImageSize.width()
135 else:
136 self.widthSpinBox.setValue(0)
137 self.heightSpinBox.setValue(0)
138 self.__originalImageSize = QSize()
139 self.__aspectRatio = 1
140
141 self.__updateOkButton()
142
143 @pyqtSlot(str)
144 def on_altTextEdit_textChanged(self, txt):
145 """
146 Private slot handling changes of the alternative text.
147
148 @param txt alternative text
149 @type str
150 """
151 self.__updateOkButton()
152
153 @pyqtSlot(bool)
154 def on_sizeCheckBox_toggled(self, checked):
155 """
156 Public slot to reset the width and height spin boxes.
157
158 @param checked flag indicating the state of the check box
159 @type bool
160 """
161 if checked:
162 self.widthSpinBox.setValue(self.__originalImageSize.width())
163 self.heightSpinBox.setValue(self.__originalImageSize.height())
164
165 @pyqtSlot(bool)
166 def on_aspectRatioCheckBox_toggled(self, checked):
167 """
168 Public slot to adjust the height to match the original aspect ratio.
169
170 @param checked flag indicating the state of the check box
171 @type bool
172 """
173 if checked and self.__originalImageSize.isValid():
174 height = self.widthSpinBox.value() * self.__aspectRatio
175 self.heightSpinBox.setValue(height)
176
177 @pyqtSlot(int)
178 def on_widthSpinBox_valueChanged(self, width):
179 """
180 Private slot to adjust the height spin box.
181
182 @param width width for the image
183 @type int
184 """
185 if self.aspectRatioCheckBox.isChecked() and \
186 self.widthSpinBox.hasFocus():
187 height = width * self.__aspectRatio
188 self.heightSpinBox.setValue(height)
189
190 @pyqtSlot(int)
191 def on_heightSpinBox_valueChanged(self, height):
192 """
193 Private slot to adjust the width spin box.
194
195 @param height height for the image
196 @type int
197 """
198 if self.aspectRatioCheckBox.isChecked() and \
199 self.heightSpinBox.hasFocus():
200 width = height / self.__aspectRatio
201 self.widthSpinBox.setValue(width)
202
203 def getData(self):
204 """
205 Public method to get the entered data.
206
207 @return tuple containing the image address, alternative text,
208 title text, flag to keep the original size, width and height
209 @rtype tuple of (str, str, str, bool, int, int)
210 """
211 return (
212 self.imagePicker.text(),
213 self.altTextEdit.text(),
214 self.titleEdit.text(),
215 self.sizeCheckBox.isChecked(),
216 self.widthSpinBox.value(),
217 self.heightSpinBox.value(),
218 )

eric ide

mercurial