umbra.ui.widgets.search_QLineEdit — Umbra 1.0.9 documentation

# Source code for umbra.ui.widgets.search_QLineEdit

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-

    """
    **search_QLineEdit.py**

    **Platform:**
    	Windows, Linux, Mac Os X.

    **Description:**
    	Defines the :class:`Search_QLineEdit` class.

    **Others:**

    """

    #**********************************************************************************************************************
    #***	Future imports.
    #**********************************************************************************************************************
    from __future__ import unicode_literals

    #**********************************************************************************************************************
    #***	External imports.
    #**********************************************************************************************************************
    import functools
    import os
    from PyQt4.QtCore import QString
    from PyQt4.QtCore import Qt
    from PyQt4.QtGui import QCompleter
    from PyQt4.QtGui import QIcon
    from PyQt4.QtGui import QLineEdit
    from PyQt4.QtGui import QPixmap
    from PyQt4.QtGui import QStyle
    from PyQt4.QtGui import QToolButton

    #**********************************************************************************************************************
    #***	Internal imports.
    #**********************************************************************************************************************
    import foundations.exceptions
    import foundations.verbose
    import umbra.ui.common
    from umbra.ui.widgets.active_QLabel import Active_QLabel

    #**********************************************************************************************************************
    #***	Module attributes.
    #**********************************************************************************************************************
    __author__ = "Thomas Mansencal"
    __copyright__ = "Copyright (C) 2008 - 2014 - Thomas Mansencal"
    __license__ = "GPL V3.0 - http://www.gnu.org/licenses/"
    __maintainer__ = "Thomas Mansencal"
    __email__ = "thomas.mansencal@gmail.com"
    __status__ = "Production"

    __all__ = ["LOGGER", "Search_QLineEdit"]

    LOGGER = foundations.verbose.installLogger()

    #**********************************************************************************************************************
    #***	Module classes and definitions.
    #**********************************************************************************************************************
    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: unicode
    		:param uiSearchClickedImage: Search button clicked image path.
    		:type uiSearchClickedImage: unicode
    		:param uiClearImage: Clear button image path.
    		:type uiClearImage: unicode
    		:param uiClearClickedImage: Clear button clicked image path.
    		:type uiClearClickedImage: unicode
    		"""

    		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: unicode
    		"""

    		return self.__uiSearchImage

    	@uiSearchImage.setter
    # Oncilla: Statement commented by auto-documentation process: 	@foundations.exceptions.handleExceptions(AssertionError)
    	def uiSearchImage(self, value):
    		"""
    		Setter for **self.__uiSearchImage** attribute.

    		:param value: Attribute value.
    		:type value: unicode
    		"""

    		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
    # Oncilla: Statement commented by auto-documentation process: 	@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: unicode
    		"""

    		return self.__uiSearchClickedImage

    	@uiSearchClickedImage.setter
    # Oncilla: Statement commented by auto-documentation process: 	@foundations.exceptions.handleExceptions(AssertionError)
    	def uiSearchClickedImage(self, value):
    		"""
    		Setter for **self.__uiSearchClickedImage** attribute.

    		:param value: Attribute value.
    		:type value: unicode
    		"""

    		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
    # Oncilla: Statement commented by auto-documentation process: 	@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: unicode
    		"""

    		return self.__uiClearImage

    	@uiClearImage.setter
    # Oncilla: Statement commented by auto-documentation process: 	@foundations.exceptions.handleExceptions(AssertionError)
    	def uiClearImage(self, value):
    		"""
    		Setter for **self.__uiClearImage** attribute.

    		:param value: Attribute value.
    		:type value: unicode
    		"""

    		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
    # Oncilla: Statement commented by auto-documentation process: 	@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: unicode
    		"""

    		return self.__uiClearClickedImage

    	@uiClearClickedImage.setter
    # Oncilla: Statement commented by auto-documentation process: 	@foundations.exceptions.handleExceptions(AssertionError)
    	def uiClearClickedImage(self, value):
    		"""
    		Setter for **self.__uiClearClickedImage** attribute.

    		:param value: Attribute value.
    		:type value: unicode
    		"""

    		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
    # Oncilla: Statement commented by auto-documentation process: 	@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
    # Oncilla: Statement commented by auto-documentation process: 	@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
    # Oncilla: Statement commented by auto-documentation process: 	@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
    # Oncilla: Statement commented by auto-documentation process: 	@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
    # Oncilla: Statement commented by auto-documentation process: 	@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
    # Oncilla: Statement commented by auto-documentation process: 	@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
    # Oncilla: Statement commented by auto-documentation process: 	@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
    # Oncilla: Statement commented by auto-documentation process: 	@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
    # Oncilla: Statement commented by auto-documentation process: 	@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; }}".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()
    # Oncilla: Statement commented by auto-documentation process:
    # Oncilla: Statement commented by auto-documentation process: if __name__ == "__main__":
    # Oncilla: Statement commented by auto-documentation process: 	import sys
    # Oncilla: Statement commented by auto-documentation process: 	from PyQt4.QtGui import QGridLayout
    # Oncilla: Statement commented by auto-documentation process: 	from PyQt4.QtGui import QStringListModel
    # Oncilla: Statement commented by auto-documentation process: 	from PyQt4.QtGui import QWidget
    # Oncilla: Statement commented by auto-documentation process:
    # Oncilla: Statement commented by auto-documentation process: 	application = umbra.ui.common.getApplicationInstance()
    # Oncilla: Statement commented by auto-documentation process:
    # Oncilla: Statement commented by auto-documentation process: 	widget = QWidget()
    # Oncilla: Statement commented by auto-documentation process:
    # Oncilla: Statement commented by auto-documentation process: 	gridLayout = QGridLayout()
    # Oncilla: Statement commented by auto-documentation process: 	widget.setLayout(gridLayout)
    # Oncilla: Statement commented by auto-documentation process:
    # Oncilla: Statement commented by auto-documentation process: 	search_QLineEditA = Search_QLineEdit()
    # Oncilla: Statement commented by auto-documentation process: 	gridLayout.addWidget(search_QLineEditA)
    # Oncilla: Statement commented by auto-documentation process:
    # Oncilla: Statement commented by auto-documentation process: 	search_QLineEditA.completer.setModel(QStringListModel([(letter * 8).title() for letter in map(chr, range(97, 123))]))
    # Oncilla: Statement commented by auto-documentation process: 	search_QLineEditA.setPlaceholderText("Search...")
    # Oncilla: Statement commented by auto-documentation process:
    # Oncilla: Statement commented by auto-documentation process: 	search_QLineEditB = Search_QLineEdit()
    # Oncilla: Statement commented by auto-documentation process: 	search_QLineEditB.searchActiveLabel.hide()
    # Oncilla: Statement commented by auto-documentation process: 	gridLayout.addWidget(search_QLineEditB)
    # Oncilla: Statement commented by auto-documentation process:
    # Oncilla: Statement commented by auto-documentation process: 	widget.show()
    # Oncilla: Statement commented by auto-documentation process: 	widget.raise_()
    # Oncilla: Statement commented by auto-documentation process:
    # Oncilla: Statement commented by auto-documentation process: 	sys.exit(application.exec_())
    # Oncilla: Statement commented by auto-documentation process:
    # Oncilla: Statement commented by auto-documentation process: