src/eric7/QScintilla/MarkupProviders/ImageMarkupDialog.py

branch
eric7
changeset 9209
b99e7fd55fd3
parent 8881
54e42bc2437a
child 9221
bf71ee032bb4
equal deleted inserted replaced
9208:3fc8dfeb6ebe 9209:b99e7fd55fd3
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2017 - 2022 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a dialog to enter data for an image markup.
8 """
9
10 import contextlib
11
12 from PyQt6.QtCore import pyqtSlot, QSize
13 from PyQt6.QtGui import QImage, QImageReader
14 from PyQt6.QtWidgets import QDialog, QDialogButtonBox
15
16 from EricWidgets.EricPathPicker import EricPathPickerModes
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 mode mode of the dialog
34 @type int
35 @param parent reference to the parent widget
36 @type QWidget
37 """
38 super().__init__(parent)
39 self.setupUi(self)
40
41 if mode == ImageMarkupDialog.MarkDownMode:
42 self.sizeCheckBox.setEnabled(False)
43 self.aspectRatioCheckBox.setEnabled(False)
44 self.widthSpinBox.setEnabled(False)
45 self.heightSpinBox.setEnabled(False)
46 elif mode == ImageMarkupDialog.RestMode:
47 self.titleEdit.setEnabled(False)
48
49 self.__mode = mode
50 self.__originalImageSize = QSize()
51
52 filters = {
53 'bmp': self.tr("Windows Bitmap File (*.bmp)"),
54 'cur': self.tr("Windows Cursor File (*.cur)"),
55 'dds': self.tr("DirectDraw-Surface File (*.dds)"),
56 'gif': self.tr("Graphic Interchange Format File (*.gif)"),
57 'icns': self.tr("Apple Icon File (*.icns)"),
58 'ico': self.tr("Windows Icon File (*.ico)"),
59 'jp2': self.tr("JPEG2000 File (*.jp2)"),
60 'jpg': self.tr("JPEG File (*.jpg)"),
61 'jpeg': self.tr("JPEG File (*.jpeg)"),
62 'mng': self.tr("Multiple-Image Network Graphics File (*.mng)"),
63 'pbm': self.tr("Portable Bitmap File (*.pbm)"),
64 'pcx': self.tr("Paintbrush Bitmap File (*.pcx)"),
65 'pgm': self.tr("Portable Graymap File (*.pgm)"),
66 'png': self.tr("Portable Network Graphics File (*.png)"),
67 'ppm': self.tr("Portable Pixmap File (*.ppm)"),
68 'sgi': self.tr("Silicon Graphics Image File (*.sgi)"),
69 'svg': self.tr("Scalable Vector Graphics File (*.svg)"),
70 'svgz': self.tr("Compressed Scalable Vector Graphics File"
71 " (*.svgz)"),
72 'tga': self.tr("Targa Graphic File (*.tga)"),
73 'tif': self.tr("TIFF File (*.tif)"),
74 'tiff': self.tr("TIFF File (*.tiff)"),
75 'wbmp': self.tr("WAP Bitmap File (*.wbmp)"),
76 'webp': self.tr("WebP Image File (*.webp)"),
77 'xbm': self.tr("X11 Bitmap File (*.xbm)"),
78 'xpm': self.tr("X11 Pixmap File (*.xpm)"),
79 }
80
81 inputFormats = []
82 readFormats = QImageReader.supportedImageFormats()
83 for readFormat in readFormats:
84 with contextlib.suppress(KeyError):
85 inputFormats.append(filters[bytes(readFormat).decode()])
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(EricPathPickerModes.OPEN_FILE_MODE)
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(
111 QDialogButtonBox.StandardButton.Ok).setEnabled(enable)
112
113 @pyqtSlot(str)
114 def on_imagePicker_textChanged(self, address):
115 """
116 Private slot handling changes of the image path.
117
118 @param address image address (URL or local path)
119 @type str
120 """
121 if address and "://" not in address:
122 image = QImage(address)
123 # load the file to set the size spin boxes
124 if image.isNull():
125 self.widthSpinBox.setValue(0)
126 self.heightSpinBox.setValue(0)
127 self.__originalImageSize = QSize()
128 self.__aspectRatio = 1
129 else:
130 self.widthSpinBox.setValue(image.width())
131 self.heightSpinBox.setValue(image.height())
132 self.__originalImageSize = image.size()
133 self.__aspectRatio = (
134 float(self.__originalImageSize.height()) /
135 self.__originalImageSize.width()
136 )
137 else:
138 self.widthSpinBox.setValue(0)
139 self.heightSpinBox.setValue(0)
140 self.__originalImageSize = QSize()
141 self.__aspectRatio = 1
142
143 self.__updateOkButton()
144
145 @pyqtSlot(str)
146 def on_altTextEdit_textChanged(self, txt):
147 """
148 Private slot handling changes of the alternative text.
149
150 @param txt alternative text
151 @type str
152 """
153 self.__updateOkButton()
154
155 @pyqtSlot(bool)
156 def on_sizeCheckBox_toggled(self, checked):
157 """
158 Private slot to reset the width and height spin boxes.
159
160 @param checked flag indicating the state of the check box
161 @type bool
162 """
163 if checked:
164 self.widthSpinBox.setValue(self.__originalImageSize.width())
165 self.heightSpinBox.setValue(self.__originalImageSize.height())
166
167 @pyqtSlot(bool)
168 def on_aspectRatioCheckBox_toggled(self, checked):
169 """
170 Private slot to adjust the height to match the original aspect ratio.
171
172 @param checked flag indicating the state of the check box
173 @type bool
174 """
175 if checked and self.__originalImageSize.isValid():
176 height = self.widthSpinBox.value() * self.__aspectRatio
177 self.heightSpinBox.setValue(height)
178
179 @pyqtSlot(int)
180 def on_widthSpinBox_valueChanged(self, width):
181 """
182 Private slot to adjust the height spin box.
183
184 @param width width for the image
185 @type int
186 """
187 if (
188 self.aspectRatioCheckBox.isChecked() and
189 self.widthSpinBox.hasFocus()
190 ):
191 height = width * self.__aspectRatio
192 self.heightSpinBox.setValue(height)
193
194 @pyqtSlot(int)
195 def on_heightSpinBox_valueChanged(self, height):
196 """
197 Private slot to adjust the width spin box.
198
199 @param height height for the image
200 @type int
201 """
202 if (
203 self.aspectRatioCheckBox.isChecked() and
204 self.heightSpinBox.hasFocus()
205 ):
206 width = height / self.__aspectRatio
207 self.widthSpinBox.setValue(width)
208
209 def getData(self):
210 """
211 Public method to get the entered data.
212
213 @return tuple containing the image address, alternative text,
214 title text, flag to keep the original size, width and height
215 @rtype tuple of (str, str, str, bool, int, int)
216 """
217 return (
218 self.imagePicker.text(),
219 self.altTextEdit.text(),
220 self.titleEdit.text(),
221 self.sizeCheckBox.isChecked(),
222 self.widthSpinBox.value(),
223 self.heightSpinBox.value(),
224 )

eric ide

mercurial