E5Gui/E5LineEdit.py

changeset 643
719db11dd4df
parent 55
b5c84934de9c
child 653
0540f3c52b46
--- a/E5Gui/E5LineEdit.py	Sun Sep 26 15:18:07 2010 +0200
+++ b/E5Gui/E5LineEdit.py	Sun Sep 26 20:25:09 2010 +0200
@@ -7,13 +7,42 @@
 Module implementing specialized line edits. 
 """
 
-from PyQt4.QtCore import Qt
-from PyQt4.QtGui import QLineEdit, QStyleOptionFrameV2, QStyle, QPainter, QPalette
+from PyQt4.QtCore import pyqtSignal, Qt, QEvent
+from PyQt4.QtGui import QLineEdit, QStyleOptionFrameV2, QStyle, QPainter, QPalette, \
+    QWidget, QHBoxLayout, QBoxLayout, QLayout, QApplication, QSpacerItem, QSizePolicy
+
+class SideWidget(QWidget):
+    """
+    Class implementing the side widgets for the line edit class.
+    """
+    sizeHintChanged = pyqtSignal()
+    
+    def __init__(self, parent = None):
+        """
+        Constructor
+        
+        @param parent reference to the parent widget (QWidget)
+        """
+        QWidget.__init__(self, parent)
+    
+    def event(self, evt):
+        """
+        Protected method to handle events.
+        
+        @param reference to the event (QEvent)
+        @return flag indicating, whether the event was recognized (boolean)
+        """
+        if evt.type() == QEvent.LayoutRequest:
+            self.sizeHintChanged.emit()
+        return QWidget.event(self, evt)
 
 class E5LineEdit(QLineEdit):
     """
     Class implementing a line edit widget showing some inactive text.
     """
+    LeftSide  = 0
+    RightSide = 1
+    
     def __init__(self, parent = None, inactiveText = ""):
         """
         Constructor
