QScintilla/MarkupProviders/ImageMarkupDialog.py

changeset 5407
f833f89571b8
child 5412
db5a520f69d3
diff -r 8d09a23a8fdd -r f833f89571b8 QScintilla/MarkupProviders/ImageMarkupDialog.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/QScintilla/MarkupProviders/ImageMarkupDialog.py	Sun Jan 08 18:52:16 2017 +0100
@@ -0,0 +1,218 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2017 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a dialog to enter data for an image markup.
+"""
+
+from __future__ import unicode_literals
+
+from PyQt5.QtCore import pyqtSlot, QSize
+from PyQt5.QtGui import QImage, QImageReader
+from PyQt5.QtWidgets import QDialog, QDialogButtonBox
+
+from E5Gui.E5PathPicker import E5PathPickerModes
+
+from .Ui_ImageMarkupDialog import Ui_ImageMarkupDialog
+
+
+class ImageMarkupDialog(QDialog, Ui_ImageMarkupDialog):
+    """
+    Class implementing a dialog to enter data for an image markup.
+    """
+    HtmlMode = 0
+    MarkDownMode = 1
+    RestMode = 2
+    
+    def __init__(self, mode, parent=None):
+        """
+        Constructor
+        
+        @param parent reference to the parent widget
+        @type QWidget
+        """
+        super(ImageMarkupDialog, self).__init__(parent)
+        self.setupUi(self)
+        
+        if mode == ImageMarkupDialog.MarkDownMode:
+            self.sizeCheckBox.setEnabled(False)
+            self.aspectRatioCheckBox.setEnabled(False)
+            self.widthSpinBox.setEnabled(False)
+            self.heightSpinBox.setEnabled(False)
+        elif mode == ImageMarkupDialog.RestMode:
+            self.titleEdit.setEnabled(False)
+        
+        self.__mode = mode
+        self.__originalImageSize = QSize()
+    
+        filters = {
+            'bmp': self.tr("Windows Bitmap File (*.bmp)"),
+            'cur': self.tr("Windows Cursor File (*.cur)"),
+            'dds': self.tr("DirectDraw-Surface File (*.dds)"),
+            'gif': self.tr("Graphic Interchange Format File (*.gif)"),
+            'icns': self.tr("Apple Icon File (*.icns)"),
+            'ico': self.tr("Windows Icon File (*.ico)"),
+            'jp2': self.tr("JPEG2000 File (*.jp2)"),
+            'jpg': self.tr("JPEG File (*.jpg)"),
+            'jpeg': self.tr("JPEG File (*.jpeg)"),
+            'mng': self.tr("Multiple-Image Network Graphics File (*.mng)"),
+            'pbm': self.tr("Portable Bitmap File (*.pbm)"),
+            'pcx': self.tr("Paintbrush Bitmap File (*.pcx)"),
+            'pgm': self.tr("Portable Graymap File (*.pgm)"),
+            'png': self.tr("Portable Network Graphics File (*.png)"),
+            'ppm': self.tr("Portable Pixmap File (*.ppm)"),
+            'sgi': self.tr("Silicon Graphics Image File (*.sgi)"),
+            'svg': self.tr("Scalable Vector Graphics File (*.svg)"),
+            'svgz': self.tr("Compressed Scalable Vector Graphics File"
+                            " (*.svgz)"),
+            'tga': self.tr("Targa Graphic File (*.tga)"),
+            'tif': self.tr("TIFF File (*.tif)"),
+            'tiff': self.tr("TIFF File (*.tiff)"),
+            'wbmp': self.tr("WAP Bitmap File (*.wbmp)"),
+            'webp': self.tr("WebP Image File (*.webp)"),
+            'xbm': self.tr("X11 Bitmap File (*.xbm)"),
+            'xpm': self.tr("X11 Pixmap File (*.xpm)"),
+        }
+        
+        inputFormats = []
+        readFormats = QImageReader.supportedImageFormats()
+        for readFormat in readFormats:
+            try:
+                inputFormats.append(filters[bytes(readFormat).decode()])
+            except KeyError:
+                pass
+        inputFormats.sort()
+        inputFormats.append(self.tr("All Files (*)"))
+        if filters["png"] in inputFormats:
+            inputFormats.remove(filters["png"])
+            inputFormats.insert(0, filters["png"])
+        self.imagePicker.setFilters(';;'.join(inputFormats))
+        self.imagePicker.setMode(E5PathPickerModes.OpenFileMode)
+        
+        self.sizeCheckBox.setChecked(True)
+        self.aspectRatioCheckBox.setChecked(True)
+        
+        msh = self.minimumSizeHint()
+        self.resize(max(self.width(), msh.width()), msh.height())
+        
+        self.__updateOkButton()
+    
+    def __updateOkButton(self):
+        """
+        Private slot to set the state of the OK button.
+        """
+        enable = bool(self.imagePicker.text())
+        if self.__mode == ImageMarkupDialog.MarkDownMode:
+            enable = enable and bool(self.altTextEdit.text())
+        
+        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enable)
+    
+    @pyqtSlot(str)
+    def on_imagePicker_textChanged(self, address):
+        """
+        Private slot handling changes of the image path.
+        
+        @param address image address (URL or local path)
+        @type str
+        """
+        if address and "://" not in address:
+            image = QImage(address)
+            # load the file to set the size spin boxes
+            if image.isNull():
+                self.widthSpinBox.setValue(0)
+                self.heightSpinBox.setValue(0)
+                self.__originalImageSize = QSize()
+                self.__aspectRatio = 1
+            else:
+                self.widthSpinBox.setValue(image.width())
+                self.heightSpinBox.setValue(image.height())
+                self.__originalImageSize = image.size()
+                self.__aspectRatio = \
+                    float(self.__originalImageSize.height()) / \
+                    self.__originalImageSize.width()
+        else:
+            self.widthSpinBox.setValue(0)
+            self.heightSpinBox.setValue(0)
+            self.__originalImageSize = QSize()
+            self.__aspectRatio = 1
+        
+        self.__updateOkButton()
+    
+    @pyqtSlot(str)
+    def on_altTextEdit_textChanged(self, txt):
+        """
+        Private slot handling changes of the alternative text.
+        
+        @param txt alternative text
+        @type str
+        """
+        self.__updateOkButton()
+
+    @pyqtSlot(bool)
+    def on_sizeCheckBox_toggled(self, checked):
+        """
+        Public slot to reset the width and height spin boxes.
+        
+        @param checked flag indicating the state of the check box
+        @type bool
+        """
+        if checked:
+            self.widthSpinBox.setValue(self.__originalImageSize.width())
+            self.heightSpinBox.setValue(self.__originalImageSize.height())
+    
+    @pyqtSlot(bool)
+    def on_aspectRatioCheckBox_toggled(self, checked):
+        """
+        Public slot to adjust the height to match the original aspect ratio.
+        
+        @param checked flag indicating the state of the check box
+        @type bool
+        """
+        if checked and self.__originalImageSize.isValid():
+            height = self.widthSpinBox.value() * self.__aspectRatio
+            self.heightSpinBox.setValue(height)
+    
+    @pyqtSlot(int)
+    def on_widthSpinBox_valueChanged(self, width):
+        """
+        Private slot to adjust the height spin box.
+        
+        @param width width for the image
+        @type int
+        """
+        if self.aspectRatioCheckBox.isChecked() and \
+                self.widthSpinBox.hasFocus():
+            height = width * self.__aspectRatio
+            self.heightSpinBox.setValue(height)
+    
+    @pyqtSlot(int)
+    def on_heightSpinBox_valueChanged(self, height):
+        """
+        Private slot to adjust the width spin box.
+        
+        @param height height for the image
+        @type int
+        """
+        if self.aspectRatioCheckBox.isChecked() and \
+                self.heightSpinBox.hasFocus():
+            width = height / self.__aspectRatio
+            self.widthSpinBox.setValue(width)
+    
+    def getData(self):
+        """
+        Public method to get the entered data.
+        
+        @return tuple containing the image address, alternative text,
+            title text, flag to keep the original size, width and height
+        @rtype tuple of (str, str, str, bool, int, int)
+        """
+        return (
+            self.imagePicker.text(),
+            self.altTextEdit.text(),
+            self.titleEdit.text(),
+            self.sizeCheckBox.isChecked(),
+            self.widthSpinBox.value(),
+            self.heightSpinBox.value(),
+        )

eric ide

mercurial