eric7/E5Gui/EricLineEdit.py

branch
eric7
changeset 8356
68ec9c3d4de5
parent 8350
74a3b2a6a944
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eric7/E5Gui/EricLineEdit.py	Sat May 22 18:51:46 2021 +0200
@@ -0,0 +1,264 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2009 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing specialized line edits.
+"""
+
+import enum
+
+from PyQt6.QtCore import pyqtSignal, Qt, QEvent
+from PyQt6.QtWidgets import (
+    QLineEdit, QWidget, QHBoxLayout, QBoxLayout, QLayout, QApplication,
+    QSpacerItem, QSizePolicy
+)
+
+
+class EricLineEditSideWidget(QWidget):
+    """
+    Class implementing the side widgets for the line edit class.
+    
+    @signal sizeHintChanged() emitted to indicate a change of the size hint
+    """
+    sizeHintChanged = pyqtSignal()
+    
+    def __init__(self, parent=None):
+        """
+        Constructor
+        
+        @param parent reference to the parent widget (QWidget)
+        """
+        super().__init__(parent)
+    
+    def event(self, evt):
+        """
+        Public method to handle events.
+        
+        @param evt reference to the event (QEvent)
+        @return flag indicating, whether the event was recognized (boolean)
+        """
+        if evt.type() == QEvent.Type.LayoutRequest:
+            self.sizeHintChanged.emit()
+        return QWidget.event(self, evt)
+
+
+class EricLineEditSide(enum.Enum):
+    """
+    Class defining the line edit sides.
+    """
+    LEFT = 0
+    RIGHT = 1
+
+
+class EricLineEdit(QLineEdit):
+    """
+    Class implementing a line edit widget showing some inactive text.
+    """
+    def __init__(self, parent=None, placeholderText=""):
+        """
+        Constructor
+        
+        @param parent reference to the parent widget
+        @type QWidget
+        @param placeholderText text to be shown on inactivity
+        @type str
+        """
+        super().__init__(parent)
+        
+        self.setMinimumHeight(22)
+        
+        self.setPlaceholderText(placeholderText)
+        
+        self.__mainLayout = QHBoxLayout(self)
+        self.__mainLayout.setContentsMargins(0, 0, 0, 0)
+        self.__mainLayout.setSpacing(0)
+        
+        self.__leftMargin = 0
+        self.__leftWidget = EricLineEditSideWidget(self)
+        self.__leftWidget.resize(0, 0)
+        self.__leftLayout = QHBoxLayout(self.__leftWidget)
+        self.__leftLayout.setContentsMargins(0, 0, 2, 0)
+        if QApplication.isRightToLeft():
+            self.__leftLayout.setDirection(QBoxLayout.Direction.RightToLeft)
+        else:
+            self.__leftLayout.setDirection(QBoxLayout.Direction.LeftToRight)
+        self.__leftLayout.setSizeConstraint(
+            QLayout.SizeConstraint.SetFixedSize)
+        
+        self.__rightWidget = EricLineEditSideWidget(self)
+        self.__rightWidget.resize(0, 0)
+        self.__rightLayout = QHBoxLayout(self.__rightWidget)
+        self.__rightLayout.setContentsMargins(0, 0, 2, 0)
+        if self.isRightToLeft():
+            self.__rightLayout.setDirection(QBoxLayout.Direction.RightToLeft)
+        else:
+            self.__rightLayout.setDirection(QBoxLayout.Direction.LeftToRight)
+        
+        horizontalSpacer = QSpacerItem(
+            0, 0, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
+        self.__mainLayout.addWidget(
+            self.__leftWidget, 0,
+            Qt.AlignmentFlag.AlignVCenter | Qt.AlignmentFlag.AlignLeft)
+        self.__mainLayout.addItem(horizontalSpacer)
+        self.__mainLayout.addWidget(
+            self.__rightWidget, 0,
+            Qt.AlignmentFlag.AlignVCenter | Qt.AlignmentFlag.AlignRight)
+        if self.isRightToLeft():
+            self.__mainLayout.setDirection(QBoxLayout.Direction.RightToLeft)
+        else:
+            self.__mainLayout.setDirection(QBoxLayout.Direction.LeftToRight)
+        
+        self.setWidgetSpacing(3)
+        self.__leftWidget.sizeHintChanged.connect(self._updateTextMargins)
+        self.__rightWidget.sizeHintChanged.connect(self._updateTextMargins)
+    
+    def setLeftMargin(self, margin):
+        """
+        Public method to set the left margin.
+        
+        @param margin left margin in pixel (integer)
+        """
+        self.__leftMargin = margin
+    
+    def leftMargin(self):
+        """
+        Public method to get the size of the left margin.
+        
+        @return left margin in pixel (integer)
+        """
+        return self.__leftMargin
+    
+    def event(self, evt):
+        """
+        Public method to handle events.
+        
+        @param evt reference to the event (QEvent)
+        @return flag indicating, whether the event was recognized (boolean)
+        """
+        if evt.type() == QEvent.Type.LayoutDirectionChange:
+            if self.isRightToLeft():
+                self.__mainLayout.setDirection(
+                    QBoxLayout.Direction.RightToLeft)
+                self.__leftLayout.setDirection(
+                    QBoxLayout.Direction.RightToLeft)
+                self.__rightLayout.setDirection(
+                    QBoxLayout.Direction.RightToLeft)
+            else:
+                self.__mainLayout.setDirection(
+                    QBoxLayout.Direction.LeftToRight)
+                self.__leftLayout.setDirection(
+                    QBoxLayout.Direction.LeftToRight)
+                self.__rightLayout.setDirection(
+                    QBoxLayout.Direction.LeftToRight)
+        return QLineEdit.event(self, evt)
+    
+    def _updateTextMargins(self):
+        """
+        Protected slot to update the text margins.
+        """
+        left = (
+            self.__leftWidget.sizeHint().width()
+            if self.__leftMargin == 0 else
+            self.__leftMargin
+        )
+        right = self.__rightWidget.sizeHint().width()
+        top = 0
+        bottom = 0
+        self.setTextMargins(left, top, right, bottom)
+    
+    def addWidget(self, widget, position):
+        """
+        Public method to add a widget to a side.
+        
+        @param widget reference to the widget to add
+        @type QWidget
+        @param position position to add to
+        @type EricLineEditSide
+        """
+        if widget is None:
+            return
+        
+        if self.isRightToLeft():
+            if position == EricLineEditSide.LEFT:
+                position = EricLineEditSide.RIGHT
+            else:
+                position = EricLineEditSide.LEFT
+        if position == EricLineEditSide.LEFT:
+            self.__leftLayout.addWidget(widget)
+        else:
+            self.__rightLayout.insertWidget(1, widget)
+    
+    def removeWidget(self, widget):
+        """
+        Public method to remove a widget from a side.
+        
+        @param widget reference to the widget to remove
+        @type QWidget
+        """
+        if widget is None:
+            return
+        
+        self.__leftLayout.removeWidget(widget)
+        self.__rightLayout.removeWidget(widget)
+        widget.hide()
+    
+    def widgetSpacing(self):
+        """
+        Public method to get the side widget spacing.
+        
+        @return side widget spacing (integer)
+        """
+        return self.__leftLayout.spacing()
+    
+    def setWidgetSpacing(self, spacing):
+        """
+        Public method to set the side widget spacing.
+        
+        @param spacing side widget spacing (integer)
+        """
+        self.__leftLayout.setSpacing(spacing)
+        self.__rightLayout.setSpacing(spacing)
+        self._updateTextMargins()
+    
+    def textMargin(self, position):
+        """
+        Public method to get the text margin for a side.
+        
+        @param position side to get margin for
+        @type EricLineEditSide
+        @return text margin
+        @rtype int
+        """
+        spacing = self.__rightLayout.spacing()
+        w = 0
+        w = (
+            self.__leftWidget.sizeHint().width()
+            if position == EricLineEditSide.LEFT else
+            self.__rightWidget.sizeHint().width()
+        )
+        if w == 0:
+            return 0
+        return w + spacing * 2
+
+class EricClearableLineEdit(EricLineEdit):
+    """
+    Class implementing a line edit widget showing some inactive text and a
+    clear button, if it has some contents.
+    """
+    def __init__(self, parent=None, placeholderText="",
+                 side=EricLineEditSide.RIGHT):
+        """
+        Constructor
+        
+        @param parent reference to the parent widget
+        @type QWidget
+        @param placeholderText text to be shown on inactivity
+        @type str
+        @param side side the clear button should be shown at
+        @type EricLineEditSide
+        """
+        super().__init__(parent, placeholderText)
+        
+        self.setClearButtonEnabled(True)

eric ide

mercurial