Пример #1
0
    def _addStringProperty(self,bool,deletable=True):

        layout2=QHBoxLayout()

        findPropertyNameLabel = QLabel("Property: ")
        findPropertyNameLineEdit = QLineEdit()
        findPropertyNameLineEdit.setToolTip("Example: Label = Particle1 ")
        findPropertyValueLabel = QLabel(" = ")
        findPropertyValueLineEdit = QLineEdit()
        findPropertyValueLineEdit.setToolTip("Example: Label = Particle1 ")
        propertyAdd = QToolButton()
        propertyAdd.setText("+")
        propertyDelete = QToolButton()
        propertyDelete.setText("-")
        
        if deletable:
            propertyAdd.hide()
        else:
            propertyDelete.hide()
        layout2.addWidget(propertyAdd)
        layout2.addWidget(propertyDelete)
        layout2.addWidget(findPropertyNameLabel)
        layout2.addWidget(findPropertyNameLineEdit)
        layout2.addWidget(findPropertyValueLabel)
        layout2.addWidget(findPropertyValueLineEdit)

        self.connect(findPropertyNameLineEdit, SIGNAL('textChanged(QString)'), self.edited)
        self.connect(findPropertyValueLineEdit, SIGNAL('textChanged(QString)'), self.edited)
        self.connect(propertyAdd, SIGNAL('clicked(bool)'), self._addStringProperty)
        self.connect(propertyDelete, SIGNAL('clicked(bool)'), self._removeProperty)

        self.layout().insertLayout(len(self._properties)+len(self._scripts)+1,layout2)
        
        self._properties+=[(layout2,findPropertyNameLineEdit,findPropertyValueLineEdit,findPropertyNameLabel,findPropertyValueLabel,propertyAdd,propertyDelete)]
Пример #2
0
    def _addScript(self,bool,deletable=True):

        layout2=QHBoxLayout()

        findScriptLabel = QLabel("Filter = ")
        findScriptLineEdit = QLineEdit("")
        findScriptLineEdit.setToolTip("Example: object.Label == 'Particle1' ")
        scriptAdd = QToolButton()
        scriptAdd.setText("+")
        scriptDelete = QToolButton()
        scriptDelete.setText("-")
        
        if deletable:
            scriptAdd.hide()
        else:
            scriptDelete.hide()
        layout2.addWidget(scriptAdd)
        layout2.addWidget(scriptDelete)
        layout2.addWidget(findScriptLabel)
        layout2.addWidget(findScriptLineEdit)

        self.connect(findScriptLineEdit, SIGNAL('textChanged(QString)'), self.edited)
        self.connect(scriptAdd, SIGNAL('clicked(bool)'), self._addScript)
        self.connect(scriptDelete, SIGNAL('clicked(bool)'), self._removeScript)

        self.layout().insertLayout(len(self._properties)+len(self._scripts)+1,layout2)
        
        self._scripts+=[(layout2,findScriptLineEdit,findScriptLabel,scriptAdd,scriptDelete)]
Пример #3
0
class ClosableProperty(QWidget):
    def __init__(self, property):
        QWidget.__init__(self)
        self.setContentsMargins(0, 0, 0, 0)
        self.setLayout(QHBoxLayout())
        self.layout().setSpacing(0)
        self.layout().setContentsMargins(0, 0, 0, 0)
        self.layout().addWidget(property)
        self._closeButton = QToolButton()
        self._closeButton.setText("x")
        self._closeButton.hide()
        self._property = property
        self.layout().addWidget(self._closeButton)

    def closableProperty(self):
        return self._property

    def closeButton(self):
        return self._closeButton

    def enterEvent(self, event):
        self._closeButton.show()

    def leaveEvent(self, event):
        self._closeButton.hide()
Пример #4
0
    def _addScript(self, bool, deletable=True):

        layout2 = QHBoxLayout()

        findScriptLabel = QLabel("Filter = ")
        findScriptLineEdit = QLineEdit("")
        findScriptLineEdit.setToolTip("Example: object.Label == 'Particle1' ")
        scriptAdd = QToolButton()
        scriptAdd.setText("+")
        scriptDelete = QToolButton()
        scriptDelete.setText("-")

        if deletable:
            scriptAdd.hide()
        else:
            scriptDelete.hide()
        layout2.addWidget(scriptAdd)
        layout2.addWidget(scriptDelete)
        layout2.addWidget(findScriptLabel)
        layout2.addWidget(findScriptLineEdit)

        self.connect(findScriptLineEdit, SIGNAL("textChanged(QString)"), self.edited)
        self.connect(scriptAdd, SIGNAL("clicked(bool)"), self._addScript)
        self.connect(scriptDelete, SIGNAL("clicked(bool)"), self._removeScript)

        self.layout().insertLayout(len(self._properties) + len(self._scripts) + 1, layout2)

        self._scripts += [(layout2, findScriptLineEdit, findScriptLabel, scriptAdd, scriptDelete)]
Пример #5
0
    def _addStringProperty(self, bool, deletable=True):

        layout2 = QHBoxLayout()

        findPropertyNameLabel = QLabel("Property: ")
        findPropertyNameLineEdit = QLineEdit()
        findPropertyNameLineEdit.setToolTip("Example: Label = Particle1 ")
        findPropertyValueLabel = QLabel(" = ")
        findPropertyValueLineEdit = QLineEdit()
        findPropertyValueLineEdit.setToolTip("Example: Label = Particle1 ")
        propertyAdd = QToolButton()
        propertyAdd.setText("+")
        propertyDelete = QToolButton()
        propertyDelete.setText("-")

        if deletable:
            propertyAdd.hide()
        else:
            propertyDelete.hide()
        layout2.addWidget(propertyAdd)
        layout2.addWidget(propertyDelete)
        layout2.addWidget(findPropertyNameLabel)
        layout2.addWidget(findPropertyNameLineEdit)
        layout2.addWidget(findPropertyValueLabel)
        layout2.addWidget(findPropertyValueLineEdit)

        self.connect(findPropertyNameLineEdit, SIGNAL("textChanged(QString)"), self.edited)
        self.connect(findPropertyValueLineEdit, SIGNAL("textChanged(QString)"), self.edited)
        self.connect(propertyAdd, SIGNAL("clicked(bool)"), self._addStringProperty)
        self.connect(propertyDelete, SIGNAL("clicked(bool)"), self._removeProperty)

        self.layout().insertLayout(len(self._properties) + len(self._scripts) + 1, layout2)

        self._properties += [
            (
                layout2,
                findPropertyNameLineEdit,
                findPropertyValueLineEdit,
                findPropertyNameLabel,
                findPropertyValueLabel,
                propertyAdd,
                propertyDelete,
            )
        ]
Пример #6
0
class ClosableProperty(QWidget):
    def __init__(self,property):
        QWidget.__init__(self)
        self.setContentsMargins(0, 0, 0, 0)
        self.setLayout(QHBoxLayout())
        self.layout().setSpacing(0)
        self.layout().setContentsMargins(0, 0, 0, 0)
        self.layout().addWidget(property)
        self._closeButton=QToolButton()
        self._closeButton.setText("x")
        self._closeButton.hide()
        self._property=property
        self.layout().addWidget(self._closeButton)
    def closableProperty(self):
        return self._property
    def closeButton(self):
        return self._closeButton
    def enterEvent(self,event):
        self._closeButton.show()
    def leaveEvent(self,event):
        self._closeButton.hide()
Пример #7
0
class XSearchEdit(XLineEdit):
    def __init__(self, parent=None):
        super(XSearchEdit, self).__init__(parent)

        # setup custom properties
        self._cancelButton = QToolButton(self)
        self._cancelButton.setIcon(QIcon(
            resources.find('img/remove_dark.png')))
        self._cancelButton.setAutoRaise(True)
        self._cancelButton.setToolTip('Clear Search Text')
        self._cancelButton.hide()
        self.addButton(self._cancelButton)

        # setup default properties
        self.setHint('enter search')
        self.setIcon(QIcon(resources.find('img/search.png')))
        self.setCornerRadius(8)
        self.adjustStyleSheet()
        self.adjustTextMargins()

        # create connections
        self._cancelButton.clicked.connect(self.clear)
        self.textChanged.connect(self.toggleCancelButton)

    def clear(self):
        """
        Clears the search text for this instance.
        """
        super(XLineEdit, self).clear()

        self.textEntered.emit('')

    def toggleCancelButton(self):
        """
        Toggles the visibility for the cancel button based on the current
        text.
        """
        self._cancelButton.setVisible(self.text() != '')
Пример #8
0
class TextEditWithButtonProperty(Property, QWidget):
    """ This class provides a PropertyView property holding an editable text and a button.
    
    It is possible to hide the button unless the mouse cursor is over the property. This feature is turned on by default. See setAutohideButton().
    If the button is pressed nothing happens. This functionality should be implemented in sub-classes. See buttonClicked().
    The text field can hold single or multiple lines. See setMultiline()
    """

    BUTTON_LABEL = ''
    AUTOHIDE_BUTTON = True

    def __init__(self, name, value, categoryName=None, multiline=False):
        """ The constructor creates a QHBoxLayout and calls createLineEdit(), createTextEdit() and createButton(). 
        """
        Property.__init__(self, name, categoryName)
        QWidget.__init__(self)
        self._lineEdit = None
        self._textEdit = None
        self._button = None
        self.setAutohideButton(self.AUTOHIDE_BUTTON)

        self.setLayout(QHBoxLayout())
        self.layout().setSpacing(0)
        self.layout().setContentsMargins(0, 0, 0, 0)

        self._readOnly = False
        self._multiline = False

        self.createLineEdit()
        self.createTextEdit()
        self.createButton()
        self.setMultiline(multiline)
        self.setValue(value)

    def setValue(self, value):
        """ Sets value of text edit.
        """
        self._originalValue = value
        if value != None:
            strValue = str(value)
        else:
            strValue = ""
        if not self._readOnly:
            self.disconnect(self._lineEdit, SIGNAL('editingFinished()'),
                            self.valueChanged)
            self.disconnect(self._textEdit, SIGNAL('editingFinished()'),
                            self.valueChanged)
        self._lineEdit.setText(strValue)
        self._textEdit.setText(strValue)
        self.setToolTip(strValue)
        if not self._readOnly:
            self.connect(self._lineEdit, SIGNAL('editingFinished()'),
                         self.valueChanged)
            self.connect(self._textEdit, SIGNAL('editingFinished()'),
                         self.valueChanged)
        # TODO: sometimes when changing value the text edit appears to be empty when new text is shorter than old text
        #if not self._multiline:
        #    self._textEdit.setCursorPosition(self._textEdit.displayText().length())

    def setToolTip(self, text):
        self._lineEdit.setToolTip(text)
        self._textEdit.setToolTip(text)

    def setMultiline(self, multi):
        """ Switch between single and multi line mode.
        """
        self.setValue(self.strValue())
        self._multiline = multi
        if self._multiline:
            self._textEdit.show()
            self._lineEdit.hide()
            self.setFocusProxy(self._textEdit)
        else:
            self._lineEdit.show()
            self._textEdit.hide()
            self.setFocusProxy(self._lineEdit)

    def createLineEdit(self, value=None):
        """ This function creates the signle line text field and adds it to the property's layout. 
        """
        self._lineEdit = QLineEdit(self)
        self._lineEdit.setFrame(False)
        self.connect(self._lineEdit, SIGNAL('editingFinished()'),
                     self.valueChanged)
        self._lineEdit.setContentsMargins(0, 0, 0, 0)
        self._lineEdit.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.MinimumExpanding))
        self.layout().addWidget(self._lineEdit)

    def createTextEdit(self, value=None):
        """ This function creates the multi line text field and adds it to the property's layout. 
        """
        self._textEdit = TextEdit(self)
        self._textEdit.setWordWrapMode(QTextOption.NoWrap)
        self._textEdit.setFrameStyle(QFrame.NoFrame)
        self.connect(self._textEdit, SIGNAL('editingFinished()'),
                     self.valueChanged)
        self._textEdit.setContentsMargins(0, 0, 0, 0)
        self._textEdit.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.MinimumExpanding))
        self.layout().addWidget(self._textEdit)

    def properyHeight(self):
        """ Return the estimated height of the property.
        
        The returned height covers the whole text, even if multiline.
        """
        if self._multiline:
            self._textEdit.document().adjustSize()
            height = self._textEdit.document().size().height() + 3
            if self._textEdit.horizontalScrollBar().isVisible():
                height += self._textEdit.horizontalScrollBar().height() + 3
            return height
        else:
            return self.DEFAULT_HEIGHT

    def lineEdit(self):
        """ Returns line edit.
        """
        return self._lineEdit

    def textEdit(self):
        """ Returns text edit.
        """
        return self._textEdit

    def createButton(self):
        """ Creates a button and adds it to the property's layout.
        """
        self._button = QToolButton(self)
        self._button.setText(self.BUTTON_LABEL)
        self._button.setContentsMargins(0, 0, 0, 0)
        self.connect(self._button, SIGNAL('clicked(bool)'), self.buttonClicked)
        self.layout().addWidget(self._button)

        if self.autohideButtonFlag:
            self._button.hide()

    def button(self):
        """ Return button.
        """
        return self._button

    def hasButton(self):
        """ Returns True if the button has been created, otherwise False is returned. 
        """
        return self._button != None

    def setReadOnly(self, readOnly):
        """ Switch between readonly and editable.
        """
        self._readOnly = readOnly
        if not self.lineEdit().isReadOnly() and readOnly:
            self.disconnect(self._lineEdit, SIGNAL('editingFinished()'),
                            self.valueChanged)
            self.disconnect(self._textEdit, SIGNAL('editingFinished()'),
                            self.valueChanged)
            if self.hasButton():
                self._button = None
        if self.lineEdit().isReadOnly() and not readOnly:
            self.connect(self._lineEdit, SIGNAL('editingFinished()'),
                         self.valueChanged)
            self.connect(self._textEdit, SIGNAL('editingFinished()'),
                         self.valueChanged)
            if not self.hasButton():
                self.createButton()
        self.lineEdit().setReadOnly(readOnly)
        self.textEdit().setReadOnly(readOnly)

    def readOnly(self):
        return self._readOnly

    def strValue(self):
        """ Returns value of text edit.
        """
        if not self._multiline:
            return str(self._lineEdit.text().toAscii())
        else:
            return str(self._textEdit.toPlainText().toAscii())
        return ""

    def value(self):
        """ Returns the value of correct type (in case its not a string).
        """
        return self.strValue()

    def setAutohideButton(self, hide):
        """ If hide is True the button will only be visible while the cursor is over the property. 
        """
        self.autohideButtonFlag = hide

    def buttonClicked(self, checked=False):
        """
        This function is called if the button was clicked. For information on the checked argument see documentation of QPushButton::clicked().
        This function should be overwritten by sub-classes.
        """
        pass

    def enterEvent(self, event):
        """ If autohideButtonFlag is set this function makes the button visible. See setAutohideButton(). 
        """
        if self.autohideButtonFlag and self.hasButton() and not self._readOnly:
            self._button.show()

    def leaveEvent(self, event):
        """ If autohideButtonFlag is set this function makes the button invisible. See setAutohideButton(). 
        """
        if self.autohideButtonFlag and self.hasButton() and not self._readOnly:
            self._button.hide()

    def valueChanged(self):
        """ Update tooltip and height when text is changed.
        """
        if self._multiline:
            self.emit(SIGNAL('updatePropertyHeight'), self)
        self.setToolTip(self.strValue())
        # set property only if button is not being pressed
        if not self.button() or not self.button().isDown():
            Property.valueChanged(self)

    def setHighlighted(self, highlight):
        """ Highlight the property by changing the background color of the textfield.
        """
        p = QPalette()
        if highlight:
            p.setColor(QPalette.Active, QPalette.ColorRole(9), Qt.red)
        else:
            p.setColor(QPalette.Active, QPalette.ColorRole(9), Qt.white)
        self._lineEdit.setPalette(p)
        self._textEdit.viewport().setPalette(p)

    def keyPressEvent(self, event):
        """ Switch back to the original value on ESC.
        """
        QWidget.keyPressEvent(self, event)
        if event.key() == Qt.Key_Escape:
            self.setValue(self._originalValue)
Пример #9
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()
Пример #10
0
class TextEditWithButtonProperty(Property, QWidget):
    """ This class provides a PropertyView property holding an editable text and a button.
    
    It is possible to hide the button unless the mouse cursor is over the property. This feature is turned on by default. See setAutohideButton().
    If the button is pressed nothing happens. This functionality should be implemented in sub-classes. See buttonClicked().
    The text field can hold single or multiple lines. See setMultiline()
    """
    
    BUTTON_LABEL = ''
    AUTOHIDE_BUTTON = True
    
    def __init__(self, name, value, categoryName=None, multiline=False):
        """ The constructor creates a QHBoxLayout and calls createLineEdit(), createTextEdit() and createButton(). 
        """
        Property.__init__(self, name, categoryName)
        QWidget.__init__(self)
        self._lineEdit = None
        self._textEdit = None
        self._button = None
        self.setAutohideButton(self.AUTOHIDE_BUTTON)
        
        self.setLayout(QHBoxLayout())
        self.layout().setSpacing(0)
        self.layout().setContentsMargins(0, 0, 0, 0)
        
        self._readOnly = False
        self._multiline = False

        self.createLineEdit()
        self.createTextEdit()
        self.createButton()
        self.setMultiline(multiline)
        self.setValue(value)
                
    def setValue(self, value):
        """ Sets value of text edit.
        """
        self._originalValue=value
        if value != None:
            strValue = str(value)
        else:
            strValue = ""
        if not self._readOnly:
            self.disconnect(self._lineEdit, SIGNAL('editingFinished()'), self.valueChanged)
            self.disconnect(self._textEdit, SIGNAL('editingFinished()'), self.valueChanged)
        self._lineEdit.setText(strValue)
        self._textEdit.setText(strValue)
        self.setToolTip(strValue)
        if not self._readOnly:
            self.connect(self._lineEdit, SIGNAL('editingFinished()'), self.valueChanged)
            self.connect(self._textEdit, SIGNAL('editingFinished()'), self.valueChanged)
        # TODO: sometimes when changing value the text edit appears to be empty when new text is shorter than old text
        #if not self._multiline:
        #    self._textEdit.setCursorPosition(self._textEdit.displayText().length())
    
    def setToolTip(self,text):
        self._lineEdit.setToolTip(text)
        self._textEdit.setToolTip(text)

    def setMultiline(self,multi):
        """ Switch between single and multi line mode.
        """
        self.setValue(self.strValue())
        self._multiline=multi
        if self._multiline:
            self._textEdit.show()
            self._lineEdit.hide()
            self.setFocusProxy(self._textEdit)
        else:
            self._lineEdit.show()
            self._textEdit.hide()
            self.setFocusProxy(self._lineEdit)
        
    def createLineEdit(self, value=None):
        """ This function creates the signle line text field and adds it to the property's layout. 
        """
        self._lineEdit = QLineEdit(self)
        self._lineEdit.setFrame(False)
        self.connect(self._lineEdit, SIGNAL('editingFinished()'), self.valueChanged)
        self._lineEdit.setContentsMargins(0, 0, 0, 0)
        self._lineEdit.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.MinimumExpanding))
        self.layout().addWidget(self._lineEdit)
        
    def createTextEdit(self, value=None):
        """ This function creates the multi line text field and adds it to the property's layout. 
        """
        self._textEdit = TextEdit(self)
        self._textEdit.setWordWrapMode(QTextOption.NoWrap)
        self._textEdit.setFrameStyle(QFrame.NoFrame)
        self.connect(self._textEdit, SIGNAL('editingFinished()'), self.valueChanged)
        self._textEdit.setContentsMargins(0, 0, 0, 0)
        self._textEdit.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.MinimumExpanding))
        self.layout().addWidget(self._textEdit)
        
    def properyHeight(self):
        """ Return the estimated height of the property.
        
        The returned height covers the whole text, even if multiline.
        """
        if self._multiline:
            self._textEdit.document().adjustSize()
            height=self._textEdit.document().size().height()+3
            if self._textEdit.horizontalScrollBar().isVisible():
                height+=self._textEdit.horizontalScrollBar().height()+3
            return height
        else:
            return self.DEFAULT_HEIGHT
            
    def lineEdit(self):
        """ Returns line edit.
        """
        return self._lineEdit
        
    def textEdit(self):
        """ Returns text edit.
        """
        return self._textEdit
        
    def createButton(self):
        """ Creates a button and adds it to the property's layout.
        """
        self._button = QToolButton(self)
        self._button.setText(self.BUTTON_LABEL)
        self._button.setContentsMargins(0, 0, 0, 0)
        self.connect(self._button, SIGNAL('clicked(bool)'), self.buttonClicked)
        self.layout().addWidget(self._button)
        
        if self.autohideButtonFlag:
            self._button.hide()
    
    def button(self):
        """ Return button.
        """
        return self._button
    
    def hasButton(self):
        """ Returns True if the button has been created, otherwise False is returned. 
        """
        return self._button != None
    
    def setReadOnly(self, readOnly):
        """ Switch between readonly and editable.
        """
        self._readOnly = readOnly
        if not self.lineEdit().isReadOnly() and readOnly:
            self.disconnect(self._lineEdit, SIGNAL('editingFinished()'), self.valueChanged)
            self.disconnect(self._textEdit, SIGNAL('editingFinished()'), self.valueChanged)
            if self.hasButton():
                self._button=None
        if self.lineEdit().isReadOnly() and not readOnly:
            self.connect(self._lineEdit, SIGNAL('editingFinished()'), self.valueChanged)
            self.connect(self._textEdit, SIGNAL('editingFinished()'), self.valueChanged)
            if not self.hasButton():
                self.createButton()
        self.lineEdit().setReadOnly(readOnly)
        self.textEdit().setReadOnly(readOnly)
    
    def readOnly(self):
        return self._readOnly
    
    def strValue(self):
        """ Returns value of text edit.
        """
        if not self._multiline:
            return str(self._lineEdit.text().toAscii())
        else:
            return str(self._textEdit.toPlainText().toAscii())
        return ""
    
    def value(self):
        """ Returns the value of correct type (in case its not a string).
        """
        return self.strValue()
    
    def setAutohideButton(self, hide):
        """ If hide is True the button will only be visible while the cursor is over the property. 
        """
        self.autohideButtonFlag = hide
        
    def buttonClicked(self, checked=False):
        """
        This function is called if the button was clicked. For information on the checked argument see documentation of QPushButton::clicked().
        This function should be overwritten by sub-classes.
        """ 
        pass
        
    def enterEvent(self, event):
        """ If autohideButtonFlag is set this function makes the button visible. See setAutohideButton(). 
        """
        if self.autohideButtonFlag and self.hasButton() and not self._readOnly:
            self._button.show()
            
    def leaveEvent(self, event):
        """ If autohideButtonFlag is set this function makes the button invisible. See setAutohideButton(). 
        """
        if self.autohideButtonFlag and self.hasButton() and not self._readOnly:
            self._button.hide()

    def valueChanged(self):
        """ Update tooltip and height when text is changed.
        """
        if self._multiline:
            self.emit(SIGNAL('updatePropertyHeight'),self)
        self.setToolTip(self.strValue())
        # set property only if button is not being pressed
        if not self.button() or not self.button().isDown():
            Property.valueChanged(self)
        
    def setHighlighted(self,highlight):
        """ Highlight the property by changing the background color of the textfield.
        """
        p=QPalette()
        if highlight:
            p.setColor(QPalette.Active, QPalette.ColorRole(9),Qt.red)
        else:
            p.setColor(QPalette.Active, QPalette.ColorRole(9),Qt.white)
        self._lineEdit.setPalette(p)
        self._textEdit.viewport().setPalette(p)
    
    def keyPressEvent(self,event):
        """ Switch back to the original value on ESC.
        """
        QWidget.keyPressEvent(self,event)
        if event.key()==Qt.Key_Escape:
            self.setValue(self._originalValue)
Пример #11
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()
Пример #12
0
class MyMainWindow(QMainWindow):
    ' Main Window '

    def __init__(self, parent=None):
        ' Initialize QWidget inside MyMainWindow '
        super(MyMainWindow, self).__init__(parent)
        self.statusBar().showMessage(__doc__.title())
        self.setWindowTitle(__doc__)
        self.setMinimumSize(600, 800)
        self.setMaximumSize(2048, 1024)
        self.resize(1024, 800)
        self.setWindowIcon(QIcon.fromTheme("face-monkey"))
        if not A11Y:
            self.setStyleSheet('''QWidget{color:#fff;font-family:Oxygen}
            QWidget:item:hover, QWidget:item:selected {
                background-color: cyan; color: #000
            }
            QWidget:disabled { color: #404040; background-color: #323232 }
            QWidget:focus { border: 1px solid cyan }
            QPushButton {
                background-color: gray;
                padding: 3px; border: 1px solid gray; border-radius: 9px;
                margin: 0;font-size: 12px;
                padding-left: 5px; padding-right: 5px
            }
            QLineEdit, QTextEdit {
                background-color: #4a4a4a; border: 1px solid gray;
                border-radius: 0; font-size: 12px;
            }
            QPushButton:pressed { background-color: #323232 }
            QComboBox {
                background-color: #4a4a4a; padding-left: 9px;
                border: 1px solid gray; border-radius: 5px;
            }
            QComboBox:pressed { background-color: gray }
            QComboBox QAbstractItemView, QMenu {
                border: 1px solid #4a4a4a; background:grey;
                selection-background-color: cyan;
                selection-color: #000;
            }
            QSlider {
                padding: 3px; font-size: 8px; padding-left: 2px;
                padding-right: 2px; border: 5px solid #1e1e1e
            }
            QSlider::sub-page:vertical {
                background-color: QLinearGradient(spread:pad, x1:0, y1:0, x2:1,
                    y2:0.27, stop:0 rgba(255, 0, 0, 255),
                    stop:1 rgba(50, 0, 0, 200));
                border: 4px solid #1e1e1e; border-radius: 5px
            }
            QSlider::add-page:vertical {
                background-color: QLinearGradient(spread:pad, x1:0, y1:0, x2:1,
                    y2:0.27, stop:0 rgba(0, 255, 0, 255),
                    stop:1 rgba(0, 99, 0, 255));
                border: 4px solid #1e1e1e; border-radius: 5px;
            }
            QSlider::handle:vertical {
                background-color: QLinearGradient(spread:pad, x1:0, y1:0, x2:1,
                    y2:0.273, stop:0 rgba(0, 0, 0, 255), stop:1 gray);
                height: 5px; border: 1px dotted #fff; text-align: center;
                border-top-left-radius: 2px; border-bottom-left-radius: 2px;
                border-top-right-radius: 2px; border-bottom-right-radius 2px;
                margin-left: 2px; margin-right: 2px;
            }
            QSlider::handle:vertical:hover { border: 1px solid cyan }
            QSlider::sub-page:vertical:disabled {
                background: #bbb; border-color: #999;
            }
            QSlider::add-page:vertical:disabled {
                background: #eee; border-color: #999;
            }
            QSlider::handle:vertical:disabled {
                background: #eee; border: 1px solid #aaa; border-radius: 4px;
            }
            QToolBar, QStatusBar, QDockWidget::title{background-color:#323232;}
            QToolBar::handle,
            QToolBar::handle:vertical, QToolBar::handle:horizontal {
                border: 1px solid gray; border-radius: 9px; width: 19px;
                height: 19px; margin: 0.5px
            }
            QGroupBox {
                border: 1px solid gray; border-radius: 9px; padding-top: 9px;
            }
            QStatusBar, QToolBar::separator:horizontal,
            QToolBar::separator:vertical {color:gray}
            QScrollBar:vertical{
                background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,
                    stop: 0 #212121,stop: 1.0 #323232);
                width: 10px;
            }
            QScrollBar:horizontal{
                background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
                    stop: 0 #212121,stop: 1.0 #323232);
                height: 10px;
            }
            QScrollBar::handle:vertical{
                padding: 2px;
                min-height: 50px;
                background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0,
                    stop: 0 #585858,stop: 1.0 #404040);
                border-radius: 5px;
                border: 1px solid #191919;
            }
            QScrollBar::handle:horizontal{
                padding: 2px;
                min-width: 50px;
                background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
                    stop: 0 #585858,stop: 1.0 #404040);
                border-radius: 5px;
                border: 1px solid #191919;
            }
            QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical,
            QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical,
            QScrollBar::add-line:horizontal, QScrollBar::sub-line:horizontal,
            QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal {
                background: none; border: none;
            }
            QDockWidget::close-button, QDockWidget::float-button {
                border: 1px solid gray;
                border-radius: 3px;
                background: darkgray;
            }''')

        self.process = QProcess()
        self.process.readyReadStandardOutput.connect(self.read_output)
        self.process.readyReadStandardError.connect(self.read_errors)
        self.process.finished.connect(self._process_finished)
        self.process.error.connect(self._process_finished)

        self.group0, self.group1 = QGroupBox("Options"), QGroupBox("Paths")
        self.group2 = QGroupBox("Nodes")
        self.group3 = QGroupBox("Python Code")
        self.group4, self.group5 = QGroupBox("Logs"), QGroupBox("Backend")
        g0grid, g1vlay = QGridLayout(self.group0), QVBoxLayout(self.group1)
        g5vlay = QVBoxLayout(self.group5)

        self.treeview_nodes, self.textedit_source = QTextEdit(), QTextEdit()
        self.dock1, self.dock2 = QDockWidget(), QDockWidget()
        self.output, self.dock3 = QTextEdit(), QDockWidget()
        self.treeview_nodes.setAutoFormatting(QTextEdit.AutoAll)
        self.treeview_nodes.setWordWrapMode(QTextOption.NoWrap)
        self.dock1.setWidget(self.treeview_nodes)
        self.dock2.setWidget(self.textedit_source)
        self.dock3.setWidget(self.output)
        self.dock1.setWindowTitle("Tree")
        self.dock2.setWindowTitle("Sources")
        self.dock3.setWindowTitle("STDOutput")
        featur = QDockWidget.DockWidgetMovable | QDockWidget.DockWidgetFloatable
        self.dock1.setFeatures(featur)
        self.dock2.setFeatures(featur)
        self.dock3.setFeatures(featur)
        QVBoxLayout(self.group2).addWidget(self.dock1)
        QVBoxLayout(self.group3).addWidget(self.dock2)
        QVBoxLayout(self.group4).addWidget(self.dock3)
        self.slider1, self.slider2 = QSlider(), QSlider()
        g0grid.addWidget(self.slider1, 0, 0)
        g0grid.addWidget(QLabel('Use Debug'), 0, 1)
        self.slider2.setValue(1)
        g0grid.addWidget(self.slider2, 1, 0)
        g0grid.addWidget(QLabel('Use verbose'), 1, 1)

        self.slider3, self.slider4 = QSlider(), QSlider()
        self.slider3.setValue(1)
        g0grid.addWidget(self.slider3, 2, 0)
        g0grid.addWidget(QLabel('Show compiling progress'), 2, 1)
        self.slider4.setValue(1)
        g0grid.addWidget(self.slider4, 3, 0)
        g0grid.addWidget(QLabel('Show Scons building debug'), 3, 1)

        self.slider5, self.slider6 = QSlider(), QSlider()
        g0grid.addWidget(self.slider5, 4, 0)
        g0grid.addWidget(QLabel('Keep debug unstriped binary'), 4, 1)
        g0grid.addWidget(self.slider6, 5, 0)
        g0grid.addWidget(QLabel('Traced execution outputs'), 5, 1)

        self.slider7, self.slider8 = QSlider(), QSlider()
        self.slider7.setValue(1)
        g0grid.addWidget(self.slider7, 6, 0)
        g0grid.addWidget(QLabel('Remove the build folder'), 6, 1)
        g0grid.addWidget(self.slider8, 7, 0)
        g0grid.addWidget(QLabel('No Python Optimizations'), 7, 1)

        self.slider9, self.slider10 = QSlider(), QSlider()
        g0grid.addWidget(self.slider9, 8, 0)
        g0grid.addWidget(QLabel('No Statements line numbers'), 8, 1)
        g0grid.addWidget(self.slider10, 9, 0)
        g0grid.addWidget(QLabel('Execute the output binary'), 9, 1)

        self.slider11, self.slider12 = QSlider(), QSlider()
        g0grid.addWidget(self.slider11, 10, 0)
        g0grid.addWidget(QLabel('Warning detected implicit exceptions'), 10, 1)
        g0grid.addWidget(self.slider12, 11, 0)
        g0grid.addWidget(QLabel('Keep the PYTHONPATH, do not Reset it'), 11, 1)

        self.slider13 = QSlider()
        g0grid.addWidget(self.slider13, 12, 0)
        g0grid.addWidget(QLabel('Enhance compile, CPython incompatible'), 12,
                         1)

        self.slider1a, self.slider2a = QSlider(), QSlider()
        g0grid.addWidget(self.slider1a, 0, 2)
        g0grid.addWidget(QLabel('Descendent Recursive Compile'), 0, 3)
        self.slider2a.setValue(1)
        g0grid.addWidget(self.slider2a, 1, 2)
        g0grid.addWidget(QLabel('Force non recursive compile'), 1, 3)

        self.slider3a, self.slider4a = QSlider(), QSlider()
        g0grid.addWidget(self.slider3a, 2, 2)
        g0grid.addWidget(QLabel('STD Lib Recursive Compile'), 2, 3)
        g0grid.addWidget(self.slider4a, 3, 2)
        g0grid.addWidget(QLabel('Enforce the use of Clang'), 3, 3)

        self.slider5a, self.slider6a = QSlider(), QSlider()
        self.slider5a.setValue(1)
        g0grid.addWidget(self.slider5a, 4, 2)
        g0grid.addWidget(QLabel('Use G++ link time optimizations'), 4, 3)
        g0grid.addWidget(self.slider6a, 5, 2)
        g0grid.addWidget(QLabel('Disable the console window'), 5, 3)

        self.slider7a, self.slider8a = QSlider(), QSlider()
        g0grid.addWidget(self.slider7a, 6, 2)
        g0grid.addWidget(QLabel('Force compile for MS Windows'), 6, 3)
        g0grid.addWidget(self.slider8a, 7, 2)
        g0grid.addWidget(QLabel('Use Python Debug versions'), 7, 3)

        self.slider9a, self.slider10a = QSlider(), QSlider()
        self.slider9a.setValue(1)
        g0grid.addWidget(self.slider9a, 8, 2)
        g0grid.addWidget(QLabel('Create standalone executable'), 8, 3)
        g0grid.addWidget(self.slider10a, 9, 2)
        g0grid.addWidget(QLabel('Enable Standalone mode build'), 9, 3)

        self.slider11a, self.slider12a = QSlider(), QSlider()
        g0grid.addWidget(self.slider11a, 10, 2)
        g0grid.addWidget(QLabel('Make module executable instead of app'), 10,
                         3)
        g0grid.addWidget(self.slider12a, 11, 2)
        g0grid.addWidget(QLabel('No froze module of stdlib as bytecode'), 11,
                         3)

        self.slider13a = QSlider()
        g0grid.addWidget(self.slider13a, 12, 2)
        g0grid.addWidget(QLabel('Force use of MinGW on MS Windows'), 12, 3)

        for each_widget in (self.slider1, self.slider2, self.slider3,
                            self.slider4, self.slider5, self.slider6,
                            self.slider7, self.slider8, self.slider9,
                            self.slider10, self.slider11, self.slider12,
                            self.slider13, self.slider1a, self.slider2a,
                            self.slider3a, self.slider4a, self.slider5a,
                            self.slider6a, self.slider7a, self.slider8a,
                            self.slider9a, self.slider10a, self.slider11a,
                            self.slider12a, self.slider13a):
            each_widget.setRange(0, 1)
            each_widget.setCursor(QCursor(Qt.OpenHandCursor))
            each_widget.setTickInterval(1)
            each_widget.TickPosition(QSlider.TicksBothSides)

        self.combo1 = QComboBox()
        self.combo1.addItems(('2.7', '2.6', '3.2', '3.3'))
        g5vlay.addWidget(QLabel('Python Version'))
        g5vlay.addWidget(self.combo1)
        self.combo2 = QComboBox()
        self.combo2.addItems(('Default', 'Low', 'High'))
        g5vlay.addWidget(QLabel('CPU priority'))
        g5vlay.addWidget(self.combo2)
        self.combo3 = QComboBox()
        self.combo3.addItems(('1', '2', '3', '4', '5', '6', '7', '8', '9'))
        g5vlay.addWidget(QLabel('MultiProcessing Workers'))
        g5vlay.addWidget(self.combo3)

        self.outdir = QLineEdit()
        self.outdir.setStyleSheet("QLineEdit{margin-left:25px}")
        self.clearButton = QToolButton(self.outdir)
        self.clearButton.setIcon(QIcon.fromTheme("edit-clear"))
        self.clearButton.setIconSize(QSize(25, 25))
        self.clearButton.setStyleSheet("QToolButton{border:none}")
        self.clearButton.hide()
        self.clearButton.clicked.connect(self.outdir.clear)
        self.outdir.textChanged.connect(
            lambda: self.clearButton.setVisible(True))
        self.clearButton.clicked.connect(
            lambda: self.clearButton.setVisible(False))
        self.outdir.setPlaceholderText('Output Directory')
        if path.isfile('.nuitka-output-dir.txt'):
            self.outdir.setText(open('.nuitka-output-dir.txt', 'r').read())
        else:
            self.outdir.setText(path.expanduser("~"))
        self.completer, self.dirs = QCompleter(self), QDirModel(self)
        self.dirs.setFilter(QDir.Dirs | QDir.NoDotAndDotDot)
        self.completer.setModel(self.dirs)
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setCompletionMode(QCompleter.PopupCompletion)
        self.completer.popup().setStyleSheet(
            """border:1px solid #4a4a4a;background:grey;
            selection-background-color:cyan;selection-color:#000""")
        self.completer.popup().setVerticalScrollBarPolicy(
            Qt.ScrollBarAlwaysOff)
        self.outdir.setCompleter(self.completer)

        self.btn1 = QPushButton(QIcon.fromTheme("document-open"),
                                'Open' if IS_WIN else '')
        self.btn1.clicked.connect(
            lambda: open('.nuitka-output-dir.txt', 'w').write(
                str(
                    QFileDialog.getExistingDirectory(
                        None, 'Open Output Directory', path.expanduser("~")))))
        self.btn1.released.connect(lambda: self.outdir.setText(
            open('.nuitka-output-dir.txt', 'r').read()))
        g1vlay.addWidget(QLabel('Output Directory'))
        g1vlay.addWidget(self.outdir)
        g1vlay.addWidget(self.btn1)

        self.target = QLineEdit()
        self.target.setStyleSheet("QLineEdit{margin-left:25px}")
        self.clearButton2 = QToolButton(self.target)
        self.clearButton2.setIcon(QIcon.fromTheme("edit-clear"))
        self.clearButton2.setIconSize(QSize(25, 25))
        self.clearButton2.setStyleSheet("QToolButton{border:none}")
        self.clearButton2.hide()
        self.clearButton2.clicked.connect(self.target.clear)
        self.target.textChanged.connect(
            lambda: self.clearButton2.setVisible(True))
        self.clearButton2.clicked.connect(
            lambda: self.clearButton2.setVisible(False))
        self.target.setPlaceholderText('Target Python App to Binary Compile')
        self.target.setCompleter(self.completer)
        self.btn2 = QPushButton(QIcon.fromTheme("document-open"),
                                'Open' if IS_WIN else '')
        self.btn2.clicked.connect(lambda: self.target.setText(
            str(
                QFileDialog.getOpenFileName(
                    None, "Open", path.expanduser("~"), ';;'.join([
                        '{}(*.{})'.format(e.upper(), e)
                        for e in ('py', 'pyw', '*')
                    ])))))
        g1vlay.addWidget(QLabel('Input File'))
        g1vlay.addWidget(self.target)
        g1vlay.addWidget(self.btn2)

        self.icon, self.icon_label = QLineEdit(), QLabel('Icon File')
        self.icon.setStyleSheet("QLineEdit{margin-left:25px}")
        self.clearButton3 = QToolButton(self.icon)
        self.clearButton3.setIcon(QIcon.fromTheme("edit-clear"))
        self.clearButton3.setIconSize(QSize(25, 25))
        self.clearButton3.setStyleSheet("QToolButton{border:none}")
        self.clearButton3.hide()
        self.clearButton3.clicked.connect(self.icon.clear)
        self.icon.textChanged.connect(
            lambda: self.clearButton3.setVisible(True))
        self.clearButton3.clicked.connect(
            lambda: self.clearButton3.setVisible(False))
        self.icon.setPlaceholderText('Path to Icon file for your App')
        self.icon.setCompleter(self.completer)
        self.btn3 = QPushButton(QIcon.fromTheme("document-open"),
                                'Open' if IS_WIN else '')
        self.btn3.clicked.connect(lambda: self.icon.setText(
            str(
                QFileDialog.getOpenFileName(
                    None, "Open", path.expanduser("~"), ';;'.join([
                        '{}(*.{})'.format(e.upper(), e)
                        for e in ('ico', 'png', 'bmp', 'svg', '*')
                    ])))))
        g1vlay.addWidget(self.icon_label)
        g1vlay.addWidget(self.icon)
        g1vlay.addWidget(self.btn3)

        # Menu Bar inicialization and detail definitions
        menu_salir = QAction(QIcon.fromTheme("application-exit"), 'Quit', self)
        menu_salir.setStatusTip('Quit')
        menu_salir.triggered.connect(exit)
        menu_minimize = QAction(QIcon.fromTheme("go-down"), 'Minimize', self)
        menu_minimize.setStatusTip('Minimize')
        menu_minimize.triggered.connect(lambda: self.showMinimized())
        menu_qt = QAction(QIcon.fromTheme("help-about"), 'About Qt', self)
        menu_qt.setStatusTip('About Qt...')
        menu_qt.triggered.connect(lambda: QMessageBox.aboutQt(self))
        menu_dev = QAction(QIcon.fromTheme("applications-development"),
                           'Developer Manual PDF', self)
        menu_dev.setStatusTip('Open Nuitka Developer Manual PDF...')
        menu_dev.triggered.connect(lambda: call(
            OPEN + '/usr/share/doc/nuitka/Developer_Manual.pdf.gz', shell=True)
                                   )
        menu_usr = QAction(QIcon.fromTheme("help-contents"), 'User Docs', self)
        menu_usr.setStatusTip('Open Nuitka End User Manual PDF...')
        menu_usr.triggered.connect(lambda: call(
            OPEN + '/usr/share/doc/nuitka/README.pdf.gz', shell=True))
        menu_odoc = QAction(QIcon.fromTheme("help-browser"), 'OnLine Doc',
                            self)
        menu_odoc.setStatusTip('Open Nuitka on line Documentation pages...')
        menu_odoc.triggered.connect(
            lambda: open_new_tab('http://nuitka.net/doc/user-manual.html'))
        menu_man = QAction(QIcon.fromTheme("utilities-terminal"), 'Man', self)
        menu_man.setStatusTip('Open Nuitka technical command line Man Pages..')
        menu_man.triggered.connect(
            lambda: call('xterm -e "man nuitka"', shell=True))
        menu_tra = QAction(QIcon.fromTheme("applications-development"),
                           'View Nuitka-GUI Source Code', self)
        menu_tra.setStatusTip('View, study, edit Nuitka-GUI Libre Source Code')
        menu_tra.triggered.connect(lambda: call(OPEN + __file__, shell=True))
        menu_foo = QAction(QIcon.fromTheme("folder"), 'Open Output Dir', self)
        menu_foo.setStatusTip('Open the actual Output Directory location...')
        menu_foo.triggered.connect(
            lambda: call(OPEN + str(self.outdir.text()), shell=True))
        menu_pic = QAction(QIcon.fromTheme("camera-photo"), 'Screenshot', self)
        menu_pic.setStatusTip('Take a Screenshot for Documentation purposes..')
        menu_pic.triggered.connect(
            lambda: QPixmap.grabWindow(QApplication.desktop().winId()).save(
                QFileDialog.getSaveFileName(None, "Save", path.expanduser("~"),
                                            'PNG(*.png)', 'png')))
        menu_don = QAction(QIcon.fromTheme("emblem-favorite"), 'Help Nuitka',
                           self)
        menu_don.setStatusTip('Help the Nuitka Open Source Libre Free Project')
        menu_don.triggered.connect(
            lambda: open_new_tab('http://nuitka.net/pages/donations.html'))

        # movable draggable toolbar
        self.toolbar = QToolBar(self)
        self.toolbar.setIconSize(QSize(16, 16))
        self.toolbar.toggleViewAction().setText("Show/Hide Toolbar")
        l_spacer, r_spacer = QWidget(self), QWidget(self)
        l_spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        r_spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.toolbar.addWidget(l_spacer)
        self.toolbar.addSeparator()
        self.toolbar.addActions((menu_salir, menu_minimize, menu_qt, menu_odoc,
                                 menu_foo, menu_pic, menu_don))
        if not IS_WIN:
            self.toolbar.addActions((menu_man, menu_dev, menu_tra, menu_usr))
        self.toolbar.addSeparator()
        self.toolbar.addWidget(r_spacer)
        self.addToolBar(Qt.BottomToolBarArea, self.toolbar)

        # Bottom Buttons Bar
        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Ok
                                          | QDialogButtonBox.Close)
        self.buttonBox.rejected.connect(exit)
        self.buttonBox.accepted.connect(self.run)

        self.guimode = QComboBox()
        self.guimode.addItems(('Full UX / UI', 'Simple UX / UI'))
        self.guimode.setStyleSheet(
            """QComboBox{background:transparent;border:0;
            margin-left:25px;color:gray;text-decoration:underline}""")
        self.guimode.currentIndexChanged.connect(self.set_guimode)

        container = QWidget()
        container_layout = QGridLayout(container)  # Y, X
        container_layout.addWidget(self.guimode, 0, 1)
        container_layout.addWidget(self.group2, 1, 0)
        container_layout.addWidget(self.group3, 2, 0)
        container_layout.addWidget(self.group0, 1, 1)
        container_layout.addWidget(self.group1, 2, 1)
        container_layout.addWidget(self.group4, 1, 2)
        container_layout.addWidget(self.group5, 2, 2)
        container_layout.addWidget(self.buttonBox, 3, 1)
        self.setCentralWidget(container)
        # Paleta de colores para pintar transparente
        if not A11Y:
            palette = self.palette()
            palette.setBrush(QPalette.Base, Qt.transparent)
            self.setPalette(palette)
            self.setAttribute(Qt.WA_OpaquePaintEvent, False)

    def get_fake_tree(self, target):
        """Return the fake tree."""
        try:
            fake_tree = check_output(NUITKA + ' --dump-xml ' + target,
                                     shell=True)
        except:
            fake_tree = "ERROR: Failed to get Tree Dump."
        finally:
            return fake_tree.strip()

    def run(self):
        ' run the actual backend process '
        self.treeview_nodes.clear()
        self.textedit_source.clear()
        self.output.clear()
        self.statusBar().showMessage('WAIT!, Working...')
        target = str(self.target.text()).strip()
        self.treeview_nodes.setText(self.get_fake_tree(target))
        self.textedit_source.setText(open(target, "r").read().strip())
        conditional_1 = sys.platform.startswith('linux')
        conditional_2 = self.combo3.currentIndex() != 2
        command_to_run_nuitka = " ".join(
            ('chrt -i 0' if conditional_1 and conditional_2 else '', NUITKA,
             '--debug' if self.slider1.value() else '',
             '--verbose' if self.slider2.value() else '',
             '--show-progress' if self.slider3.value() else '',
             '--show-scons --show-modules' if self.slider4.value() else '',
             '--unstriped' if self.slider5.value() else '',
             '--trace-execution' if self.slider6.value() else '',
             '--remove-output' if self.slider7.value() else '',
             '--no-optimization' if self.slider8.value() else '',
             '--code-gen-no-statement-lines' if self.slider9.value() else '',
             '--execute' if self.slider10.value() else '',
             '--recurse-all' if self.slider1a.value() else '',
             '--recurse-none' if self.slider2a.value() else '',
             '--recurse-stdlib' if self.slider3a.value() else '',
             '--clang' if self.slider4a.value() else '',
             '--lto' if self.slider5a.value() else '',
             '--windows-disable-console' if self.slider6a.value() else '',
             '--windows-target' if self.slider7a.value() else '',
             '--python-debug' if self.slider8a.value() else '',
             '--exe' if self.slider9a.value() else '',
             '--standalone' if self.slider10a.value() else '',
             '--module' if self.slider11a.value() else '',
             '--nofreeze-stdlib' if self.slider12a.value() else '',
             '--mingw' if self.slider13a.value() else '',
             '--warn-implicit-exceptions' if self.slider11.value() else '',
             '--execute-with-pythonpath' if self.slider12.value() else '',
             '--enhanced' if self.slider13.value() else '',
             '--icon="{}"'.format(self.icon.text())
             if self.icon.text() else '', '--python-version={}'.format(
                 self.combo1.currentText()), '--jobs={}'.format(
                     self.combo3.currentText()), '--output-dir="{}"'.format(
                         self.outdir.text()), "{}".format(target)))
        if DEBUG:
            print(command_to_run_nuitka)
        self.process.start(command_to_run_nuitka)
        if not self.process.waitForStarted() and not IS_WIN:
            return  # ERROR !
        self.statusBar().showMessage(__doc__.title())

    def _process_finished(self):
        """finished sucessfully"""
        self.output.setFocus()
        self.output.selectAll()

    def read_output(self):
        """Read and append output to the log"""
        self.output.append(str(self.process.readAllStandardOutput()))

    def read_errors(self):
        """Read and append errors to the log"""
        self.output.append(str(self.process.readAllStandardError()))

    def paintEvent(self, event):
        """Paint semi-transparent background,animated pattern,background text"""
        if not A11Y:
            p = QPainter(self)
            p.setRenderHint(QPainter.Antialiasing)
            p.setRenderHint(QPainter.TextAntialiasing)
            p.setRenderHint(QPainter.HighQualityAntialiasing)
            p.fillRect(event.rect(), Qt.transparent)
            # animated random dots background pattern
            for i in range(4096):
                x = randint(25, self.size().width() - 25)
                y = randint(25, self.size().height() - 25)
                # p.setPen(QPen(QColor(randint(9, 255), 255, 255), 1))
                p.drawPoint(x, y)
            p.setPen(QPen(Qt.white, 1))
            p.rotate(40)
            p.setFont(QFont('Ubuntu', 250))
            p.drawText(200, 99, "Nuitka")
            p.rotate(-40)
            p.setPen(Qt.NoPen)
            p.setBrush(QColor(0, 0, 0))
            p.setOpacity(0.8)
            p.drawRoundedRect(self.rect(), 9, 9)
            p.end()

    def set_guimode(self):
        """Switch between simple and full UX"""
        for widget in (self.group2, self.group3, self.group4, self.group5,
                       self.icon, self.icon_label, self.btn3, self.toolbar,
                       self.statusBar()):
            widget.hide() if self.guimode.currentIndex() else widget.show()