@@ -23,7 +52,184 @@
         """
         QLineEdit.__init__(self, parent)
         
+        self.setMinimumHeight(22)
+        
         self.__inactiveText = inactiveText
+        
+        self.__leftWidget = SideWidget(self)
+        self.__leftWidget.resize(0, 0)
+        self.__leftLayout = QHBoxLayout(self.__leftWidget)
+        self.__leftLayout.setContentsMargins(0, 0, 0, 0)
+        if QApplication.isRightToLeft():
+            self.__leftLayout.setDirection(QBoxLayout.RightToLeft)
+        else:
+            self.__leftLayout.setDirection(QBoxLayout.LeftToRight)
+        self.__leftLayout.setSizeConstraint(QLayout.SetFixedSize)
+        
+        self.__rightWidget = SideWidget(self)
+        self.__rightWidget.resize(0, 0)
+        self.__rightLayout = QHBoxLayout(self.__rightWidget)
+        self.__rightLayout.setContentsMargins(0, 0, 0, 0)
+        if self.isRightToLeft():
+            self.__rightLayout.setDirection(QBoxLayout.RightToLeft)
+        else:
+            self.__rightLayout.setDirection(QBoxLayout.LeftToRight)
+        horizontalSpacer = QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum)
+        self.__rightLayout.addItem(horizontalSpacer)
+        
+        self.setWidgetSpacing(3)
+        self.__leftWidget.sizeHintChanged.connect(self._updateTextMargins)
+        self.__rightWidget.sizeHintChanged.connect(self._updateTextMargins)
+    
+    def event(self, evt):
+        """
+        Protected method to handle events.
+        
+        @param reference to the event (QEvent)
+        @return flag indicating, whether the event was recognized (boolean)
+        """
+        if evt.type() == QEvent.LayoutDirectionChange:
+            if self.isRightToLeft():
+                self.__leftLayout.setDirection(QBoxLayout.RightToLeft)
+                self.__rightLayout.setDirection(QBoxLayout.RightToLeft)
+            else:
+                self.__leftLayout.setDirection(QBoxLayout.LeftToRight)
+                self.__rightLayout.setDirection(QBoxLayout.LeftToRight)
+        return QLineEdit.event(self, evt)
+    
+    def resizeEvent(self, evt):
+        """
+        Protected method to handle resize events.
+        
+        @param evt reference to the resize event (QResizeEvent)
+        """
+        self.__updateSideWidgetLocations()
+        QLineEdit.resizeEvent(self, evt)
+    
+    def paintEvent(self, evt):
+        """
+        Protected method handling a paint event.
+        
+        @param evt reference to the paint event (QPaintEvent)
+        """
+        QLineEdit.paintEvent(self, evt)
+        if not self.text() and \
+           self.__inactiveText and \
+           not self.hasFocus():
+            panel = QStyleOptionFrameV2()
+            self.initStyleOption(panel)
+            textRect = \
+                self.style().subElementRect(QStyle.SE_LineEditContents, panel, self)
+            textRect.adjust(2, 0, 0, 0)
+            left = self.textMargin(self.LeftSide)
+            right = self.textMargin(self.RightSide)
+            textRect.adjust(left, 0, -right, 0)
+            painter = QPainter(self)
+            painter.setPen(self.palette().brush(QPalette.Disabled, QPalette.Text).color())
+            painter.drawText(
+                textRect, Qt.AlignLeft | Qt.AlignVCenter, self.__inactiveText)
+    
+    def __updateSideWidgetLocations(self):
+        """
+        Private method to update the side widget locations.
+        """
+        opt = QStyleOptionFrameV2()
+        self.initStyleOption(opt)
+        textRect = \
+            self.style().subElementRect(QStyle.SE_LineEditContents, opt, self)
+        textRect.adjust(2, 0, 0, 0)
+        
+        left = self.textMargin(self.LeftSide)
+        
+        midHeight = textRect.center().y() + 1
+        
+        if self.__leftLayout.count() > 0:
+            leftHeight = midHeight - self.__leftWidget.height() // 2
+            leftWidth = self.__leftWidget.width()
+            if leftWidth == 0:
+                leftHeight = midHeight - self.__leftWidget.sizeHint().height() // 2
+            self.__leftWidget.move(textRect.x(), leftHeight)
+        
+        textRect.setX(left)
+        textRect.setY(midHeight - self.__rightWidget.sizeHint().height() // 2)
+        textRect.setHeight(self.__rightWidget.sizeHint().height())
+        self.__rightWidget.setGeometry(textRect)
+    
+    def _updateTextMargins(self):
+        """
+        Protected slot to update the text margins.
+        """
+        left = self.textMargin(self.LeftSide)
+        right = self.textMargin(self.RightSide)
+        self.setTextMargins(left, 0, right, 0)
+        self.__updateSideWidgetLocations()
+    
+    def addWidget(self, widget, position):
+        """
+        Public method to add a widget to a side.
+        
+        @param widget reference to the widget to add (QWidget)
+        @param position position to add to (E5LineEdit.LeftSide, E5LineEdit.RightSide)
+        """
+        if widget is None:
+            return
+        
+        if self.isRightToLeft():
+            if position == self.LeftSide:
+                position = self.RightSide
+            else:
+                position = self.LeftSide
+        if position == self.LeftSide:
+            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 (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 (E5LineEdit.LeftSide, E5LineEdit.RightSide)
+        """
+        spacing = self.__rightLayout.spacing()
+        w = 0
+        if position == self.LeftSide:
+            w = self.__leftWidget.sizeHint().width()
+        else:
+            w = self.__rightWidget.sizeHint().width()
+        if w == 0:
+            return 0
+        return w + spacing * 2
     
     def inactiveText(self):
         """
@@ -41,22 +247,3 @@
         """
         self.__inactiveText = inactiveText
         self.update()
-    
-    def paintEvent(self, evt):
-        """
-        Protected method handling a paint event.
-        
-        @param evt reference to the paint event (QPaintEvent)
-        """
-        QLineEdit.paintEvent(self, evt)
-        if not self.text() and \
-           self.__inactiveText and \
-           not self.hasFocus():
-            panel = QStyleOptionFrameV2()
-            self.initStyleOption(panel)
-            textRect = \
-                self.style().subElementRect(QStyle.SE_LineEditContents, panel, self)
-            textRect.adjust(2, 0, 0, 0)
-            painter = QPainter(self)
-            painter.setPen(self.palette().brush(QPalette.Disabled, QPalette.Text).color())
-            painter.drawText(textRect, Qt.AlignLeft | Qt.AlignVCenter, self.__inactiveText)
\ No newline at end of file

eric ide

mercurial