Example #1
0
File: Main.py Project: rmasad/Caldo
class SearchLineEdit(QLineEdit):
  def __init__(self, parent = None):
    QLineEdit.__init__(self, parent)
    self.searchButton = QToolButton(self)
    self.searchButton.setCursor(QCursor())
    self.searchButton.setIcon(QIcon("./img/search.svg"))
    frameWidth = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth);
    self.searchButton.setStyleSheet("QToolButton {border: none; padding: 0px;}")
    self.setStyleSheet(QString(
    '''QLineEdit
    {
      padding-right: %1px;
      padding-left: 2px;
      padding-top: 1px;
      padding-bottom: 1px;
    }
    ''').arg(self.searchButton.sizeHint().width() + frameWidth + 1));

  def resizeEvent(self, event = None):
    if event: QLineEdit.resizeEvent(self, event)
    sz = self.searchButton.sizeHint()
    frameWidth = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth)
    self.searchButton.move(self.rect().right() - frameWidth - sz.width(), (self.rect().bottom() + 1 - sz.height())/2)

  def focusInEvent(self, event = None):
    QLineEdit.focusInEvent(self, event)
    self.emit(SIGNAL("focusChange()"))

  def focusOutEvent(self, event = None):
    QLineEdit.focusOutEvent(self, event)
    self.emit(SIGNAL("focusChange()"))
Example #2
0
class HighlightEdit(QLineEdit):
    clicked = pyqtSignal(name="clicked")

    def __init__(self, parent):
        QLineEdit.__init__(self, parent)
        self._highlight_effect = QGraphicsDropShadowEffect(self)
        self._highlight_effect.setOffset(0.0)
        self._highlight_effect.setBlurRadius(5.0)
        self._highlight_effect.setColor(QColor(50, 50, 200))
        self.setGraphicsEffect(self._highlight_effect)
        self._highlight_effect.setEnabled(False)

        self.clear_button = QToolButton(self)
        self.clear_button.setIcon(QIcon.fromTheme("edit-clear", QIcon("icons/delete_icon.png")))
        self.clear_button.setCursor(Qt.ArrowCursor)
        self.clear_button.setStyleSheet("QToolButton { border: none; padding: 1.5px; }")
        icon_size = int(self.sizeHint().height() * 0.65)
        self.clear_button.setIconSize(QSize(icon_size, icon_size))
        self.clear_button.clicked.connect(self.clear)
        # self.clear_button.hide()

        # some padding stuff
        frameWidth = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth)
        self.setStyleSheet(
            "QLineEdit {{ padding-right: {}px; }} ".format(self.clear_button.sizeHint().width() + frameWidth)
        )

    # create a signal on doubleclick events
    def mouseDoubleClickEvent(self, ev):
        ev.accept()
        self.clicked.emit()

    # fix up the clear button positioning
    def resizeEvent(self, ev):
        sz = self.clear_button.sizeHint()

        frameWidth = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth)
        self.clear_button.move(
            self.rect().right() - frameWidth - sz.width(), (self.rect().bottom() + 1 - sz.height()) / 2
        )

    # a slot for turning the graphics effect on and off
    @pyqtSlot(bool)
    def highlight(self, val):
        self._highlight_effect.setEnabled(val)
Example #3
0
class HighlightEdit(QLineEdit):
    clicked = pyqtSignal(name='clicked')

    def __init__(self, parent):
        QLineEdit.__init__(self, parent)
        self._highlight_effect = QGraphicsDropShadowEffect(self)
        self._highlight_effect.setOffset(0.0)
        self._highlight_effect.setBlurRadius(5.0)
        self._highlight_effect.setColor(QColor(50, 50, 200))
        self.setGraphicsEffect(self._highlight_effect)
        self._highlight_effect.setEnabled(False)

        self.clear_button = QToolButton(self)
        self.clear_button.setIcon(
            QIcon.fromTheme("edit-clear", QIcon("icons/delete_icon.png")))
        self.clear_button.setCursor(Qt.ArrowCursor)
        self.clear_button.setStyleSheet(
            "QToolButton { border: none; padding: 1.5px; }")
        icon_size = int(self.sizeHint().height() * 0.65)
        self.clear_button.setIconSize(QSize(icon_size, icon_size))
        self.clear_button.clicked.connect(self.clear)
        #self.clear_button.hide()

        # some padding stuff
        frameWidth = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth)
        self.setStyleSheet("QLineEdit {{ padding-right: {}px; }} ".format(
            self.clear_button.sizeHint().width() + frameWidth))

    #create a signal on doubleclick events
    def mouseDoubleClickEvent(self, ev):
        ev.accept()
        self.clicked.emit()

    # fix up the clear button positioning
    def resizeEvent(self, ev):
        sz = self.clear_button.sizeHint()

        frameWidth = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth)
        self.clear_button.move(self.rect().right() - frameWidth - sz.width(),
                               (self.rect().bottom() + 1 - sz.height()) / 2)

    # a slot for turning the graphics effect on and off
    @pyqtSlot(bool)
    def highlight(self, val):
        self._highlight_effect.setEnabled(val)
Example #4
0
 def rebuildButtons( self ):
     """
     Rebuilds the buttons for the advanced actions.
     """
     for btn in self.findChildren(QToolButton):
         btn.close()
         btn.setParent(None)
         btn.deleteLater()
     
     for standard, advanced in self._advancedMap.items():
         rect    = self.actionGeometry(standard)
         btn     = QToolButton(self)
         btn.setFixedWidth(22)
         btn.setFixedHeight(rect.height())
         btn.setDefaultAction(advanced)
         btn.setAutoRaise(True)
         btn.move(rect.right() + 1, rect.top())
         
         if btn.icon().isNull():
             btn.setIcon(QIcon(resources.find('img/advanced.png')))
         
         btn.clicked.connect(self.acceptAdvanced)
class IconLineEdit(QLineEdit):
    def __init__(self, parent=None):
        QLineEdit.__init__(self, parent)

        self.setPlaceholderText(self.tr('Email'))

        self.btnIcon = QToolButton(self)
        self.btnIcon.setIcon(QIcon(os.path.join(pluginPath, 'icons', 'envelope.svg')))
        self.btnIcon.setEnabled(False)
        self.btnIcon.setStyleSheet('QToolButton { border: none; padding: 0px; }')

        frameWidth = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth)
        self.setStyleSheet('QLineEdit {{ padding-left: {}px; }} '.format(self.btnIcon.sizeHint().width() + frameWidth + 1))
        msz = self.minimumSizeHint()
        self.setMinimumSize(max(msz.width(), self.btnIcon.sizeHint().height() + frameWidth * 2 + 2),
                            max(msz.height(), self.btnIcon.sizeHint().height() + frameWidth * 2 + 2))

    def resizeEvent(self, event):
        frameWidth = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth)

        sz = self.btnIcon.sizeHint()
        self.btnIcon.move(frameWidth + 1,
                           (self.rect().bottom() + 1 - sz.height()) / 2)
Example #6
0
class Search_QLineEdit(QLineEdit):
    """
	Defines a `QLineEdit <http://doc.qt.nokia.com/qlinedit.html>`_ subclass providing
	a search field with clearing capabilities.
	"""

    def __init__(
        self, parent=None, uiSearchImage=None, uiSearchClickedImage=None, uiClearImage=None, uiClearClickedImage=None
    ):
        """
		Initializes the class.

		:param parent: Widget parent.
		:type parent: QObject
		:param uiSearchImage: Search button image path.
		:type uiSearchImage: str
		:param uiSearchClickedImage: Search button clicked image path.
		:type uiSearchClickedImage: str
		:param uiClearImage: Clear button image path.
		:type uiClearImage: str
		:param uiClearClickedImage: Clear button clicked image path.
		:type uiClearClickedImage: str
		"""

        LOGGER.debug("> Initializing '{0}()' class.".format(self.__class__.__name__))

        QLineEdit.__init__(self, parent)

        # --- Setting class attributes. ---
        self.__uiSearchImage = None
        self.uiSearchImage = uiSearchImage or umbra.ui.common.getResourcePath("images/Search_Glass.png")
        self.__uiSearchClickedImage = None
        self.uiSearchClickedImage = uiSearchClickedImage or umbra.ui.common.getResourcePath(
            "images/Search_Glass_Clicked.png"
        )
        self.__uiClearImage = None
        self.uiClearImage = uiClearImage or umbra.ui.common.getResourcePath("images/Search_Clear.png")
        self.__uiClearClickedImage = None
        self.uiClearClickedImage = uiClearClickedImage or umbra.ui.common.getResourcePath(
            "images/Search_Clear_Clicked.png"
        )

        self.__searchActiveLabel = Active_QLabel(
            self, QPixmap(self.__uiSearchImage), QPixmap(self.__uiSearchImage), QPixmap(self.__uiSearchClickedImage)
        )
        self.__searchActiveLabel.setObjectName("Search_Field_activeLabel")
        self.__searchActiveLabel.showEvent = lambda event: reduce(
            lambda *args: None, (self.__setStyleSheet(), Active_QLabel.showEvent(self.__searchActiveLabel, event))
        )
        self.__searchActiveLabel.hideEvent = lambda event: reduce(
            lambda *args: None, (self.__setStyleSheet(), Active_QLabel.hideEvent(self.__searchActiveLabel, event))
        )

        self.__clearButton = QToolButton(self)
        self.__clearButton.setObjectName("Clear_Field_button")

        self.__completer = QCompleter()
        self.setCompleter(self.__completer)
        self.__completerVisibleItemsCount = 16

        Search_QLineEdit.__initializeUi(self)
        self.__setClearButtonVisibility(self.text())

        # Signals / Slots.
        self.__clearButton.clicked.connect(self.clear)
        self.textChanged.connect(self.__setClearButtonVisibility)

        # ******************************************************************************************************************
        # ***	Attributes properties.
        # ******************************************************************************************************************

    @property
    def uiSearchImage(self):
        """
		Property for **self.__uiSearchImage** attribute.

		:return: self.__uiSearchImage.
		:rtype: str
		"""

        return self.__uiSearchImage

    @uiSearchImage.setter
    @foundations.exceptions.handleExceptions(AssertionError)
    def uiSearchImage(self, value):
        """
		Setter for **self.__uiSearchImage** attribute.

		:param value: Attribute value.
		:type value: str
		"""

        if value is not None:
            assert type(value) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format(
                "uiSearchImage", value
            )
            assert os.path.exists(value), "'{0}' attribute: '{1}' file doesn't exists!".format("uiSearchImage", value)
        self.__uiSearchImage = value

    @uiSearchImage.deleter
    @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
    def uiSearchImage(self):
        """
		Deleter for **self.__uiSearchImage** attribute.
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "uiSearchImage")
        )

    @property
    def uiSearchClickedImage(self):
        """
		Property for **self.__uiSearchClickedImage** attribute.

		:return: self.__uiSearchClickedImage.
		:rtype: str
		"""

        return self.__uiSearchClickedImage

    @uiSearchClickedImage.setter
    @foundations.exceptions.handleExceptions(AssertionError)
    def uiSearchClickedImage(self, value):
        """
		Setter for **self.__uiSearchClickedImage** attribute.

		:param value: Attribute value.
		:type value: str
		"""

        if value is not None:
            assert type(value) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format(
                "uiSearchClickedImage", value
            )
            assert os.path.exists(value), "'{0}' attribute: '{1}' file doesn't exists!".format(
                "uiSearchClickedImage", value
            )
        self.__uiSearchClickedImage = value

    @uiSearchClickedImage.deleter
    @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
    def uiSearchClickedImage(self):
        """
		Deleter for **self.__uiSearchClickedImage** attribute.
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "uiSearchClickedImage")
        )

    @property
    def uiClearImage(self):
        """
		Property for **self.__uiClearImage** attribute.

		:return: self.__uiClearImage.
		:rtype: str
		"""

        return self.__uiClearImage

    @uiClearImage.setter
    @foundations.exceptions.handleExceptions(AssertionError)
    def uiClearImage(self, value):
        """
		Setter for **self.__uiClearImage** attribute.

		:param value: Attribute value.
		:type value: str
		"""

        if value is not None:
            assert type(value) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format("uiClearImage", value)
            assert os.path.exists(value), "'{0}' attribute: '{1}' file doesn't exists!".format("uiClearImage", value)
        self.__uiClearImage = value

    @uiClearImage.deleter
    @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
    def uiClearImage(self):
        """
		Deleter for **self.__uiClearImage** attribute.
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "uiClearImage")
        )

    @property
    def uiClearClickedImage(self):
        """
		Property for **self.__uiClearClickedImage** attribute.

		:return: self.__uiClearClickedImage.
		:rtype: str
		"""

        return self.__uiClearClickedImage

    @uiClearClickedImage.setter
    @foundations.exceptions.handleExceptions(AssertionError)
    def uiClearClickedImage(self, value):
        """
		Setter for **self.__uiClearClickedImage** attribute.

		:param value: Attribute value.
		:type value: str
		"""

        if value is not None:
            assert type(value) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format(
                "uiClearClickedImage", value
            )
            assert os.path.exists(value), "'{0}' attribute: '{1}' file doesn't exists!".format(
                "uiClearClickedImage", value
            )
        self.__uiClearClickedImage = value

    @uiClearClickedImage.deleter
    @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
    def uiClearClickedImage(self):
        """
		Deleter for **self.__uiClearClickedImage** attribute.
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "uiClearClickedImage")
        )

    @property
    def searchActiveLabel(self):
        """
		Property for **self.__searchActiveLabel** attribute.

		:return: self.__searchActiveLabel.
		:rtype: QPushButton
		"""

        return self.__searchActiveLabel

    @searchActiveLabel.setter
    @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
    def searchActiveLabel(self, value):
        """
		Setter for **self.__searchActiveLabel** attribute.

		:param value: Attribute value.
		:type value: QPushButton
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "searchActiveLabel")
        )

    @searchActiveLabel.deleter
    @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
    def searchActiveLabel(self):
        """
		Deleter for **self.__searchActiveLabel** attribute.
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "searchActiveLabel")
        )

    @property
    def clearButton(self):
        """
		Property for **self.__clearButton** attribute.

		:return: self.__clearButton.
		:rtype: QPushButton
		"""

        return self.__clearButton

    @clearButton.setter
    @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
    def clearButton(self, value):
        """
		Setter for **self.__clearButton** attribute.

		:param value: Attribute value.
		:type value: QPushButton
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "clearButton")
        )

    @clearButton.deleter
    @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
    def clearButton(self):
        """
		Deleter for **self.__clearButton** attribute.
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "clearButton")
        )

    @property
    def completer(self):
        """
		Property for **self.__completer** attribute.

		:return: self.__completer.
		:rtype: QCompleter
		"""

        return self.__completer

    @completer.setter
    @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
    def completer(self, value):
        """
		Setter for **self.__completer** attribute.

		:param value: Attribute value.
		:type value: QCompleter
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "completer")
        )

    @completer.deleter
    @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
    def completer(self):
        """
		Deleter for **self.__completer** attribute.
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "completer")
        )

    @property
    def completerVisibleItemsCount(self):
        """
		Property for **self.__completerVisibleItemsCount** attribute.

		:return: self.__completerVisibleItemsCount.
		:rtype: int
		"""

        return self.__completerVisibleItemsCount

    @completerVisibleItemsCount.setter
    @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
    def completerVisibleItemsCount(self, value):
        """
		Setter for **self.__completerVisibleItemsCount** attribute.

		:param value: Attribute value.
		:type value: int
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "completerVisibleItemsCount")
        )

    @completerVisibleItemsCount.deleter
    @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
    def completerVisibleItemsCount(self):
        """
		Deleter for **self.__completerVisibleItemsCount** attribute.
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "completerVisibleItemsCount")
        )

        # ******************************************************************************************************************
        # ***	Class methods.
        # ******************************************************************************************************************

    def resizeEvent(self, event):
        """
		Reimplements the :meth:`QLineEdit.QResizeEvent` method.

		:param event: Resize event.
		:type event: QResizeEvent
		"""

        frameWidth = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth)
        searchActiveLabelSize = self.__searchActiveLabel.sizeHint()
        self.__searchActiveLabel.move(
            self.rect().left() + frameWidth,
            (self.rect().bottom() - searchActiveLabelSize.height()) / 2 + frameWidth / 2,
        )
        clearButtonSize = self.__clearButton.sizeHint()
        self.__clearButton.move(
            self.rect().right() - frameWidth - clearButtonSize.width(),
            (self.rect().bottom() - clearButtonSize.height()) / 2 + frameWidth / 2,
        )

    def __initializeUi(self):
        """
		Initializes the Widget ui.
		"""

        self.__clearButton.setCursor(Qt.ArrowCursor)
        if self.__uiClearImage and self.__uiClearClickedImage:
            pixmap = QPixmap(self.__uiClearImage)
            clickedPixmap = QPixmap(self.__uiClearClickedImage)
            self.__clearButton.setIcon(QIcon(pixmap))
            self.__clearButton.setMaximumSize(pixmap.size())

            # Signals / Slots.
            self.__clearButton.pressed.connect(functools.partial(self.__clearButton.setIcon, QIcon(clickedPixmap)))
            self.__clearButton.released.connect(functools.partial(self.__clearButton.setIcon, QIcon(pixmap)))
        else:
            self.__clearButton.setText("Clear")

        self.__setStyleSheet()

        frameWidth = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth)
        self.setMinimumSize(
            max(self.minimumSizeHint().width(), self.__clearButton.sizeHint().height() + frameWidth * 2),
            max(self.minimumSizeHint().height(), self.__clearButton.sizeHint().height() + frameWidth * 2),
        )

        self.__completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.__completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        # self.__completer.setMaxVisibleItems(self.__completerVisibleItemsCount)

    def __setStyleSheet(self):
        """
		Sets the Widget stylesheet.
		"""

        frameWidth = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth)
        self.setStyleSheet(
            QString(
                "QLineEdit {{ padding-left: {0}px; padding-right: {1}px; }}\nQToolButton {{ border: none; padding: 0px; }}".format(
                    self.__searchActiveLabel.sizeHint().width()
                    if self.__searchActiveLabel.isVisible()
                    else 0 + frameWidth,
                    self.__clearButton.sizeHint().width() + frameWidth,
                )
            )
        )

    def __setClearButtonVisibility(self, text):
        """
		Sets the clear button visibility.

		:param text: Current field text.
		:type text: QString
		"""

        if text:
            self.__clearButton.show()
        else:
            self.__clearButton.hide()
Example #7
0
class LineEdit(QLineEdit):
    """Extended QLineEdit.
    Supports prompt and Clear button
    """
    
    clearButtonClicked = pyqtSignal()
    """
    clearButtonClicked()
    
    **Signal** emitted, when Clear button has been clicked
    """

    def __init__(self, parent):
        QLineEdit.__init__(self, parent)

        self._margin = self.sizeHint().height() -2
        self._spacing = 0
        
        self._tbClear = QToolButton( self )
        self._tbClear.setIcon( QIcon(":enkiicons/fresh/edit-clear-rtl.png"))
        self._tbClear.setToolTip( tr( "Clear" ) )
        self._tbClear.setStyleSheet( "QToolButton { border: none; padding: 0px; }" )
        self._tbClear.setCursor( Qt.ArrowCursor )
        self._tbClear.setFocusPolicy( Qt.NoFocus )
        
        self.setClearButtonVisible( False )
        
        self.textChanged.connect(self._onTextChanged)
        self._tbClear.clicked.connect(self.clear)
        self._tbClear.clicked.connect(self.clearButtonClicked)

    def promptText(self):
        """Current prompt text
        """
        return self._promptText

    def setPromptText(self, prompt ):
        """Set prompt text
        """
        self._promptText = prompt
        self.update()

    def paintEvent(self, event ):
        """QLineEdit.paintEvent implementation.
        Draws prompt
        """
        QLineEdit.paintEvent( self, event )
        
        if self._promptText and not self.text() and self.isEnabled() :
            option = QStyleOptionFrameV3()
            self.initStyleOption( option )
            
            left, top, right, bottom = self.getTextMargins()
            
            va = self.style().visualAlignment( self.layoutDirection(), self.alignment() )
            rect = self.style().subElementRect( 
                QStyle.SE_LineEditContents, option, self ).adjusted( 2, 0, 0, 0 ).adjusted( left, top, -right, -bottom )
            fm = QFontMetrics ( self.font() )
            text = fm.elidedText( self._promptText, Qt.ElideRight, rect.width() )
            painter = QPainter ( self )
            
            painter.setPen( self.palette().color( QPalette.Disabled, QPalette.Text ) )
            painter.drawText( rect, va, text )

    def resizeEvent(self, event ):
        """QLineEdit.resizeEvent implementation
        Adjusts Clear button position
        """
        QLineEdit.resizeEvent( self, event )
        
        self._tbClear.resize( QSize( self._margin, self.height() -2 ) )
        self._tbClear.move( self.width() -self._margin -3, 0 )

    def setClearButtonVisible(self, visible ):
        """Set Clear button visible
        """
        self._tbClear.setVisible( visible )
        
        left, top, right, bottom = self.getTextMargins()
        
        if  visible :
            right = self._margin +self._spacing
        else:
            right = 0

        self.setTextMargins( left, top, right, bottom )

    def _onTextChanged(self, text ):
        """Text changed, update Clear button visibility
        """
        self.setClearButtonVisible( len(text) > 0 )