Пример #13
0
class SearchBox(QWidget):
    def __init__(self, parent = None):
        super(SearchBox, self).__init__(parent) 
        self.setFixedHeight(30)
        
        self.lineEdit = QLineEdit()                
        self.lineEdit.setFixedHeight(29)
        self.lineEdit.setToolTip("输入搜索关键词")
        self.lineEdit.setFocusPolicy(Qt.ClickFocus)
        
        self.searchButton = QToolButton()
        self.searchButton.setText("搜索")
        self.searchButton.setFixedHeight(30)
        self.searchButton.setToolTip("点击搜索")
        self.searchButton.setCursor(QCursor(Qt.PointingHandCursor))
        
        self.resetButton = QToolButton()
        self.resetButton.setIcon(QIcon(":/iconSources/icons/reset.png"))
        self.resetButton.setIconSize(QSize(24, 24))
        self.resetButton.setFixedSize(27, 27)
        self.resetButton.setToolTip("重置搜索")
        self.resetButton.setCursor(QCursor(Qt.PointingHandCursor))
        
        self.clearButton = QToolButton()
        self.searchComboBox = QComboBox()
        self.searchComboBox.setToolTip("选择搜索类型")
        musicIcon = QIcon(":/iconSources/icons/music.png")
        artistIcon = QIcon(":/iconSources/icons/artist.png")
        albumIcon = QIcon(":/iconSources/icons/album.png")       
        self.searchComboBox.setIconSize(QSize(20,20))
        self.searchComboBox.insertItem(0, musicIcon, "歌曲")
        self.searchComboBox.insertItem(1, artistIcon, "歌手")
        self.searchComboBox.insertItem(2, albumIcon, "专辑")
        self.searchComboBox.setFixedSize(78, 27)
        self.searchComboBox.setCursor(Qt.PointingHandCursor)
        
        searchIcon = QIcon(":/iconSources/icons/delete.png")
        self.clearButton.setFixedSize(27, 27)
        self.clearButton.setIcon(searchIcon)
        self.clearButton.setIconSize(QSize(18, 18))
        self.clearButton.setAutoRaise(True)
        self.clearButton.setToolTip("清空搜索栏")
        self.clearButton.setCursor(Qt.PointingHandCursor)
        self.clearButton.hide()
        
        searchLayout = QHBoxLayout()
        searchLayout.addWidget(self.searchComboBox)
        searchLayout.addStretch()
        searchLayout.addWidget(self.clearButton)
        searchLayout.setMargin(1)
        searchLayout.setSpacing(0)
        searchLayout.setContentsMargins(0, 0, 0, 0)
        self.lineEdit.setLayout(searchLayout)
        self.lineEdit.setTextMargins(self.searchComboBox.width(), 0, self.clearButton.width(), 0)
        
        mainLayout = QHBoxLayout(self)
        mainLayout.setMargin(0)
        mainLayout.setSpacing(1)
        mainLayout.addWidget(self.resetButton)
        mainLayout.addWidget(self.lineEdit)
        mainLayout.addWidget(self.searchButton)

        #self.connect(self.clearButton, SIGNAL("clicked()"), self.lineEdit.clear)
        self.clearButton.clicked.connect(self.lineEdit.clear)
        self.lineEdit.textChanged.connect(self.clrbutton_show)
        
    def clrbutton_show(self):
        if self.lineEdit.text():
            self.clearButton.show()
        else:
            self.clearButton.hide()
Пример #14
0
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()
Пример #15
0
class projectInfoWidget(infoWidget):
	__master_url = ""
	__projectCached = None

	__mainLayout = None

	__projectInfo = None
	__projectInfoLayout = None
	__projectSettings = None

	#informacie o projekte
	__masterUrlLabel       = None
	__masterUrlText        = None
	__projectNameLabel     = None
	__projectNameText      = None
	__userNameLabel        = None
	__userNameText         = None
	__teamNameLabel        = None
	__teamNameText         = None
	__userTotalCreditLabel = None
	__userTotalCreditText  = None
	__hostTotalCreditLabel = None
	__hostTotalCreditText  = None
	__suspendedLabel       = None
	__newTasksLabel        = None

	__projectLinksButton = None
	__projectSettingsMenu   = None

	def __init__(self, client, project, parent = None):
		infoWidget.__init__(self, client, parent)

		self.__mainLayout = QGridLayout()
		self.__mainLayout.setRowStretch(1, 1)
		self.setMainLayout(self.__mainLayout)

		self.__projectInfo = QGroupBox(self.tr("Project Info"));
		self.__projectInfoLayout = QGridLayout()
		self.__projectInfo.setLayout(self.__projectInfoLayout)

		self.__projectSettings = QHBoxLayout()
		self.__projectLinksButton = QToolButton()
		self.__projectLinksButton.setText(self.tr("Project Links"))
		self.__projectLinksButton.hide()

		self.__updateProjectButton  = QPushButton(self.tr("Update"))
		self.__suspendProjectButton = QPushButton()
		self.__allowNewTasksButton  = QPushButton()
		self.__resetProjectButton   = QPushButton(self.tr("Reset project"))
		self.__detachProjectButton  = QPushButton(self.tr("Detach project"))

		self.__resetProjectButton.setEnabled(False)
		self.__detachProjectButton.setEnabled(False)

		self.__updateProjectButton.hide()
		self.__suspendProjectButton.hide()
		self.__allowNewTasksButton.hide()
		self.__resetProjectButton.hide()
		self.__detachProjectButton.hide()

		self.connect(self.__updateProjectButton, SIGNAL('clicked()'), self.__updateProject)
		self.connect(self.__suspendProjectButton, SIGNAL('clicked()'), self.__suspendProject)
		self.connect(self.__allowNewTasksButton, SIGNAL('clicked()'), self.__allowNewTasksProject)

		self.__projectSettings.addWidget(self.__projectLinksButton)
		self.__projectSettings.addWidget(self.__updateProjectButton)
		self.__projectSettings.addWidget(self.__suspendProjectButton)
		self.__projectSettings.addWidget(self.__allowNewTasksButton)
		#self.__projectSettings.addStretch(1)

		self.__projectAdmin = QHBoxLayout()
		self.__projectAdmin.addWidget(self.__resetProjectButton)
		self.__projectAdmin.addWidget(self.__detachProjectButton)
		#self.__projectAdmin.addStretch(1)

		self.__mainLayout.addWidget(self.__projectInfo, 0, 0)
		self.__mainLayout.addLayout(self.__projectSettings, 2, 0)
		self.__mainLayout.addLayout(self.__projectAdmin, 3, 0)

		self.__masterUrlLabel       = QLabel(self.tr("Master URL"))
		self.__projectNameLabel     = QLabel(self.tr("Project Name"))
		self.__userNameLabel        = QLabel(self.tr("User Name"))
		self.__teamNameLabel        = QLabel(self.tr("Team Name"))
		self.__userTotalCreditLabel = QLabel(self.tr("Total User Credits"))
		self.__hostTotalCreditLabel = QLabel(self.tr("Total Host Credits"))
		self.__suspendedLabel       = QLabel(self.tr("Suspended by user"))
		self.__newTasksLabel        = QLabel(self.tr("Won't get new tasks"))

		self.__masterUrlText       = QLabel()
		self.__projectNameText     = QLabel()
		self.__userNameText        = QLabel()
		self.__teamNameText        = QLabel()
		self.__userTotalCreditText = QLabel()
		self.__hostTotalCreditText = QLabel()

		self.__masterUrlText.setTextFormat(Qt.PlainText)
		self.__projectNameText.setTextFormat(Qt.PlainText)
		self.__userNameText.setTextFormat(Qt.PlainText)
		self.__teamNameText.setTextFormat(Qt.PlainText)
		self.__userTotalCreditText.setTextFormat(Qt.PlainText)
		self.__hostTotalCreditText.setTextFormat(Qt.PlainText)

		self.__masterUrlLabel.hide()
		self.__projectNameLabel.hide()
		self.__userNameLabel.hide()
		self.__teamNameLabel.hide()
		self.__userTotalCreditLabel.hide()
		self.__hostTotalCreditLabel.hide()

		self.__masterUrlText.hide()
		self.__projectNameText.hide()
		self.__userNameText.hide()
		self.__teamNameText.hide()
		self.__userTotalCreditText.hide()
		self.__hostTotalCreditText.hide()
		self.__suspendedLabel.hide()
		self.__newTasksLabel.hide()

		self.__projectInfoLayout.addWidget(self.__masterUrlLabel,        0, 0)
		self.__projectInfoLayout.addWidget(self.__projectNameLabel,      1, 0)
		self.__projectInfoLayout.addWidget(self.__userNameLabel,         2, 0)
		self.__projectInfoLayout.addWidget(self.__teamNameLabel,         3, 0)
		self.__projectInfoLayout.addWidget(self.__userTotalCreditLabel, 4, 0)
		self.__projectInfoLayout.addWidget(self.__hostTotalCreditLabel, 5, 0)

		self.__projectInfoLayout.addWidget(self.__masterUrlText,        0, 1)
		self.__projectInfoLayout.addWidget(self.__projectNameText,      1, 1)
		self.__projectInfoLayout.addWidget(self.__userNameText,         2, 1)
		self.__projectInfoLayout.addWidget(self.__teamNameText,         3, 1)
		self.__projectInfoLayout.addWidget(self.__userTotalCreditText, 4, 1)
		self.__projectInfoLayout.addWidget(self.__hostTotalCreditText, 5, 1)
		self.__projectInfoLayout.addWidget(self.__suspendedLabel, 6, 0, 1, 2)
		self.__projectInfoLayout.addWidget(self.__newTasksLabel, 7, 0, 1, 2)

		self.__master_url = project.data(0, Qt.UserRole + 1).toString()
		self.__projectCached = None

		self.__projectSettingsMenu = QMenu()
		self.__projectLinksButton.setPopupMode(QToolButton.InstantPopup)
		self.__projectLinksButton.setMenu(self.__projectSettingsMenu)

		projects = client.projectState()
		if not projects is None:
			self.updateProjects(projects)
		self.connect(client, SIGNAL("projectState(PyQt_PyObject)"), self.updateProjects)
		self.connect(client, SIGNAL("projectUpdateRecv(PyQt_PyObject)"), self.__updateProjectRecv)
		self.connect(client, SIGNAL("projectSuspendRecv(PyQt_PyObject)"), self.__suspendProjectRecv)
		self.connect(client, SIGNAL("projectResumeRecv(PyQt_PyObject)"), self.__resumeProjectRecv)
		self.connect(client, SIGNAL("projectNomoreworkRecv(PyQt_PyObject)"), self.__nomoreworkProjectRecv)
		self.connect(client, SIGNAL("projectAllowmoreworkRecv(PyQt_PyObject)"), self.__allowmoreworkProjectRecv)

	def __updateProject(self):
		self.emit(SIGNAL("showStatusBarMsg(QString)"), self.tr("Updating project"))
		self.client().projectUpdate(self.__projectCached['master_url'])

	def __suspendProject(self):
		if self.__projectCached['suspended_via_gui']:
			self.emit(SIGNAL("showStatusBarMsg(QString)"), self.tr("Resuming project"))
			self.client().projectResume(self.__projectCached['master_url'])
		else:
			self.emit(SIGNAL("showStatusBarMsg(QString)"), self.tr("Suspending project"))
			self.client().projectSuspend(self.__projectCached['master_url'])

	def __allowNewTasksProject(self):
		if self.__projectCached['dont_request_more_work']:
			self.emit(SIGNAL("showStatusBarMsg(QString)"), self.tr("Allowing new tasks"))
			self.client().projectAllowmorework(self.__projectCached['master_url'])
		else:
			self.emit(SIGNAL("showStatusBarMsg(QString)"), self.tr("Disallowing new tasks"))
			self.client().projectNomorework(self.__projectCached['master_url'])

	def __updateProjectRecv(self, status):
		if status:
			self.emit(SIGNAL("showStatusBarMsg(QString)"), status)
		else:
			self.emit(SIGNAL("showStatusBarMsg(QString)"), self.tr("Project updated"))
		self.client().getState()

	def __suspendProjectRecv(self, status):
		if status:
			self.emit(SIGNAL("showStatusBarMsg(QString)"), status)
		else:
			self.emit(SIGNAL("showStatusBarMsg(QString)"), self.tr("Project suspended"))
			self.__projectCached['suspended_via_gui'] = 1
			self.__suspendedLabel.show()
			self.__suspendProjectButton.setText(self.tr("Resume"))

		self.client().getState()

	def __resumeProjectRecv(self, status):
		if status:
			self.emit(SIGNAL("showStatusBarMsg(QString)"), status)
		else:
			self.emit(SIGNAL("showStatusBarMsg(QString)"), self.tr("Project restored"))
			self.__projectCached['suspended_via_gui'] = 0
			self.__suspendedLabel.hide()
			self.__suspendProjectButton.setText(self.tr("Suspend"))

		self.client().getState()

	def __nomoreworkProjectRecv(self, status):
		if status:
			self.emit(SIGNAL("showStatusBarMsg(QString)"), status)
		else:
			self.emit(SIGNAL("showStatusBarMsg(QString)"), self.tr("New tasks disallowed"))
			self.__projectCached['dont_request_more_work'] = 1
			self.__newTasksLabel.show()
			self.__allowNewTasksButton.setText(self.tr("Allow new tasks"))

		self.client().getState()

	def __allowmoreworkProjectRecv(self, status):
		if status:
			self.emit(SIGNAL("showStatusBarMsg(QString)"), status)
		else:
			self.emit(SIGNAL("showStatusBarMsg(QString)"), self.tr("New tasks allowed"))
			self.__projectCached['dont_request_more_work'] = 0
			self.__newTasksLabel.hide()
			self.__allowNewTasksButton.setText(self.tr("No new tasks"))

		self.client().getState()

	def __changeLabels(self, project, key, label, text):
		try:
			inf = project[key]
			if type(inf) == type(u""):
				text.setText(inf)
				text.show()
				label.show()
		except KeyError:
			text.hide()
			label.hide()

	def updateProjects(self, projects):
		projects = projects['project']
		project = None

		for proj in projects:
			if proj['master_url'] == self.__master_url:
				project = proj
				break

		# ak sme nenasli projekt
		if project is None:
			return

		if project != self.__projectCached:
			self.__projectCached = project
			try:
				self.setTitle(titleFrame(project['project_name']))
			except KeyError:
				pass

			self.__changeLabels(project, 'master_url', self.__masterUrlLabel, self.__masterUrlText)
			self.__changeLabels(project, 'project_name', self.__projectNameLabel, self.__projectNameText)
			self.__changeLabels(project, 'user_name', self.__userNameLabel, self.__userNameText)
			self.__changeLabels(project, 'team_name', self.__teamNameLabel, self.__teamNameText)
			self.__changeLabels(project, 'user_total_credit', self.__userTotalCreditLabel, self.__userTotalCreditText)
			self.__changeLabels(project, 'host_total_credit', self.__hostTotalCreditLabel, self.__hostTotalCreditText)

			if project['suspended_via_gui']:
				self.__suspendProjectButton.setText(self.tr("Resume"))
				self.__suspendedLabel.show()
			else:
				self.__suspendProjectButton.setText(self.tr("Suspend"))
				self.__suspendedLabel.hide()

			if project['dont_request_more_work']:
				self.__allowNewTasksButton.setText(self.tr("Allow new tasks"))
				self.__newTasksLabel.show()
			else:
				self.__allowNewTasksButton.setText(self.tr("No new tasks"))
				self.__newTasksLabel.hide()

			self.__updateProjectButton.show()
			self.__suspendProjectButton.show()
			self.__allowNewTasksButton.show()
			self.__resetProjectButton.show()
			self.__detachProjectButton.show()

			try:
				self.__projectSettingsMenu.clear()
				guiUrls = project['gui_urls']['gui_url']

				if type(guiUrls) == type({}):
					self.__projectSettingsMenu.addAction(urlAction(guiUrls['url'], guiUrls['name'], guiUrls['description'], self.__projectSettingsMenu))
				else:
					for url in guiUrls:
						self.__projectSettingsMenu.addAction(urlAction(url['url'], url['name'], url['description'], self.__projectSettingsMenu))

				try:
					ifTeamUrls = project['gui_urls']['ifteam']['gui_url']
					self.__projectSettingsMenu.addSeparator()
					if type(ifTeamUrls) == type({}):
						self.__projectSettingsMenu.addAction(urlAction(ifTeamUrls['url'], ifTeamUrls['name'], ifTeamUrls['description'], self.__projectSettingsMenu))
					else:
						for url in ifTeamUrls:
							self.__projectSettingsMenu.addAction(urlAction(url['url'], url['name'], url['description'], self.__projectSettingsMenu))
				except KeyError, msg:
					pass
				self.__projectLinksButton.show()
			except KeyError:
				self.__projectLinksButton.hide()