Example #8
0
class Search_QLineEdit(QLineEdit):
    """
	Defines a `QLineEdit <http://doc.qt.nokia.com/qlinedit.html>`_ subclass providing
	a search field with clearing capabilities.
	"""
    def __init__(self,
                 parent=None,
                 uiSearchImage=None,
                 uiSearchClickedImage=None,
                 uiClearImage=None,
                 uiClearClickedImage=None):
        """
		Initializes the class.

		:param parent: Widget parent.
		:type parent: QObject
		:param uiSearchImage: Search button image path.
		:type uiSearchImage: str
		:param uiSearchClickedImage: Search button clicked image path.
		:type uiSearchClickedImage: str
		:param uiClearImage: Clear button image path.
		:type uiClearImage: str
		:param uiClearClickedImage: Clear button clicked image path.
		:type uiClearClickedImage: str
		"""

        LOGGER.debug("> Initializing '{0}()' class.".format(
            self.__class__.__name__))

        QLineEdit.__init__(self, parent)

        # --- Setting class attributes. ---
        self.__uiSearchImage = None
        self.uiSearchImage = uiSearchImage or umbra.ui.common.getResourcePath(
            "images/Search_Glass.png")
        self.__uiSearchClickedImage = None
        self.uiSearchClickedImage = uiSearchClickedImage or umbra.ui.common.getResourcePath(
            "images/Search_Glass_Clicked.png")
        self.__uiClearImage = None
        self.uiClearImage = uiClearImage or umbra.ui.common.getResourcePath(
            "images/Search_Clear.png")
        self.__uiClearClickedImage = None
        self.uiClearClickedImage = uiClearClickedImage or umbra.ui.common.getResourcePath(
            "images/Search_Clear_Clicked.png")

        self.__searchActiveLabel = Active_QLabel(
            self, QPixmap(self.__uiSearchImage), QPixmap(self.__uiSearchImage),
            QPixmap(self.__uiSearchClickedImage))
        self.__searchActiveLabel.setObjectName("Search_Field_activeLabel")
        self.__searchActiveLabel.showEvent = lambda event: reduce(
            lambda *args: None,
            (self.__setStyleSheet(),
             Active_QLabel.showEvent(self.__searchActiveLabel, event)))
        self.__searchActiveLabel.hideEvent = lambda event: reduce(
            lambda *args: None,
            (self.__setStyleSheet(),
             Active_QLabel.hideEvent(self.__searchActiveLabel, event)))

        self.__clearButton = QToolButton(self)
        self.__clearButton.setObjectName("Clear_Field_button")

        self.__completer = QCompleter()
        self.setCompleter(self.__completer)
        self.__completerVisibleItemsCount = 16

        Search_QLineEdit.__initializeUi(self)
        self.__setClearButtonVisibility(self.text())

        # Signals / Slots.
        self.__clearButton.clicked.connect(self.clear)
        self.textChanged.connect(self.__setClearButtonVisibility)

    #******************************************************************************************************************
    #***	Attributes properties.
    #******************************************************************************************************************
    @property
    def uiSearchImage(self):
        """
		Property for **self.__uiSearchImage** attribute.

		:return: self.__uiSearchImage.
		:rtype: str
		"""

        return self.__uiSearchImage

    @uiSearchImage.setter
    @foundations.exceptions.handleExceptions(AssertionError)
    def uiSearchImage(self, value):
        """
		Setter for **self.__uiSearchImage** attribute.

		:param value: Attribute value.
		:type value: str
		"""

        if value is not None:
            assert type(
                value
            ) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format(
                "uiSearchImage", value)
            assert os.path.exists(
                value), "'{0}' attribute: '{1}' file doesn't exists!".format(
                    "uiSearchImage", value)
        self.__uiSearchImage = value

    @uiSearchImage.deleter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def uiSearchImage(self):
        """
		Deleter for **self.__uiSearchImage** attribute.
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is not deletable!".format(
                self.__class__.__name__, "uiSearchImage"))

    @property
    def uiSearchClickedImage(self):
        """
		Property for **self.__uiSearchClickedImage** attribute.

		:return: self.__uiSearchClickedImage.
		:rtype: str
		"""

        return self.__uiSearchClickedImage

    @uiSearchClickedImage.setter
    @foundations.exceptions.handleExceptions(AssertionError)
    def uiSearchClickedImage(self, value):
        """
		Setter for **self.__uiSearchClickedImage** attribute.

		:param value: Attribute value.
		:type value: str
		"""

        if value is not None:
            assert type(
                value
            ) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format(
                "uiSearchClickedImage", value)
            assert os.path.exists(
                value), "'{0}' attribute: '{1}' file doesn't exists!".format(
                    "uiSearchClickedImage", value)
        self.__uiSearchClickedImage = value

    @uiSearchClickedImage.deleter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def uiSearchClickedImage(self):
        """
		Deleter for **self.__uiSearchClickedImage** attribute.
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is not deletable!".format(
                self.__class__.__name__, "uiSearchClickedImage"))

    @property
    def uiClearImage(self):
        """
		Property for **self.__uiClearImage** attribute.

		:return: self.__uiClearImage.
		:rtype: str
		"""

        return self.__uiClearImage

    @uiClearImage.setter
    @foundations.exceptions.handleExceptions(AssertionError)
    def uiClearImage(self, value):
        """
		Setter for **self.__uiClearImage** attribute.

		:param value: Attribute value.
		:type value: str
		"""

        if value is not None:
            assert type(
                value
            ) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format(
                "uiClearImage", value)
            assert os.path.exists(
                value), "'{0}' attribute: '{1}' file doesn't exists!".format(
                    "uiClearImage", value)
        self.__uiClearImage = value

    @uiClearImage.deleter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def uiClearImage(self):
        """
		Deleter for **self.__uiClearImage** attribute.
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is not deletable!".format(
                self.__class__.__name__, "uiClearImage"))

    @property
    def uiClearClickedImage(self):
        """
		Property for **self.__uiClearClickedImage** attribute.

		:return: self.__uiClearClickedImage.
		:rtype: str
		"""

        return self.__uiClearClickedImage

    @uiClearClickedImage.setter
    @foundations.exceptions.handleExceptions(AssertionError)
    def uiClearClickedImage(self, value):
        """
		Setter for **self.__uiClearClickedImage** attribute.

		:param value: Attribute value.
		:type value: str
		"""

        if value is not None:
            assert type(
                value
            ) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format(
                "uiClearClickedImage", value)
            assert os.path.exists(
                value), "'{0}' attribute: '{1}' file doesn't exists!".format(
                    "uiClearClickedImage", value)
        self.__uiClearClickedImage = value

    @uiClearClickedImage.deleter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def uiClearClickedImage(self):
        """
		Deleter for **self.__uiClearClickedImage** attribute.
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is not deletable!".format(
                self.__class__.__name__, "uiClearClickedImage"))

    @property
    def searchActiveLabel(self):
        """
		Property for **self.__searchActiveLabel** attribute.

		:return: self.__searchActiveLabel.
		:rtype: QPushButton
		"""

        return self.__searchActiveLabel

    @searchActiveLabel.setter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def searchActiveLabel(self, value):
        """
		Setter for **self.__searchActiveLabel** attribute.

		:param value: Attribute value.
		:type value: QPushButton
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is read only!".format(
                self.__class__.__name__, "searchActiveLabel"))

    @searchActiveLabel.deleter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def searchActiveLabel(self):
        """
		Deleter for **self.__searchActiveLabel** attribute.
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is not deletable!".format(
                self.__class__.__name__, "searchActiveLabel"))

    @property
    def clearButton(self):
        """
		Property for **self.__clearButton** attribute.

		:return: self.__clearButton.
		:rtype: QPushButton
		"""

        return self.__clearButton

    @clearButton.setter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def clearButton(self, value):
        """
		Setter for **self.__clearButton** attribute.

		:param value: Attribute value.
		:type value: QPushButton
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is read only!".format(
                self.__class__.__name__, "clearButton"))

    @clearButton.deleter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def clearButton(self):
        """
		Deleter for **self.__clearButton** attribute.
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is not deletable!".format(
                self.__class__.__name__, "clearButton"))

    @property
    def completer(self):
        """
		Property for **self.__completer** attribute.

		:return: self.__completer.
		:rtype: QCompleter
		"""

        return self.__completer

    @completer.setter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def completer(self, value):
        """
		Setter for **self.__completer** attribute.

		:param value: Attribute value.
		:type value: QCompleter
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is read only!".format(
                self.__class__.__name__, "completer"))

    @completer.deleter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def completer(self):
        """
		Deleter for **self.__completer** attribute.
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is not deletable!".format(
                self.__class__.__name__, "completer"))

    @property
    def completerVisibleItemsCount(self):
        """
		Property for **self.__completerVisibleItemsCount** attribute.

		:return: self.__completerVisibleItemsCount.
		:rtype: int
		"""

        return self.__completerVisibleItemsCount

    @completerVisibleItemsCount.setter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def completerVisibleItemsCount(self, value):
        """
		Setter for **self.__completerVisibleItemsCount** attribute.

		:param value: Attribute value.
		:type value: int
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is read only!".format(
                self.__class__.__name__, "completerVisibleItemsCount"))

    @completerVisibleItemsCount.deleter
    @foundations.exceptions.handleExceptions(
        foundations.exceptions.ProgrammingError)
    def completerVisibleItemsCount(self):
        """
		Deleter for **self.__completerVisibleItemsCount** attribute.
		"""

        raise foundations.exceptions.ProgrammingError(
            "{0} | '{1}' attribute is not deletable!".format(
                self.__class__.__name__, "completerVisibleItemsCount"))

    #******************************************************************************************************************
    #***	Class methods.
    #******************************************************************************************************************
    def resizeEvent(self, event):
        """
		Reimplements the :meth:`QLineEdit.QResizeEvent` method.

		:param event: Resize event.
		:type event: QResizeEvent
		"""

        frameWidth = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth)
        searchActiveLabelSize = self.__searchActiveLabel.sizeHint()
        self.__searchActiveLabel.move(
            self.rect().left() + frameWidth,
            (self.rect().bottom() - searchActiveLabelSize.height()) / 2 +
            frameWidth / 2)
        clearButtonSize = self.__clearButton.sizeHint()
        self.__clearButton.move(
            self.rect().right() - frameWidth - clearButtonSize.width(),
            (self.rect().bottom() - clearButtonSize.height()) / 2 +
            frameWidth / 2)

    def __initializeUi(self):
        """
		Initializes the Widget ui.
		"""

        self.__clearButton.setCursor(Qt.ArrowCursor)
        if self.__uiClearImage and self.__uiClearClickedImage:
            pixmap = QPixmap(self.__uiClearImage)
            clickedPixmap = QPixmap(self.__uiClearClickedImage)
            self.__clearButton.setIcon(QIcon(pixmap))
            self.__clearButton.setMaximumSize(pixmap.size())

            # Signals / Slots.
            self.__clearButton.pressed.connect(
                functools.partial(self.__clearButton.setIcon,
                                  QIcon(clickedPixmap)))
            self.__clearButton.released.connect(
                functools.partial(self.__clearButton.setIcon, QIcon(pixmap)))
        else:
            self.__clearButton.setText("Clear")

        self.__setStyleSheet()

        frameWidth = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth)
        self.setMinimumSize(
            max(self.minimumSizeHint().width(),
                self.__clearButton.sizeHint().height() + frameWidth * 2),
            max(self.minimumSizeHint().height(),
                self.__clearButton.sizeHint().height() + frameWidth * 2))

        self.__completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.__completer.setCompletionMode(
            QCompleter.UnfilteredPopupCompletion)
        # self.__completer.setMaxVisibleItems(self.__completerVisibleItemsCount)

    def __setStyleSheet(self):
        """
		Sets the Widget stylesheet.
		"""

        frameWidth = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth)
        self.setStyleSheet(
            QString(
                "QLineEdit {{ padding-left: {0}px; padding-right: {1}px; }}\nQToolButton {{ border: none; padding: 0px; }}"
                .format(
                    self.__searchActiveLabel.sizeHint().width() if
                    self.__searchActiveLabel.isVisible() else 0 + frameWidth,
                    self.__clearButton.sizeHint().width() + frameWidth)))

    def __setClearButtonVisibility(self, text):
        """
		Sets the clear button visibility.

		:param text: Current field text.
		:type text: QString
		"""

        if text:
            self.__clearButton.show()
        else:
            self.__clearButton.hide()
class Search_QLineEdit(QLineEdit):
	"""
	This class is a `QLineEdit <http://doc.qt.nokia.com/qlinedit.html>`_ subclass providing
	a search field with clearing capabilities.
	"""

	@core.executionTrace
	def __init__(self,
				parent=None,
				uiSearchImage=None,
				uiSearchClickedImage=None,
				uiClearImage=None,
				uiClearClickedImage=None):
		"""
		This method initializes the class.

		:param parent: Widget parent. ( QObject )
		:param uiSearchImage: Search button image path. ( String )
		:param uiSearchClickedImage: Search button clicked image path. ( String )
		:param uiClearImage: Clear button image path. ( String )
		:param uiClearClickedImage: Clear button clicked image path. ( String )
		"""

		LOGGER.debug("> Initializing '{0}()' class.".format(self.__class__.__name__))

		QLineEdit.__init__(self, parent)

		# --- Setting class attributes. ---
		self.__uiSearchImage = None
		self.uiSearchImage = uiSearchImage or snippets.ui.common.getResourcePath("images/Search_Glass.png")
		self.__uiSearchClickedImage = None
		self.uiSearchClickedImage = uiSearchClickedImage or snippets.ui.common.getResourcePath(
		"images/Search_Glass_Clicked.png")
		self.__uiClearImage = None
		self.uiClearImage = uiClearImage or snippets.ui.common.getResourcePath("images/Search_Clear.png")
		self.__uiClearClickedImage = None
		self.uiClearClickedImage = uiClearClickedImage or snippets.ui.common.getResourcePath(
		"images/Search_Clear_Clicked.png")

		self.__searchActiveLabel = Active_QLabel(self,
												QPixmap(self.__uiSearchImage),
												QPixmap(self.__uiSearchImage),
												QPixmap(self.__uiSearchClickedImage))
		self.__searchActiveLabel.setObjectName("Search_Field_activeLabel")

		self.__clearButton = QToolButton(self)
		self.__clearButton.setObjectName("Clear_Field_button")

		self.__completer = QCompleter()
		self.setCompleter(self.__completer)
		self.__completerVisibleItemsCount = 16

		# TODO: Rollback to Search_QLineEdit.__initializeUi(self) whenever MPC changes it's PyQt version.
		self.__initializeUi()
		self.__setClearButtonVisibility(self.text())

		# Signals / Slots.
		self.__clearButton.clicked.connect(self.clear)
		self.textChanged.connect(self.__setClearButtonVisibility)

	#******************************************************************************************************************
	#***	Attributes properties.
	#******************************************************************************************************************
	@property
	def uiSearchImage(self):
		"""
		This method is the property for **self.__uiSearchImage** attribute.

		:return: self.__uiSearchImage. ( String )
		"""

		return self.__uiSearchImage

	@uiSearchImage.setter
	@foundations.exceptions.exceptionsHandler(None, False, AssertionError)
	def uiSearchImage(self, value):
		"""
		This method is the setter method for **self.__uiSearchImage** attribute.

		:param value: Attribute value. ( String )
		"""

		if value is not None:
			assert type(value) in (str, unicode), "'{0}' attribute: '{1}' type is not 'str' or 'unicode'!".format(
			"uiSearchImage", value)
			assert os.path.exists(value), "'{0}' attribute: '{1}' file doesn't exists!".format("uiSearchImage", value)
		self.__uiSearchImage = value

	@uiSearchImage.deleter
	@foundations.exceptions.exceptionsHandler(None, False, foundations.exceptions.ProgrammingError)
	def uiSearchImage(self):
		"""
		This method is the deleter method for **self.__uiSearchImage** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "uiSearchImage"))

	@property
	def uiSearchClickedImage(self):
		"""
		This method is the property for **self.__uiSearchClickedImage** attribute.

		:return: self.__uiSearchClickedImage. ( String )
		"""

		return self.__uiSearchClickedImage

	@uiSearchClickedImage.setter
	@foundations.exceptions.exceptionsHandler(None, False, AssertionError)
	def uiSearchClickedImage(self, value):
		"""
		This method is the setter method for **self.__uiSearchClickedImage** attribute.

		:param value: Attribute value. ( String )
		"""

		if value is not None:
			assert type(value) in (str, unicode), "'{0}' attribute: '{1}' type is not 'str' or 'unicode'!".format(
			"uiSearchClickedImage", value)
			assert os.path.exists(value), "'{0}' attribute: '{1}' file doesn't exists!".format(
			"uiSearchClickedImage", value)
		self.__uiSearchClickedImage = value

	@uiSearchClickedImage.deleter
	@foundations.exceptions.exceptionsHandler(None, False, foundations.exceptions.ProgrammingError)
	def uiSearchClickedImage(self):
		"""
		This method is the deleter method for **self.__uiSearchClickedImage** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "uiSearchClickedImage"))

	@property
	def uiClearImage(self):
		"""
		This method is the property for **self.__uiClearImage** attribute.

		:return: self.__uiClearImage. ( String )
		"""

		return self.__uiClearImage

	@uiClearImage.setter
	@foundations.exceptions.exceptionsHandler(None, False, AssertionError)
	def uiClearImage(self, value):
		"""
		This method is the setter method for **self.__uiClearImage** attribute.

		:param value: Attribute value. ( String )
		"""

		if value is not None:
			assert type(value) in (str, unicode), "'{0}' attribute: '{1}' type is not 'str' or 'unicode'!".format(
			"uiClearImage", value)
			assert os.path.exists(value), "'{0}' attribute: '{1}' file doesn't exists!".format(
			"uiClearImage", value)
		self.__uiClearImage = value

	@uiClearImage.deleter
	@foundations.exceptions.exceptionsHandler(None, False, foundations.exceptions.ProgrammingError)
	def uiClearImage(self):
		"""
		This method is the deleter method for **self.__uiClearImage** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "uiClearImage"))

	@property
	def uiClearClickedImage(self):
		"""
		This method is the property for **self.__uiClearClickedImage** attribute.

		:return: self.__uiClearClickedImage. ( String )
		"""

		return self.__uiClearClickedImage

	@uiClearClickedImage.setter
	@foundations.exceptions.exceptionsHandler(None, False, AssertionError)
	def uiClearClickedImage(self, value):
		"""
		This method is the setter method for **self.__uiClearClickedImage** attribute.

		:param value: Attribute value. ( String )
		"""

		if value is not None:
			assert type(value) in (str, unicode), "'{0}' attribute: '{1}' type is not 'str' or 'unicode'!".format(
			"uiClearClickedImage", value)
			assert os.path.exists(value), "'{0}' attribute: '{1}' file doesn't exists!".format(
			"uiClearClickedImage", value)
		self.__uiClearClickedImage = value

	@uiClearClickedImage.deleter
	@foundations.exceptions.exceptionsHandler(None, False, foundations.exceptions.ProgrammingError)
	def uiClearClickedImage(self):
		"""
		This method is the deleter method for **self.__uiClearClickedImage** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "uiClearClickedImage"))

	@property
	def searchActiveLabel(self):
		"""
		This method is the property for **self.__searchActiveLabel** attribute.

		:return: self.__searchActiveLabel. ( QPushButton )
		"""

		return self.__searchActiveLabel

	@searchActiveLabel.setter
	@foundations.exceptions.exceptionsHandler(None, False, foundations.exceptions.ProgrammingError)
	def searchActiveLabel(self, value):
		"""
		This method is the setter method for **self.__searchActiveLabel** attribute.

		:param value: Attribute value. ( QPushButton )
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "searchActiveLabel"))

	@searchActiveLabel.deleter
	@foundations.exceptions.exceptionsHandler(None, False, foundations.exceptions.ProgrammingError)
	def searchActiveLabel(self):
		"""
		This method is the deleter method for **self.__searchActiveLabel** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "searchActiveLabel"))

	@property
	def clearButton(self):
		"""
		This method is the property for **self.__clearButton** attribute.

		:return: self.__clearButton. ( QPushButton )
		"""

		return self.__clearButton

	@clearButton.setter
	@foundations.exceptions.exceptionsHandler(None, False, foundations.exceptions.ProgrammingError)
	def clearButton(self, value):
		"""
		This method is the setter method for **self.__clearButton** attribute.

		:param value: Attribute value. ( QPushButton )
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "clearButton"))

	@clearButton.deleter
	@foundations.exceptions.exceptionsHandler(None, False, foundations.exceptions.ProgrammingError)
	def clearButton(self):
		"""
		This method is the deleter method for **self.__clearButton** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "clearButton"))

	@property
	def completer(self):
		"""
		This method is the property for **self.__completer** attribute.

		:return: self.__completer. ( QCompleter )
		"""

		return self.__completer

	@completer.setter
	@foundations.exceptions.exceptionsHandler(None, False, foundations.exceptions.ProgrammingError)
	def completer(self, value):
		"""
		This method is the setter method for **self.__completer** attribute.

		:param value: Attribute value. ( QCompleter )
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "completer"))

	@completer.deleter
	@foundations.exceptions.exceptionsHandler(None, False, foundations.exceptions.ProgrammingError)
	def completer(self):
		"""
		This method is the deleter method for **self.__completer** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "completer"))

	@property
	def completerVisibleItemsCount(self):
		"""
		This method is the property for **self.__completerVisibleItemsCount** attribute.

		:return: self.__completerVisibleItemsCount. ( Integer )
		"""

		return self.__completerVisibleItemsCount

	@completerVisibleItemsCount.setter
	@foundations.exceptions.exceptionsHandler(None, False, foundations.exceptions.ProgrammingError)
	def completerVisibleItemsCount(self, value):
		"""
		This method is the setter method for **self.__completerVisibleItemsCount** attribute.

		:param value: Attribute value. ( Integer )
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "completerVisibleItemsCount"))

	@completerVisibleItemsCount.deleter
	@foundations.exceptions.exceptionsHandler(None, False, foundations.exceptions.ProgrammingError)
	def completerVisibleItemsCount(self):
		"""
		This method is the deleter method for **self.__completerVisibleItemsCount** attribute.
		"""

		raise foundations.exceptions.ProgrammingError(
		"{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "completerVisibleItemsCount"))

	#******************************************************************************************************************
	#***	Class methods.
	#******************************************************************************************************************
	@core.executionTrace
	def resizeEvent(self, event):
		"""
		This method reimplements the :meth:`QLineEdit.QResizeEvent` method.

		:param event: Resize event. ( QResizeEvent )
		"""

		frameWidth = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth)
		searchActiveLabelSize = self.__searchActiveLabel.sizeHint()
		self.__searchActiveLabel.move(self.rect().left() + frameWidth,
		(self.rect().bottom() - searchActiveLabelSize.height()) / 2 + frameWidth / 2)
		clearButtonSize = self.__clearButton.sizeHint()
		self.__clearButton.move(self.rect().right() - frameWidth - clearButtonSize.width(),
		(self.rect().bottom() - clearButtonSize.height()) / 2 + frameWidth / 2)

	@core.executionTrace
	def __initializeUi(self):
		"""
		This method initializes the Widget ui.
		"""

		self.__clearButton.setCursor(Qt.ArrowCursor)
		if self.__uiClearImage and self.__uiClearClickedImage:
			pixmap = QPixmap(self.__uiClearImage)
			clickedPixmap = QPixmap(self.__uiClearClickedImage)
			self.__clearButton.setStyleSheet("QToolButton { border: none; padding: 0px; }")
			self.__clearButton.setIcon(QIcon(pixmap))
			self.__clearButton.setMaximumSize(pixmap.size())

			# Signals / Slots.
			self.__clearButton.pressed.connect(functools.partial(self.__clearButton.setIcon, QIcon(clickedPixmap)))
			self.__clearButton.released.connect(functools.partial(self.__clearButton.setIcon, QIcon(pixmap)))
		else:
			self.__clearButton.setText("Clear")

		frameWidth = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth)
		self.setStyleSheet(QString("QLineEdit {{ padding-left: {0}px; padding-right: {1}px; }}".format(
		self.__searchActiveLabel.sizeHint().width() + frameWidth, self.__clearButton.sizeHint().width() + frameWidth)))

		self.setMinimumSize(max(self.minimumSizeHint().width(), self.__clearButton.sizeHint().height() + frameWidth * 2),
		 					max(self.minimumSizeHint().height(), self.__clearButton.sizeHint().height() + frameWidth * 2))

		self.__completer.setCaseSensitivity(Qt.CaseInsensitive)
		self.__completer.setCompletionMode(QCompleter.PopupCompletion)
		# TODO: Restore next line whnever MPC changes it's PyQt version.
		# self.__completer.setMaxVisibleItems(self.__completerVisibleItemsCount)

	@core.executionTrace
	def __setClearButtonVisibility(self, text):
		"""
		This method sets the clear button visibility.

		:param text: Current field text. ( QString )
		"""

		if text:
			self.__clearButton.show()
		else:
			self.__clearButton.hide()
Example #10
0
class LineEdit(QLineEdit):
    """Extended QLineEdit.
    Supports prompt and Clear button
    """

    clearButtonClicked = pyqtSignal()
    """
    clearButtonClicked()
    
    **Signal** emitted, when Clear button has been clicked
    """
    def __init__(self, parent):
        QLineEdit.__init__(self, parent)

        self._margin = self.sizeHint().height() - 2
        self._spacing = 0

        self._tbClear = QToolButton(self)
        self._tbClear.setIcon(QIcon(":enkiicons/edit-clear-rtl.png"))
        self._tbClear.setToolTip(tr("Clear"))
        self._tbClear.setStyleSheet(
            "QToolButton { border: none; padding: 0px; }")
        self._tbClear.setCursor(Qt.ArrowCursor)
        self._tbClear.setFocusPolicy(Qt.NoFocus)

        self.setClearButtonVisible(False)

        self.textChanged.connect(self._onTextChanged)
        self._tbClear.clicked.connect(self.clear)
        self._tbClear.clicked.connect(self.clearButtonClicked)

    def promptText(self):
        """Current prompt text
        """
        return self._promptText

    def setPromptText(self, prompt):
        """Set prompt text
        """
        self._promptText = prompt
        self.update()

    def paintEvent(self, event):
        """QLineEdit.paintEvent implementation.
        Draws prompt
        """
        QLineEdit.paintEvent(self, event)

        if self._promptText and not self.text() and self.isEnabled():
            option = QStyleOptionFrameV3()
            self.initStyleOption(option)

            left, top, right, bottom = self.getTextMargins()

            va = self.style().visualAlignment(self.layoutDirection(),
                                              self.alignment())
            rect = self.style().subElementRect(
                QStyle.SE_LineEditContents, option,
                self).adjusted(2, 0, 0, 0).adjusted(left, top, -right, -bottom)
            fm = QFontMetrics(self.font())
            text = fm.elidedText(self._promptText, Qt.ElideRight, rect.width())
            painter = QPainter(self)

            painter.setPen(self.palette().color(QPalette.Disabled,
                                                QPalette.Text))
            painter.drawText(rect, va, text)

    def resizeEvent(self, event):
        """QLineEdit.resizeEvent implementation
        Adjusts Clear button position
        """
        QLineEdit.resizeEvent(self, event)

        self._tbClear.resize(QSize(self._margin, self.height() - 2))
        self._tbClear.move(self.width() - self._margin - 3, 0)

    def setClearButtonVisible(self, visible):
        """Set Clear button visible
        """
        self._tbClear.setVisible(visible)

        left, top, right, bottom = self.getTextMargins()

        if visible:
            right = self._margin + self._spacing
        else:
            right = 0

        self.setTextMargins(left, top, right, bottom)

    def _onTextChanged(self, text):
        """Text changed, update Clear button visibility
        """
        self.setClearButtonVisible(len(text) > 0)