Exemplo n.º 1
0
    def __init__(self, parent):
        super(ProjectData, self).__init__()
        self._parent = parent
        grid = QGridLayout(self)
        grid.addWidget(QLabel(translations.TR_PROJECT_NAME), 0, 0)
        self.name = QLineEdit()
        if not len(self._parent.project.name):
            self.name.setText(file_manager.get_basename(
                self._parent.project.path))
        else:
            self.name.setText(self._parent.project.name)
        grid.addWidget(self.name, 0, 1)
        grid.addWidget(QLabel(translations.TR_PROJECT_LOCATION), 1, 0)
        self.txtPath = QLineEdit()
        self.txtPath.setReadOnly(True)
        self.txtPath.setText(self._parent.project.path)
        grid.addWidget(self.txtPath, 1, 1)
        grid.addWidget(QLabel(translations.TR_PROJECT_TYPE), 2, 0)
        self.txtType = QLineEdit()
        completer = QCompleter(sorted(settings.PROJECT_TYPES))
        completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.txtType.setCompleter(completer)
        self.txtType.setPlaceholderText("python")
        self.txtType.setText(self._parent.project.project_type)
        grid.addWidget(self.txtType, 2, 1)
        grid.addWidget(QLabel(translations.TR_PROJECT_DESCRIPTION), 3, 0)
        self.description = QPlainTextEdit()
        self.description.setPlainText(self._parent.project.description)
        grid.addWidget(self.description, 3, 1)
        grid.addWidget(QLabel(translations.TR_PROJECT_URL), 4, 0)
        self.url = QLineEdit()
        self.url.setText(self._parent.project.url)
        self.url.setPlaceholderText('https://www.{}.com'.format(getuser()))
        grid.addWidget(self.url, 4, 1)
        grid.addWidget(QLabel(translations.TR_PROJECT_LICENSE), 5, 0)
        self.cboLicense = QComboBox()
        self.cboLicense.addItems(LICENCES)
        self.cboLicense.setCurrentIndex(12)
        index = self.cboLicense.findText(self._parent.project.license)
        self.cboLicense.setCurrentIndex(index)
        grid.addWidget(self.cboLicense, 5, 1)

        self.txtExtensions = QLineEdit()
        self.txtExtensions.setText(', '.join(self._parent.project.extensions))
        grid.addWidget(QLabel(translations.TR_PROJECT_EXTENSIONS), 6, 0)
        grid.addWidget(self.txtExtensions, 6, 1)

        grid.addWidget(QLabel(translations.TR_PROJECT_INDENTATION), 7, 0)
        self.spinIndentation = QSpinBox()
        self.spinIndentation.setValue(self._parent.project.indentation)
        self.spinIndentation.setRange(2, 10)
        self.spinIndentation.setValue(4)
        self.spinIndentation.setSingleStep(2)
        grid.addWidget(self.spinIndentation, 7, 1)
        self.checkUseTabs = QComboBox()
        self.checkUseTabs.addItems([
            translations.TR_PREFERENCES_EDITOR_CONFIG_SPACES.capitalize(),
            translations.TR_PREFERENCES_EDITOR_CONFIG_TABS.capitalize()])
        self.checkUseTabs.setCurrentIndex(int(self._parent.project.use_tabs))
        grid.addWidget(self.checkUseTabs, 7, 2)
Exemplo n.º 2
0
    def __init__(self, table_p, parent, product=None, *args, **kwargs):
        QDialog.__init__(self, parent, *args, **kwargs)

        self.table_p = table_p
        self.prod = product
        self.parent = parent
        self.filename = "Parcourire ..."
        self.path_filename = None

        if self.prod:
            self.title = u"Modification de l'article {}".format(self.prod.name)
            self.succes_msg = u"L'article <b>%s</b> a été mise à jour" % self.prod.name
            try:
                self.filename = self.prod.file_join.file_name
            except:
                pass
        else:
            self.succes_msg = u"L'article a été bien enregistré"
            self.title = u"Ajout de nouvel article"
            self.prod = Product()

        self.setWindowTitle(self.title)

        # self.code = LineEdit(self.prod.code)
        self.name_field = LineEdit(self.prod.name)
        try:
            self.category_name = Category.select().where(
                Category.name == self.prod.category.name).get().name
        except:
            self.category_name = ""
        self.category_field = LineEdit(self.category_name)

        self.number_parts_box_field = IntLineEdit(
            str(self.prod.number_parts_box))
        self.number_parts_box_field.setValidator(QIntValidator())

        completion_values = [catg.name for catg in Category.all()]
        completer = QCompleter(completion_values, parent=self)
        completer.setCaseSensitivity(Qt.CaseInsensitive)
        completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.category_field.setCompleter(completer)

        vbox = QVBoxLayout()
        formbox = QFormLayout()
        formbox.addRow(FLabel(u"Nom"), self.name_field)
        formbox.addRow(FLabel(u"Categorie"), self.category_field)
        # formbox.addRow(
        #     FLabel(u"Quantité (carton)"), self.number_parts_box_field)
        self.butt_parco = QPushButton(
            QIcon.fromTheme('document-open', QIcon('')), self.filename)
        self.butt_parco.clicked.connect(self.import_image)
        butt_cancel = Warning_btt(u"Annuler")
        butt_cancel.clicked.connect(self.cancel)
        # formbox.addRow(FLabel(u"Image"), self.butt_parco)
        butt = Button_save(u"&Enregistrer")
        butt.clicked.connect(self.add_or_edit_prod)
        formbox.addRow(butt_cancel, butt)

        vbox.addLayout(formbox)
        self.setLayout(vbox)
Exemplo n.º 3
0
class MyLineEdit(Plasma.LineEdit):

    """Custom LineEdit for Pylou."""

    def __init__(self, *args):
        """Init class."""
        Plasma.LineEdit.__init__(self, *args)
        self.nativeWidget().setClearButtonShown(True)
        self.nativeWidget().setPlaceholderText("Type to Search...")
        self.nativeWidget().setToolTip("""<p>Type and press ENTER:to Search<br>
        UP-DOWN: History navigation<br>Search Empty Query: Clear out""")
        self.completer = QCompleter(tuple(sorted(set(
            [_ for _ in listdir(path.expanduser("~")) if not _.startswith(".")]
        ))), self.nativeWidget())
        self.completer.setCompletionMode(QCompleter.InlineCompletion)
        self.completer.setCaseSensitivity(0)  # Qt.CaseInsensitive
        self.nativeWidget().setCompleter(self.completer)

    def event(self, event):
        """Override to enable History Navigation."""
        # Qt.Key_Up
        if event.type() == QEvent.KeyPress and event.key() == 0x01000013:
            self.emit(SIGNAL("keyUPPressed"))
            return True
        # Qt.Key_Down
        if event.type() == QEvent.KeyPress and event.key() == 0x01000015:
            self.emit(SIGNAL("keyDownPressed"))
            return True
        return Plasma.LineEdit.event(self, event)
Exemplo n.º 4
0
    def handle_login(self):
        identifier = self.db.check_user_password(self.ui.usernameEdit.text(), self.ui.passwordEdit.text())
        # if the username and password are found in the database, allow the user to edit the other widgets
        if identifier:
            self.widget_dict = {self.ui.usernameEdit: False,
                                self.ui.passwordEdit: False,
                                self.ui.loginButton: False,
                                self.ui.cancelButton: False,
                                self.ui.enviroTree: True,
                                self.ui.aEdit: True,
                                self.ui.bEdit: True,
                                self.ui.cEdit: True,
                                self.ui.uncertEdit: True,
                                self.ui.dateEdit: True,
                                self.ui.applyButton: True}

            # Set up auto completion for the date field
            dateList = QtCore.QStringList([datetime.datetime.strftime(datetime.datetime.now(), "%Y-%m-%d")])
            dateEditCompleter = QCompleter(dateList)
            dateEditCompleter.setCompletionMode(QCompleter.InlineCompletion)
            self.ui.dateEdit.setCompleter(dateEditCompleter)

            self.update_widgets()
        # if the user/pass aren't found,
        else:
            ErrorMessage('Login Failed')
Exemplo n.º 5
0
    def __init__(self, parent):
        super(ProjectData, self).__init__()
        self._parent = parent
        grid = QGridLayout(self)
        grid.addWidget(QLabel(self.tr("Name:")), 0, 0)
        self.name = QLineEdit()
        if self._parent._item.name == '':
            self.name.setText(file_manager.get_basename(
                self._parent._item.path))
        else:
            self.name.setText(self._parent._item.name)
        grid.addWidget(self.name, 0, 1)
        grid.addWidget(QLabel(self.tr("Project Type:")), 1, 0)
        self.txtType = QLineEdit()
        completer = QCompleter(sorted(settings.PROJECT_TYPES))
        completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.txtType.setCompleter(completer)
        self.txtType.setText(self._parent._item.projectType)
        grid.addWidget(self.txtType, 1, 1)
        grid.addWidget(QLabel(self.tr("Description:")), 2, 0)
        self.description = QPlainTextEdit()
        self.description.setPlainText(self._parent._item.description)
        grid.addWidget(self.description, 2, 1)
        grid.addWidget(QLabel(self.tr("URL:")), 3, 0)
        self.url = QLineEdit()
        self.url.setText(self._parent._item.url)
        grid.addWidget(self.url, 3, 1)
        grid.addWidget(QLabel(self.tr("Licence:")), 4, 0)
        self.cboLicense = QComboBox()
        self.cboLicense.addItem('Apache License 2.0')
        self.cboLicense.addItem('Artistic License/GPL')
        self.cboLicense.addItem('Eclipse Public License 1.0')
        self.cboLicense.addItem('GNU General Public License v2')
        self.cboLicense.addItem('GNU General Public License v3')
        self.cboLicense.addItem('GNU Lesser General Public License')
        self.cboLicense.addItem('MIT License')
        self.cboLicense.addItem('Mozilla Public License 1.1')
        self.cboLicense.addItem('New BSD License')
        self.cboLicense.addItem('Other Open Source')
        self.cboLicense.addItem('Other')
        self.cboLicense.setCurrentIndex(4)
        index = self.cboLicense.findText(self._parent._item.license)
        self.cboLicense.setCurrentIndex(index)
        grid.addWidget(self.cboLicense, 4, 1)

        self.txtExtensions = QLineEdit()
        self.txtExtensions.setText(', '.join(self._parent._item.extensions))
        grid.addWidget(QLabel(self.tr("Supported Extensions:")), 5, 0)
        grid.addWidget(self.txtExtensions, 5, 1)

        grid.addWidget(QLabel(self.tr("Indentation: ")), 6, 0)
        self.spinIndentation = QSpinBox()
        self.spinIndentation.setValue(self._parent._item.indentation)
        self.spinIndentation.setMinimum(1)
        grid.addWidget(self.spinIndentation, 6, 1)
        self.checkUseTabs = QCheckBox(self.tr("Use Tabs."))
        self.checkUseTabs.setChecked(self._parent._item.useTabs)
        grid.addWidget(self.checkUseTabs, 6, 2)
    def __init__(self, parent):
        super(ProjectData, self).__init__()
        self._parent = parent
        grid = QGridLayout(self)
        grid.addWidget(QLabel(self.tr("Name:")), 0, 0)
        self.name = QLineEdit()
        if self._parent._item.name == '':
            self.name.setText(
                file_manager.get_basename(self._parent._item.path))
        else:
            self.name.setText(self._parent._item.name)
        grid.addWidget(self.name, 0, 1)
        grid.addWidget(QLabel(self.tr("Project Type:")), 1, 0)
        self.txtType = QLineEdit()
        completer = QCompleter(sorted(settings.PROJECT_TYPES))
        completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.txtType.setCompleter(completer)
        self.txtType.setText(self._parent._item.projectType)
        grid.addWidget(self.txtType, 1, 1)
        grid.addWidget(QLabel(self.tr("Description:")), 2, 0)
        self.description = QPlainTextEdit()
        self.description.setPlainText(self._parent._item.description)
        grid.addWidget(self.description, 2, 1)
        grid.addWidget(QLabel(self.tr("URL:")), 3, 0)
        self.url = QLineEdit()
        self.url.setText(self._parent._item.url)
        grid.addWidget(self.url, 3, 1)
        grid.addWidget(QLabel(self.tr("Licence:")), 4, 0)
        self.cboLicense = QComboBox()
        self.cboLicense.addItem('Apache License 2.0')
        self.cboLicense.addItem('Artistic License/GPL')
        self.cboLicense.addItem('Eclipse Public License 1.0')
        self.cboLicense.addItem('GNU General Public License v2')
        self.cboLicense.addItem('GNU General Public License v3')
        self.cboLicense.addItem('GNU Lesser General Public License')
        self.cboLicense.addItem('MIT License')
        self.cboLicense.addItem('Mozilla Public License 1.1')
        self.cboLicense.addItem('New BSD License')
        self.cboLicense.addItem('Other Open Source')
        self.cboLicense.addItem('Other')
        self.cboLicense.setCurrentIndex(4)
        index = self.cboLicense.findText(self._parent._item.license)
        self.cboLicense.setCurrentIndex(index)
        grid.addWidget(self.cboLicense, 4, 1)

        self.txtExtensions = QLineEdit()
        self.txtExtensions.setText(', '.join(self._parent._item.extensions))
        grid.addWidget(QLabel(self.tr("Supported Extensions:")), 5, 0)
        grid.addWidget(self.txtExtensions, 5, 1)

        grid.addWidget(QLabel(self.tr("Indentation: ")), 6, 0)
        self.spinIndentation = QSpinBox()
        self.spinIndentation.setValue(self._parent._item.indentation)
        self.spinIndentation.setMinimum(1)
        grid.addWidget(self.spinIndentation, 6, 1)
        self.checkUseTabs = QCheckBox(self.tr("Use Tabs."))
        self.checkUseTabs.setChecked(self._parent._item.useTabs)
        grid.addWidget(self.checkUseTabs, 6, 2)
Exemplo n.º 7
0
    def _load_labels(self):
        labels = self.github.get_labels()

        model = QStringListModel()
        completer_model = model
        compl = QCompleter()
        compl.setModel(model)
        compl.setCaseSensitivity(Qt.CaseInsensitive)
        compl.setMaxVisibleItems(50)
        compl.setModelSorting(QCompleter.CaseInsensitivelySortedModel)
        compl.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        completer_model.setStringList(labels)

        self.LabelsLineEdit.setCompleter(compl)
        self.LabelsLineEdit.setText("")
Exemplo n.º 8
0
class ExtendedComboBox(QComboBox):
    def __init__(self, parent=None):
        super(ExtendedComboBox, self).__init__(parent)

        self.setFocusPolicy(Qt.StrongFocus)
        self.setEditable(True)
        self.pFilterModel = QSortFilterProxyModel(self)
        self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.pFilterModel.setSourceModel(self.model())
        self.completer = QCompleter(self.pFilterModel, self)
        self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.completer.popup().setStyleSheet('min-height: 150px')
        self.completer.popup().setAlternatingRowColors(True)
        self.setCompleter(self.completer)
        self.lineEdit().textEdited[unicode].connect(self.pFilterModel.setFilterFixedString)
Exemplo n.º 9
0
    def setOptions(self, options):
        """
        Sets the tag option list for this widget.  If used, tags need to be
        found within the list of options when added.
        
        :param      options | [<str>, ..]
        """
        self._options = map(str, options)

        if (options):
            completer = QCompleter(options, self)
            completer.setCompletionMode(QCompleter.InlineCompletion)
            self.setCompleter(completer)
        else:
            self.setCompleter(None)
Exemplo n.º 10
0
class ExtendedCombo(QComboBox):
    def __init__(self, parent=None):
        """Default constructor
        """
        super(ExtendedCombo, self).__init__(parent)

        self.setFocusPolicy(Qt.StrongFocus)
        self.setEditable(True)

        # add a filter model to filter matching items
        self.pFilterModel = QSortFilterProxyModel(self)
        self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.pFilterModel.setSourceModel(self.model())

        # add a completer, which uses the filter model
        self.completer = QCompleter(self.pFilterModel, self)
        # always show all (filtered) completions
        self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.setCompleter(self.completer)

        # connect signals
        self.lineEdit().textEdited[unicode].connect(
            self.pFilterModel.setFilterFixedString)
        self.completer.activated.connect(self.on_completer_activated)

    # on selection of an item from the completer, select the corresponding item from combobox
    def on_completer_activated(self, text):
        """
        """
        if text:
            index = self.findText(text)
            self.setCurrentIndex(index)

    # on model change, update the models of the filter and completer as well
    def setModel(self, model):
        """
        """
        super(ExtendedCombo, self).setModel(model)
        self.pFilterModel.setSourceModel(model)
        self.completer.setModel(self.pFilterModel)

    # on model column change, update the model column of the filter and completer as well
    def setModelColumn(self, column):
        """
        """
        self.completer.setCompletionColumn(column)
        self.pFilterModel.setFilterKeyColumn(column)
        super(ExtendedCombo, self).setModelColumn(column)
Exemplo n.º 11
0
class ExtendedComboBox(QComboBox):
    def __init__(self, parent=None):
        super(ExtendedComboBox, self).__init__(parent)

        self.setFocusPolicy(Qt.StrongFocus)
        self.setEditable(True)
        self.setCurrentIndex(-1)
        # self.activated.connect(self.on_completer_activated)

        # add a filter model to filter matching items
        self.pFilterModel = QSortFilterProxyModel(self)
        self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.pFilterModel.setSourceModel(self.model())

        # add a completer, which uses the filter model
        self.completer = QCompleter(self.pFilterModel, self)
        # always show all (filtered) completions
        self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.setCompleter(self.completer)

        # connect signals
        # self.lineEdit().textEdited[unicode].connect(self.pFilterModel.setFilterFixedString)
        # self.completer.activated.connect(self.on_completer_activated)

    # # on selection of an item from the completer, select the corresponding item from combobox
    # def on_completer_activated(self, received):
    #
    #     if type( received ) != int:
    #         # index = self.findText(received)
    #         # self.setCurrentIndex(index)
    #         # print "Es el texto: %s & index: %s" % (self.itemText(index), index)
    #         print "Es el texto como viene: %s" % received
    #         return received
    #     else:
    #         print "Es el texto extraido del numero enviado: %s " % self.itemText(received)
    #         return self.itemText(received)

    # on model change, update the models of the filter and completer as well
    def setModel(self, model):
        super(ExtendedComboBox, self).setModel(model)
        self.pFilterModel.setSourceModel(model)
        self.completer.setModel(self.pFilterModel)

    # on model column change, update the model column of the filter and completer as well
    def setModelColumn(self, column):
        self.completer.setCompletionColumn(column)
        self.pFilterModel.setFilterKeyColumn(column)
        super(ExtendedComboBox, self).setModelColumn(column)
Exemplo n.º 12
0
def set_model_by_list(string_list, widget, proxy_model):
    """ Set the model according to the list """
    model = QStringListModel()
    model.setStringList(string_list)
    proxy_model.setSourceModel(model)
    proxy_model.setFilterKeyColumn(0)
    proxy_model_aux = QSortFilterProxyModel()
    proxy_model_aux.setSourceModel(model)
    proxy_model_aux.setFilterKeyColumn(0)
    widget.setModel(proxy_model_aux)
    widget.setModelColumn(0)
    completer = QCompleter()
    completer.setModel(proxy_model)
    completer.setCompletionColumn(0)
    completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
    widget.setCompleter(completer)
Exemplo n.º 13
0
class ExtendedCombo(QComboBox):
    def __init__(self,  parent=None):
        super(ExtendedCombo, self).__init__(parent)

        self.setFocusPolicy(Qt.StrongFocus)
        self.setEditable(True)
        self.completer = QCompleter(self)
        self.selected_id = None

        # always show all completions
        self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion )
        self.pFilterModel = QSortFilterProxyModel(self)
        self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive)

        self.completer.setPopup(self.view())
        self.setCompleter(self.completer)


        self.lineEdit().textEdited[unicode].connect(self.pFilterModel.setFilterFixedString)
        self.completer.activated.connect(self.setTextIfCompleterIsClicked)
        self.currentIndexChanged.connect(self.currentSelected)

    def setModel( self, model ):
        super(ExtendedCombo, self).setModel( model )
        self.pFilterModel.setSourceModel( model )
        self.completer.setModel(self.pFilterModel)

    def setModelColumn( self, column):
        self.completer.setCompletionColumn( column )
        self.pFilterModel.setFilterKeyColumn( column )
        super(ExtendedCombo, self).setModelColumn( column )


    def view(self):
        return self.completer.popup()

    def index(self):
        return self.currentIndex()

    def setTextIfCompleterIsClicked(self, text):
      if text:
        index = self.findText(text)
        self.setCurrentIndex(index)

    def currentSelected(self, text):
        if text:
            self.selected_id = self.currentText()
Exemplo n.º 14
0
 def search_tag(self):
     ' dialog with an entry field and autocompleter to search and use tags '
     dialog, group0, stringy = QDialog(), QGroupBox(), QLineEdit()
     button, glow = QPushButton(' Make Django Template Tag '), QGraphicsDropShadowEffect()
     group0.setTitle(__doc__)
     stringy.setPlaceholderText(' Type to Search . . . ')
     button.setMinimumSize(200, 50)
     button.clicked.connect(lambda: self.templatag(str(stringy.text()).lower().strip()))
     stringy.returnPressed.connect(lambda: self.templatag(str(stringy.text()).lower().strip()))
     button.released.connect(lambda: dialog.close())
     glow.setOffset(0)
     glow.setBlurRadius(99)
     glow.setColor(QColor(99, 255, 255))
     button.setGraphicsEffect(glow)
     vboxg0 = QVBoxLayout(group0)
     for each_widget in (QLabel('<b>Search Tags and Filters as I Type'), stringy,
         QLabel('<center><small><i>{}'.format(''.join((__doc__, __version__, __license__, 'by', __author__)))),
         button):
         vboxg0.addWidget(each_widget)
         each_widget.setToolTip(each_widget.text())
     stringy.setToolTip(' Type and press ENTER ')
     QVBoxLayout(dialog).addWidget(group0)
     completer = QCompleter(('autoescape', 'block', 'comment',
     'csrf_token', 'cycle', 'debug', 'extends', 'filter', 'firstof', 'for',
     'for...empty', 'if', 'ifchanged', 'ifequal', 'ifnotequal', 'include',
     'load', 'now', 'regroup', 'spaceless', 'ssi', 'templatetag', 'verbatim',
     'in operator', 'not in operator', 'widthratio', 'with', 'add',
     'addslashes', 'capfirst', 'center', 'cut', 'date', 'default',
     'default_if_none', 'dictsort', 'dictsortreversed', 'divisibleby',
     'escape', 'escapejs', 'filesizeformat', 'first', 'fix_ampersands',
     'floatformat', 'force_escape', 'get_digit', 'iriencode', 'join', 'last',
     'lenght', 'lenght_is', 'linebreaks', 'linebreaksbr', 'linenumbers',
     'ljust', 'lower', 'make_list', 'phone2numeric', 'pluralize', 'pprint',
     'random', 'removetags', 'rjust', 'safe', 'safeseq', 'slice', 'slugify',
     'stringformat', 'striptags', 'time', 'timesince', 'timeuntil', 'title',
     'truncatechars', 'truncatewords', 'truncatewords_html', 'htmlcomment',
     'unordered_list', 'upper', 'urlencode', 'urlize', 'urlizetrunc',
     'wordcount', 'wordwrap', 'yesno', 'apnumber', 'intcomma', 'intword',
     'naturalday', 'naturaltime', 'ordinal', 'lorem', 'static', 'iecomment',
     'get_static_prefix', 'get_media_prefix', 'singlelinecomment',
     'multilinecomment', 'singlelinecommentpopup', 'multilinecommentpopup',
     'singlelinecommentclipboard', 'multilinecommentclipboard',
     'multilinecommentfile', 'singlelinecommentdatetime'), self)
     completer.setCompletionMode(QCompleter.PopupCompletion)
     completer.setCaseSensitivity(0)
     stringy.setCompleter(completer)
     dialog.show()
Exemplo n.º 15
0
    def set_model_by_list(self, string_list, widget):

        model = QStringListModel()
        model.setStringList(string_list)
        self.proxy_model = QSortFilterProxyModel()
        self.proxy_model.setSourceModel(model)
        self.proxy_model.setFilterKeyColumn(0)
        proxy_model_aux = QSortFilterProxyModel()
        proxy_model_aux.setSourceModel(model)
        proxy_model_aux.setFilterKeyColumn(0)
        widget.setModel(proxy_model_aux)
        widget.setModelColumn(0)
        completer = QCompleter()
        completer.setModel(self.proxy_model)
        completer.setCompletionColumn(0)
        completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        widget.setCompleter(completer)
class ExtendedComboBox(QComboBox):
    """ Based off the extension of the combo box from below:
        http://stackoverflow.com/questions/4827207/how-do-i-filter-the-pyqt-qcombobox-items-based-on-the-text-input
    """
    def __init__(self, parent = None):
        super(ExtendedComboBox, self).__init__(parent)

        self.setFocusPolicy(Qt.StrongFocus)
        self.setEditable(True)

        self.setEditable(True)
        self.completer = QCompleter(self)

        # always show all completions
        self.completer.setCompletionMode(QCompleter.PopupCompletion)
        self.pFilterModel = QSortFilterProxyModel(self)
        self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive)

        self.completer.setPopup(self.view())
        self.setCompleter(self.completer)

        self.lineEdit().textEdited[unicode].connect(self.pFilterModel.setFilterFixedString)
        self.completer.activated.connect(self.setTextIfCompleterIsClicked)

    def setModel(self, model):
        super(ExtendedComboBox, self).setModel( model )
        self.pFilterModel.setSourceModel( model )
        self.completer.setModel(self.pFilterModel)

    def setModelColumn(self, column):
        self.completer.setCompletionColumn(column)
        self.pFilterModel.setFilterKeyColumn(column)
        super(ExtendedComboBox, self).setModelColumn(column)


    def view(self):
        return self.completer.popup()

    def index(self):
        return self.currentIndex()

    def setTextIfCompleterIsClicked(self, text):
      if text:
        index = self.findText(text)
        self.setCurrentIndex(index)
class ExtendedComboBox(QComboBox):
    """ Based off the extension of the combo box from below:
        http://stackoverflow.com/questions/4827207/how-do-i-filter-the-pyqt-qcombobox-items-based-on-the-text-input
    """
    def __init__(self, parent=None):
        super(ExtendedComboBox, self).__init__(parent)

        self.setFocusPolicy(Qt.StrongFocus)
        self.setEditable(True)

        self.setEditable(True)
        self.completer = QCompleter(self)

        # always show all completions
        self.completer.setCompletionMode(QCompleter.PopupCompletion)
        self.pFilterModel = QSortFilterProxyModel(self)
        self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive)

        self.completer.setPopup(self.view())
        self.setCompleter(self.completer)

        self.lineEdit().textEdited[unicode].connect(
            self.pFilterModel.setFilterFixedString)
        self.completer.activated.connect(self.setTextIfCompleterIsClicked)

    def setModel(self, model):
        super(ExtendedComboBox, self).setModel(model)
        self.pFilterModel.setSourceModel(model)
        self.completer.setModel(self.pFilterModel)

    def setModelColumn(self, column):
        self.completer.setCompletionColumn(column)
        self.pFilterModel.setFilterKeyColumn(column)
        super(ExtendedComboBox, self).setModelColumn(column)

    def view(self):
        return self.completer.popup()

    def index(self):
        return self.currentIndex()

    def setTextIfCompleterIsClicked(self, text):
        if text:
            index = self.findText(text)
            self.setCurrentIndex(index)
Exemplo n.º 18
0
class CompletingComboBox(QComboBox):
    """An editable combo box that filters and autocompletes."""
    def __init__(self, parent=None):
        super(CompletingComboBox, self).__init__(parent)
        self.setEditable(True)
        self.filter = QSortFilterProxyModel(self)
        self.filter.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.filter.setSourceModel(self.model())
        self.completer = QCompleter(self.filter, self)
        self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.setCompleter(self.completer)
        self.lineEdit().textEdited[unicode]\
            .connect(self.filter.setFilterFixedString)
        self.currentIndexChanged.connect(self._index_changed)
        self.setAutoCompletion(True)

    def _index_changed(self, index):
        self.lineEdit().selectAll()
Exemplo n.º 19
0
class ExtendedComboBox(QComboBox):
    def __init__(self, parent=None):
        super(ExtendedComboBox, self).__init__(parent)

        self.setFocusPolicy(Qt.StrongFocus)
        self.setEditable(True)

        # add a filter model to filter matching items
        self.pFilterModel = QSortFilterProxyModel(self)
        self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.pFilterModel.setSourceModel(self.model())

        # add a completer, which uses the filter model
        self.completer = QCompleter(self.pFilterModel, self)
        # always show all (filtered) completions
        self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.setCompleter(self.completer)

        # connect signals
        self.lineEdit().textEdited[unicode].connect(self.pFilterModel.setFilterFixedString)
        self.completer.activated.connect(self.on_completer_activated)


    # on selection of an item from the completer, select the corresponding item from combobox 
    def on_completer_activated(self, text):
        if text:
            index = self.findText(text)
            self.setCurrentIndex(index)


    # on model change, update the models of the filter and completer as well 
    def setModel(self, model):
        super(ExtendedComboBox, self).setModel(model)
        self.pFilterModel.setSourceModel(model)
        self.completer.setModel(self.pFilterModel)


    # on model column change, update the model column of the filter and completer as well
    def setModelColumn(self, column):
        self.completer.setCompletionColumn(column)
        self.pFilterModel.setFilterKeyColumn(column)
        super(ExtendedComboBox, self).setModelColumn(column)
Exemplo n.º 20
0
    def __init__(self):
        super(GeneralPreferences, self).__init__()
        grid = QGridLayout(self)
        grid.setSpacing(20)
        grid.setColumnStretch(1, 10)

        # directory auto completer
        completer = QCompleter(self)
        dirs = QDirModel(self)
        dirs.setFilter(QDir.AllDirs | QDir.NoDotAndDotDot)
        completer.setModel(dirs)
        completer.setCaseSensitivity(Qt.CaseInsensitive)
        completer.setCompletionMode(QCompleter.PopupCompletion)

        l = QLabel(
            u"<b>Ingresá el directorio donde descargar los videos...</b>")
        l.setTextFormat(Qt.RichText)
        grid.addWidget(l, 0, 0, 1, 2)

        grid.addWidget(QLabel(u"Descargar en:"), 1, 0, 2, 1)
        prv = config.get('downloaddir', '')
        self.downloaddir_entry = QLineEdit(prv)
        self.downloaddir_entry.setCompleter(completer)
        self.downloaddir_entry.setPlaceholderText(u'Ingresá un directorio')
        grid.addWidget(self.downloaddir_entry, 1, 1, 2, 2)

        self.downloaddir_buttn = QPushButton(u"Elegir un directorio")
        self.downloaddir_buttn.clicked.connect(self._choose_dir)
        grid.addWidget(self.downloaddir_buttn, 2, 1, 3, 2)

        self.autoreload_checkbox = QCheckBox(
            u"Recargar automáticamente la lista de episodios al iniciar")
        prv = config.get('autorefresh', False)
        self.autoreload_checkbox.setChecked(prv)
        grid.addWidget(self.autoreload_checkbox, 3, 0, 4, 2)

        self.shownotifs_checkbox = QCheckBox(
            u"Mostrar una notificación cuando termina cada descarga")
        prv = config.get('notification', True)
        self.shownotifs_checkbox.setChecked(prv)
        grid.addWidget(self.shownotifs_checkbox, 4, 0, 5, 2)
Exemplo n.º 21
0
    def __init__(self):
        super(GeneralPreferences, self).__init__()
        grid = QGridLayout(self)
        grid.setSpacing(20)
        grid.setColumnStretch(1, 10)

        # directory auto completer
        completer = QCompleter(self)
        dirs = QDirModel(self)
        dirs.setFilter(QDir.AllDirs | QDir.NoDotAndDotDot)
        completer.setModel(dirs)
        completer.setCaseSensitivity(Qt.CaseInsensitive)
        completer.setCompletionMode(QCompleter.PopupCompletion)

        l = QLabel(
            u"<b>Ingresá el directorio donde descargar los videos...</b>")
        l.setTextFormat(Qt.RichText)
        grid.addWidget(l, 0, 0, 1, 2)

        grid.addWidget(QLabel(u"Descargar en:"), 1, 0, 2, 1)
        prv = config.get('downloaddir', '')
        self.downloaddir_entry = QLineEdit(prv)
        self.downloaddir_entry.setCompleter(completer)
        self.downloaddir_entry.setPlaceholderText(u'Ingresá un directorio')
        grid.addWidget(self.downloaddir_entry, 1, 1, 2, 2)

        self.downloaddir_buttn = QPushButton(u"Elegir un directorio")
        self.downloaddir_buttn.clicked.connect(self._choose_dir)
        grid.addWidget(self.downloaddir_buttn, 2, 1, 3, 2)

        self.autoreload_checkbox = QCheckBox(
            u"Recargar automáticamente la lista de episodios al iniciar")
        prv = config.get('autorefresh', False)
        self.autoreload_checkbox.setChecked(prv)
        grid.addWidget(self.autoreload_checkbox, 3, 0, 4, 2)

        self.shownotifs_checkbox = QCheckBox(
            u"Mostrar una notificación cuando termina cada descarga")
        prv = config.get('notification', True)
        self.shownotifs_checkbox.setChecked(prv)
        grid.addWidget(self.shownotifs_checkbox, 4, 0, 5, 2)
Exemplo n.º 22
0
class ExtendedComboBox( QComboBox ):
    def __init__( self,  parent = None):
        super( ExtendedComboBox, self ).__init__( parent )
        self.setFocusPolicy( Qt.StrongFocus )
        self.setEditable( True )
        # add a filter model to filter matching items
        self.pFilterModel = QSortFilterProxyModel( self )
        self.pFilterModel.setFilterCaseSensitivity( Qt.CaseInsensitive )
        self.pFilterModel.setSourceModel(self.model())
        # add a completer, which uses the filter model
        self.completer = QCompleter(self.pFilterModel, self)
        # always show all completions
        self.completer.setCompletionMode( QCompleter.UnfilteredPopupCompletion )
        self.completer.setPopup( self.view() )
        self.setCompleter( self.completer )
        self.lineEdit().textEdited[unicode].connect( self.pFilterModel.setFilterFixedString )
        self.completer.activated.connect(self.on_completer_activated)

    def setModel( self, model ):
        super(ExtendedComboBox, self).setModel( model )
        self.pFilterModel.setSourceModel( model )
        self.completer.setModel(self.pFilterModel)

    def setModelColumn( self, column ):
        self.completer.setCompletionColumn( column )
        self.pFilterModel.setFilterKeyColumn( column )
        super(ExtendedComboBox, self).setModelColumn( column )

    def view( self ):
        return self.completer.popup()

    def index( self ):
        return self.currentIndex()

    def on_completer_activated(self, text):
        if text:
            index = self.findText(text)
            self.setCurrentIndex(index)
Exemplo n.º 23
0
class Main(plugin.Plugin):
    " Main Class "
    def initialize(self, *args, **kwargs):
        " Init Main Class "
        super(Main, self).initialize(*args, **kwargs)
        self.infile = QLineEdit(path.expanduser("~"))
        self.infile.setPlaceholderText(' /full/path/to/file ')
        self.infile.returnPressed.connect(self.run)
        self.completer, self.dirs = QCompleter(self), QDirModel(self)
        self.dirs.setFilter(QDir.AllEntries | QDir.NoDotAndDotDot)
        self.completer.setModel(self.dirs)
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setCompletionMode(QCompleter.PopupCompletion)
        self.infile.setCompleter(self.completer)

        self.menu = QMenu('Base64')
        self.menu.aboutToShow.connect(self.build_submenu)
        self.ex_locator = self.locator.get_service('explorer')
        self.ex_locator.add_project_menu(self.menu, lang='all')

        self.open = QPushButton(QIcon.fromTheme("folder-open"), 'Open')
        self.open.setCursor(QCursor(Qt.PointingHandCursor))
        self.open.clicked.connect(lambda: self.infile.setText(str(
            QFileDialog.getOpenFileName(self.dock, "Open a File to Encode...",
            path.expanduser("~"), ';;'.join(['{}(*.{})'.format(e.upper(), e)
            for e in ['*', 'jpg', 'png', 'webp', 'svg', 'gif', 'webm']])))))
        self.chckbx1 = QCheckBox('Use basic Caesar Cipher (ROT13)')
        self.chckbx1.setToolTip('Use "string".decode("rot13") to Decipher ! ')
        self.chckbx2 = QCheckBox('Use "data:type/subtype;base64,..."')
        self.chckbx2.setChecked(True)
        self.chckbx3 = QCheckBox('Copy encoded output to Clipboard')
        self.chckbx4 = QCheckBox('Use URL-Safe Base64 Encoder')
        self.combo1 = QComboBox()
        self.combo1.addItems(['Do Not Generate Code', 'Generate CSS embed Code',
            'Generate Python Embed Code', 'Generate HTML embed Code',
            'Generate JS embed Code', 'Generate QML embed Code'])
        self.combo1.currentIndexChanged.connect(self.combo_changed)

        self.output = QTextEdit('''
        We can only see a short distance ahead,
        but we can see plenty there that needs to be done.
        - Alan Turing ''')
        self.output.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        self.button = QPushButton(QIcon.fromTheme("face-cool"), 'Encode BASE64')
        self.button.setCursor(QCursor(Qt.PointingHandCursor))
        self.button.setMinimumSize(100, 50)
        self.button.clicked.connect(self.run)
        glow = QGraphicsDropShadowEffect(self)
        glow.setOffset(0)
        glow.setBlurRadius(99)
        glow.setColor(QColor(99, 255, 255))
        self.button.setGraphicsEffect(glow)
        glow.setEnabled(True)

        class TransientWidget(QWidget):
            ' persistant widget thingy '
            def __init__(self, widget_list):
                ' init sub class '
                super(TransientWidget, self).__init__()
                vbox = QVBoxLayout(self)
                for each_widget in widget_list:
                    vbox.addWidget(each_widget)

        tw = TransientWidget((QLabel('<i>Encode file as plain text string</i>'),
            QLabel('<b>File to Encode:'), self.infile, self.open, self.chckbx2,
            self.chckbx3, self.chckbx1, self.chckbx4,
            QLabel('<b>Embedding Template Code:'), self.combo1,
            QLabel(' <b>Base64 String Output: '), self.output,
            QLabel('<center><small><i>' + ''.join((__doc__, __version__,
                   __license__, 'by', __author__))), self.button
        ))
        self.scrollable, self.dock = QScrollArea(), QDockWidget()
        self.scrollable.setWidgetResizable(True)
        self.scrollable.setWidget(tw)
        self.dock.setWindowTitle(__doc__)
        self.dock.setStyleSheet('QDockWidget::title{text-align: center;}')
        self.dock.setWidget(self.scrollable)
        ExplorerContainer().addTab(self.dock, "Base64")
        self.guimode = QComboBox(self.dock)
        self.guimode.addItems(['Full Mode', 'Simple Mode'])
        self.guimode.currentIndexChanged.connect(self.guimode_change)

    def guimode_change(self):
        """ Change from Simple Mode to Full Mode by Hide or Show Widgets """
        if self.guimode.currentIndex() is 0:
            self.chckbx1.show()
            self.chckbx2.show()
            self.chckbx3.show()
            self.chckbx4.show()
        else:
            self.chckbx1.hide()
            self.chckbx2.hide()
            self.chckbx3.hide()
            self.chckbx4.hide()
            self.chckbx1.setChecked(False)
            self.chckbx2.setChecked(True)
            self.chckbx3.setChecked(False)
            self.chckbx4.setChecked(False)

    def build_submenu(self):
        ''' build sub menu on the fly based on file path '''
        self.menu.clear()
        if self.ex_locator.get_current_project_item().isFolder is not True:
            filenam = self.ex_locator.get_current_project_item().get_full_path()
            self.menu.addActions([
                QAction('Copy {} as Base64'.format(path.basename(filenam)[:50]),
                        self, triggered=lambda:
                        QApplication.clipboard().setText(
                        '"data:{};charset=utf-8;base64,{}"'.format(
                            guess_type(filenam, strict=False)[0],
                            b64encode(open(filenam, "rb").read())))),
                QAction('Copy {} as Base64 URL-Safe'.format(
                        path.basename(filenam)[:50]),
                        self, triggered=lambda:
                        QApplication.clipboard().setText(
                        '"data:{};charset=utf-8;base64,{}"'.format(
                            guess_type(filenam, strict=False)[0],
                            urlsafe_b64encode(open(filenam, "rb").read()))))])
            self.menu.show()

    def run(self):
        ' run the encoding '
        mimetype = guess_type(str(self.infile.text()).strip(), strict=False)[0]
        _mime = mimetype if mimetype is not None else self.ask_mime()
        fle = str(self.infile.text()).strip().replace('file:///', '/')
        encoder = urlsafe_b64encode if self.chckbx4.isChecked() else b64encode
        if int(path.getsize(fle)) / 1024 / 1024 >= 1:
            QMessageBox.information(self.dock, __doc__,
            '''<b style="color:red"> WARNING!: File size is > 1 Megabyte!,<br>
            this will take some time, depending your CPU Processing power!.''')
        output = '"{}{}{}{}"'.format(
            'data:' if self.chckbx2.isChecked() is True else '',
            _mime if self.chckbx2.isChecked() is True else '',
           ';charset=utf-8;base64,' if self.chckbx2.isChecked() is True else '',
            encoder(open(fle, "rb").read()))
        if self.combo1.currentIndex() is 1:
            output = ('html, body { margin:0; padding:0; background: url(' +
            output + ') no-repeat center center fixed; background-size:cover }')
        elif self.combo1.currentIndex() is 2:
            output = PY_EMBED.format(getuser(),
                     datetime.now().isoformat().split('.')[0], output)
        elif self.combo1.currentIndex() is 3:
            output = '<img src={} alt="{}" title="{}"/>'.format(output,
                     fle.split(sep)[-1], fle.split(sep)[-1])
        elif self.combo1.currentIndex() is 4:
            output = 'var embedded_file = window.atob({}); '.format(output)
        elif self.combo1.currentIndex() is 5:
            output = 'Image { source: ' + output + ' } '
        if self.chckbx1.isChecked() is True:
            output = str(output).encode('rot13')
        if self.chckbx3.isChecked() is True:
            QApplication.clipboard().setText(output)
        self.output.setPlainText(output)
        self.output.setFocus()
        self.output.selectAll()

    def ask_mime(self):
        ' ask user for mime type '
        return str(QInputDialog.getText(self.dock, __doc__, 'Write a MIME-Type',
               QLineEdit.Normal, 'application/octet-stream')[0]).strip().lower()

    def combo_changed(self):
        ' on combo changed '
        if self.combo1.currentIndex() is 1 or self.combo1.currentIndex() is 3:
            self.chckbx1.setChecked(False)
            self.chckbx2.setChecked(True)
        elif self.combo1.currentIndex() is 2 or self.combo1.currentIndex() is 4:
            self.chckbx1.setChecked(False)
            self.chckbx2.setChecked(False)
Exemplo n.º 24
0
class Main(plugin.Plugin):
    " Main Class "
    def initialize(self, *args, **kwargs):
        " Init Main Class "
        ec = ExplorerContainer()
        super(Main, self).initialize(*args, **kwargs)

        self.editor_s = self.locator.get_service('editor')
        # directory auto completer
        self.completer = QCompleter(self)
        self.dirs = QDirModel(self)
        self.dirs.setFilter(QDir.AllEntries | QDir.NoDotAndDotDot)
        self.completer.setModel(self.dirs)
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setCompletionMode(QCompleter.PopupCompletion)

        self.group0 = QGroupBox()
        self.group0.setTitle(' Source ')
        self.source = QComboBox()
        self.source.addItems(['Clipboard', 'Local File', 'Remote URL', 'Ninja'])
        self.source.currentIndexChanged.connect(self.on_source_changed)
        self.infile = QLineEdit(path.expanduser("~"))
        self.infile.setPlaceholderText(' /full/path/to/file.html ')
        self.infile.setCompleter(self.completer)
        self.open = QPushButton(QIcon.fromTheme("folder-open"), 'Open')
        self.open.setCursor(QCursor(Qt.PointingHandCursor))
        self.open.clicked.connect(lambda: self.infile.setText(str(
            QFileDialog.getOpenFileName(self.dock, "Open a File to read from",
            path.expanduser("~"), ';;'.join(['{}(*.{})'.format(e.upper(), e)
            for e in ['css', 'html', 'js', 'txt', '*']])))))
        self.inurl = QLineEdit('http://www.')
        self.inurl.setPlaceholderText('http://www.full/url/to/remote/file.html')
        self.output = QPlainTextEdit(SAMPLE_TEXT)
        vboxg0 = QVBoxLayout(self.group0)
        for each_widget in (self.source, self.infile, self.open, self.inurl,
            self.output, ):
            vboxg0.addWidget(each_widget)
        [a.hide() for a in iter((self.infile, self.open, self.inurl))]

        self.group1 = QGroupBox()
        self.group1.setTitle(' CSS3 ')
        self.group1.setCheckable(True)
        self.group1.setGraphicsEffect(QGraphicsBlurEffect(self))
        self.group1.graphicsEffect().setEnabled(False)
        self.group1.toggled.connect(self.toggle_css_group)
        self.ckcss1 = QCheckBox('Remove unnecessary Comments')
        self.ckcss2 = QCheckBox('Remove unnecessary Whitespace characters')
        self.ckcss3 = QCheckBox('Remove unnecessary Semicolons')
        self.ckcss4 = QCheckBox('Remove unnecessary Empty rules')
        self.ckcss5 = QCheckBox('Condense and Convert Colors from RGB to HEX')
        self.ckcss6 = QCheckBox('Condense all Zero units')
        self.ckcss7 = QCheckBox('Condense Multidimensional Zero units')
        self.ckcss8 = QCheckBox('Condense Floating point numbers')
        self.ckcss9 = QCheckBox('Condense HEX Colors')
        self.ckcss10 = QCheckBox('Condense multiple adjacent Whitespace chars')
        self.ckcss11 = QCheckBox('Condense multiple adjacent semicolon chars')
        self.ckcss12 = QCheckBox('Wrap the lines of the to 80 character length')
        self.ckcss13 = QCheckBox('Condense Font Weight values')
        self.ckcss14 = QCheckBox('Condense the 17 Standard Named Colors values')
        self.ckcss15 = QCheckBox('Condense the 124 Extra Named Colors values')
        self.ckcss16 = QCheckBox('Condense all Percentages values when posible')
        self.ckcss17 = QCheckBox('Condense all Pixels values when posible')
        self.ckcss18 = QCheckBox('Remove unnecessary quotes from url()')
        self.ckcss19 = QCheckBox('Add standard Encoding Declaration if missing')
        vboxg1 = QVBoxLayout(self.group1)
        for each_widget in (self.ckcss1, self.ckcss2, self.ckcss3, self.ckcss4,
            self.ckcss5, self.ckcss6, self.ckcss7, self.ckcss8, self.ckcss9,
            self.ckcss10, self.ckcss11, self.ckcss12, self.ckcss13,
            self.ckcss14, self.ckcss15, self.ckcss16, self.ckcss17,
            self.ckcss18, self.ckcss19):
            vboxg1.addWidget(each_widget)
            each_widget.setToolTip(each_widget.text())

        self.group2 = QGroupBox()
        self.group2.setTitle(' HTML5 ')
        self.group2.setCheckable(True)
        self.group2.setGraphicsEffect(QGraphicsBlurEffect(self))
        self.group2.graphicsEffect().setEnabled(False)
        self.group2.toggled.connect(self.toggle_html_group)
        self.ckhtml0 = QCheckBox('Condense Style and Script HTML Tags')
        self.ckhtml1 = QCheckBox('Condense DOCTYPE to new HTML5 Tags')
        self.ckhtml2 = QCheckBox('Condense Href and Src to protocol agnostic')
        self.ckhtml4 = QCheckBox('Remove unnecessary Tags but keep HTML valid')
        self.help1 = QLabel('''<a href=
            "https://developers.google.com/speed/articles/optimizing-html">
            <small><center>Help about Unneeded Unnecessary HTML tags ?</a>''')
        self.help1.setTextInteractionFlags(Qt.LinksAccessibleByMouse)
        self.help1.setOpenExternalLinks(True)
        vboxg2 = QVBoxLayout(self.group2)
        for each_widget in (self.ckhtml0, self.ckhtml1, self.ckhtml2,
            self.ckhtml4, self.help1, ):
            vboxg2.addWidget(each_widget)
            each_widget.setToolTip(each_widget.text())

        self.group3 = QGroupBox()
        self.group3.setTitle(' Javascript ')
        self.ckjs0 = QCheckBox('Condense and Compress Javascript')
        self.ckjs1 = QCheckBox('Condense $(document).ready(function(){ });')
        vboxg2 = QVBoxLayout(self.group3)
        for each_widget in (self.ckjs0, self.ckjs1):
            vboxg2.addWidget(each_widget)
            each_widget.setToolTip(each_widget.text())

        self.group4 = QGroupBox()
        self.group4.setTitle(' General ')
        self.chckbx1 = QCheckBox('Lower case ALL the text')
        self.chckbx2 = QCheckBox('Remove Spaces, Tabs, New Lines, Empty Lines')
        self.befor, self.after = QProgressBar(), QProgressBar()
        self.befor.setFormat("%v Chars")
        self.after.setFormat("%v Chars")
        vboxg4 = QVBoxLayout(self.group4)
        for each_widget in (self.chckbx1, self.chckbx2,
            QLabel('<b>Before:'), self.befor, QLabel('<b>After:'), self.after):
            vboxg4.addWidget(each_widget)
            each_widget.setToolTip(each_widget.text())

        [a.setChecked(True) for a in iter((self.ckcss1, self.ckcss2,
            self.ckcss3, self.ckcss4, self.ckcss5, self.ckcss6, self.ckcss7,
            self.ckcss8, self.ckcss9, self.ckcss10, self.ckcss11, self.ckcss12,
            self.ckcss13, self.ckcss14, self.ckcss15, self.ckcss16,
            self.ckcss17, self.ckcss18, self.ckcss19, self.ckjs1, self.ckhtml0,
            self.ckhtml1, self.ckhtml2, self.ckhtml4, self.chckbx1,
            self.chckbx2))]

        self.button = QPushButton(QIcon.fromTheme("face-cool"), 'Process Text')
        self.button.setCursor(QCursor(Qt.PointingHandCursor))
        self.button.setMinimumSize(100, 50)
        self.button.clicked.connect(self.run)

        def must_glow(widget_list):
            ' apply an glow effect to the widget '
            for glow, each_widget in enumerate(widget_list):
                try:
                    if each_widget.graphicsEffect() is None:
                        glow = QGraphicsDropShadowEffect(self)
                        glow.setOffset(0)
                        glow.setBlurRadius(99)
                        glow.setColor(QColor(99, 255, 255))
                        each_widget.setGraphicsEffect(glow)
                        glow.setEnabled(True)
                except:
                    pass

        must_glow((self.button, ))

        class TransientWidget(QWidget):
            ' persistant widget thingy '
            def __init__(self, widget_list):
                ' init sub class '
                super(TransientWidget, self).__init__()
                vbox = QVBoxLayout(self)
                for each_widget in widget_list:
                    vbox.addWidget(each_widget)

        tw = TransientWidget((QLabel('<b>HTML5/CSS3/JS Optimizer Compressor'),
            self.group0, self.group1, self.group2, self.group3, self.group4,
            self.button, ))
        self.scrollable = QScrollArea()
        self.scrollable.setWidgetResizable(True)
        self.scrollable.setWidget(tw)
        self.dock = QDockWidget()
        self.dock.setWindowTitle(__doc__)
        self.dock.setStyleSheet('QDockWidget::title{text-align: center;}')
        self.dock.setMinimumWidth(350)
        self.dock.setWidget(self.scrollable)
        ec.addTab(self.dock, "Web")
        QPushButton(QIcon.fromTheme("help-about"), 'About', self.dock
          ).clicked.connect(lambda: QMessageBox.information(self.dock, __doc__,
            HELPMSG))

    def run(self):
        ' run the string replacing '
        if self.source.currentText() == 'Local File':
            with open(path.abspath(str(self.infile.text()).strip()), 'r') as f:
                txt = f.read()
        elif self.source.currentText() == 'Remote URL':
            txt = urlopen(str(self.inurl.text()).strip()).read()
        elif  self.source.currentText() == 'Clipboard':
            txt = str(self.output.toPlainText()) if str(self.output.toPlainText()) is not '' else str(QApplication.clipboard().text())
        else:
            txt = self.editor_s.get_text()
        self.output.clear()
        self.befor.setMaximum(len(txt) + 10)
        self.after.setMaximum(len(txt) + 10)
        self.befor.setValue(len(txt))
        txt = txt.lower() if self.chckbx1.isChecked() is True else txt
        txt = condense_style(txt) if self.ckhtml0.isChecked() is True else txt
        txt = condense_script(txt) if self.ckhtml0.isChecked() is True else txt
        txt = condense_doctype(txt) if self.ckhtml1.isChecked() is True else txt
        txt = condense_href_src(txt) if self.ckhtml2 is True else txt
        txt = clean_unneeded_tags(txt) if self.ckhtml4.isChecked() is True else txt
        txt = condense_doc_ready(txt) if self.ckjs1.isChecked() is True else txt
        txt = jsmin(txt) if self.ckjs0.isChecked() is True else txt
        txt = remove_comments(txt) if self.ckcss1.isChecked() is True else txt
        txt = condense_whitespace(txt) if self.ckcss10.isChecked() is True else txt
        txt = remove_empty_rules(txt) if self.ckcss4.isChecked() is True else txt
        txt = remove_unnecessary_whitespace(txt) if self.ckcss2.isChecked() is True else txt
        txt = remove_unnecessary_semicolons(txt) if self.ckcss3.isChecked() is True else txt
        txt = condense_zero_units(txt) if self.ckcss6.isChecked() is True else txt
        txt = condense_multidimensional_zeros(txt) if self.ckcss7.isChecked() is True else txt
        txt = condense_floating_points(txt) if self.ckcss8.isChecked() is True else txt
        txt = normalize_rgb_colors_to_hex(txt) if self.ckcss5.isChecked() is True else txt
        txt = condense_hex_colors(txt) if self.ckcss9.isChecked() is True else txt
        txt = wrap_css_lines(txt, 80) if self.ckcss12.isChecked() is True else txt
        txt = condense_semicolons(txt) if self.ckcss11.isChecked() is True else txt
        txt = condense_font_weight(txt) if self.ckcss13.isChecked() is True else txt
        txt = condense_std_named_colors(txt) if self.ckcss14.isChecked() is True else txt
        # txt = condense_xtra_named_colors(txt) if self.ckcss14.isChecked() is True else txt  # FIXME
        txt = condense_percentage_values(txt) if self.ckcss16.isChecked() is True else txt
        txt = condense_pixel_values(txt) if self.ckcss17.isChecked() is True else txt
        txt = remove_url_quotes(txt) if self.ckcss18.isChecked() is True else txt
        txt = add_encoding(txt) if self.ckcss19.isChecked() is True else txt
        txt = " ".join(txt.strip().split()) if self.chckbx2.isChecked() is True else txt
        self.after.setValue(len(txt))
        self.output.setPlainText(txt)
        self.output.show()
        self.output.setFocus()
        self.output.selectAll()

    def on_source_changed(self):
        ' do something when the desired source has changed '
        if self.source.currentText() == 'Local File':
            self.open.show()
            self.infile.show()
            self.inurl.hide()
            self.output.hide()
        elif  self.source.currentText() == 'Remote URL':
            self.inurl.show()
            self.open.hide()
            self.infile.hide()
            self.output.hide()
        elif  self.source.currentText() == 'Clipboard':
            self.output.show()
            self.open.hide()
            self.infile.hide()
            self.inurl.hide()
            self.output.setText(QApplication.clipboard().text())
        else:
            self.output.show()
            self.open.hide()
            self.infile.hide()
            self.inurl.hide()
            self.output.setText(self.editor_s.get_text())

    def toggle_css_group(self):
        ' toggle on or off the css checkboxes '
        if self.group1.isChecked() is True:
            [a.setChecked(True) for a in iter((self.ckcss1, self.ckcss2,
            self.ckcss3, self.ckcss4, self.ckcss5, self.ckcss6, self.ckcss7,
            self.ckcss8, self.ckcss9, self.ckcss10, self.ckcss11, self.ckcss12,
            self.ckcss13, self.ckcss14, self.ckcss15, self.ckcss16,
            self.ckcss17, self.ckcss18, self.ckcss19))]
            self.group1.graphicsEffect().setEnabled(False)
        else:
            [a.setChecked(False) for a in iter((self.ckcss1, self.ckcss2,
            self.ckcss3, self.ckcss4, self.ckcss5, self.ckcss6, self.ckcss7,
            self.ckcss8, self.ckcss9, self.ckcss10, self.ckcss11, self.ckcss12,
            self.ckcss13, self.ckcss14, self.ckcss15, self.ckcss16,
            self.ckcss17, self.ckcss18, self.ckcss19))]
            self.group1.graphicsEffect().setEnabled(True)

    def toggle_html_group(self):
        ' toggle on or off the css checkboxes '
        if self.group2.isChecked() is True:
            [a.setChecked(True) for a in iter((self.ckhtml0, self.ckhtml1,
                                               self.ckhtml2, self.ckhtml4))]
            self.group2.graphicsEffect().setEnabled(False)
        else:
            [a.setChecked(False) for a in iter((self.ckhtml0, self.ckhtml1,
                                                self.ckhtml2, self.ckhtml4))]
            self.group2.graphicsEffect().setEnabled(True)
Exemplo n.º 25
0
class DiffGUI(object):
    ' diff gui class '
    def __init__(self):
        ' make a diff method with GUI '
        self.dialog = QDialog()
        self.diff_path = None

        # directory auto completer
        self.completer = QCompleter(self.dialog)
        self.dirs = QDirModel(self.dialog)
        self.dirs.setFilter(QDir.AllEntries | QDir.NoDotAndDotDot)
        self.completer.setModel(self.dirs)
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setCompletionMode(QCompleter.PopupCompletion)
        #self.completer.setCompletionMode(QCompleter.InlineCompletion)

        self.group1 = QGroupBox()
        self.group1.setTitle('Diff')
        self.frmt = QComboBox(self.group1)
        self.frmt.addItems(['Unified', 'Normal', 'Context'])
        self.file1 = QLineEdit()
        self.file1.setPlaceholderText('/full/path/to/one_file.py')
        self.file1.setCompleter(self.completer)
        self.file2 = QLineEdit()
        self.file2.setPlaceholderText('/full/path/to/another_file.py')
        self.file2.setCompleter(self.completer)
        self.fout = QLineEdit()
        self.fout.setText(''.join((path.join(gettempdir(),
                     datetime.now().strftime('%d-%b-%Y_%H:%M:%S.diff')))))
        self.fout.setPlaceholderText('/full/path/to/output_file.diff')
        self.fout.setCompleter(self.completer)
        self.regex = QLineEdit()
        self.regex.setPlaceholderText('DONT use unless you know what are doing')
        self.regex.setToolTip('Do NOT use unless you know what you are doing !')
        self.borig = QPushButton(QIcon.fromTheme("folder-open"), 'Open')
        self.borig.clicked.connect(lambda: self.file1.setText(str(
            QFileDialog.getOpenFileName(self.dialog, 'Open file to compare',
                                           path.expanduser("~"), ';;(*.*)'))))

        self.bmodi = QPushButton(QIcon.fromTheme("folder-open"), 'Open')
        self.bmodi.clicked.connect(lambda: self.file2.setText(str(
            QFileDialog.getOpenFileName(self.dialog, 'Open file to compare',
                                           path.expanduser("~"), ';;(*.*)'))))
        self.bout = QPushButton(QIcon.fromTheme("folder-open"), 'Open')
        self.bout.clicked.connect(lambda: self.fout.setText(str(
            QFileDialog.getSaveFileName(self.dialog, 'Save a Diff file',
                                        path.expanduser("~"), ';;(*.diff)'))))
        vboxg1 = QVBoxLayout(self.group1)
        for each_widget in (QLabel('Original file full path'),
                            self.file1, self.borig,
                            QLabel('Modified file full path'),
                            self.file2, self.bmodi,
                            QLabel('Output file full Path'),
                            self.fout, self.bout,
                            QLabel('Diff Output Format'), self.frmt,
                            QLabel('Diff REGEX to Ignore (ADVANCED)'),
                            self.regex):
            vboxg1.addWidget(each_widget)

        self.group2 = QGroupBox()
        self.group2.setTitle('Options')
        self.nwfl = QCheckBox('Treat new files as Empty')
        self.smll = QCheckBox('Look for smaller changes')
        self.lrgf = QCheckBox('Optimize for large files')
        self.case = QCheckBox('Ignore case changes on content')
        self.cnvt = QCheckBox('Convert Tabs to Spaces')
        self.blnk = QCheckBox('Ignore added or removed Blank lines')
        self.spac = QCheckBox('Ignore changes in amount of Spaces')
        self.whit = QCheckBox('Ignore ALL white Spaces')
        self.tabz = QCheckBox('Ignore changes by Tab expansions')
        self.sprs = QCheckBox('Remove Space or Tab before empty lines')
        self.filn = QCheckBox('Ignore case when comparing file names')
        self.tbs = QComboBox(self.group2)
        self.tbs.addItems(['4', '6', '8', '10', '2'])
        self.nice = QComboBox(self.group2)
        self.nice.addItems(['20', '15', '10', '5', '0'])
        vboxg2 = QVBoxLayout(self.group2)
        for each_widget in (self.nwfl, self.smll, self.lrgf, self.case,
                            self.cnvt, self.blnk, self.spac, self.whit,
                            self.tabz, self.sprs, self.filn,
                            QLabel('Diff Tabs-to-Spaces Size'), self.tbs,
                            QLabel('Diff Backend CPU Priority'), self.nice):
            vboxg2.addWidget(each_widget)
            try:
                each_widget.setToolTip(each_widget.text())
            except:
                each_widget.setToolTip(each_widget.currentText())
            each_widget.setCursor(QCursor(Qt.PointingHandCursor))

        group3 = QGroupBox()
        group3.setTitle('Even More Options')
        self.plai = QCheckBox('Force treat all files as plain text')
        self.nocr = QCheckBox('Force strip trailing carriage return')
        self.ridt = QCheckBox('Report when two files are identical')
        self.nocm = QCheckBox('Do not output common lines')
        self.rdif = QCheckBox('Report only when files differ')
        self.clip = QCheckBox('Copy Diff to Clipboard when done')
        self.noti = QCheckBox('Use system Notification when done')
        self.pret = QCheckBox('Align all Tabs by prepending a Tab')
        self.lolz = QCheckBox('Output Diff in two equal columns')
        self.odif = QCheckBox('Open Diff with Ninja-IDE when done')
        self.plac = QCheckBox('Make an Awesome Diff view when done')
        self.wdth = QComboBox(group3)
        self.wdth.addItems(['80', '100', '120', '130', '250', '500', '999999'])
        self.bcknd = QComboBox(group3)
        self.bcknd.addItems(['diff', 'diff.py'])
        self.bcknd.setDisabled(True)  #TODO this feature needs work
        vboxg3 = QVBoxLayout(group3)
        for each_widget in (self.plai, self.nocr, self.ridt, self.nocm,
                            self.rdif, self.pret, self.clip, self.noti,
                            self.lolz, self.odif, self.plac,
                            QLabel('Diff Maximum Total Width'), self.wdth,
                            QLabel('Diff Backend (EXPERIMENTAL)'), self.bcknd):
            vboxg3.addWidget(each_widget)
            try:
                each_widget.setToolTip(each_widget.text())
            except:
                each_widget.setToolTip(each_widget.currentText())
            each_widget.setCursor(QCursor(Qt.PointingHandCursor))

        for widget_should_be_checked in (self.nwfl, self.smll, self.lrgf,
                                   self.clip, self.cnvt, self.plai, self.noti):
            widget_should_be_checked.setChecked(True)

        container = QWidget()
        hbox = QHBoxLayout(container)
        for each_widget in (self.group2, self.group1, group3):
            hbox.addWidget(each_widget)

        buttons = QDialogButtonBox()
        buttons.resize(self.dialog.size().width(), buttons.size().height() * 2)
        buttons.setOrientation(Qt.Horizontal)
        buttons.setStandardButtons(
            QDialogButtonBox.Ok |
            QDialogButtonBox.Cancel |
            QDialogButtonBox.Close |
            QDialogButtonBox.Help)
        buttons.setCenterButtons(False)
        buttons.helpRequested.connect(lambda: QMessageBox.about(
            self.dialog, __doc__,
            ''.join((__doc__, ' GUI and Visualizer Plugin,', linesep,
            'version ', __version__, ', (', __license__, '), by ', linesep,
            __author__, ', ( ', __email__, ' ).', linesep))))
        buttons.rejected.connect(self.dialog.close)
        buttons.accepted.connect(self.make_diff)

        info = QLabel(''.join(('<b> Current Backend Diff Engine: </b>',
                      getoutput('diff --version').split(linesep)[0])))

        vbox = QVBoxLayout(self.dialog)
        for each_widget in (
                QLabel('<center><h2> Ninja IDE Diff and Patch </h2></center>'),
                container, info, buttons):
            vbox.addWidget(each_widget)

        self.dialog.resize(1024, self.dialog.size().height())
        self.dialog.exec_()

    def make_diff(self):
        ' make the diff '
        diff_command = ''.join((
        'nice --adjustment=', str(self.nice.currentText()).strip(), ' ',
        str(self.bcknd.currentText()).strip(), ' --',
        str(self.frmt.currentText()).strip().lower(),

        ' --new-file ' if self.nwfl.isChecked() is True else '',
        ' --minimal ' if self.smll.isChecked() is True else '',
        ' --speed-large-files ' if self.lrgf.isChecked() is True else '',
        ' --ignore-self.case ' if self.case.isChecked() is True else '',
        ' --expand-tabs ' if self.cnvt.isChecked() is True else '',
        ' --ignore-blank-lines ' if self.blnk.isChecked() is True else '',
        ' --ignore-space-change ' if self.spac.isChecked() is True else '',
        ' --ignore-all-space ' if self.whit.isChecked() is True else '',
        ' --ignore-tab-expansion ' if self.tabz.isChecked() is True else '',
        ' --suppress-blank-empty ' if self.sprs.isChecked() is True else '',
        ' --ignore-file-name-case ' if self.filn.isChecked() is True else '',
        ' --text ' if self.plai.isChecked() is True else '',
        ' --strip-trailing-cr ' if self.nocr.isChecked() is True else '',
        ' --suppress-common-lines ' if self.nocm.isChecked() is True else '',
        ' --initial-tab ' if self.pret.isChecked() is True else '',
        ' --side-by-side ' if self.lolz.isChecked() is True else '',

        ' --tabsize=', str(self.tbs.currentText()).strip(),
        ' --width=', str(self.wdth.currentText()).strip(),

        str(' --ignore-matching-lines=' + str(self.regex.text()).strip())
                           if str(self.regex.text()).strip() is not '' else '',
        ' ',
        path.abspath(str(self.file1.text()))
                    if str(self.file1.text()).strip() is not '' else __file__,
        ' ',
        path.abspath(str(self.file2.text()))
                    if str(self.file2.text()).strip() is not '' else __file__
        ))

        print(diff_command)
        diff_output = getoutput(diff_command)
        try:
            print(' INFO: OK, Saving new Diff to disk...')
            output_file = file(path.abspath(str(self.fout.text())), 'w')
            output_file.write(diff_output)
            output_file.close()
        except:
            print(' ERROR: FAIL, Can not save Diff to disk!')
        if self.clip.isChecked() is True:
            print(' INFO: OK, Diff Copied to Clipboard...')
            QApplication.clipboard().setText(diff_output)
        if self.noti.isChecked() is True:
            call('notify-send [Ninja-IDE] ¡Diff_is_Ready!', shell=True)
        if self.odif.isChecked() is True:
            print(' INFO: OK, Opening Diff with Ninja-IDE')
            call('ninja-ide ' + path.abspath(str(self.fout.text())), shell=True)

        self.diff_path = path.abspath(str(self.fout.text()))
        return self.diff_path
Exemplo n.º 26
0
 def __init__(self):
     QLineEdit.__init__(self)
     completer = QCompleter(sorted(self.types))
     completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
     self.setCompleter(completer)
Exemplo n.º 27
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()
Exemplo n.º 28
0
class Main(plugin.Plugin):
    ' main class for plugin '
    def initialize(self, *args, **kwargs):
        ' class init '
        super(Main, self).initialize(*args, **kwargs)
        self.process = QProcess()
        self.process.readyReadStandardOutput.connect(self.readOutput)
        self.process.readyReadStandardError.connect(self.readErrors)
        self.process.finished.connect(self._process_finished)
        self.process.error.connect(self._process_finished)
        # directory auto completer
        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)
        # menu
        menu = QMenu('VirtualEnv')
        menu.addAction('Make VirtualEnv here', lambda: self.make_virtualenv())
        self.locator.get_service('explorer').add_project_menu(menu, lang='all')

        self.group1 = QGroupBox()
        self.group1.setTitle(' Paths ')
        self.outdir = QLineEdit(path.expanduser("~"))
        self.outdir.setPlaceholderText('Target Directory for Virtualenv files')
        self.outdir.setCompleter(self.completer)
        self.btn1 = QPushButton(QIcon.fromTheme("document-open"), ' Open ')
        self.btn1.clicked.connect(lambda: self.outdir.setText(str(
            QFileDialog.getExistingDirectory(self.dock,
            'Please, Open a Target Directory for the Python VirtualEnv...',
            path.expanduser("~")))))
        self.srcdir, self.prefx = QLineEdit(), QLineEdit()
        self.srcdir.setPlaceholderText(
                    'Extra search path to look for setuptools/distribute/pip')
        self.srcdir.setToolTip('''
        Specify Extra search path to look for setuptools/distribute/pip.
        Defaults to Empty, then the setting is ignored.Defaults are OK.''')
        self.srcdir.setCompleter(self.completer)
        self.btn2 = QPushButton(QIcon.fromTheme("document-open"), ' Open ')
        self.btn2.setToolTip(
            'Specify Extra search path to look for setuptools/distribute/pip')
        self.btn2.clicked.connect(lambda: self.srcdir.setText(str(
            QFileDialog.getExistingDirectory(self.dock,
            'Please, Open a Extra search path to look for setuptools/pip...',
            path.expanduser("~")))))
        self.prefx.setPlaceholderText('Prompt prefix for this environment')
        self.prefx.setToolTip('''
        Specify a custom alternative prompt prefix for this environment.
        Defaults to Empty,this is optional,short prefix are recommended.''')
        self.btn3 = QPushButton(QIcon.fromTheme("face-smile-big"), 'Suggestion')
        self.btn3.setToolTip('Suggest me a Random CLI prompt prefix !')
        self.btn3.clicked.connect(lambda: self.prefx.setText(choice((getuser(),
        'tesla', 'einstein', 'turing', 'ritchie', 'darwin', 'curie', 'planck',
        'lovelace', 'dijsktra', 'galileo', 'schroedinger', 'perlman', 'hopper',
        'newton', 'pasteur', 'maxwell', 'aristotle‎', 'volta', 'mendelev',
        'bohr', 'crick', 'watson', 'archimedes', 'nash', 'fermi', 'dirac',
        'feynman', 'kepler', 'copernicus', 'lorentz', 'faraday', 'heisenberg',
        ))))
        vboxg1 = QVBoxLayout(self.group1)
        for each_widget in (
            QLabel(' Target directory dath: '), self.outdir, self.btn1,
            QLabel(' Extra search path: '), self.srcdir, self.btn2,
            QLabel(' CLI Prompt prefix (Optional): '), self.prefx, self.btn3):
            vboxg1.addWidget(each_widget)

        self.group2 = QGroupBox()
        self.group2.setTitle(' Options ')
        self.group2.setCheckable(True)
        self.group2.setGraphicsEffect(QGraphicsBlurEffect(self))
        self.group2.graphicsEffect().setEnabled(False)
        self.group2.toggled.connect(self.toggle_options_group)
        self.qckb1, self.combo1 = QCheckBox(' Use Debug'), QDoubleSpinBox()
        self.qckb2 = QCheckBox(' Clear out the target directory')
        self.qckb3 = QCheckBox(' System-wide Python Packages')
        self.qckb4 = QCheckBox(' Unzip Setuptool or Distribute to virtualenv')
        self.qckb5 = QCheckBox(' Force the use of SetupTools')
        self.qckb6 = QCheckBox(' Never download packages')
        self.qckb7 = QCheckBox(' Delete .PYC files from virtualenv')
        self.qckb8 = QCheckBox(' Open target directory later')
        self.qckb9 = QCheckBox(' Save a LOG file to target later')
        self.qckb10 = QCheckBox(' No install PIP in the new virtualenv')
        self.qckb11 = QCheckBox('Save Bash script to reproduce virtenv later')
        self.chrt = QCheckBox('LOW CPU priority for Backend Process')
        self.combo1.setValue(2.7)
        self.combo1.setMaximum(3.4)
        self.combo1.setMinimum(2.4)
        self.combo1.setDecimals(1)
        self.combo1.setSingleStep(0.1)
        try:
            self.vinfo = QLabel('<small><b> Virtualenv Version: </b>' +
                            getoutput('virtualenv --version', shell=1).strip())
        except:
            self.vinfo = QLabel('Warning: Failed to query Virtualenv Backend!')
        [a.setChecked(True) for a in (self.qckb1, self.qckb4, self.qckb7,
                                self.chrt, self.qckb8, self.qckb9, self.qckb11)]
        vboxg2 = QVBoxLayout(self.group2)
        for each_widget in (self.qckb1, self.qckb2, self.qckb3, self.qckb4,
            self.qckb5, self.qckb6, self.qckb7, self.qckb8, self.qckb9,
            self.qckb10, self.qckb11, QLabel(' Python interpreter version: '),
            self.combo1, QLabel(' Backend CPU priority: '), self.chrt):
            vboxg2.addWidget(each_widget)

        self.button = QPushButton(' Make Virtualenv ')
        self.button.setCursor(QCursor(Qt.PointingHandCursor))
        self.button.setMinimumSize(75, 50)
        self.button.clicked.connect(self.run)
        glow = QGraphicsDropShadowEffect(self)
        glow.setOffset(0)
        glow.setBlurRadius(99)
        glow.setColor(QColor(99, 255, 255))
        self.button.setGraphicsEffect(glow)
        self.output = QTextEdit(''' " Let the future tell the truth,
        and evaluate each one according to his work and accomplishments.
        The present is theirs; the future, for which I really worked, is mine. "
        -Nikola Tesla. ''')

        class TransientWidget(QWidget):
            ' persistant widget thingy '
            def __init__(self, widget_list):
                ' init sub class '
                super(TransientWidget, self).__init__()
                vbox = QVBoxLayout(self)
                for each_widget in widget_list:
                    vbox.addWidget(each_widget)

        tw = TransientWidget((self.group1, self.group2, QLabel('Backend Logs'),
                              self.output, self.vinfo, self.button))
        self.scrollable, self.dock = QScrollArea(), QDockWidget()
        self.scrollable.setWidgetResizable(True)
        self.scrollable.setWidget(tw)
        self.dock.setWindowTitle(__doc__)
        self.dock.setStyleSheet('QDockWidget::title{text-align: center;}')
        self.dock.setWidget(self.scrollable)
        ExplorerContainer().addTab(self.dock, "Virtualenv")
        QPushButton(QIcon.fromTheme("help-about"), 'About', self.dock
            ).clicked.connect(lambda:
            QMessageBox.information(self.dock, __doc__, HELPMSG))

    def readOutput(self):
        """Read and append sphinx-build output to the logBrowser"""
        self.output.append(str(self.process.readAllStandardOutput()).strip())

    def readErrors(self):
        """Read and append sphinx-build errors to the logBrowser"""
        self.output.append(self.formatErrorMsg(str(
                                        self.process.readAllStandardError())))

    def formatErrorMsg(self, msg):
        """Format error messages in red color"""
        return self.formatMsg(msg, 'red')

    def formatInfoMsg(self, msg):
        """Format informative messages in blue color"""
        return self.formatMsg(msg, 'green')

    def formatMsg(self, msg, color):
        """Format message with the given color"""
        return '<font color="{}">{}</font>'.format(color, msg)

    def make_virtualenv(self):
        ' make virtualenv from contextual sub menu '
        self.outdir.setText(self.ex_locator.get_current_project_item().path)
        self.run()

    def run(self):
        ' run the actions '
        self.output.clear()
        self.output.append(self.formatInfoMsg(
                            'INFO: OK: Starting at {}'.format(datetime.now())))
        self.button.setDisabled(True)
        # Parse Values
        arg0 = '' if self.qckb10.isChecked() is False else '--no-pip '
        arg1 = '--quiet ' if self.qckb1.isChecked() is False else '--verbose '
        arg2 = '' if self.qckb2.isChecked() is False else '--clear '
        arg3 = '' if self.qckb3.isChecked() is False else '--system-site-packages '
        arg4 = '' if self.qckb4.isChecked() is False else '--unzip-setuptools '
        arg5 = '' if self.qckb5.isChecked() is False else '--setuptools '
        arg6 = '' if self.qckb6.isChecked() is False else '--never-download '
        # if the target is empty return
        if not len(str(self.outdir.text()).strip()):
            self.output.append(self.formatErrorMsg('ERROR: FAIL: Target empty'))
            self.button.setEnabled(True)
            return
        else:
            self.output.append(self.formatInfoMsg(
            'INFO: OK: Output Directory is {}'.format(self.outdir.text())))
        # prefix
        prf = str(self.prefx.text()).upper().strip().replace(' ', '')
        arg10 = '' if prf is '' else '--prompt="{}_" '.format(prf)
        self.output.append(self.formatInfoMsg('INFO: Prefix: {}'.format(arg10)))
        # extra search dir
        src = str(self.srcdir.text()).strip()
        arg11 = '' if src is '' else '--extra-search-dir="{}" '.format(src)
        self.output.append(self.formatInfoMsg(' INFO: Extra: {}'.format(arg11)))
        self.output.append(self.formatInfoMsg(
            ' INFO: OK: Write Logs ?: {} '.format(self.qckb9.isChecked())))
        self.output.append(self.formatInfoMsg(
            ' INFO: OK: Open Directory ?: {} '.format(self.qckb8.isChecked())))
        # run the subprocesses
        cmd = '{}virtualenv {}{}{}{}{}{}{}-p python{} {}{} {}'.format(
            'chrt --verbose -i 0 ' if self.chrt.isChecked() is True else '',
            arg0, arg1, arg2, arg3, arg4, arg5, arg6,
            self.combo1.value(), arg11, arg10, str(self.outdir.text()).strip())
        self.output.append(self.formatInfoMsg('INFO:OK:Command:{}'.format(cmd)))
        self.process.start(cmd)
        if not self.process.waitForStarted():
            self.output.append(self.formatErrorMsg(' ERROR: FAIL: Meh. '))
            self.output.append(self.formatErrorMsg(
                'ERROR: FAIL: Failed with Arguments: {} '.format(cmd)))
            self.button.setEnabled(True)
            return
         # write a .sh bash script file on target
        if self.qckb11.isChecked() is True:
            sh_file = 'create_virtualenv.sh'
            with open(path.join(str(self.outdir.text()), sh_file), 'w') as _sh:
                self.output.append(self.formatInfoMsg('''INFO: OK: Writing Bash:
                    {}'''.format(path.join(str(self.outdir.text()), sh_file))))
                _sh.write('#!/usr/bin/env bash' + linesep + cmd)
                _sh.close()
            self.output.append(self.formatInfoMsg('INFO: OK: Bash chmod: 775'))
            try:
                chmod(path.join(str(self.outdir.text()), sh_file), 0775)  # Py2
            except:
                chmod(path.join(str(self.outdir.text()), sh_file), 0o775)  # Py3
        self.readOutput()
        self.readErrors()
        self.button.setEnabled(True)

    def _process_finished(self):
        """ finished sucessfully """
        self.output.append(self.formatInfoMsg(
                            'INFO: OK: Finished at {}'.format(datetime.now())))
        # remove all *.PYC bytecode
        if self.qckb7.isChecked() is True:
            self.output.append(self.formatInfoMsg(' INFO: OK: Removing *.PYC '))
            self.output.append(self.formatInfoMsg(' INFO: This takes a moment'))
            [remove(path.join(root, f)) for root, f in list(itertools.chain(*
            [list(itertools.product([root], files))
            for root, dirs, files in walk(str(self.outdir.text()).strip())]))
            if f.endswith(('.pyc', '.PYC')) and not f.startswith('.')]
        # write a .log file on target
        if self.qckb9.isChecked() is True:
            log_file = 'virtualenv_gui.log'
            with open(path.join(str(self.outdir.text()), log_file), 'w') as log:
                self.output.append(self.formatInfoMsg('''INFO: OK: Writing Logs:
                    {}'''.format(path.join(str(self.outdir.text()), log_file))))
                log.write(self.output.toPlainText())
                log.close()
        # open target dir
        if self.qckb8.isChecked() is True:
            try:
                startfile(str(self.outdir.text()))
            except:
                Popen(["xdg-open", str(self.outdir.text())])
        self.output.selectAll()
        self.output.setFocus()

    def toggle_options_group(self):
        ' toggle on off the options group '
        if self.group2.isChecked() is True:
            [a.setChecked(True) for a in (self.qckb1, self.qckb4, self.qckb7,
                                self.chrt, self.qckb8, self.qckb9, self.qckb11)]
            self.combo1.setValue(2.7)
            self.group2.graphicsEffect().setEnabled(False)
        else:
            [a.setChecked(False) for a in (self.qckb1, self.qckb4, self.qckb7,
                                self.chrt, self.qckb8, self.qckb9, self.qckb11)]
            self.group2.graphicsEffect().setEnabled(True)

    def finish(self):
        ' clear when finish '
        self.process.kill()
Exemplo n.º 29
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()
Exemplo n.º 30
0
    def data(self, index, role):
        if role == Qt.ForegroundRole:
            return self.colors[index.row()]
        return super(MyListModel, self).data(index, role);


def make_model():
    model = MyListModel()
    #model = QStringListModel()
    model.setStringList(["paddington", "bakerloo"])
    model.colors[0] = QBrush(Qt.red)
    model.colors[1] = QBrush(Qt.blue)
    return model

if __name__ == "__main__":

    app = QApplication(sys.argv)
    edit = QLineEdit()
    completer = QCompleter()
    completer.setCompletionMode(QCompleter.PopupCompletion)
    #completer.setCompletionMode(QCompleter.InlineCompletion)
    #completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
    edit.setCompleter(completer)

    model = make_model()
    completer.setModel(model)

    edit.show()
    sys.exit(app.exec_())
Exemplo n.º 31
0
class ParentAction(object):
    def __init__(self, iface, settings, controller, plugin_dir):
        ''' Class constructor '''

        # Initialize instance attributes
        self.tree_manage_version = "1.0"
        self.iface = iface
        self.canvas = self.iface.mapCanvas()
        self.settings = settings
        self.controller = controller
        self.plugin_dir = plugin_dir
        self.dao = self.controller.dao
        self.schema_name = self.controller.schema_name
        self.project_type = None
        self.file_gsw = None
        self.gsw_settings = None
        self.lazy_widget = None

    def set_controller(self, controller):
        """ Set controller class """

        self.controller = controller
        self.schema_name = self.controller.schema_name

    def get_plugin_version(self):
        """ Get plugin version from metadata.txt file """

        # Check if metadata file exists
        metadata_file = os.path.join(self.plugin_dir, 'metadata.txt')
        if not os.path.exists(metadata_file):
            message = "Metadata file not found" + metadata_file
            self.controller.show_warning(message, parameter=metadata_file)
            return None

        metadata = ConfigParser.ConfigParser()
        metadata.read(metadata_file)
        plugin_version = metadata.get('general', 'version')
        if plugin_version is None:
            message = "Plugin version not found"
            self.controller.show_warning(message)

        return plugin_version

    def load_settings(self, dialog=None):
        """ Load QGIS settings related with dialog position and size """
        screens = ctypes.windll.user32
        screen_x = screens.GetSystemMetrics(78)
        screen_y = screens.GetSystemMetrics(79)
        if dialog is None:
            dialog = self.dlg

        try:
            x = self.controller.plugin_settings_value(dialog.objectName() +
                                                      "_x")
            y = self.controller.plugin_settings_value(dialog.objectName() +
                                                      "_y")
            width = self.controller.plugin_settings_value(
                dialog.objectName() + "_width", dialog.property('width'))
            height = self.controller.plugin_settings_value(
                dialog.objectName() + "_height", dialog.property('height'))

            if int(x) < 0 or int(y) < 0:
                dialog.resize(int(width), int(height))
            else:
                if int(x) > screen_x:
                    x = int(screen_x) - int(width)
                if int(y) > screen_y:
                    y = int(screen_y)
                dialog.setGeometry(int(x), int(y), int(width), int(height))
        except:
            pass

    def save_settings(self, dialog=None):
        """ Save QGIS settings related with dialog position and size """

        if dialog is None:
            dialog = self.dlg

        self.controller.plugin_settings_set_value(
            dialog.objectName() + "_width", dialog.width())
        self.controller.plugin_settings_set_value(
            dialog.objectName() + "_height", dialog.height())
        self.controller.plugin_settings_set_value(dialog.objectName() + "_x",
                                                  dialog.pos().x() + 8)
        self.controller.plugin_settings_set_value(dialog.objectName() + "_y",
                                                  dialog.pos().y() + 31)

    def open_dialog(self,
                    dlg=None,
                    dlg_name=None,
                    maximize_button=True,
                    stay_on_top=True):
        """ Open dialog """

        if dlg is None or type(dlg) is bool:
            dlg = self.dlg

        # Manage i18n of the dialog
        if dlg_name:
            self.controller.manage_translation(dlg_name, dlg)

        # Manage stay on top and maximize button
        if maximize_button and stay_on_top:
            dlg.setWindowFlags(Qt.WindowMinimizeButtonHint
                               | Qt.WindowMaximizeButtonHint
                               | Qt.WindowStaysOnTopHint)
        elif not maximize_button and stay_on_top:
            dlg.setWindowFlags(Qt.WindowMinimizeButtonHint
                               | Qt.WindowStaysOnTopHint)
        elif maximize_button and not stay_on_top:
            dlg.setWindowFlags(Qt.WindowMaximizeButtonHint)

        # Open dialog
        dlg.open()

    def close_dialog(self, dlg=None):
        """ Close dialog """

        try:
            self.save_settings(dlg)
            dlg.close()
            map_tool = self.canvas.mapTool()
            # If selected map tool is from the plugin, set 'Pan' as current one
            if map_tool.toolName() == '':
                self.iface.actionPan().trigger()
        except AttributeError:
            pass

    def hide_colums(self, widget, comuns_to_hide):
        for i in range(0, len(comuns_to_hide)):
            widget.hideColumn(comuns_to_hide[i])

    def set_icon(self, widget, icon):
        """ Set @icon to selected @widget """

        # Get icons folder
        icons_folder = os.path.join(self.plugin_dir, 'icons')
        icon_path = os.path.join(icons_folder, str(icon) + ".png")
        if os.path.exists(icon_path):
            widget.setIcon(QIcon(icon_path))
        else:
            self.controller.log_info("File not found", parameter=icon_path)

    def check_expression(self, expr_filter, log_info=False):
        """ Check if expression filter @expr_filter is valid """

        if log_info:
            self.controller.log_info(expr_filter)
        expr = QgsExpression(expr_filter)
        if expr.hasParserError():
            message = "Expression Error"
            self.controller.log_warning(message, parameter=expr_filter)
            return False, expr

        return True, expr

    def set_table_columns(self, dialog, widget, table_name, project_type=None):
        """ Configuration of tables. Set visibility and width of columns """

        widget = widget_manager.getWidget(dialog, widget)
        if not widget:
            return

        # Set width and alias of visible columns
        columns_to_delete = []
        sql = ("SELECT column_index, width, alias, status"
               " FROM " + self.schema_name + ".config_client_forms"
               " WHERE table_id = '" + table_name + "'")
        if project_type is not None:
            sql += (" AND project_type = '" + project_type + "' ")
        sql += (" ORDER BY column_index")

        rows = self.controller.get_rows(sql, log_info=False)
        if not rows:
            return

        for row in rows:
            if not row['status']:
                columns_to_delete.append(row['column_index'] - 1)
            else:
                width = row['width']
                if width is not None:
                    widget.setColumnWidth(row['column_index'] - 1, width)
                widget.model().setHeaderData(row['column_index'] - 1,
                                             Qt.Horizontal, row['alias'])

        widget.model().select()

        # Delete columns
        for column in columns_to_delete:
            widget.hideColumn(column)

    def set_completer_object(self, tablename, widget, field_search):
        """ Set autocomplete of widget @table_object + "_id"
            getting id's from selected @table_object
        """

        if not widget:
            return

        # Set SQL
        sql = ("SELECT DISTINCT(" + field_search + ")"
               " FROM " + self.schema_name + "." + tablename + ""
               " ORDER BY " + field_search + "")
        row = self.controller.get_rows(sql)

        for i in range(0, len(row)):
            aux = row[i]
            row[i] = aux[0]

        # Set completer and model: add autocomplete in the widget
        self.completer = QCompleter()
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setCompletionMode(0)
        widget.setCompleter(self.completer)
        model = QStringListModel()
        model.setStringList(row)
        self.completer.setModel(model)

    def refresh_map_canvas(self, restore_cursor=False):
        """ Refresh all layers present in map canvas """

        self.canvas.refreshAllLayers()
        for layer_refresh in self.canvas.layers():
            layer_refresh.triggerRepaint()

        if restore_cursor:
            self.set_cursor_restore()

    def set_cursor_restore(self):
        """ Restore to previous cursors """
        QApplication.restoreOverrideCursor()

    def get_cursor_multiple_selection(self):
        """ Set cursor for multiple selection """

        path_folder = os.path.join(os.path.dirname(__file__), os.pardir)
        path_cursor = os.path.join(path_folder, 'icons', '201.png')
        if os.path.exists(path_cursor):
            cursor = QCursor(QPixmap(path_cursor))
        else:
            cursor = QCursor(Qt.ArrowCursor)

        return cursor

    def fill_table(self,
                   qtable,
                   table_name,
                   set_edit_triggers=QTableView.NoEditTriggers,
                   expr_filter=None):
        """ Fill table @widget filtering query by @workcat_id
         Set a model with selected filter.
         Attach that model to selected table
         @setEditStrategy:
             0: OnFieldChange
             1: OnRowChange
             2: OnManualSubmit
         """
        expr = None
        if expr_filter:
            # Check expression
            (is_valid,
             expr) = self.check_expression(expr_filter)  # @UnusedVariable
            if not is_valid:
                return expr

        # Set a model with selected filter expression
        if self.schema_name not in table_name:
            table_name = self.schema_name + "." + table_name

        # Set model
        model = QSqlTableModel()
        model.setTable(table_name)
        model.setEditStrategy(QSqlTableModel.OnManualSubmit)
        model.setSort(0, 0)
        model.select()

        # When change some field we need to refresh Qtableview and filter by psector_id
        qtable.setEditTriggers(set_edit_triggers)

        # Check for errors
        if model.lastError().isValid():
            self.controller.show_warning(model.lastError().text())
        # Attach model to table view
        if expr:
            qtable.setModel(model)
            qtable.model().setFilter(expr_filter)
        else:
            qtable.setModel(model)

        return expr

    def get_feature_by_id(self, layer, id, field_id):
        iter = layer.getFeatures()
        for feature in iter:
            if feature[field_id] == id:
                return feature
        return False
Exemplo n.º 32
0
class Main(plugin.Plugin):
    " Main Class "

    def initialize(self, *args, **kwargs):
        " Init Main Class "
        ec = ExplorerContainer()
        super(Main, self).initialize(*args, **kwargs)
        # directory auto completer
        self.completer, self.dirs = QCompleter(self), QDirModel(self)
        self.dirs.setFilter(QDir.AllEntries | QDir.NoDotAndDotDot)
        self.completer.setModel(self.dirs)
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setCompletionMode(QCompleter.PopupCompletion)
        self.RUNS, self.FAILS = 0, 0
        self.group0 = QGroupBox()
        self.group0.setTitle(' Source and Target ')
        self.baseurl = QLineEdit('http://google.com')
        self.outfile = QLineEdit(path.join(path.expanduser("~"), 'test.py'))
        self.outfile.setCompleter(self.completer)
        self.open = QPushButton(QIcon.fromTheme("folder-open"), 'Open')
        self.open.clicked.connect(lambda: self.outfile.setText(
            QFileDialog.getSaveFileName(self.dock, "Save", path.expanduser(
                "~"), 'PYTHON(*.py)')))
        vboxg0 = QVBoxLayout(self.group0)
        for each_widget in (QLabel('<b>Base URL'), self.baseurl,
                            QLabel('<b>Local File Target'), self.outfile,
                            self.open):
            vboxg0.addWidget(each_widget)

        self.group1 = QGroupBox()
        self.group1.setTitle(' Selenium ')
        self.group1.setCheckable(True)
        self.group1.setGraphicsEffect(QGraphicsBlurEffect(self))
        self.group1.graphicsEffect().setEnabled(False)
        self.group1.toggled.connect(self.toggle_group)
        self.ckcss1 = QCheckBox('Test for correct Page Loading behaviour')
        self.ckcss2 = QCheckBox('Test for Sucessfull Status Code return')
        self.ckcss3 = QCheckBox('Test for valid Title of the web page')
        self.ckcss4 = QCheckBox('Test for Cookies Basic functionality')
        self.ckcss5 = QCheckBox('Test for Back, Forward, Reload behaviour')
        self.ckcss6 = QCheckBox('Take a Screenshot of page (CSS Debug)')
        self.ckcss7 = QCheckBox('Test for Search Form Field of the page')
        self.ckcss8 = QCheckBox(
            'Test for Arbitrary Javascript (User provided)')
        self.ckcss9 = QCheckBox('Test for iFrame of the web page')
        self.ckcss10 = QCheckBox('Test for HTML5 Canvas element on the page')
        self.ckcss11 = QCheckBox('Test for HTML5 SVG element on the page')
        self.ckcss12 = QCheckBox('Test for HTML5 Audio element on the page')
        self.ckcss13 = QCheckBox('Test for HTML5 Video element on the page')
        self.ckcss14 = QCheckBox('Test for File Upload form on the page')
        self.ckcss15 = QCheckBox('Add ChromeDriver path to sys.path')
        self.webdriver = QComboBox()
        self.webdriver.addItems(
            ['firefox', 'chrome', 'zope.testbrowser', 'phantomjs'])
        self.titletxt = QLineEdit('Google')
        self.javascript = QLineEdit('console.log("test")')
        self.authdata, self.formdata = QLineEdit(), QLineEdit()
        self.authdata.setPlaceholderText(
            "{'username':'******','password':'******'}")
        self.formdata.setPlaceholderText("{'name': 'Joe', 'age': '25'}")
        self.iframurl = QLineEdit()
        self.chrmedrv = QLineEdit('/usr/bin/chromedriver')
        self.timeout = QSpinBox()
        self.timeout.setMaximum(99)
        self.timeout.setMinimum(0)
        self.timeout.setValue(9)
        vboxg1 = QVBoxLayout(self.group1)
        for each_widget in (
                self.ckcss1, self.ckcss2, self.ckcss3, self.ckcss4,
                self.ckcss5, self.ckcss6, self.ckcss7, self.ckcss8,
                self.ckcss9, self.ckcss10, self.ckcss11,
                self.ckcss12, self.ckcss13, self.ckcss14, self.ckcss15,
                QLabel('<b>WebDriver'), self.webdriver,
                QLabel('''<center><small><i>Firefox is only Driver that dont
                   require additional configuration'''),
                QLabel('<b>Title Content must contain'), self.titletxt,
                QLabel('<b>Minified Javascript for Test'), self.javascript,
                QLabel('<b>Arbitrary Authentication Data for Test'),
                self.authdata, QLabel('<b>Arbitrary Form Data for Test'),
                self.formdata, QLabel('<b>iFrame URL for Test'), self.iframurl,
                QLabel('<b>Chrome Driver'), self.chrmedrv,
                QLabel('<b>Timeout Timer Limit'), self.timeout):
            vboxg1.addWidget(each_widget)
            try:
                each_widget.setToolTip(each_widget.text())
            except:
                each_widget.setToolTip(each_widget.currentText())

        self.group4 = QGroupBox()
        self.group4.setTitle(' General ')
        self.chckbx1 = QCheckBox('Run the Tests after Writing')
        self.chckbx2 = QCheckBox('Open the Tests with Ninja after Writing')
        self.chckbx3 = QCheckBox('Add SheBang, Encoding and Metadata to Tests')
        self.nice = QSpinBox()
        self.nice.setMaximum(20)
        self.nice.setMinimum(0)
        self.nice.setValue(20)
        self.help1 = QLabel(
            '''<a href="http://splinter.cobrateam.info/docs/api"
            ><center><b>API Reference</a>''')
        self.help1.setTextInteractionFlags(Qt.LinksAccessibleByMouse)
        self.help1.setOpenExternalLinks(True)
        vboxg4 = QVBoxLayout(self.group4)
        for each_widget in (self.chckbx1, self.chckbx2, self.chckbx3,
                            QLabel('Backend CPU priority:'), self.nice,
                            self.help1):
            vboxg4.addWidget(each_widget)
            each_widget.setToolTip(each_widget.text())

        [
            a.setChecked(True)
            for a in (self.ckcss1, self.ckcss2, self.ckcss3, self.ckcss4,
                      self.ckcss5, self.ckcss6, self.ckcss7, self.ckcss8,
                      self.ckcss15, self.chckbx1, self.chckbx2, self.chckbx3)
        ]

        self.button = QPushButton(QIcon.fromTheme("face-cool"),
                                  'Write and Run Test')
        self.button.setCursor(QCursor(Qt.PointingHandCursor))
        self.button.setMinimumSize(100, 50)
        self.button.clicked.connect(self.run)
        glow = QGraphicsDropShadowEffect(self)
        glow.setOffset(0)
        glow.setBlurRadius(99)
        glow.setColor(QColor(99, 255, 255))
        self.button.setGraphicsEffect(glow)
        glow.setEnabled(True)
        self.output = QPlainTextEdit()
        self.runs = QLabel('<font color="green"><b>Runs: 0')
        self.failures = QLabel('<font color="red"><b>Failures: 0')

        class TransientWidget(QWidget):
            ' persistant widget thingy '

            def __init__(self, widget_list):
                ' init sub class '
                super(TransientWidget, self).__init__()
                vbox = QVBoxLayout(self)
                for each_widget in widget_list:
                    vbox.addWidget(each_widget)

        tw = TransientWidget(
            (QLabel('<b>Selenium Tests'), self.group0, self.group1,
             self.group4, QLabel('<b>Log'), self.output, self.runs,
             self.failures, self.button))
        self.scrollable, self.dock = QScrollArea(), QDockWidget()
        self.scrollable.setWidgetResizable(True)
        self.scrollable.setWidget(tw)
        self.dock.setWindowTitle(__doc__)
        self.dock.setStyleSheet('QDockWidget::title{text-align: center;}')
        self.dock.setWidget(self.scrollable)
        ec.addTab(self.dock, "Selenium")
        QPushButton(
            QIcon.fromTheme("help-about"), 'About', self.dock).clicked.connect(
                lambda: QMessageBox.information(self.dock, __doc__, HELPMSG))
        QPushButton(
            QIcon.fromTheme("media-record"),
            'Record',
            self.group1,
        ).clicked.connect(lambda: QMessageBox.information(
            self.dock, __doc__,
            'Not working. If you know how to make it Record, send me Pull Request'
        ))

    def run(self):
        ' run '
        self.RUNS = self.RUNS + 1
        self.runs.setText('<font color="green"><b>Runs: {}'.format(self.RUNS))
        self.output.clear()
        self.output.append(self.formatInfoMsg('INFO:{}'.format(
            datetime.now())))
        self.button.setDisabled(True)
        self.output.append(self.formatInfoMsg(' INFO: OK: Parsing Data '))
        selenium_test = SELENIUM_TEMPLATE.format(
            HEADER if self.chckbx3.isChecked() is True else '',
            self.chrmedrv.text() if self.ckcss15.isChecked() is True else '',
            self.baseurl.text(),
            self.authdata.text()
            if str(self.authdata.text()) is not '' else {},
            self.formdata.text() if str(
                self.formdata.text()) is not '' else {}, self.iframurl.text(),
            self.javascript.text(), self.titletxt.text(),
            self.webdriver.currentText(),
            '# ' if self.ckcss1.isChecked() is not True else '',
            '# ' if self.ckcss2.isChecked() is not True else '',
            '# ' if self.ckcss2.isChecked() is not True else '',
            '# ' if self.ckcss3.isChecked() is not True else '',
            '# ' if self.ckcss4.isChecked() is not True else '',
            '# ' if self.ckcss5.isChecked() is not True else '',
            '# ' if self.ckcss6.isChecked() is not True else '',
            '# ' if self.ckcss7.isChecked() is not True else '',
            '# ' if self.ckcss8.isChecked() is not True else '',
            '# ' if self.ckcss9.isChecked() is not True else '',
            '# ' if self.ckcss10.isChecked() is not True else '',
            '# ' if self.ckcss11.isChecked() is not True else '',
            '# ' if self.ckcss12.isChecked() is not True else '',
            '# ' if self.ckcss13.isChecked() is not True else '',
            '# ' if self.ckcss14.isChecked() is not True else '',
            self.timeout.value())
        with open(path.abspath(self.outfile.text()), 'w') as f:
            self.output.append(self.formatInfoMsg(' INFO: OK: Writing Tests '))
            f.write(selenium_test)
        if self.chckbx2.isChecked() is True:
            self.output.append(self.formatInfoMsg(' INFO: OK: Opening Tests '))
            try:
                startfile(str(path.abspath(self.outfile.text())))
            except:
                Popen(["ninja-ide", str(path.abspath(self.outfile.text()))])
        if self.chckbx1.isChecked() is True:
            try:
                self.output.append(
                    self.formatInfoMsg('INFO: OK: Runing Tests'))
                Popen(["python", str(path.abspath(self.outfile.text()))])
            except:
                self.output.append(
                    self.formatErrorMsg('INFO:FAIL: Tests Fail'))
                self.FAILS = self.FAILS + 1
                self.failures.setText(
                    '<font color="red"><b>Failures: {}'.format(self.FAILS))
        self.output.append(self.formatInfoMsg('INFO:{}'.format(
            datetime.now())))
        self.button.setDisabled(False)
        self.output.setFocus()
        self.output.selectAll()

    def toggle_group(self):
        ' toggle on or off the css checkboxes '
        if self.group1.isChecked() is True:
            [
                a.setChecked(True)
                for a in (self.ckcss1, self.ckcss2, self.ckcss3, self.ckcss4,
                          self.ckcss5, self.ckcss6, self.ckcss7, self.ckcss8,
                          self.ckcss15)
            ]
            self.group1.graphicsEffect().setEnabled(False)
        else:
            [
                a.setChecked(False)
                for a in (self.ckcss1, self.ckcss2, self.ckcss3, self.ckcss4,
                          self.ckcss5, self.ckcss6, self.ckcss7, self.ckcss8,
                          self.ckcss15)
            ]
            self.group1.graphicsEffect().setEnabled(True)

    def formatErrorMsg(self, msg):
        """Format error messages in red color"""
        return self.formatMsg(msg, 'red')

    def formatInfoMsg(self, msg):
        """Format informative messages in blue color"""
        return self.formatMsg(msg, 'green')

    def formatMsg(self, msg, color):
        """Format message with the given color"""
        return '<font color="{}">{}</font>'.format(color, msg)
Exemplo n.º 33
0
 def __init__(self):
     QLineEdit.__init__(self)
     completer = QCompleter(sorted(self.types))
     completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
     self.setCompleter(completer)
class MyMainWindow(QMainWindow):
    " Main Window "

    def __init__(self, parent=None):
        " Initialize QWidget inside MyMainWindow "
        super(MyMainWindow, self).__init__(parent)
        QWidget.__init__(self)
        self.statusBar().showMessage("               {}".format(__doc__))
        self.setStyleSheet("QStatusBar{color:grey;}")
        self.setWindowTitle(__doc__)
        self.setWindowIcon(QIcon.fromTheme("face-monkey"))
        self.setFont(QFont("Ubuntu Light", 10))
        self.setMaximumSize(QDesktopWidget().screenGeometry().width(), QDesktopWidget().screenGeometry().height())

        # directory auto completer
        self.completer = QCompleter(self)
        self.dirs = QDirModel(self)
        self.dirs.setFilter(QDir.AllEntries | QDir.NoDotAndDotDot)
        self.completer.setModel(self.dirs)
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setCompletionMode(QCompleter.PopupCompletion)

        # Proxy support, by reading http_proxy os env variable
        proxy_url = QUrl(environ.get("http_proxy", ""))
        QNetworkProxy.setApplicationProxy(
            QNetworkProxy(
                QNetworkProxy.HttpProxy if str(proxy_url.scheme()).startswith("http") else QNetworkProxy.Socks5Proxy,
                proxy_url.host(),
                proxy_url.port(),
                proxy_url.userName(),
                proxy_url.password(),
            )
        ) if "http_proxy" in environ else None
        print((" INFO: Proxy Auto-Config as " + str(proxy_url)))

        # basic widgets layouts and set up
        self.mainwidget = QTabWidget()
        self.mainwidget.setToolTip(__doc__)
        self.mainwidget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.mainwidget.tabCloseRequested.connect(lambda: self.mainwidget.setTabPosition(randint(0, 3)))
        # if self.mainwidget.tabPosition() == 0
        # else self.mainwidget.setTabPosition(0))
        self.mainwidget.setStyleSheet("QTabBar{color:white;font-weight:bold;}")
        self.mainwidget.setTabBar(TabBar(self))
        self.mainwidget.setMovable(True)
        self.mainwidget.setTabsClosable(True)
        self.mainwidget.setTabShape(QTabWidget.Triangular)
        self.setCentralWidget(self.mainwidget)
        self.dock1 = QDockWidget()
        self.dock2 = QDockWidget()
        self.dock3 = QDockWidget()
        for a in (self.dock1, self.dock2, self.dock3):
            a.setWindowModality(Qt.NonModal)
            a.setWindowOpacity(0.9)
            a.setWindowTitle(__doc__ if a.windowTitle() == "" else a.windowTitle())
            a.setStyleSheet(" QDockWidget::title{text-align:center;}")
            self.mainwidget.addTab(a, QIcon.fromTheme("face-smile"), "Double Click Me")

        # Paleta de colores para pintar transparente
        self.palette().setBrush(QPalette.Base, Qt.transparent)
        self.setPalette(self.palette())
        self.setAttribute(Qt.WA_OpaquePaintEvent, False)

        # toolbar and basic actions
        self.toolbar = QToolBar(self)
        self.toolbar.setIconSize(QSize(24, 24))
        # spacer widget for left
        self.left_spacer = QWidget(self)
        self.left_spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        # spacer widget for right
        self.right_spacer = QWidget(self)
        self.right_spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        qaqq = QAction(QIcon.fromTheme("application-exit"), "Quit", self)
        qaqq.setShortcut("Ctrl+Q")
        qaqq.triggered.connect(exit)
        qamin = QAction(QIcon.fromTheme("go-down"), "Minimize", self)
        qamin.triggered.connect(lambda: self.showMinimized())
        qamax = QAction(QIcon.fromTheme("go-up"), "Maximize", self)
        qanor = QAction(QIcon.fromTheme("view-fullscreen"), "AutoCenter AutoResize", self)
        qanor.triggered.connect(self.center)
        qatim = QAction(QIcon.fromTheme("mail-signed-verified"), "View Date and Time", self)
        qatim.triggered.connect(self.timedate)
        qabug = QAction(QIcon.fromTheme("help-about"), "Report a Problem", self)
        qabug.triggered.connect(
            lambda: qabug.setDisabled(True)
            if not call("xdg-open mailto:" + "*****@*****.**".decode("rot13"), shell=True)
            else " ERROR "
        )
        qamax.triggered.connect(lambda: self.showMaximized())
        qaqt = QAction(QIcon.fromTheme("help-about"), "About Qt", self)
        qaqt.triggered.connect(lambda: QMessageBox.aboutQt(self))
        qakde = QAction(QIcon.fromTheme("help-about"), "About KDE", self)
        if KDE:
            qakde.triggered.connect(KHelpMenu(self, "", False).aboutKDE)
        qaslf = QAction(QIcon.fromTheme("help-about"), "About Self", self)
        if KDE:
            qaslf.triggered.connect(KAboutApplicationDialog(aboutData, self).exec_)
        else:
            qaslf.triggered.connect(
                lambda: QMessageBox.about(
                    self.mainwidget,
                    __doc__,
                    "".join(
                        (
                            __doc__,
                            linesep,
                            "version ",
                            __version__,
                            ", (",
                            __license__,
                            "), by ",
                            __author__,
                            ", ( ",
                            __email__,
                            " )",
                            linesep,
                        )
                    ),
                )
            )
        qafnt = QAction(QIcon.fromTheme("tools-check-spelling"), "Set GUI Font", self)
        if KDE:
            font = QFont()
            qafnt.triggered.connect(
                lambda: self.setStyleSheet(
                    "".join(("*{font-family:", str(font.toString()), "}"))
                    if KFontDialog.getFont(font)[0] == QDialog.Accepted
                    else ""
                )
            )
        else:
            qafnt.triggered.connect(
                lambda: self.setStyleSheet("".join(("*{font-family:", str(QFontDialog.getFont()[0].toString()), "}")))
            )
        qasrc = QAction(QIcon.fromTheme("applications-development"), "View Source Code", self)
        qasrc.triggered.connect(lambda: call("xdg-open {}".format(__file__), 1))
        qakb = QAction(QIcon.fromTheme("input-keyboard"), "Keyboard Shortcuts", self)
        qakb.triggered.connect(
            lambda: QMessageBox.information(self.mainwidget, "Keyboard Shortcuts", " Ctrl+Q = Quit ")
        )
        qapic = QAction(QIcon.fromTheme("camera-photo"), "Take a Screenshot", self)
        qapic.triggered.connect(
            lambda: QPixmap.grabWindow(QApplication.desktop().winId()).save(
                QFileDialog.getSaveFileName(
                    self.mainwidget, " Save Screenshot As ...", path.expanduser("~"), ";;(*.png) PNG", "png"
                )
            )
        )
        qatb = QAction(QIcon.fromTheme("go-top"), "Toggle ToolBar", self)
        qatb.triggered.connect(lambda: self.toolbar.hide() if self.toolbar.isVisible() is True else self.toolbar.show())
        qati = QAction(QIcon.fromTheme("help-browser"), "Switch ToolBar Icon Size", self)
        qati.triggered.connect(
            lambda: self.toolbar.setIconSize(self.toolbar.iconSize() * 4)
            if self.toolbar.iconSize().width() * 4 == 24
            else self.toolbar.setIconSize(self.toolbar.iconSize() / 4)
        )
        qasb = QAction(QIcon.fromTheme("zoom-in"), "Toggle Tabs Bar", self)
        qasb.triggered.connect(
            lambda: self.mainwidget.tabBar().hide()
            if self.mainwidget.tabBar().isVisible() is True
            else self.mainwidget.tabBar().show()
        )
        qadoc = QAction(QIcon.fromTheme("help-browser"), "On-line Docs", self)
        qadoc.triggered.connect(lambda: open_new_tab(__url__))
        qapy = QAction(QIcon.fromTheme("help-about"), "About Python", self)
        qapy.triggered.connect(lambda: open_new_tab("http://python.org/about"))
        qali = QAction(QIcon.fromTheme("help-browser"), "Read Licence", self)
        qali.triggered.connect(lambda: open_new_tab(__full_licence__))
        qacol = QAction(QIcon.fromTheme("preferences-system"), "Set GUI Colors", self)
        if KDE:
            color = QColor()
            qacol.triggered.connect(
                lambda: self.setStyleSheet("".join(("* { background-color: ", str(color.name()), "}")))
                if KColorDialog.getColor(color, self)
                else ""
            )
        else:
            qacol.triggered.connect(
                lambda: self.setStyleSheet(
                    "".join((" * { background-color: ", str(QColorDialog.getColor().name()), " } "))
                )
            )
        qatit = QAction(QIcon.fromTheme("preferences-system"), "Set the App Window Title", self)
        qatit.triggered.connect(self.seTitle)
        self.toolbar.addWidget(self.left_spacer)
        self.toolbar.addSeparator()
        for b in (
            qaqq,
            qamin,
            qanor,
            qamax,
            qasrc,
            qakb,
            qacol,
            qatim,
            qatb,
            qafnt,
            qati,
            qasb,
            qatit,
            qapic,
            qadoc,
            qali,
            qaslf,
            qaqt,
            qakde,
            qapy,
            qabug,
        ):
            self.toolbar.addAction(b)
        self.addToolBar(Qt.TopToolBarArea, self.toolbar)
        self.toolbar.addSeparator()
        self.toolbar.addWidget(self.right_spacer)
        # define the menu
        menu = self.menuBar()
        # File menu items
        menu.addMenu("&File").addActions((qaqq,))
        menu.addMenu("&Window").addActions((qamax, qanor, qamin))
        # Settings menu
        menu.addMenu("&Settings").addActions((qasrc, qacol, qafnt, qatim, qatb, qati, qasb, qapic))
        # Help menu items
        menu.addMenu("&Help").addActions((qadoc, qakb, qabug, qali, qaqt, qakde, qapy, qaslf))
        # Tray Icon
        tray = QSystemTrayIcon(QIcon.fromTheme("face-devilish"), self)
        tray.setToolTip(__doc__)
        traymenu = QMenu()
        traymenu.addActions((qamax, qanor, qamin, qaqq))
        tray.setContextMenu(traymenu)
        tray.show()

        def contextMenuRequested(point):
            " quick and dirty custom context menu "
            menu = QMenu()
            menu.addActions(
                (
                    qaqq,
                    qamin,
                    qanor,
                    qamax,
                    qasrc,
                    qakb,
                    qacol,
                    qafnt,
                    qati,
                    qasb,
                    qatb,
                    qatim,
                    qatit,
                    qapic,
                    qadoc,
                    qali,
                    qaslf,
                    qaqt,
                    qakde,
                    qapy,
                    qabug,
                )
            )
            menu.exec_(self.mapToGlobal(point))

        self.mainwidget.customContextMenuRequested.connect(contextMenuRequested)

        def must_be_checked(widget_list):
            " widget tuple passed as argument should be checked as ON "
            for each_widget in widget_list:
                try:
                    each_widget.setChecked(True)
                except:
                    pass

        def must_have_tooltip(widget_list):
            " widget tuple passed as argument should have tooltips "
            for each_widget in widget_list:
                try:
                    each_widget.setToolTip(each_widget.text())
                except:
                    each_widget.setToolTip(each_widget.currentText())
                finally:
                    each_widget.setCursor(QCursor(Qt.PointingHandCursor))

        def must_autofillbackground(widget_list):
            " widget tuple passed as argument should have filled background "
            for each_widget in widget_list:
                try:
                    each_widget.setAutoFillBackground(True)
                except:
                    pass

        def must_glow(widget_list):
            " apply an glow effect to the widget "
            for glow, each_widget in enumerate(widget_list):
                try:
                    if each_widget.graphicsEffect() is None:
                        glow = QGraphicsDropShadowEffect(self)
                        glow.setOffset(0)
                        glow.setBlurRadius(99)
                        glow.setColor(QColor(99, 255, 255))
                        each_widget.setGraphicsEffect(glow)
                        # glow.setEnabled(False)
                        try:
                            each_widget.clicked.connect(
                                lambda: each_widget.graphicsEffect().setEnabled(True)
                                if each_widget.graphicsEffect().isEnabled() is False
                                else each_widget.graphicsEffect().setEnabled(False)
                            )
                        except:
                            each_widget.sliderPressed.connect(
                                lambda: each_widget.graphicsEffect().setEnabled(True)
                                if each_widget.graphicsEffect().isEnabled() is False
                                else each_widget.graphicsEffect().setEnabled(False)
                            )
                except:
                    pass

        #######################################################################

        self.group1 = QGroupBox()
        self.group1.setTitle(__doc__)
        self.frmt = QComboBox(self.group1)
        self.frmt.addItems(["blah ", "blah blah", "blah blah blah"])
        self.file1 = QLineEdit()
        self.file1.setPlaceholderText("/full/path/to/one_file.py")
        self.file1.setCompleter(self.completer)
        self.borig = QPushButton(QIcon.fromTheme("folder-open"), "Open")
        vboxg1 = QVBoxLayout(self.group1)
        for each_widget in (
            QLabel('<b style="color:white;">some comment'),
            self.file1,
            self.borig,
            QLabel('<b style="color:white;">Lorem Impsum'),
            self.frmt,
        ):
            vboxg1.addWidget(each_widget)

        self.group2 = QGroupBox()
        self.group2.setTitle(__doc__)
        self.nwfl = QCheckBox("Be Awesome")
        self.smll = QCheckBox("Solve the Squaring of the Circle")
        self.lrgf = QCheckBox("Im just a QCheckBox")
        self.case = QCheckBox("Use Quantum Processing")
        vboxg2 = QVBoxLayout(self.group2)
        for each_widget in (self.nwfl, self.smll, self.lrgf, self.case):
            vboxg2.addWidget(each_widget)

        group3 = QGroupBox()
        group3.setTitle(__doc__)
        self.plai = QCheckBox("May the Force be with You")
        self.nocr = QCheckBox("Im just a Place Holder")
        self.ridt = QCheckBox("Lorem Impsum")
        self.nocm = QCheckBox("Divide by Zero")
        vboxg3 = QVBoxLayout(group3)
        for each_widget in (self.plai, self.nocr, self.ridt, self.nocm):
            vboxg3.addWidget(each_widget)
        container = QWidget()
        hbox = QHBoxLayout(container)
        for each_widget in (self.group2, self.group1, group3):
            hbox.addWidget(each_widget)
        self.dock1.setWidget(container)

        # dock 2
        self.dock2.setWidget(QPlainTextEdit())

        # dock 3
        self.dock3.setWidget(QCalendarWidget())

        # configure some widget settings
        must_be_checked((self.nwfl, self.smll, self.lrgf, self.plai))
        must_have_tooltip((self.plai, self.nocr, self.ridt, self.nocm, self.nwfl, self.smll, self.lrgf, self.case))
        must_autofillbackground(
            (self.plai, self.nocr, self.ridt, self.nocm, self.nwfl, self.smll, self.lrgf, self.case)
        )
        must_glow((self.plai, self.nocr, self.ridt, self.nocm, self.nwfl))

    def run(self):
        " run forest run "
        print((" INFO: Working at {}".format(str(datetime.datetime.now()))))

    ###########################################################################

    def paintEvent(self, event):
        "Paint semi-transparent background, animated pattern, background text"
        # because we are on 2012 !, its time to showcase how Qt we are !
        QWidget.paintEvent(self, event)
        # make a painter
        p = QPainter(self)
        p.setRenderHint(QPainter.TextAntialiasing)
        p.setRenderHint(QPainter.HighQualityAntialiasing)
        # fill a rectangle with transparent painting
        p.fillRect(event.rect(), Qt.transparent)
        # animated random dots background pattern
        for i in range(4096):
            x = randint(9, self.size().width() - 9)
            y = randint(9, self.size().height() - 9)
            p.setPen(QPen(QColor(randint(9, 255), randint(9, 255), 255), 1))
            p.drawPoint(x, y)
        # set pen to use white color
        p.setPen(QPen(QColor(randint(9, 255), randint(9, 255), 255), 1))
        # Rotate painter 45 Degree
        p.rotate(30)
        # Set painter Font for text
        p.setFont(QFont("Ubuntu", 200))
        # draw the background text, with antialiasing
        if KDE:
            p.drawText(99, 99, "PyKDE")
        else:
            p.drawText(99, 99, "PyQt")
        # Rotate -45 the QPen back !
        p.rotate(-30)
        # set the pen to no pen
        p.setPen(Qt.NoPen)
        # Background Color
        p.setBrush(QColor(0, 0, 0))
        # Background Opacity
        p.setOpacity(0.75)
        # Background Rounded Borders
        p.drawRoundedRect(self.rect(), 50, 50)
        # finalize the painter
        p.end()

    def seTitle(self):
        " set the title of the main window "
        dialog = QDialog(self)
        textEditInput = QLineEdit(" Type Title Here ")
        ok = QPushButton(" O K ")
        ok.clicked.connect(lambda: self.setWindowTitle(textEditInput.text()))
        ly = QVBoxLayout()
        [ly.addWidget(wdgt) for wdgt in (QLabel("Title:"), textEditInput, ok)]
        dialog.setLayout(ly)
        dialog.exec_()

    def timedate(self):
        " get the time and date "
        dialog = QDialog(self)
        clock = QLCDNumber()
        clock.setNumDigits(24)
        timer = QTimer()
        timer.timeout.connect(lambda: clock.display(datetime.now().strftime("%d-%m-%Y %H:%M:%S %p")))
        timer.start(1000)
        clock.setToolTip(datetime.now().strftime("%c %x"))
        ok = QPushButton(" O K ")
        ok.clicked.connect(dialog.close)
        ly = QVBoxLayout()
        [ly.addWidget(wdgt) for wdgt in (QCalendarWidget(), clock, ok)]
        dialog.setLayout(ly)
        dialog.exec_()

    def closeEvent(self, event):
        " Ask to Quit "
        if (
            QMessageBox.question(self, " Close ", " Quit ? ", QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
            == QMessageBox.Yes
        ):
            event.accept()
        else:
            event.ignore()

    def center(self):
        " Center and resize the window "
        self.showNormal()
        self.resize(
            QDesktopWidget().screenGeometry().width() // 1.25, QDesktopWidget().screenGeometry().height() // 1.25
        )
        qr = self.frameGeometry()
        qr.moveCenter(QDesktopWidget().availableGeometry().center())
        self.move(qr.topLeft())

    def nepomuk_set(self, file_tag=None, __tag="", _label="", _description=""):
        " Quick and Easy Nepomuk Taggify for Files "
        print(
            (
                """ INFO: Semantic Desktop Experience is Tagging Files :
              {}, {}, {}, {})""".format(
                    file_tag, __tag, _label, _description
                )
            )
        )
        if Nepomuk.ResourceManager.instance().init() is 0:
            fle = Nepomuk.Resource(KUrl(QFileInfo(file_tag).absoluteFilePath()))
            _tag = Nepomuk.Tag(__tag)
            _tag.setLabel(_label)
            fle.addTag(_tag)
            fle.setDescription(_description)
            print(([str(a.label()) for a in fle.tags()], fle.description()))
            return ([str(a.label()) for a in fle.tags()], fle.description())
        else:
            print(" ERROR: FAIL: Nepomuk is not running ! ")
            return

    def nepomuk_get(self, query_to_search):
        " Quick and Easy Nepomuk Query for Files "
        print(
            (
                """ INFO: Semantic Desktop Experience is Quering Files :
              {} """.format(
                    query_to_search
                )
            )
        )
        results = []
        nepo = Nepomuk.Query.QueryServiceClient()
        nepo.desktopQuery("hasTag:{}".format(query_to_search))

        def _query(data):
            """ ('filename.ext', 'file description', ['list', 'of', 'tags']) """
            results.append(
                (
                    [str(a.resource().genericLabel()) for a in data][0],
                    [str(a.resource().description()) for a in data][0],
                    [str(a.label()) for a in iter([a.resource().tags() for a in data][0])],
                )
            )

        nepo.newEntries.connect(_query)

        def _end():
            """
            [  ('filename.ext', 'file description', ['list', 'of', 'tags']),
               ('filename.ext', 'file description', ['list', 'of', 'tags']),
               ('filename.ext', 'file description', ['list', 'of', 'tags'])  ]
            """
            nepo.newEntries.disconnect
            print(results)
            return results

        nepo.finishedListing.connect(_end)

    def kio_get(self, url_string):
        " multi-threaded, multi-protocol, resumable, error-checked download "
        downloader_thread = KIO.storedGet(KUrl(str(url_string).strip()))

        def kio_job_data_or_error(job):
            " retrieve job data or job error "
            print((job.data() if not job.error() else job.error()))
            return job.data() if not job.error() else job.error()

        downloader_thread.result.connect(kio_job_data_or_error)
Exemplo n.º 35
0
class Console(QObject):

    @property
    def _currentCursor(self):
        return self.widget.textCursor()

    @_currentCursor.setter
    def _currentCursor(self, cursor):
        self.widget.setTextCursor(cursor)

    @property
    def _endCursor(self):
        return self._lastBlock.endCursor()

    @property
    def _currentBlock(self):
        return TextBlock(self._currentCursor)

    @property
    def _document(self):
        return self.widget.document()

    def _canDeletePreviousChar(self):
        if self._currentBlock.type in TextBlock.EDITABLE_TYPES and self._cursorInEditableArea():
            return self._currentBlock.containsCursor(self._currentCursor, in_active_area='strict')
        return False

    def _cursorInEditableArea(self, cursor=None):
        if cursor is None:
            cursor = self._currentCursor
        return self._lastBlock.isCursorInRelatedBlock(cursor) and self._currentBlock.containsCursor(cursor)

    def _canEditCurrentChar(self):
        if not self._currentBlock.type in TextBlock.EDITABLE_TYPES:
            return False
        if not self._currentBlock.containsCursor(self._currentCursor):
            return False

    def _gotoBlockStart(self):
        self._currentCursor = self._currentBlock.startCursor()

    def _gotoBlockEnd(self):
        self._currentCursor = self._currentBlock.endCursor()

    @property
    def _lastBlock(self):
        return TextBlock(self._document.lastBlock())

    def _gotoEnd(self):
        self._currentCursor = self._endCursor

    def _insertBlock(self, cursor=None, block_type=TextBlock.TYPE_CODE_CONTINUED, content=""):
        if cursor is None:
            cursor = self._currentCursor
        b = TextBlock(cursor, create_new=True, typ=block_type)
        if len(content):
            b.appendText(content)
        return b

    def _appendBlock(self, block_type, content="", html=False):
        b = TextBlock(self._endCursor, create_new=True, typ=block_type)
        if len(content) > 0:
            if html:
                b.appendHtml(content)
            else:
                b.appendText(content)
        return b

    def _blocks(self):
        b = TextBlock(self._document.begin())
        ret = []
        while not b.isLast():
            ret.append(b)
            b = b.next()
        ret.append(b)
        return ret

    def _saveBlocksToJSON(self,num_of_blocks=None):
        if num_of_blocks is None:
            num_of_blocks = 0
        ret = []
        for b in self._blocks()[-num_of_blocks:]:
            ret += [json.dumps({'block_type':b.type,'content':b.content()})]
        return '\n'.join(ret)

    def save_history(self, fname=None):
        if fname is None:
            fname = config.history_file
        fname = expanduser(fname)
        if fname.endswith('.gz'):
            f = gzip.open(fname,'wb')
        else:
            f = open(fname,'wb')
        try:
            hist_size = config.history_size
        except:
            hist_size = None
        f.write(self._saveBlocksToJSON(num_of_blocks=hist_size))
        f.close()

    def load_history(self, fname=None):
        if fname is None:
            fname = config.history_file
        fname = expanduser(fname)
        if not os.path.exists(fname):
            return
        if fname.endswith('.gz'):
            f = gzip.open(fname,'rb')
        else:
            f = open(fname,'rb')
        blocks = f.readlines()
        for b in blocks:
            bl = json.loads(b.strip())
            self._appendBlock(**bl)


    def _joinCurrentToPreviousBlock(self):
        logger.debug(msg("Deleting current block"))
        cur = self._currentBlock
        prev = cur.previous()
        prev.appendText(cur.content())
        cur.deleteBlock()

    def wordUnderCursor(self, cursor=None, delta=0):
        """ Returns the word (name) under cursor @cursor (or self._currentCursor)
            if @cursor is None. The cursor is shifted by @delta """
        if cursor is None:
            cursor = self._currentCursor
        if delta > 0:
            cursor.movePosition(QTextCursor.Right, QTextCursor.MoveAnchor, delta)
        elif delta < 0:
            cursor.movePosition(QTextCursor.Left, QTextCursor.MoveAnchor, abs(delta))
        return self._currentBlock.wordUnderCursor(cursor)

    def _containing_function(self):
        """ Determines whether the cursor is located in the argument part of a function.
            If yes, returns a (@cursor,@func_name) where  @cursor points to the opening brace
            and @func_name is the function name. """
        ct = self.textToCursor()
        i=len(ct)-1
        brackets = 0
        logger.debug("ct == " + ct)
        while i >= 0:
            if ct[i] == ')':
                brackets -=1
            if ct[i] == '(':
                if brackets < 0:
                    brackets += 1
                elif i > 0 and ct[i-1] not in TextBlock.WORD_STOP_CHARS:
                    cursor = self._currentBlock.cursorAt(i-1)
                    func_name = self._currentBlock.wordUnderCursor(cursor)
                    cursor = self._currentBlock.cursorAt(i+len(func_name))
                    logger.debug("func_name == "+ func_name)
                    return (cursor,func_name)
            i -= 1
        return None


    def textToCursor(self):
        return self._currentBlock.contentToCursor(self._currentCursor)

    def _guessDictPrefix(self, char):
        """ Tries to determine whether the user is typing a string-key in a dict. If yes
            returns the dict name and the key typed so far. Otherwise returns None. """
        c = self._currentCursor
        block_content = self._currentBlock.content(include_decoration=True)
        pos = min(c.positionInBlock(), len(block_content))
        block_content = unicode(block_content[:pos]+char)

        double_quotes = block_content.count('"')
        single_quotes = block_content.count("'")

        if double_quotes % 2 == 0 and single_quotes % 2 == 0:
            return None

        stop_chars = '"\' '
        ret = []
        while pos >= 0 and block_content[pos] not in stop_chars:
            ret.append(block_content[pos])
            pos -= 1
        ret.reverse()
        if pos > 0 and block_content[pos-1] == '[':
            pos -= 1
            dct = []
            while pos >= 0 and block_content[pos] not in [ ' ', "\n", "\t"]:
                dct.append(block_content[pos])
                pos -= 1
            dct.reverse()
            logger.debug(msg('dct:',''.join(dct[:-1]), 'key:',''.join(ret)))
            return ''.join(dct[:-1]), ''.join(ret)
        else:
            return None

    def _guessStringPrefix(self, char):
        """Tries to guess whether the user is typing a string (i.e. inside quotes)
           and if yes, returns the string typed so far. Otherwise returns None. """
        c = self._currentCursor
        block_content = self._currentBlock.content(include_decoration=True)
        pos = min(c.positionInBlock(), len(block_content))
        block_content = unicode(block_content[:pos]+char)

        double_quotes = block_content.count('"')
        single_quotes = block_content.count("'")

        if double_quotes % 2 == 0 and single_quotes % 2 == 0:
            return None

        stop_chars = '"\' '
        ret = []
        while pos >= 0 and block_content[pos] not in stop_chars:
            ret.append(block_content[pos])
            pos -= 1
        ret.reverse()
        logger.debug(''.join(ret))
        return ''.join(ret)

    @pyqtSlot(unicode)
    def _insertCompletion(self, completion):
        insertion = completion[len(self.completer.completionPrefix()):]
        if len(insertion) == 0:
            self._process_enter()
        else:
            c = self._currentCursor
            c.movePosition(QTextCursor.Left)
            c.movePosition(QTextCursor.EndOfWord)
            c.insertText(insertion)
            self._currentCursor = c

    DEFAULT_INDENT = 4

    MODE_RUNNING = 0
    MODE_CODE_EDITING = 1
    MODE_RAW_INPUT = 2
    MODE_READ_ONLY = 3
    MODE_WAITING_FOR_INTERRUPT = 4

    # run_code = pyqtSignal(unicode)
    run_code = signal(unicode)
    read_line = signal(unicode)
    restart_shell = signal()
    interrupt_shell = signal()
    quit = pyqtSignal()
    file_watched = signal(unicode)

    def __init__(self, widget):
        super(Console, self).__init__()
        self.font_size = 10
        self.font = QFont("Ubuntu Mono", self.font_size)
        self.allow_quit = True
        self.indent = self.DEFAULT_INDENT
        self.widget = widget
        self.hilighter = PythonHighlighter(self.widget.document())
        self.parser = PyParser(self.indent, self.indent)

        self.widget.setFont(self.font)

        # The source file's we are watching
        self.watcher = QFileSystemWatcher()
        self.watcher.fileChanged.connect(self._sourceChanged)
        self._watched_files_menu = QMenu(self.widget.tr("&Watched Files"))
        self._watched_files_actions = {}
        self._lost_files = []

        self._widgetKeyPressEvent = self.widget.keyPressEvent
        self.widget.keyPressEvent = self.keyPressEvent
        self._widgetFocusInEvent = self.widget.focusInEvent
        self.widget.focusInEvent = self.focusInEvent
        self.widget.dragEnterEvent = self.dragEnterEvent
        self.widget.dragMoveEvent = self.dragMoveEvent
        self.widget.dropEvent = self.dropEvent

        # Code Completion
        self.completer = QCompleter(
            [kw for kw in PythonHighlighter.keywords if len(kw) > 3])
        self.completer.setCompletionMode(QCompleter.PopupCompletion)
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.activated.connect(self._insertCompletion)
        self.completer.popup().setStyleSheet(
            "QWidget {border-width: 1px; border-color: black;}")
        self.completer.popup().setVerticalScrollBarPolicy(
            Qt.ScrollBarAlwaysOff)
        self.completer.setWidget(self.widget)
        self.completion_enabled = True

        if config.history:
            self.load_history()

        self._lastBlock.setType(TextBlock.TYPE_MESSAGE)
        self._lastBlock.appendText("PyShell v 0.5: Starting ...")
        self._write_message("Python version ", sys.version)
        self.start_editing()

        # Restart shell timer
        self.timer = QTimer(self)

    @property
    def watched_files_menu(self):
        return self._watched_files_menu

    @property
    def mode(self):
        return self._mode

    @pyqtSlot()
    def increase_font(self):
        self.font_size += 1
        self.font = QFont("Ubuntu Mono", self.font_size)
        self.widget.setFont(self.font)

    @pyqtSlot()
    def decrease_font(self):
        self.font_size -= 1
        self.font = QFont("Ubuntu Mono", self.font_size)
        self.widget.setFont(self.font)

    @pyqtSlot(unicode, unicode)
    def write(self, stream, string):
        #assert self.mode == Console.MODE_RUNNING or self.mode == Console.MODE_WAITING_FOR_INTERRUPT, "Cannot write " + \
        #    string + " to console stream "+stream+" in "+str(
        #        self.mode) + " (need to be RUNNING/INTERRUPT mode) "
        if string.startswith('<html_snippet>'):
            self._lastBlock.appendHtml(string.replace(
                "<html_snippet>", "").replace("</html_snippet>", ""))
        else:
            lines = string.split('\n')
            block_type = block_type_for_stream(stream)
            for ln in lines[:-1]:
                self._lastBlock.appendText(ln)
                self._lastBlock.setType(block_type)
                self._appendBlock(block_type)
            self._lastBlock.appendText(lines[-1])
            self._gotoEnd()

    def write_object(self, obj):
        logger.debug(msg("Received object", obj, "writing it to stdout"))
        self.write('stdout',print_hooks.html_repr(obj, self._document))

    @pyqtSlot()
    def do_readline(self):
        assert self.mode != Console.MODE_RAW_INPUT, "Cannot call readline before previous call finished"
        assert self.mode == Console.MODE_RUNNING, "readline may be called only in the RUNNING mode"
        self._lastBlock.setType(TextBlock.TYPE_RAW_INPUT)
        self._mode = Console.MODE_RAW_INPUT

    @pyqtSlot()
    def shell_restarted(self):
        logger.debug("Shell restarted!")
        self._write_message("<span style='color:green'>","="*20,
                            "</span> SHELL RESTARTED <span style='color:green'>","="*20,"</span>", html=True)
        self._write_message('Python version ',sys.version, html=True)
        self.start_editing()

    @pyqtSlot()
    def finished_running(self):
        logger.debug("Finished running.")
        if len(self._lastBlock.content()) == 0:
            self._lastBlock.deleteBlock()
        self.start_editing()

    @pyqtSlot()
    def start_editing(self):
        new_code_block = self._appendBlock(TextBlock.TYPE_CODE_START)
        self._gotoEnd()
        self._mode = Console.MODE_CODE_EDITING

    @pyqtSlot()
    def exec_command(self,*args, **kwargs):
        """ Executes a command in the console context.
            The command is given by the cmd keyword argument.
            It is either a predefined command or the name of
            a method of the console object, in which case this
            method is called with *args and **kwargs (where cmd
            is first deleted from kwargs) """
        if 'cmd' in kwargs:
            cmd = kwargs['cmd']
            del kwargs['cmd']
            if cmd == 'watch.list_files':
                self._write_message("Currently watching the following files:")
                self._write_message([unicode(x) for x in self.watcher.files()])
                self._write_message("Total watched:",len(self.watcher.files()))
                logger.debug(msg([x for x in self.watcher.files()]))
            elif cmd == 'watch.reload':
                self._reload_watch_files()
            elif cmd in dir(self):
                attr = self.__getattribute__(cmd)
                if type(attr) == type(self.exec_command):
                    attr(*args, **kwargs)
                else:
                    self.write_object(attr)

    def _write_message(self, *args, **kwargs):
        """ Outputs a "System" message to the console. The message is composed
            of string representations of args. If the keyword argument html
            is present, the message is assumed to be html. """
        if 'html' in kwargs:
            html = kwargs['html']
        else:
            html = True
        msg = u''
        for a in args:
            try:
                msg += unicode(a)
            except Exception, e:
                logger.warn("Exception while writing to console" + str(e))
        self._appendBlock(TextBlock.TYPE_MESSAGE, msg, html)
Exemplo n.º 36
0
class ParentAction(object):
    def __init__(self, iface, settings, controller, plugin_dir):
        """ Class constructor """

        # Initialize instance attributes
        self.giswater_version = "3.1"
        self.iface = iface
        self.canvas = self.iface.mapCanvas()
        self.settings = settings
        self.controller = controller
        self.plugin_dir = plugin_dir
        self.dao = self.controller.dao
        self.schema_name = self.controller.schema_name
        self.project_type = None
        self.file_gsw = None
        self.gsw_settings = None

        # Get files to execute giswater jar (only in Windows)
        if 'nt' in sys.builtin_module_names:
            self.plugin_version = self.get_plugin_version()
            self.java_exe = self.get_java_exe()
            (self.giswater_file_path,
             self.giswater_build_version) = self.get_giswater_jar()

    def set_controller(self, controller):
        """ Set controller class """

        self.controller = controller
        self.schema_name = self.controller.schema_name

    def get_plugin_version(self):
        """ Get plugin version from metadata.txt file """

        # Check if metadata file exists
        metadata_file = os.path.join(self.plugin_dir, 'metadata.txt')
        if not os.path.exists(metadata_file):
            message = "Metadata file not found" + metadata_file
            self.controller.show_warning(message, parameter=metadata_file)
            return None

        metadata = ConfigParser.ConfigParser()
        metadata.read(metadata_file)
        plugin_version = metadata.get('general', 'version')
        if plugin_version is None:
            message = "Plugin version not found"
            self.controller.show_warning(message)

        return plugin_version

    def get_giswater_jar(self):
        """ Get executable Giswater file and build version from windows registry """

        reg_hkey = "HKEY_LOCAL_MACHINE"
        reg_path = "SOFTWARE\\Giswater\\" + self.giswater_version
        reg_name = "InstallFolder"
        giswater_folder = utils_giswater.get_reg(reg_hkey, reg_path, reg_name)
        if giswater_folder is None:
            message = "Cannot get giswater folder from windows registry"
            self.controller.log_info(message, parameter=reg_path)
            return (None, None)

        # Check if giswater folder exists
        if not os.path.exists(giswater_folder):
            message = "Giswater folder not found"
            self.controller.log_info(message, parameter=giswater_folder)
            return (None, None)

        # Check if giswater executable file file exists
        giswater_file_path = giswater_folder + "\giswater.jar"
        if not os.path.exists(giswater_file_path):
            message = "Giswater executable file not found"
            self.controller.log_info(message, parameter=giswater_file_path)
            return (None, None)

        # Get giswater major version
        reg_name = "MajorVersion"
        major_version = utils_giswater.get_reg(reg_hkey, reg_path, reg_name)
        if major_version is None:
            message = "Cannot get giswater major version from windows registry"
            self.controller.log_info(message, parameter=reg_path)
            return (giswater_file_path, None)

        # Get giswater minor version
        reg_name = "MinorVersion"
        minor_version = utils_giswater.get_reg(reg_hkey, reg_path, reg_name)
        if minor_version is None:
            message = "Cannot get giswater minor version from windows registry" + reg_path
            self.controller.log_info(message, parameter=reg_path)
            return (giswater_file_path, None)

        # Get giswater build version
        reg_name = "BuildVersion"
        build_version = utils_giswater.get_reg(reg_hkey, reg_path, reg_name)
        if build_version is None:
            message = "Cannot get giswater build version from windows registry"
            self.controller.log_info(message, parameter=reg_path)
            return (giswater_file_path, None)

        giswater_build_version = major_version + '.' + minor_version + '.' + build_version

        return (giswater_file_path, giswater_build_version)

    def get_java_exe(self):
        """ Get executable Java file from windows registry """

        reg_hkey = "HKEY_LOCAL_MACHINE"
        reg_path = "SOFTWARE\\JavaSoft\\Java Runtime Environment"
        reg_name = "CurrentVersion"
        java_version = utils_giswater.get_reg(reg_hkey, reg_path, reg_name)

        # Check if java version exists (64 bits)
        if java_version is None:
            reg_path = "SOFTWARE\\Wow6432Node\\JavaSoft\\Java Runtime Environment"
            java_version = utils_giswater.get_reg(reg_hkey, reg_path, reg_name)
            # Check if java version exists (32 bits)
            if java_version is None:
                message = "Cannot get current Java version from windows registry"
                self.controller.log_info(message, parameter=reg_path)
                return None

        # Get java folder
        reg_path += "\\" + java_version
        reg_name = "JavaHome"
        java_folder = utils_giswater.get_reg(reg_hkey, reg_path, reg_name)
        if java_folder is None:
            message = "Cannot get Java folder from windows registry"
            self.controller.log_info(message, parameter=reg_path)
            return None

        # Check if java folder exists
        if not os.path.exists(java_folder):
            message = "Java folder not found"
            self.controller.log_info(message, parameter=java_folder)
            return None

        # Check if java executable file exists
        java_exe = java_folder + "/bin/java.exe"
        if not os.path.exists(java_exe):
            message = "Java executable file not found"
            self.controller.log_info(message, parameter=java_exe)
            return None

        return java_exe

    def execute_giswater(self, parameter):
        """ Executes giswater with selected parameter """

        if self.giswater_file_path is None or self.java_exe is None:
            return

        # Save database connection parameters into GSW file
        self.save_database_parameters()

        # Check if gsw file exists. If not giswater will open with the last .gsw file
        if self.file_gsw is None:
            self.file_gsw = ""
        if self.file_gsw:
            if self.file_gsw != "" and not os.path.exists(self.file_gsw):
                message = "GSW file not found"
                self.controller.show_info(message, parameter=self.file_gsw)
                self.file_gsw = ""

        # Start program
        aux = '"' + self.giswater_file_path + '"'
        if self.file_gsw != "":
            aux += ' "' + self.file_gsw + '"'
            program = [
                self.java_exe, "-jar", self.giswater_file_path, self.file_gsw,
                parameter
            ]
        else:
            program = [
                self.java_exe, "-jar", self.giswater_file_path, "", parameter
            ]

        self.controller.start_program(program)

        # Compare Java and Plugin versions
        if self.plugin_version <> self.giswater_build_version:
            msg = ("Giswater and plugin versions are different. "
                   "Giswater version: " + self.giswater_build_version + ""
                   " - Plugin version: " + self.plugin_version)
            self.controller.show_info(msg, 10)
        # Show information message
        else:
            message = "Executing..."
            self.controller.show_info(message, parameter=aux)

    def set_java_settings(self, show_warning=True):

        # Get giswater properties file
        users_home = os.path.expanduser("~")
        filename = "giswater_" + self.giswater_version + ".properties"
        java_properties_path = users_home + os.sep + "giswater" + os.sep + "config" + os.sep + filename
        if not os.path.exists(java_properties_path):
            message = "Giswater properties file not found"
            if show_warning:
                self.controller.show_warning(
                    message, parameter=str(java_properties_path))
            return False

        self.java_settings = QSettings(java_properties_path,
                                       QSettings.IniFormat)
        self.java_settings.setIniCodec(sys.getfilesystemencoding())
        self.file_gsw = utils_giswater.get_settings_value(
            self.java_settings, 'FILE_GSW')

    def set_gsw_settings(self):

        if not self.file_gsw:
            self.set_java_settings(False)

        self.gsw_settings = QSettings(self.file_gsw, QSettings.IniFormat)

    def save_database_parameters(self):
        """ Save database connection parameters into GSW file """

        if self.gsw_settings is None:
            self.set_gsw_settings()

        # Get layer version
        layer = self.controller.get_layer_by_tablename('version')
        if not layer:
            return

        # Get database connection paramaters and save them into GSW file
        layer_source = self.controller.get_layer_source_from_credentials()
        if layer_source is None:
            return

        self.gsw_settings.setValue('POSTGIS_DATABASE', layer_source['db'])
        self.gsw_settings.setValue('POSTGIS_HOST', layer_source['host'])
        self.gsw_settings.setValue('POSTGIS_PORT', layer_source['port'])
        self.gsw_settings.setValue('POSTGIS_USER', layer_source['user'])
        self.gsw_settings.setValue('POSTGIS_USESSL', 'false')

    def open_web_browser(self, dialog, widget=None):
        """ Display url using the default browser """

        if widget is not None:
            url = utils_giswater.getWidgetText(dialog, widget)
            if url == 'null':
                url = 'www.giswater.org'
        else:
            url = 'www.giswater.org'

        webbrowser.open(url)

    def get_file_dialog(self, dialog, widget):
        """ Get file dialog """

        # Check if selected file exists. Set default value if necessary
        file_path = utils_giswater.getWidgetText(dialog, widget)
        if file_path is None or file_path == 'null' or not os.path.exists(
                str(file_path)):
            folder_path = self.plugin_dir
        else:
            folder_path = os.path.dirname(file_path)

        # Open dialog to select file
        os.chdir(folder_path)
        file_dialog = QFileDialog()
        file_dialog.setFileMode(QFileDialog.AnyFile)
        message = "Select file"
        folder_path = file_dialog.getOpenFileName(
            parent=None, caption=self.controller.tr(message))
        if folder_path:
            utils_giswater.setWidgetText(dialog, widget, str(folder_path))

    def get_folder_dialog(self, dialog, widget):
        """ Get folder dialog """

        # Check if selected folder exists. Set default value if necessary
        folder_path = utils_giswater.getWidgetText(dialog, widget)
        if folder_path is None or folder_path == 'null' or not os.path.exists(
                folder_path):
            folder_path = os.path.expanduser("~")

        # Open dialog to select folder
        os.chdir(folder_path)
        file_dialog = QFileDialog()
        file_dialog.setFileMode(QFileDialog.Directory)
        message = "Select folder"
        folder_path = file_dialog.getExistingDirectory(
            parent=None,
            caption=self.controller.tr(message),
            directory=folder_path)
        if folder_path:
            utils_giswater.setWidgetText(dialog, widget, str(folder_path))

    def load_settings(self, dialog=None):
        """ Load QGIS settings related with dialog position and size """

        if dialog is None:
            dialog = self.dlg

        try:
            x = self.controller.plugin_settings_value(dialog.objectName() +
                                                      "_x")
            y = self.controller.plugin_settings_value(dialog.objectName() +
                                                      "_y")
            width = self.controller.plugin_settings_value(
                dialog.objectName() + "_width", dialog.property('width'))
            height = self.controller.plugin_settings_value(
                dialog.objectName() + "_height", dialog.property('height'))

            if int(x) < 0 or int(y) < 0:
                dialog.resize(int(width), int(height))
            else:
                screens = ctypes.windll.user32
                screen_x = screens.GetSystemMetrics(78)
                screen_y = screens.GetSystemMetrics(79)
                if int(x) > screen_x:
                    x = int(screen_x) - int(width)
                if int(y) > screen_y:
                    y = int(screen_y)
                dialog.setGeometry(int(x), int(y), int(width), int(height))
        except:
            pass

    def save_settings(self, dialog=None):
        """ Save QGIS settings related with dialog position and size """

        if dialog is None:
            dialog = self.dlg

        self.controller.plugin_settings_set_value(
            dialog.objectName() + "_width", dialog.property('width'))
        self.controller.plugin_settings_set_value(
            dialog.objectName() + "_height", dialog.property('height'))
        self.controller.plugin_settings_set_value(dialog.objectName() + "_x",
                                                  dialog.pos().x() + 8)
        self.controller.plugin_settings_set_value(dialog.objectName() + "_y",
                                                  dialog.pos().y() + 31)

    def open_dialog(self,
                    dlg=None,
                    dlg_name=None,
                    maximize_button=True,
                    stay_on_top=True):
        """ Open dialog """

        if dlg is None or type(dlg) is bool:
            dlg = self.dlg

        # Manage i18n of the dialog
        if dlg_name:
            self.controller.manage_translation(dlg_name, dlg)

        # Manage stay on top and maximize button
        if maximize_button and stay_on_top:
            dlg.setWindowFlags(Qt.WindowMinimizeButtonHint
                               | Qt.WindowMaximizeButtonHint
                               | Qt.WindowStaysOnTopHint)
        elif not maximize_button and stay_on_top:
            dlg.setWindowFlags(Qt.WindowMinimizeButtonHint
                               | Qt.WindowStaysOnTopHint)
        elif maximize_button and not stay_on_top:
            dlg.setWindowFlags(Qt.WindowMaximizeButtonHint)

        # Open dialog
        dlg.open()

    def close_dialog(self, dlg=None):
        """ Close dialog """

        if dlg is None or type(dlg) is bool:
            dlg = self.dlg
        try:
            self.save_settings(dlg)
            dlg.close()
            map_tool = self.canvas.mapTool()
            # If selected map tool is from the plugin, set 'Pan' as current one
            if map_tool.toolName() == '':
                self.iface.actionPan().trigger()
        except AttributeError:
            pass

    def multi_row_selector(self,
                           dialog,
                           tableleft,
                           tableright,
                           field_id_left,
                           field_id_right,
                           name='name',
                           index=[
                               0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
                               15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
                               27, 28, 29, 30
                           ]):

        # fill QTableView all_rows
        tbl_all_rows = dialog.findChild(QTableView, "all_rows")
        tbl_all_rows.setSelectionBehavior(QAbstractItemView.SelectRows)

        query_left = "SELECT * FROM " + self.schema_name + "." + tableleft + " WHERE " + name + " NOT IN "
        query_left += "(SELECT " + tableleft + "." + name + " FROM " + self.schema_name + "." + tableleft
        query_left += " RIGHT JOIN " + self.schema_name + "." + tableright + " ON " + tableleft + "." + field_id_left + " = " + tableright + "." + field_id_right
        query_left += " WHERE cur_user = current_user)"

        self.fill_table_by_query(tbl_all_rows, query_left)
        self.hide_colums(tbl_all_rows, index)
        tbl_all_rows.setColumnWidth(1, 200)

        # fill QTableView selected_rows
        tbl_selected_rows = dialog.findChild(QTableView, "selected_rows")
        tbl_selected_rows.setSelectionBehavior(QAbstractItemView.SelectRows)
        query_right = "SELECT " + tableleft + "." + name + ", cur_user, " + tableleft + "." + field_id_left + ", " + tableright + "." + field_id_right + " FROM " + self.schema_name + "." + tableleft
        query_right += " JOIN " + self.schema_name + "." + tableright + " ON " + tableleft + "." + field_id_left + " = " + tableright + "." + field_id_right
        query_right += " WHERE cur_user = current_user"

        self.fill_table_by_query(tbl_selected_rows, query_right)
        self.hide_colums(tbl_selected_rows, [1, 2, 3])
        tbl_selected_rows.setColumnWidth(0, 200)
        # Button select
        dialog.btn_select.clicked.connect(
            partial(self.multi_rows_selector, tbl_all_rows, tbl_selected_rows,
                    field_id_left, tableright, field_id_right, query_left,
                    query_right, field_id_right))

        # Button unselect
        query_delete = "DELETE FROM " + self.schema_name + "." + tableright
        query_delete += " WHERE current_user = cur_user AND " + tableright + "." + field_id_right + "="
        dialog.btn_unselect.clicked.connect(
            partial(self.unselector, tbl_all_rows, tbl_selected_rows,
                    query_delete, query_left, query_right, field_id_right))
        # QLineEdit
        dialog.txt_name.textChanged.connect(
            partial(self.query_like_widget_text, dialog, dialog.txt_name,
                    tbl_all_rows, tableleft, tableright, field_id_right,
                    field_id_left, name))

    def hide_colums(self, widget, comuns_to_hide):
        for i in range(0, len(comuns_to_hide)):
            widget.hideColumn(comuns_to_hide[i])

    def unselector(self, qtable_left, qtable_right, query_delete, query_left,
                   query_right, field_id_right):

        selected_list = qtable_right.selectionModel().selectedRows()
        if len(selected_list) == 0:
            message = "Any record selected"
            self.controller.show_warning(message)
            return
        expl_id = []
        for i in range(0, len(selected_list)):
            row = selected_list[i].row()
            id_ = str(qtable_right.model().record(row).value(field_id_right))
            expl_id.append(id_)
        for i in range(0, len(expl_id)):
            self.controller.execute_sql(query_delete + str(expl_id[i]))

        # Refresh
        self.fill_table_by_query(qtable_left, query_left)
        self.fill_table_by_query(qtable_right, query_right)
        self.refresh_map_canvas()

    def multi_rows_selector(self, qtable_left, qtable_right, id_ori,
                            tablename_des, id_des, query_left, query_right,
                            field_id):
        """
            :param qtable_left: QTableView origin
            :param qtable_right: QTableView destini
            :param id_ori: Refers to the id of the source table
            :param tablename_des: table destini
            :param id_des: Refers to the id of the target table, on which the query will be made
            :param query_right:
            :param query_left:
            :param field_id:
        """

        selected_list = qtable_left.selectionModel().selectedRows()

        if len(selected_list) == 0:
            message = "Any record selected"
            self.controller.show_warning(message)
            return
        expl_id = []
        curuser_list = []
        for i in range(0, len(selected_list)):
            row = selected_list[i].row()
            id_ = qtable_left.model().record(row).value(id_ori)
            expl_id.append(id_)
            curuser = qtable_left.model().record(row).value("cur_user")
            curuser_list.append(curuser)
        for i in range(0, len(expl_id)):
            # Check if expl_id already exists in expl_selector
            sql = ("SELECT DISTINCT(" + id_des + ", cur_user)"
                   " FROM " + self.schema_name + "." + tablename_des + ""
                   " WHERE " + id_des + " = '" + str(expl_id[i]) +
                   "' AND cur_user = current_user")
            row = self.controller.get_row(sql)

            if row:
                # if exist - show warning
                message = "Id already selected"
                self.controller.show_info_box(message,
                                              "Info",
                                              parameter=str(expl_id[i]))
            else:
                sql = ("INSERT INTO " + self.schema_name + "." +
                       tablename_des + " (" + field_id + ", cur_user) "
                       " VALUES (" + str(expl_id[i]) + ", current_user)")
                self.controller.execute_sql(sql)

        # Refresh
        self.fill_table_by_query(qtable_right, query_right)
        self.fill_table_by_query(qtable_left, query_left)
        self.refresh_map_canvas()

    def fill_table_psector(self,
                           widget,
                           table_name,
                           set_edit_strategy=QSqlTableModel.OnManualSubmit):
        """ Set a model with selected @table_name. Attach that model to selected table """
        if self.schema_name not in table_name:
            table_name = self.schema_name + "." + table_name
        # Set model
        self.model = QSqlTableModel()
        self.model.setTable(table_name)
        self.model.setEditStrategy(set_edit_strategy)
        self.model.setSort(0, 0)
        self.model.select()

        # Check for errors
        if self.model.lastError().isValid():
            self.controller.show_warning(self.model.lastError().text())

        # Attach model to table view
        widget.setModel(self.model)

    def fill_table(self,
                   widget,
                   table_name,
                   set_edit_strategy=QSqlTableModel.OnManualSubmit):
        """ Set a model with selected filter.
        Attach that model to selected table """
        if self.schema_name not in table_name:
            table_name = self.schema_name + "." + table_name
        # Set model
        self.model = QSqlTableModel()
        self.model.setTable(table_name)
        self.model.setEditStrategy(set_edit_strategy)
        self.model.setSort(0, 0)
        self.model.select()

        # Check for errors
        if self.model.lastError().isValid():
            self.controller.show_warning(self.model.lastError().text())
        # Attach model to table view
        widget.setModel(self.model)

    def fill_table_by_query(self, qtable, query):
        """
        :param qtable: QTableView to show
        :param query: query to set model
        """
        model = QSqlQueryModel()
        model.setQuery(query)
        qtable.setModel(model)
        qtable.show()

        # Check for errors
        if model.lastError().isValid():
            self.controller.show_warning(model.lastError().text())

    def query_like_widget_text(self,
                               dialog,
                               text_line,
                               qtable,
                               tableleft,
                               tableright,
                               field_id_r,
                               field_id_l,
                               name='name'):
        """ Fill the QTableView by filtering through the QLineEdit"""

        query = utils_giswater.getWidgetText(dialog,
                                             text_line,
                                             return_string_null=False).lower()
        sql = ("SELECT * FROM " + self.schema_name + "." + tableleft +
               " WHERE " + name + " NOT IN "
               "(SELECT " + tableleft + "." + name + " FROM " +
               self.schema_name + "." + tableleft + ""
               " RIGHT JOIN " + self.schema_name + "." + tableright + ""
               " ON " + tableleft + "." + field_id_l + " = " + tableright +
               "." + field_id_r + ""
               " WHERE cur_user = current_user) AND LOWER(" + name +
               "::text) LIKE '%" + query + "%'")
        self.fill_table_by_query(qtable, sql)

    def set_icon(self, widget, icon):
        """ Set @icon to selected @widget """

        # Get icons folder
        icons_folder = os.path.join(self.plugin_dir, 'icons')
        icon_path = os.path.join(icons_folder, str(icon) + ".png")
        if os.path.exists(icon_path):
            widget.setIcon(QIcon(icon_path))
        else:
            self.controller.log_info("File not found", parameter=icon_path)

    def check_expression(self, expr_filter, log_info=False):
        """ Check if expression filter @expr_filter is valid """

        if log_info:
            self.controller.log_info(expr_filter)
        expr = QgsExpression(expr_filter)
        if expr.hasParserError():
            message = "Expression Error"
            self.controller.log_warning(message, parameter=expr_filter)
            return (False, expr)
        return (True, expr)

    def refresh_map_canvas(self, restore_cursor=False):
        """ Refresh all layers present in map canvas """

        self.canvas.refreshAllLayers()
        for layer_refresh in self.canvas.layers():
            layer_refresh.triggerRepaint()

        if restore_cursor:
            self.set_cursor_restore()

    def set_cursor_wait(self):
        """ Change cursor to 'WaitCursor' """
        QApplication.setOverrideCursor(Qt.WaitCursor)

    def set_cursor_restore(self):
        """ Restore to previous cursors """
        QApplication.restoreOverrideCursor()

    def get_cursor_multiple_selection(self):
        """ Set cursor for multiple selection """

        path_folder = os.path.join(os.path.dirname(__file__), os.pardir)
        path_cursor = os.path.join(path_folder, 'icons', '201.png')
        if os.path.exists(path_cursor):
            cursor = QCursor(QPixmap(path_cursor))
        else:
            cursor = QCursor(Qt.ArrowCursor)

        return cursor

    def set_table_columns(self, dialog, widget, table_name):
        """ Configuration of tables. Set visibility and width of columns """

        widget = utils_giswater.getWidget(dialog, widget)
        if not widget:
            return

        # Set width and alias of visible columns
        columns_to_delete = []
        sql = ("SELECT column_index, width, alias, status"
               " FROM " + self.schema_name + ".config_client_forms"
               " WHERE table_id = '" + table_name + "'"
               " ORDER BY column_index")
        rows = self.controller.get_rows(sql, log_info=False)
        if not rows:
            return

        for row in rows:
            if not row['status']:
                columns_to_delete.append(row['column_index'] - 1)
            else:
                width = row['width']
                if width is None:
                    width = 100
                widget.setColumnWidth(row['column_index'] - 1, width)
                widget.model().setHeaderData(row['column_index'] - 1,
                                             Qt.Horizontal, row['alias'])

        # Set order
        # widget.model().setSort(0, Qt.AscendingOrder)
        widget.model().select()

        # Delete columns
        for column in columns_to_delete:
            widget.hideColumn(column)

    def connect_signal_selection_changed(self, option):
        """ Connect signal selectionChanged """

        try:
            if option == "mincut_connec":
                self.canvas.selectionChanged.connect(
                    partial(self.snapping_selection_connec))
            elif option == "mincut_hydro":
                self.canvas.selectionChanged.connect(
                    partial(self.snapping_selection_hydro))
        except Exception:
            pass

    def disconnect_signal_selection_changed(self):
        """ Disconnect signal selectionChanged """

        try:
            self.canvas.selectionChanged.disconnect()
        except Exception:
            pass

    def set_label_current_psector(self, dialog):

        sql = (
            "SELECT t1.name FROM " + self.schema_name + ".plan_psector AS t1 "
            " INNER JOIN " + self.schema_name +
            ".config_param_user AS t2 ON t1.psector_id::text = t2.value "
            " WHERE t2.parameter='psector_vdefault' AND cur_user = current_user"
        )
        row = self.controller.get_row(sql)
        if not row:
            return
        utils_giswater.setWidgetText(dialog, 'lbl_vdefault_psector', row[0])

    def multi_rows_delete(self, widget, table_name, column_id):
        """ Delete selected elements of the table
        :param QTableView widget: origin
        :param table_name: table origin
        :param column_id: Refers to the id of the source table
        """

        # Get selected rows
        selected_list = widget.selectionModel().selectedRows()
        if len(selected_list) == 0:
            message = "Any record selected"
            self.controller.show_warning(message)
            return

        inf_text = ""
        list_id = ""
        for i in range(0, len(selected_list)):
            row = selected_list[i].row()
            id_ = widget.model().record(row).value(str(column_id))
            inf_text += str(id_) + ", "
            list_id = list_id + "'" + str(id_) + "', "
        inf_text = inf_text[:-2]
        list_id = list_id[:-2]
        message = "Are you sure you want to delete these records?"
        title = "Delete records"
        answer = self.controller.ask_question(message, title, inf_text)
        if answer:
            sql = "DELETE FROM " + self.schema_name + "." + table_name
            sql += " WHERE " + column_id + " IN (" + list_id + ")"
            self.controller.execute_sql(sql)
            widget.model().select()

    def select_features_by_expr(self, layer, expr):
        """ Select features of @layer applying @expr """

        if expr is None:
            layer.removeSelection()
        else:
            it = layer.getFeatures(QgsFeatureRequest(expr))
            # Build a list of feature id's from the previous result and select them
            id_list = [i.id() for i in it]
            if len(id_list) > 0:
                layer.selectByIds(id_list)
            else:
                layer.removeSelection()

    def zoom_to_selected_features(self, layer, geom_type=None, zoom=None):
        """ Zoom to selected features of the @layer with @geom_type """

        if not layer:
            return

        self.iface.setActiveLayer(layer)
        self.iface.actionZoomToSelected().trigger()

        if geom_type:

            # Set scale = scale_zoom
            if geom_type in ('node', 'connec', 'gully'):
                scale = self.scale_zoom

            # Set scale = max(current_scale, scale_zoom)
            elif geom_type == 'arc':
                scale = self.iface.mapCanvas().scale()
                if int(scale) < int(self.scale_zoom):
                    scale = self.scale_zoom
            else:
                scale = 5000

            if zoom is not None:
                scale = zoom

            self.iface.mapCanvas().zoomScale(float(scale))

    def set_completer(self, tablename, widget, field_search, color='black'):
        """ Set autocomplete of widget @table_object + "_id"
            getting id's from selected @table_object
        """

        if not widget:
            return

        # Set SQL
        sql = ("SELECT DISTINCT(" + field_search + ")"
               " FROM " + self.schema_name + "." + tablename + ""
               " ORDER BY " + field_search + "")
        row = self.controller.get_rows(sql)

        for i in range(0, len(row)):
            aux = row[i]
            row[i] = str(aux[0])

        # Set completer and model: add autocomplete in the widget
        self.completer = QCompleter()
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setCompletionMode(0)
        self.completer.popup().setStyleSheet("color: " + color + ";")
        widget.setCompleter(self.completer)

        model = QStringListModel()
        model.setStringList(row)
        self.completer.setModel(model)

    def zoom_to_rectangle(self, x1, y1, x2, y2, margin=5):
        # rect = QgsRectangle(float(x1)+10, float(y1)+10, float(x2)-10, float(y2)-10)
        rect = QgsRectangle(
            float(x1) - margin,
            float(y1) - margin,
            float(x2) + margin,
            float(y2) + margin)
        self.canvas.setExtent(rect)
        self.canvas.refresh()

    def create_action(self,
                      action_name,
                      action_group,
                      icon_num=None,
                      text=None):
        """ Creates a new action with selected parameters """

        icon = None
        icon_folder = self.plugin_dir + '/icons/'
        icon_path = icon_folder + icon_num + '.png'
        if os.path.exists(icon_path):
            icon = QIcon(icon_path)

        if icon is None:
            action = QAction(text, action_group)
        else:
            action = QAction(icon, text, action_group)
        action.setObjectName(action_name)

        return action
Exemplo n.º 37
0
class MyMainWindow(QMainWindow):
    " Main Window "

    def __init__(self, parent=None):
        " Initialize QWidget inside MyMainWindow "
        super(MyMainWindow, self).__init__(parent)
        QWidget.__init__(self)
        self.statusBar().showMessage("               " + __doc__)
        self.setStyleSheet("QStatusBar{color:grey;}")
        self.setWindowTitle(__doc__)
        self.setWindowIcon(QIcon.fromTheme("face-monkey"))
        self.setFont(QFont("Ubuntu Light", 10))
        self.setMaximumSize(QDesktopWidget().screenGeometry().width(), QDesktopWidget().screenGeometry().height())

        # directory auto completer
        self.completer = QCompleter(self)
        self.dirs = QDirModel(self)
        self.dirs.setFilter(QDir.AllEntries | QDir.NoDotAndDotDot)
        self.completer.setModel(self.dirs)
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setCompletionMode(QCompleter.PopupCompletion)

        # process
        self.process = QProcess(self)
        # self.process.finished.connect(self.on_process_finished)
        # self.process.error.connect(self.on_process_error)

        # Proxy support, by reading http_proxy os env variable
        proxy_url = QUrl(environ.get("http_proxy", ""))
        QNetworkProxy.setApplicationProxy(
            QNetworkProxy(
                QNetworkProxy.HttpProxy if str(proxy_url.scheme()).startswith("http") else QNetworkProxy.Socks5Proxy,
                proxy_url.host(),
                proxy_url.port(),
                proxy_url.userName(),
                proxy_url.password(),
            )
        ) if "http_proxy" in environ else None
        print((" INFO: Proxy Auto-Config as " + str(proxy_url)))

        # basic widgets layouts and set up
        self.mainwidget = QTabWidget()
        self.mainwidget.setToolTip(__doc__)
        self.mainwidget.setMovable(True)
        self.mainwidget.setTabShape(QTabWidget.Triangular)
        self.mainwidget.setTabsClosable(True)
        self.mainwidget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.mainwidget.tabCloseRequested.connect(
            lambda: self.mainwidget.setTabPosition(1)
            if self.mainwidget.tabPosition() == 0
            else self.mainwidget.setTabPosition(0)
        )
        self.setCentralWidget(self.mainwidget)
        self.dock1 = QDockWidget()
        self.dock2 = QDockWidget()
        self.dock3 = QDockWidget()
        for a in (self.dock1, self.dock2, self.dock3):
            a.setWindowModality(Qt.NonModal)
            a.setWindowOpacity(0.9)
            a.setWindowTitle(__doc__ if a.windowTitle() == "" else a.windowTitle())
            a.setStyleSheet(" QDockWidget::title{text-align:center;}")
            a.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable)
            self.mainwidget.addTab(a, QIcon.fromTheme("face-cool"), str(a.windowTitle()).strip().lower())

        # Paleta de colores para pintar transparente
        self.palette().setBrush(QPalette.Base, Qt.transparent)
        self.setPalette(self.palette())
        self.setAttribute(Qt.WA_OpaquePaintEvent, False)

        # toolbar and basic actions
        self.toolbar = QToolBar(self)
        self.toolbar.setIconSize(QSize(24, 24))
        # spacer widget for left
        self.left_spacer = QWidget(self)
        self.left_spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        # spacer widget for right
        self.right_spacer = QWidget(self)
        self.right_spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        qaqq = QAction(QIcon.fromTheme("application-exit"), "Quit", self)
        qaqq.setShortcut("Ctrl+Q")
        qaqq.triggered.connect(exit)
        qamin = QAction(QIcon.fromTheme("go-down"), "Minimize", self)
        qamin.triggered.connect(lambda: self.showMinimized())
        qamax = QAction(QIcon.fromTheme("go-up"), "Maximize", self)
        qanor = QAction(QIcon.fromTheme("go-up"), "AutoCenter AutoResize", self)
        qanor.triggered.connect(self.center)
        qatim = QAction(QIcon.fromTheme("go-up"), "View Date and Time", self)
        qatim.triggered.connect(self.timedate)
        qabug = QAction(QIcon.fromTheme("help-about"), "Report a Problem", self)
        qabug.triggered.connect(
            lambda: qabug.setDisabled(True)
            if not call("xdg-open mailto:" + "*****@*****.**".decode("rot13"), shell=True)
            else " ERROR "
        )
        qamax.triggered.connect(lambda: self.showMaximized())
        qaqt = QAction(QIcon.fromTheme("help-about"), "About Qt", self)
        qaqt.triggered.connect(lambda: QMessageBox.aboutQt(self))
        qaslf = QAction(QIcon.fromTheme("help-about"), "About Self", self)
        qaslf.triggered.connect(
            lambda: QMessageBox.about(
                self.mainwidget,
                __doc__,
                "".join(
                    (
                        __doc__,
                        linesep,
                        "version ",
                        __version__,
                        ", (",
                        __license__,
                        "), by ",
                        __author__,
                        ", ( ",
                        __email__,
                        " )",
                        linesep,
                    )
                ),
            )
        )
        qasrc = QAction(QIcon.fromTheme("applications-development"), "View Source Code", self)
        qasrc.triggered.connect(lambda: call("xdg-open " + __file__, shell=1))
        qakb = QAction(QIcon.fromTheme("input-keyboard"), "Keyboard Shortcuts", self)
        qakb.triggered.connect(
            lambda: QMessageBox.information(self.mainwidget, "Keyboard Shortcuts", " Ctrl+Q = Quit ")
        )
        qapic = QAction(QIcon.fromTheme("camera-photo"), "Take a Screenshot", self)
        qapic.triggered.connect(
            lambda: QPixmap.grabWindow(QApplication.desktop().winId()).save(
                QFileDialog.getSaveFileName(
                    self.mainwidget, " Save Screenshot As ...", path.expanduser("~"), ";;(*.png) PNG", "png"
                )
            )
        )
        qatb = QAction(QIcon.fromTheme("help-browser"), "Toggle ToolBar", self)
        qatb.triggered.connect(lambda: self.toolbar.hide() if self.toolbar.isVisible() is True else self.toolbar.show())
        qati = QAction(QIcon.fromTheme("help-browser"), "Switch ToolBar Icon Size", self)
        qati.triggered.connect(
            lambda: self.toolbar.setIconSize(self.toolbar.iconSize() * 4)
            if self.toolbar.iconSize().width() * 4 == 24
            else self.toolbar.setIconSize(self.toolbar.iconSize() / 4)
        )
        qasb = QAction(QIcon.fromTheme("help-browser"), "Toggle Tabs Bar", self)
        qasb.triggered.connect(
            lambda: self.mainwidget.tabBar().hide()
            if self.mainwidget.tabBar().isVisible() is True
            else self.mainwidget.tabBar().show()
        )
        qadoc = QAction(QIcon.fromTheme("help-browser"), "On-line Docs", self)
        qadoc.triggered.connect(lambda: open_new_tab(__url__))
        qapy = QAction(QIcon.fromTheme("help-browser"), "About Python", self)
        qapy.triggered.connect(lambda: open_new_tab("http://python.org/about"))
        qali = QAction(QIcon.fromTheme("help-browser"), "Read Licence", self)
        qali.triggered.connect(lambda: open_new_tab(__full_licence__))
        qacol = QAction(QIcon.fromTheme("preferences-system"), "Set GUI Colors", self)
        qacol.triggered.connect(
            lambda: self.setStyleSheet(
                """ * {
                background-color: %s } """
                % QColorDialog.getColor().name()
            )
        )
        qatit = QAction(QIcon.fromTheme("preferences-system"), "Set the App Window Title", self)
        qatit.triggered.connect(self.seTitle)
        qafnt = QAction(QIcon.fromTheme("help-about"), "Set GUI Font", self)
        if KDE:
            font = QFont()
            qafnt.triggered.connect(
                lambda: self.setStyleSheet("*{font-family: %s}" % font.toString())
                if KFontDialog.getFont(font)[0] == QDialog.Accepted
                else ""
            )
        else:
            qafnt.triggered.connect(
                lambda: self.setStyleSheet("*{font-family: %s}" % QFontDialog.getFont()[0].toString())
            )
        self.toolbar.addWidget(self.left_spacer)
        self.toolbar.addSeparator()
        for b in (
            qaqq,
            qamin,
            qanor,
            qamax,
            qasrc,
            qakb,
            qacol,
            qatim,
            qatb,
            qati,
            qasb,
            qatit,
            qafnt,
            qapic,
            qadoc,
            qali,
            qaslf,
            qaqt,
            qapy,
            qabug,
        ):
            self.toolbar.addAction(b)
        self.addToolBar(Qt.TopToolBarArea, self.toolbar)
        self.toolbar.addSeparator()
        self.toolbar.addWidget(self.right_spacer)

        def contextMenuRequested(point):
            " quick and dirty custom context menu "
            menu = QMenu()
            menu.addActions(
                (
                    qaqq,
                    qamin,
                    qanor,
                    qamax,
                    qasrc,
                    qakb,
                    qacol,
                    qati,
                    qasb,
                    qatb,
                    qatim,
                    qatit,
                    qafnt,
                    qapic,
                    qadoc,
                    qali,
                    qaslf,
                    qaqt,
                    qapy,
                    qabug,
                )
            )
            menu.exec_(self.mapToGlobal(point))

        self.mainwidget.customContextMenuRequested.connect(contextMenuRequested)

        def must_be_checked(widget_list):
            " widget tuple passed as argument should be checked as ON "
            for each_widget in widget_list:
                try:
                    each_widget.setChecked(True)
                except:
                    pass

        def must_have_tooltip(widget_list):
            " widget tuple passed as argument should have tooltips "
            for each_widget in widget_list:
                try:
                    each_widget.setToolTip(each_widget.text())
                except:
                    each_widget.setToolTip(each_widget.currentText())
                finally:
                    each_widget.setCursor(QCursor(Qt.PointingHandCursor))

        def must_autofillbackground(widget_list):
            " widget tuple passed as argument should have filled background "
            for each_widget in widget_list:
                try:
                    each_widget.setAutoFillBackground(True)
                except:
                    pass

        #######################################################################

        self.group1 = QGroupBox()
        self.group1.setTitle(" Blender ")
        self.arch = QLabel("<center><b>" + architecture()[0])
        self.ost = QLabel("<center><b>" + sys.platform)
        self.downf = QLineEdit(path.join(path.expanduser("~"), "blender"))
        self.downf.setCompleter(self.completer)
        self.borig = QPushButton(QIcon.fromTheme("folder-open"), "Open")
        self.borig.clicked.connect(
            lambda: self.downf.setText(
                path.join(
                    str(QFileDialog.getExistingDirectory(self.mainwidget, "Open a Folder", path.expanduser("~"))),
                    "blender",
                )
            )
        )
        self.bugs = QPushButton(QIcon.fromTheme("help-faq"), "Report Bugs!")
        self.bugs.clicked.connect(lambda: open_new_tab("http://www.blender.org/development/report-a-bug"))
        self.go = QPushButton(QIcon.fromTheme("emblem-favorite"), "Run Blender")
        self.go.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.go.clicked.connect(self.run)
        vboxg1 = QVBoxLayout(self.group1)
        for each_widget in (
            self.go,
            QLabel(""),
            QLabel('<h3 style="color:white;"> Download Folder Path: </h3>'),
            self.downf,
            self.borig,
            QLabel('<h3 style="color:white;"> Bugs: </h3>'),
            self.bugs,
            QLabel('<h3 style="color:white;"> OS: </h3>'),
            self.ost,
            QLabel('<h3 style="color:white;"> Architexture: </h3>'),
            self.arch,
            QLabel(
                """<i style="color:white;"> Warning:
        this builds arent as stable as releases, use at your own risk</i>"""
            ),
        ):
            vboxg1.addWidget(each_widget)

        self.group2 = QGroupBox()
        self.group2.setTitle("Options")
        self.nwfl = QCheckBox("Force opening with borders")
        self.smll = QCheckBox("Auto Center and Auto Resize the Window")
        self.lrgf = QCheckBox("Start with the console window open")
        self.case = QCheckBox("BGE: Run on 50 hertz without dropping frames")
        self.cnvt = QCheckBox("BGE: Use Vertex Arrays for rendering")
        self.blnk = QCheckBox("BGE: No Texture Mipmapping")
        self.spac = QCheckBox("BGE: Linear Texture Mipmap instead of Nearest")
        self.whit = QCheckBox("Turn Debugging ON")
        self.tabz = QCheckBox("Enable floating point exceptions")
        self.sprs = QCheckBox("Disable the crash handler")
        self.filn = QCheckBox("Enable debug messages from FFmpeg library")

        self.plac = QCheckBox("Enable debug messages for python")
        self.plac = QCheckBox("Enable debug messages for the event system")
        self.plac = QCheckBox("Enable debug messages for event handling")
        self.plac = QCheckBox("Enable debug messages for the window manager")

        self.tbs = QComboBox(self.group2)
        self.tbs.addItems(["0", "1", "2", "3"])
        self.nice = QComboBox(self.group2)
        self.nice.addItems(["0", "1", "2", "3"])
        vboxg2 = QVBoxLayout(self.group2)
        for each_widget in (
            self.nwfl,
            self.smll,
            self.lrgf,
            self.case,
            self.cnvt,
            self.blnk,
            self.spac,
            self.whit,
            self.tabz,
            self.sprs,
            self.filn,
            QLabel("BLAH BLAH BLAH"),
            self.tbs,
            QLabel("BLAH BLAH BLAH"),
            self.nice,
        ):
            vboxg2.addWidget(each_widget)

        group3 = QGroupBox()
        group3.setTitle("Even More Options")
        self.plai = QCheckBox("Enable debug messages from libmv library")
        self.nocr = QCheckBox("Skip reading the startup.blend in the home dir")
        self.ridt = QCheckBox("Set BLENDER_SYSTEM_DATAFILES environment var")
        self.nocm = QCheckBox("Set BLENDER_SYSTEM_SCRIPTS environment var")
        self.rdif = QCheckBox("Set BLENDER_SYSTEM_PYTHON environment var")
        self.clip = QCheckBox("Disable joystick support")
        self.noti = QCheckBox("Disable GLSL shading")
        self.pret = QCheckBox("Force sound system to None")
        self.lolz = QCheckBox("Disable automatic python script execution")
        self.odif = QCheckBox("Run blender with an interactive console")

        self.plac = QCheckBox("Enable all debug messages, excludes libmv")
        self.plac = QCheckBox("Enable time profiling for background jobs")
        self.plac = QCheckBox("Do not use native pixel size for high res")

        self.wdth = QComboBox(group3)
        self.wdth.addItems(["OPENAL", "NULL", "SDL", "JACK"])
        self.bcknd = QComboBox(group3)
        self.bcknd.addItems(["0", "5", "10", "15", "20"])
        vboxg3 = QVBoxLayout(group3)
        for each_widget in (
            self.plai,
            self.nocr,
            self.ridt,
            self.nocm,
            self.rdif,
            self.pret,
            self.clip,
            self.noti,
            self.lolz,
            self.odif,
            self.plac,
            QLabel('<b style="color:white">Force sound system to specific device'),
            self.wdth,
            QLabel('<b style="color:white">CPU Priority'),
            self.bcknd,
        ):
            vboxg3.addWidget(each_widget)

        # dock 2 the waterfall
        scrollable = QScrollArea()
        scrollable.setWidget(QLabel("".join((urlopen("http://builder.blender.org/waterfall").readlines()[23:]))))
        self.dock2.setWidget(scrollable)

        # dock 3 the build status
        stats = QLabel(
            "<center>"
            + "".join((urlopen("http://builder.blender.org/one_line_per_build").readlines()[23:])).strip()
            + "</center>"
        )
        self.dock3.setWidget(stats)

        # configure some widget settings
        must_be_checked((self.nwfl, self.smll, self.lrgf, self.clip, self.cnvt, self.plai, self.noti))
        must_have_tooltip(
            (
                self.plai,
                self.nocr,
                self.ridt,
                self.nocm,
                self.rdif,
                self.pret,
                self.clip,
                self.noti,
                self.lolz,
                self.odif,
                self.plac,
                self.wdth,
                self.bcknd,
                self.nwfl,
                self.smll,
                self.lrgf,
                self.case,
                self.cnvt,
                self.blnk,
                self.spac,
                self.whit,
                self.tabz,
                self.sprs,
                self.filn,
                self.tbs,
                self.nice,
                self.arch,
                self.ost,
            )
        )
        must_autofillbackground(
            (
                self.plai,
                self.nocr,
                self.ridt,
                self.nocm,
                self.rdif,
                self.pret,
                self.clip,
                self.noti,
                self.lolz,
                self.odif,
                self.plac,
                self.wdth,
                self.bcknd,
                self.nwfl,
                self.smll,
                self.lrgf,
                self.case,
                self.cnvt,
                self.blnk,
                self.spac,
                self.whit,
                self.tabz,
                self.sprs,
                self.filn,
                self.tbs,
                self.nice,
                scrollable,
                stats,
                self.arch,
                self.ost,
            )
        )

        container = QWidget()
        hbox = QHBoxLayout(container)
        for each_widget in (self.group2, self.group1, group3):
            hbox.addWidget(each_widget)

        self.dock1.setWidget(container)

    def run(self):
        " run the actual conversion "
        print((" INFO: Working at " + str(datetime.now())))
        print(" INFO: Loading Blender awesomeness . . . ")
        self.go.setDisabled(True)
        # create the output directory
        try:
            mkdir(str(self.downf.text()))
            print((" INFO: Preparing Directory " + str(self.downf.text())))
        except:
            print((" INFO: Preparing Directory " + str(self.downf.text())))
        # parse local system architecture
        architecturez = "x86_64" if "64bit" in architecture()[0] else "i686"
        print((" INFO: System Architecture is " + architecturez))
        # parse remote blender filename
        blenderfile = [
            a.strip().lower().replace('<td><a href="', "").replace("</a></td>", "").split('">')[0]
            for a in urlopen("http://builder.blender.org/download/").readlines()[40:80]
            if '<td><a href="blender-' in a and sub("[^a-z]", "", str(sys.platform).lower()) in a and architecturez in a
        ][0]
        print((" INFO: System OS is " + sys.platform))
        print((" INFO: Blender Remote Filename is " + blenderfile))
        if path.isfile(path.join(str(self.downf.text()), blenderfile)):
            print((" INFO: Blender Local Filename is " + blenderfile))
            print(" INFO: Local and Remote Files are similar, Skiping Download")
        else:
            print(" INFO: Local and Remote Files differ, Requesting Download")
            print((" INFO: URL is builder.blender.org/download/" + blenderfile))
            # get the file
            downloader = Downloader(
                self.mainwidget, "http://builder.blender.org/download/" + blenderfile, str(self.downf.text())
            )
            downloader.show()

    ###########################################################################

    def paintEvent(self, event):
        "Paint semi-transparent background, animated pattern, background text"
        # because we are on 2012 !, its time to showcase how Qt we are !
        QWidget.paintEvent(self, event)
        # make a painter
        p = QPainter(self)
        p.setRenderHint(QPainter.TextAntialiasing)
        p.setRenderHint(QPainter.HighQualityAntialiasing)
        # fill a rectangle with transparent painting
        p.fillRect(event.rect(), Qt.transparent)
        # animated random dots background pattern
        for i in range(8192):
            x = randint(9, self.size().width() - 9)
            y = randint(9, self.size().height() - 9)
            p.setPen(QPen(QColor(randint(9, 255), randint(9, 255), 255), 1))
            p.drawPoint(x, y)
        # set pen to use white color
        p.setPen(QPen(QColor(randint(9, 255), randint(9, 255), 255), 1))
        # Rotate painter 45 Degree
        p.rotate(30)
        # Set painter Font for text
        p.setFont(QFont("Ubuntu", 200))
        # draw the background text, with antialiasing
        p.drawText(99, 99, "Blender")
        # Rotate -45 the QPen back !
        p.rotate(-30)
        # set the pen to no pen
        p.setPen(Qt.NoPen)
        # Background Color
        p.setBrush(QColor(0, 0, 0))
        # Background Opacity
        p.setOpacity(0.75)
        # Background Rounded Borders
        p.drawRoundedRect(self.rect(), 50, 50)
        # finalize the painter
        p.end()

    def seTitle(self):
        " set the title of the main window "
        dialog = QDialog(self)
        textEditInput = QLineEdit(" Type Title Here ")
        ok = QPushButton(" O K ")
        ok.clicked.connect(lambda: self.setWindowTitle(textEditInput.text()))
        ly = QVBoxLayout()
        [ly.addWidget(wdgt) for wdgt in (QLabel("Title:"), textEditInput, ok)]
        dialog.setLayout(ly)
        dialog.exec_()

    def timedate(self):
        " get the time and date "
        dialog = QDialog(self)
        clock = QLCDNumber()
        clock.setNumDigits(24)
        timer = QTimer()
        timer.timeout.connect(lambda: clock.display(datetime.now().strftime("%d-%m-%Y %H:%M:%S %p")))
        timer.start(1000)
        clock.setToolTip(datetime.now().strftime("%c %x"))
        ok = QPushButton(" O K ")
        ok.clicked.connect(dialog.close)
        ly = QVBoxLayout()
        [ly.addWidget(wdgt) for wdgt in (QCalendarWidget(), clock, ok)]
        dialog.setLayout(ly)
        dialog.exec_()

    def closeEvent(self, event):
        " Ask to Quit "
        if (
            QMessageBox.question(self, " Close ", " Quit ? ", QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
            == QMessageBox.Yes
        ):
            event.accept()
        else:
            event.ignore()

    def center(self):
        " Center and resize the window "
        self.resize(
            QDesktopWidget().screenGeometry().width() // 1.25, QDesktopWidget().screenGeometry().height() // 1.25
        )
        qr = self.frameGeometry()
        qr.moveCenter(QDesktopWidget().availableGeometry().center())
        self.move(qr.topLeft())
Exemplo n.º 38
0
class SearchPanel(QComboBox):
    def __init__(self, model, parent=None, showTable=False):
        super(SearchPanel, self).__init__(parent)

        self.tabla = None
        self.setFocusPolicy(Qt.StrongFocus)
        self.setEditable(True)
        #        self.setModel( model )
        self.setEditable(True)
        self.completer = QCompleter(self)
        # always show all completions
        self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.pFilterModel = QSortFilterProxyModel(self)
        self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.showTable = showTable

        if model != None:
            self.setModel(model)


#        self.pFilterModel.setSourceModel( model );

        self.completer.setModel(self.pFilterModel)
        self.completerTable = SearchPanelView()
        self.completer.setPopup(self.completerTable)
        #Mostrar el Popup en forma de Tabla
        if self.showTable:
            self.tabla = SearchPanelView()
            self.setView(self.tabla)

        self.setCompleter(self.completer)

        self.setColumn(1)

        self.lineEdit().textEdited[unicode].connect(
            self.pFilterModel.setFilterFixedString if not showTable else self.
            pFilterModel.setFilterWildcard)

    def setModel(self, model):
        QComboBox.setModel(self, model)
        self.pFilterModel.setSourceModel(model)

    def setColumn(self, column):
        self.setModelColumn(1)
        self.completer.setCompletionColumn(column)
        self.pFilterModel.setFilterKeyColumn(column)
        self.setModelColumn(column)

    def view(self):
        return self.completer.popup()

    def data(self):
        return self.currentIndex()

    def index(self):
        return self.currentIndex()

    def setColumnHidden(self, col):
        self.completerTable.hiddenColumns.append(col)
        if self.showTable:
            self.tabla.hiddenColumns.append(col)

    def setMinimumWidth(self, width):
        self.completerTable.setMinimumWidth(width)
        if self.showTable:
            self.tabla.setMinimumWidth(width)
class MyMainWindow(QMainWindow):
    ' Main Window '
    def __init__(self, AUTO):
        ' Initialize QWidget inside MyMainWindow '
        super(MyMainWindow, self).__init__()
        QWidget.__init__(self)
        self.auto = AUTO
        self.statusBar().showMessage('               {}'.format(__doc__))
        self.setStyleSheet('QStatusBar{color:grey;}')
        self.setWindowTitle(__doc__)
        self.setWindowIcon(QIcon.fromTheme("face-monkey"))
        self.setFont(QFont('Ubuntu Light', 10))
        self.setMaximumSize(QDesktopWidget().screenGeometry().width(),
                            QDesktopWidget().screenGeometry().height())

        self.base = path.abspath(path.join(getcwd(), str(datetime.now().year)))

        # directory auto completer
        self.completer = QCompleter(self)
        self.dirs = QDirModel(self)
        self.dirs.setFilter(QDir.AllEntries | QDir.NoDotAndDotDot)
        self.completer.setModel(self.dirs)
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setCompletionMode(QCompleter.PopupCompletion)

        # process
        self.process1 = None
        self.process2 = None
        self.cmd1 = 'nice -n {n} arecord{v} -f {f} -c {c} -r {b} -t raw'
        self.cmd2 = 'oggenc - -r -C {c} -R {b} -q {q} {d}{t}{a} -o {o}'
        self.process3 = QProcess(self)
        #self.process3.finished.connect(self.on_process3_finished)
        #self.process3.error.connect(self.on_process3_error)

        self.cmd3 = ('nice -n 20 ' +
          'sox "{o}" -n spectrogram -x {x} -y {y} -z 99 -t "{o}" -o "{o}.png"')
        self.actual_file = ''

        # re starting timers, one stops, one starts
        self.timerFirst = QTimer(self)
        self.timerFirst.timeout.connect(self.end)
        self.timerSecond = QTimer(self)
        self.timerSecond.timeout.connect(self.run)

        # Proxy support, by reading http_proxy os env variable
        proxy_url = QUrl(environ.get('http_proxy', ''))
        QNetworkProxy.setApplicationProxy(QNetworkProxy(QNetworkProxy.HttpProxy
            if str(proxy_url.scheme()).startswith('http')
            else QNetworkProxy.Socks5Proxy, proxy_url.host(), proxy_url.port(),
                 proxy_url.userName(), proxy_url.password())) \
            if 'http_proxy' in environ else None
        print((' INFO: Proxy Auto-Config as ' + str(proxy_url)))

        # basic widgets layouts and set up
        self.mainwidget = QTabWidget()
        self.mainwidget.setToolTip(__doc__)
        self.mainwidget.setMovable(True)
        self.mainwidget.setTabShape(QTabWidget.Triangular)
        self.mainwidget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.mainwidget.setStyleSheet('QTabBar{color:white;font-weight:bold;}')
        self.mainwidget.setTabBar(TabBar(self))
        self.mainwidget.setTabsClosable(False)
        self.setCentralWidget(self.mainwidget)
        self.dock1 = QDockWidget()
        self.dock2 = QDockWidget()
        self.dock3 = QDockWidget()
        self.dock4 = QDockWidget()
        self.dock5 = QDockWidget()
        for a in (self.dock1, self.dock2, self.dock3, self.dock4, self.dock5):
            a.setWindowModality(Qt.NonModal)
            # a.setWindowOpacity(0.9)
            a.setWindowTitle(__doc__
                             if a.windowTitle() == '' else a.windowTitle())
            a.setStyleSheet('QDockWidget::title{text-align:center;}')
            self.mainwidget.addTab(a, QIcon.fromTheme("face-smile"),
                                   'Double Click Me')

        # Paleta de colores para pintar transparente
        self.palette().setBrush(QPalette.Base, Qt.transparent)
        self.setPalette(self.palette())
        self.setAttribute(Qt.WA_OpaquePaintEvent, False)

        # toolbar and basic actions
        self.toolbar = QToolBar(self)
        self.toolbar.setIconSize(QSize(24, 24))
        # spacer widget for left
        self.left_spacer = QWidget(self)
        self.left_spacer.setSizePolicy(QSizePolicy.Expanding,
                                       QSizePolicy.Expanding)
        # spacer widget for right
        self.right_spacer = QWidget(self)
        self.right_spacer.setSizePolicy(QSizePolicy.Expanding,
                                        QSizePolicy.Expanding)
        qaqq = QAction(QIcon.fromTheme("application-exit"), 'Quit', self)
        qaqq.setShortcut('Ctrl+Q')
        qaqq.triggered.connect(exit)
        qamin = QAction(QIcon.fromTheme("go-down"), 'Minimize', self)
        qamin.triggered.connect(lambda: self.showMinimized())
        qamax = QAction(QIcon.fromTheme("go-up"), 'Maximize', self)
        qanor = QAction(QIcon.fromTheme("view-fullscreen"),
                        'AutoCenter AutoResize', self)
        qanor.triggered.connect(self.center)
        qatim = QAction(QIcon.fromTheme("mail-signed-verified"),
                        'View Date and Time', self)
        qatim.triggered.connect(self.timedate)
        qabug = QAction(QIcon.fromTheme("help-about"), 'Report a Problem', self)
        qabug.triggered.connect(lambda: qabug.setDisabled(True) if not call(
            'xdg-open mailto:' + '*****@*****.**'.decode('rot13'),
            shell=True) else ' ERROR ')
        qamax.triggered.connect(lambda: self.showMaximized())
        qaqt = QAction(QIcon.fromTheme("help-about"), 'About Qt', self)
        qaqt.triggered.connect(lambda: QMessageBox.aboutQt(self))
        qakde = QAction(QIcon.fromTheme("help-about"), 'About KDE', self)
        if KDE:
            qakde.triggered.connect(KHelpMenu(self, "", False).aboutKDE)
        qaslf = QAction(QIcon.fromTheme("help-about"), 'About Self', self)
        if KDE:
            qaslf.triggered.connect(
                                KAboutApplicationDialog(aboutData, self).exec_)
        else:
            qaslf.triggered.connect(lambda: QMessageBox.about(self.mainwidget,
            __doc__, ''.join((__doc__, linesep, 'version ', __version__, ', (',
            __license__, '), by ', __author__, ', ( ', __email__, ' )', linesep
            ))))
        qafnt = QAction(QIcon.fromTheme("tools-check-spelling"),
                        'Set GUI Font', self)
        if KDE:
            font = QFont()
            qafnt.triggered.connect(lambda:
            self.setStyleSheet(''.join((
                '*{font-family:', str(font.toString()), '}'))
                if KFontDialog.getFont(font)[0] == QDialog.Accepted else ''))
        else:
            qafnt.triggered.connect(lambda:
                self.setStyleSheet(''.join(('*{font-family:',
                            str(QFontDialog.getFont()[0].toString()), '}'))))
        qasrc = QAction(QIcon.fromTheme("applications-development"),
                        'View Source Code', self)
        qasrc.triggered.connect(lambda:
                            call('xdg-open {}'.format(__file__), shell=True))
        qakb = QAction(QIcon.fromTheme("input-keyboard"),
                       'Keyboard Shortcuts', self)
        qakb.triggered.connect(lambda: QMessageBox.information(self.mainwidget,
                               'Keyboard Shortcuts', ' Ctrl+Q = Quit '))
        qapic = QAction(QIcon.fromTheme("camera-photo"),
                        'Take a Screenshot', self)
        qapic.triggered.connect(lambda: QPixmap.grabWindow(
            QApplication.desktop().winId()).save(QFileDialog.getSaveFileName(
            self.mainwidget, " Save Screenshot As ...", path.expanduser("~"),
            ';;(*.png) PNG', 'png')))
        qatb = QAction(QIcon.fromTheme("go-top"), 'Toggle ToolBar', self)
        qatb.triggered.connect(lambda: self.toolbar.hide()
                if self.toolbar.isVisible() is True else self.toolbar.show())
        qati = QAction(QIcon.fromTheme("zoom-in"),
                       'Switch ToolBar Icon Size', self)
        qati.triggered.connect(lambda:
            self.toolbar.setIconSize(self.toolbar.iconSize() * 4)
            if self.toolbar.iconSize().width() * 4 == 24
            else self.toolbar.setIconSize(self.toolbar.iconSize() / 4))
        qasb = QAction(QIcon.fromTheme("preferences-other"),
                       'Toggle Tabs Bar', self)
        qasb.triggered.connect(lambda: self.mainwidget.tabBar().hide()
                               if self.mainwidget.tabBar().isVisible() is True
                               else self.mainwidget.tabBar().show())
        qadoc = QAction(QIcon.fromTheme("help-browser"), 'On-line Docs', self)
        qadoc.triggered.connect(lambda: open_new_tab(str(__url__).strip()))
        qapy = QAction(QIcon.fromTheme("help-about"), 'About Python', self)
        qapy.triggered.connect(lambda: open_new_tab('http://python.org/about'))
        qali = QAction(QIcon.fromTheme("help-browser"), 'Read Licence', self)
        qali.triggered.connect(lambda: open_new_tab(__full_licence__))
        qacol = QAction(QIcon.fromTheme("preferences-system"), 'Set GUI Colors',
                        self)
        if KDE:
            color = QColor()
            qacol.triggered.connect(lambda:
                self.setStyleSheet(''.join(('* { background-color: ',
                                            str(color.name()), '}')))
                if KColorDialog.getColor(color, self) else '')
        else:
            qacol.triggered.connect(lambda: self.setStyleSheet(''.join((
                ' * { background-color: ', str(QColorDialog.getColor().name()),
                ' } '))))
        qatit = QAction(QIcon.fromTheme("preferences-system"),
                        'Set the App Window Title', self)
        qatit.triggered.connect(self.seTitle)
        self.toolbar.addWidget(self.left_spacer)
        self.toolbar.addSeparator()
        self.toolbar.addActions((qaqq, qamin, qanor, qamax, qasrc, qakb, qacol,
            qatim, qatb, qafnt, qati, qasb, qatit, qapic, qadoc, qali, qaslf,
            qaqt, qakde, qapy, qabug))
        self.addToolBar(Qt.TopToolBarArea, self.toolbar)
        self.toolbar.addSeparator()
        self.toolbar.addWidget(self.right_spacer)
        # define the menu
        menu = self.menuBar()
        # File menu items
        menu.addMenu('&File').addActions((qaqq, ))
        menu.addMenu('&Window').addActions((qamax, qanor, qamin))
        # Settings menu
        menu.addMenu('&Settings').addActions((qasrc, qacol, qafnt, qatim,
                                              qatb, qati, qasb, qapic))
        # Help menu items
        menu.addMenu('&Help').addActions((qadoc, qakb, qabug, qali,
                                          qaqt, qakde, qapy, qaslf))
        # Tray Icon
        tray = QSystemTrayIcon(QIcon.fromTheme("face-devilish"), self)
        tray.setToolTip(__doc__)
        traymenu = QMenu()
        traymenu.addActions((qamax, qanor, qamin, qaqq))
        tray.setContextMenu(traymenu)
        tray.show()

        def contextMenuRequested(point):
            ' quick and dirty custom context menu '
            menu = QMenu()
            menu.addActions((qaqq, qamin, qanor, qamax, qasrc, qakb, qacol,
                qafnt, qati, qasb, qatb, qatim, qatit, qapic, qadoc, qali,
                qaslf, qaqt, qakde, qapy, qabug))
            menu.exec_(self.mapToGlobal(point))
        self.mainwidget.customContextMenuRequested.connect(contextMenuRequested)

        def must_be_checked(widget_list):
            ' widget tuple passed as argument should be checked as ON '
            for each_widget in widget_list:
                try:
                    each_widget.setChecked(True)
                except:
                    pass

        def must_have_tooltip(widget_list):
            ' widget tuple passed as argument should have tooltips '
            for each_widget in widget_list:
                try:
                    each_widget.setToolTip(each_widget.text())
                except:
                    each_widget.setToolTip(each_widget.currentText())
                finally:
                    each_widget.setCursor(QCursor(Qt.PointingHandCursor))

        def must_autofillbackground(widget_list):
            ' widget tuple passed as argument should have filled background '
            for each_widget in widget_list:
                try:
                    each_widget.setAutoFillBackground(True)
                except:
                    pass

        def must_glow(widget_list):
            ' apply an glow effect to the widget '
            for glow, each_widget in enumerate(widget_list):
                try:
                    if each_widget.graphicsEffect() is None:
                        glow = QGraphicsDropShadowEffect(self)
                        glow.setOffset(0)
                        glow.setBlurRadius(99)
                        glow.setColor(QColor(99, 255, 255))
                        each_widget.setGraphicsEffect(glow)
                        # glow.setEnabled(False)
                        try:
                            each_widget.clicked.connect(lambda:
                            each_widget.graphicsEffect().setEnabled(True)
                            if each_widget.graphicsEffect().isEnabled() is False
                            else each_widget.graphicsEffect().setEnabled(False))
                        except:
                            each_widget.sliderPressed.connect(lambda:
                            each_widget.graphicsEffect().setEnabled(True)
                            if each_widget.graphicsEffect().isEnabled() is False
                            else each_widget.graphicsEffect().setEnabled(False))
                except:
                    pass

        #######################################################################

        # dock 1
        QLabel('<h1 style="color:white;"> Record !</h1>', self.dock1).resize(
               self.dock3.size().width() / 4, 25)
        self.group1 = QGroupBox()
        self.group1.setTitle(__doc__)

        self.spec = QPushButton(self)
        self.spec.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.spec.setMinimumSize(self.spec.size().width(), 250)
        self.spec.setFlat(True)
        self.spec.clicked.connect(self.spectro)

        self.clock = QLCDNumber()
        self.clock.setSegmentStyle(QLCDNumber.Flat)
        self.clock.setMinimumSize(self.clock.size().width(), 50)
        self.clock.setNumDigits(25)
        self.timer1 = QTimer(self)
        self.timer1.timeout.connect(lambda: self.clock.display(
            datetime.now().strftime("%d-%m-%Y %H:%M:%S %p")))
        self.timer1.start(1000)
        self.clock.setToolTip(datetime.now().strftime("%c %x"))
        self.clock.setCursor(QCursor(Qt.CrossCursor))

        self.diskBar = QProgressBar()
        self.diskBar.setMinimum(0)
        self.diskBar.setMaximum(statvfs(HOME).f_blocks *
            statvfs(HOME).f_frsize / 1024 / 1024 / 1024)
        self.diskBar.setValue(statvfs(HOME).f_bfree *
            statvfs(HOME).f_frsize / 1024 / 1024 / 1024)
        self.diskBar.setToolTip(str(statvfs(HOME).f_bfree *
            statvfs(HOME).f_frsize / 1024 / 1024 / 1024) + ' Gigabytes free')

        self.feedback = QPlainTextEdit(''.join(('<center><h3>', __doc__,
            ', version', __version__, __license__, ' <br> by ', __author__,
            ' <i>(Dev)</i>, Radio Comunitaria FM Reconquista <i>(Q.A.)</i><br>',
            'FMReconquista.org.ar & GitHub.com/JuanCarlosPaco/Cinta-Testigo')))

        self.rec = QPushButton(QIcon.fromTheme("media-record"), 'Record')
        self.rec.setMinimumSize(self.rec.size().width(), 50)
        self.rec.clicked.connect(self.go)  # self.run

        self.stop = QPushButton(QIcon.fromTheme("media-playback-stop"), 'Stop')
        self.stop.clicked.connect(self.end)

        self.kill = QPushButton(QIcon.fromTheme("process-stop"), 'Kill')
        self.kill.clicked.connect(self.killer)

        vboxg1 = QVBoxLayout(self.group1)
        for each_widget in (
            QLabel('<b style="color:white;"> Spectro'), self.spec,
            QLabel('<b style="color:white;"> Time '), self.clock,
            QLabel('<b style="color:white;"> Disk '), self.diskBar,
            QLabel('<b style="color:white;"> STDOUT + STDIN '), self.feedback,
            QLabel('<b style="color:white;"> Record '), self.rec, self.stop,
            self.kill):
            vboxg1.addWidget(each_widget)

        self.group2 = QGroupBox()
        self.group2.setTitle(__doc__)

        self.slider = QSlider(self)
        self.slid_l = QLabel(self.slider)
        self.slider.setCursor(QCursor(Qt.OpenHandCursor))
        self.slider.sliderPressed.connect(lambda:
                            self.slider.setCursor(QCursor(Qt.ClosedHandCursor)))
        self.slider.sliderReleased.connect(lambda:
                            self.slider.setCursor(QCursor(Qt.OpenHandCursor)))
        self.slider.valueChanged.connect(lambda:
                            self.slider.setToolTip(str(self.slider.value())))
        self.slider.valueChanged.connect(lambda: self.slid_l.setText(
                    '<h2 style="color:white;">{}'.format(self.slider.value())))
        self.slider.setMinimum(10)
        self.slider.setMaximum(99)
        self.slider.setValue(30)
        self.slider.setOrientation(Qt.Vertical)
        self.slider.setTickPosition(QSlider.TicksBothSides)
        self.slider.setTickInterval(2)
        self.slider.setSingleStep(10)
        self.slider.setPageStep(10)

        vboxg2 = QVBoxLayout(self.group2)
        for each_widget in (
            QLabel('<b style="color:white;">MINUTES of recording'), self.slider,
            QLabel('<b style="color:white;"> Default: 30 Min')):
            vboxg2.addWidget(each_widget)

        group3 = QGroupBox()
        group3.setTitle(__doc__)
        try:
            self.label2 = QLabel(getoutput('sox --version', shell=True))
            self.label4 = QLabel(getoutput('arecord --version', shell=1)[:25])
            self.label6 = QLabel(str(getoutput('oggenc --version', shell=True)))
        except:
            print(''' ERROR: No SOX, OGGenc avaliable !
                  ( sudo apt-get install vorbis-tools sox alsa-utils ) ''')
            exit()

        self.button5 = QPushButton(QIcon.fromTheme("audio-x-generic"),
                                   'OGG --> ZIP')
        self.button5.clicked.connect(lambda: make_archive(
            str(QFileDialog.getSaveFileName(self, "Save OGG to ZIP file As...",
            getcwd(), ';;(*.zip)', 'zip')).replace('.zip', ''), "zip",
            path.abspath(path.join(getcwd(), str(datetime.now().year)))))

        self.button1 = QPushButton(QIcon.fromTheme("folder-open"), 'Files')
        self.button1.clicked.connect(lambda:
                                     call('xdg-open ' + getcwd(), shell=True))

        self.button0 = QPushButton(
            QIcon.fromTheme("preferences-desktop-screensaver"), 'LCD OFF')
        self.button0.clicked.connect(lambda:
            call('sleep 3 ; xset dpms force off', shell=True))

        vboxg3 = QVBoxLayout(group3)
        for each_widget in (
            QLabel('<b style="color:white;"> OGG Output Codec '), self.label6,
            QLabel('<b style="color:white;"> Raw Record Backend '), self.label4,
            QLabel('<b style="color:white;"> Helper Libs '), self.label2,
            QLabel('<b style="color:white;"> OGG ZIP '), self.button5,
            QLabel('<b style="color:white;"> Files '), self.button1,
            QLabel('<b style="color:white;"> LCD '), self.button0):
            vboxg3.addWidget(each_widget)
        container = QWidget()
        hbox = QHBoxLayout(container)
        for each_widget in (self.group2, self.group1, group3):
            hbox.addWidget(each_widget)
        self.dock1.setWidget(container)

        # dock 2
        QLabel('<h1 style="color:white;"> Hardware !</h1>', self.dock2).resize(
               self.dock2.size().width() / 4, 25)
        try:
            audioDriverStr = {Solid.AudioInterface.Alsa: "ALSA",
                Solid.AudioInterface.OpenSoundSystem: "Open Sound",
                Solid.AudioInterface.UnknownAudioDriver: "Unknown?"}
            audioInterfaceTypeStr = {
                Solid.AudioInterface.AudioControl: "Control",
                Solid.AudioInterface.UnknownAudioInterfaceType: "Unknown?",
                Solid.AudioInterface.AudioInput: "In",
                Solid.AudioInterface.AudioOutput: "Out"}
            soundcardTypeStr = {
                Solid.AudioInterface.InternalSoundcard: "Internal",
                Solid.AudioInterface.UsbSoundcard: "USB3",
                Solid.AudioInterface.FirewireSoundcard: "FireWire",
                Solid.AudioInterface.Headset: "Headsets",
                Solid.AudioInterface.Modem: "Modem"}
            display = QTreeWidget()
            display.setAlternatingRowColors(True)
            display.setHeaderLabels(["Items", "ID", "Drivers", "I / O", "Type"])
            display.setColumnWidth(0, 350)
            display.setColumnWidth(1, 350)
            display.setColumnWidth(3, 75)
            # retrieve a list of Solid.Device for this machine
            deviceList = Solid.Device.allDevices()
            # filter the list of all devices and display matching results
            # note that we never create a Solid.AudioInterface object, but
            # receive one from the 'asDeviceInterface' call
            for device in deviceList:
                if device.isDeviceInterface(
                                         Solid.DeviceInterface.AudioInterface):
                    audio = device.asDeviceInterface(
                            Solid.DeviceInterface.AudioInterface)
                    devtype = audio.deviceType()
                    devstr = []
                    for key in audioInterfaceTypeStr:
                        flag = key & devtype
                        if flag:
                            devstr.append(audioInterfaceTypeStr[key])
                    QTreeWidgetItem(display, [device.product(), audio.name(),
                        audioDriverStr[audio.driver()], "/".join(devstr),
                        soundcardTypeStr[audio.soundcardType()]])
            self.dock2.setWidget(display)
        except:
            self.dock2.setWidget(QLabel(""" <center style='color:white;'>
            <h1>:(<br>ERROR: Please, install PyKDE !</h1><br>
            <br><i> (Sorry, can not use non-Qt Libs). Thanks </i><center>"""))

        ## dock 3
        QLabel('<h1 style="color:white;"> Previews !</h1>', self.dock3).resize(
               self.dock3.size().width() / 4, 25)
        self.fileView = QColumnView()
        self.fileView.updatePreviewWidget.connect(self.play)
        self.fileView.setToolTip(' Browse and Preview Files ')
        self.media = None
        self.model = QDirModel()
        self.fileView.setModel(self.model)
        self.dock3.setWidget(self.fileView)

        # dock4
        QLabel('<h1 style="color:white;"> Setup !</h1>', self.dock4).resize(
               self.dock4.size().width() / 4, 25)
        self.group4 = QGroupBox()
        self.group4.setTitle(__doc__)

        self.combo0 = QComboBox()
        self.combo0.addItems(['S16_LE', 'S32_LE', 'S16_BE', 'U16_LE', 'U16_BE',
          'S24_LE', 'S24_BE', 'U24_LE', 'U24_BE', 'S32_BE', 'U32_LE', 'U32_BE'])

        self.combo1 = QComboBox()
        self.combo1.addItems(['1', '-1', '0', '2', '3', '4',
                              '5', '6', '7', '8', '9', '10'])

        self.combo2 = QComboBox()
        self.combo2.addItems(['128', '256', '512', '1024', '64', '32', '16'])

        self.combo3 = QComboBox(self)
        self.combo3.addItems(['MONO', 'STEREO', 'Surround'])

        self.combo4 = QComboBox()
        self.combo4.addItems(['44100', '96000', '48000', '32000',
                              '22050', '16000', '11025', '8000'])

        self.combo5 = QComboBox(self)
        self.combo5.addItems(['20', '19', '18', '17', '16', '15', '14', '13',
            '12', '10', '9', '8', '7', '6', '5', '4', '3', '2', '1', '0'])

        self.nepochoose = QCheckBox('Auto-Tag Files using Nepomuk Semantic')

        self.chckbx0 = QCheckBox('Disable Software based Volume Control')

        self.chckbx1 = QCheckBox('Output Sound Stereo-to-Mono Downmix')

        self.chckbx2 = QCheckBox('Add Date and Time MetaData to Sound files')

        self.chckbx3 = QCheckBox('Add Yourself as the Author Artist of Sound')

        vboxg4 = QVBoxLayout(self.group4)
        for each_widget in (
            QLabel('<b style="color:white;"> Sound OGG Quality'), self.combo1,
            QLabel('<b style="color:white;"> Sound Record Format'), self.combo0,
            QLabel('<b style="color:white;"> Sound KBps '), self.combo2,
            QLabel('<b style="color:white;"> Sound Channels '), self.combo3,
            QLabel('<b style="color:white;"> Sound Sample Rate '), self.combo4,
            QLabel('<b style="color:white;"> Sound Volume'), self.chckbx0,
            QLabel('<b style="color:white;"> Sound Mix'), self.chckbx1,
            QLabel('<b style="color:white;"> Sound Meta'), self.chckbx2,
            QLabel('<b style="color:white;"> Sound Authorship'), self.chckbx3,
            QLabel('<b style="color:white;"> CPUs Priority'), self.combo5,
            QLabel('<b style="color:white;">Nepomuk Semantic User Experience'),
            self.nepochoose):
            vboxg4.addWidget(each_widget)
        self.dock4.setWidget(self.group4)

        # dock 5
        QLabel('<h1 style="color:white;"> Voice Changer ! </h1>', self.dock5
               ).resize(self.dock5.size().width() / 3, 25)
        self.group5 = QGroupBox()
        self.group5.setTitle(__doc__)

        self.dial = QDial()
        self.dial.setCursor(QCursor(Qt.OpenHandCursor))
        self.di_l = QLabel(self.dial)
        self.di_l.resize(self.dial.size() / 8)
        self.dial.sliderPressed.connect(lambda:
                            self.dial.setCursor(QCursor(Qt.ClosedHandCursor)))
        self.dial.sliderReleased.connect(lambda:
                            self.dial.setCursor(QCursor(Qt.OpenHandCursor)))
        self.dial.valueChanged.connect(lambda:
                            self.dial.setToolTip(str(self.dial.value())))
        self.dial.valueChanged.connect(lambda: self.di_l.setText(
                    '<h1 style="color:white;">{}'.format(self.dial.value())))
        self.dial.setValue(0)
        self.dial.setMinimum(-999)
        self.dial.setMaximum(999)
        self.dial.setSingleStep(100)
        self.dial.setPageStep(100)
        self.dial.setWrapping(False)
        self.dial.setNotchesVisible(True)

        self.defo = QPushButton(QIcon.fromTheme("media-playback-start"), 'Run')
        self.defo.setMinimumSize(self.defo.size().width(), 50)
        self.defo.clicked.connect(lambda: self.process3.start(
            'play -q -V0 "|rec -q -V0 -n -d -R riaa pitch {} "'
            .format(self.dial.value()) if int(self.dial.value()) != 0 else
            'play -q -V0 "|rec -q -V0 --multi-threaded -n -d -R bend {} "'
            .format(' 3,2500,3 3,-2500,3 ' * 999)))

        self.qq = QPushButton(QIcon.fromTheme("media-playback-stop"), 'Stop')
        self.qq.clicked.connect(self.process3.kill)

        self.die = QPushButton(QIcon.fromTheme("process-stop"), 'Kill')
        self.die.clicked.connect(lambda: call('killall rec', shell=True))

        vboxg5 = QVBoxLayout(self.group5)
        for each_widget in (self.dial, self.defo, self.qq, self.die):
            vboxg5.addWidget(each_widget)
        self.dock5.setWidget(self.group5)

        # configure some widget settings
        must_be_checked((self.nepochoose, self.chckbx1,
                         self.chckbx2, self.chckbx3))
        must_have_tooltip((self.label2, self.label4, self.label6, self.combo0,
            self.nepochoose, self.combo1, self.combo2, self.combo3, self.combo4,
            self.combo5, self.chckbx0, self.chckbx1, self.chckbx2, self.chckbx3,
            self.rec, self.stop, self.defo, self.qq, self.die, self.kill,
            self.button0, self.button1, self.button5))
        must_autofillbackground((self.clock, self.label2, self.label4,
            self.label6, self.nepochoose, self.chckbx0, self.chckbx1,
            self.chckbx2, self.chckbx3))
        must_glow((self.rec, self.dial, self.combo1))
        self.nepomuk_get('testigo')
        if self.auto is True:
            self.go()

    def play(self, index):
        ' play with delay '
        if not self.media:
            self.media = Phonon.MediaObject(self)
            audioOutput = Phonon.AudioOutput(Phonon.MusicCategory, self)
            Phonon.createPath(self.media, audioOutput)
        self.media.setCurrentSource(Phonon.MediaSource(
            self.model.filePath(index)))
        self.media.play()

    def end(self):
        ' kill it with fire '
        print((' INFO: Stoping Processes at {}'.format(str(datetime.now()))))
        self.process1.terminate()
        self.process2.terminate()
        self.feedback.setText('''
            <h5>Errors for RECORDER QProcess 1:</h5>{}<hr>
            <h5>Errors for ENCODER QProcess 2:</h5>{}<hr>
            <h5>Output for RECORDER QProcess 1:</h5>{}<hr>
            <h5>Output for ENCODER QProcess 2:</h5>{}<hr>
            '''.format(self.process1.readAllStandardError(),
                       self.process2.readAllStandardError(),
                       self.process1.readAllStandardOutput(),
                       self.process2.readAllStandardOutput(),
        ))

    def killer(self):
        ' kill -9 '
        QMessageBox.information(self.mainwidget, __doc__,
            ' KILL -9 was sent to the multi-process backend ! ')
        self.process1.kill()
        self.process2.kill()

    def go(self):
        ' run timeout re-starting timers '
        self.timerFirst.start(int(self.slider.value()) * 60 * 1000 + 2000)
        self.timerSecond.start(int(self.slider.value()) * 60 * 1000 + 2010)
        self.run()

    def run(self):
        ' run forest run '
        print((' INFO: Working at {}'.format(str(datetime.now()))))

        chnl = 1 if self.combo3.currentText() == 'MONO' else 2
        print((' INFO: Using {} Channels . . . '.format(chnl)))

        btrt = int(self.combo4.currentText())
        print((' INFO: Using {} Hz per Second . . . '.format(btrt)))

        threshold = int(self.dial.value())
        print((' INFO: Using Thresold of {} . . . '.format(threshold)))

        print((' INFO: Using Recording time of {}'.format(self.slider.value())))

        frmt = str(self.combo0.currentText()).strip()
        print((' INFO: Using Recording quality of {} ...'.format(frmt)))

        qlt = str(self.combo1.currentText()).strip()
        print((' INFO: Using Recording quality of {} ...'.format(qlt)))

        prio = str(self.combo5.currentText()).strip()
        print((' INFO: Using CPU Priority of {} ...'.format(prio)))

        downmix = '--downmix ' if self.chckbx1.isChecked() is True else ''
        print((' INFO: Using Downmix is {} ...'.format(downmix)))

        aut = '-a ' + getuser() if self.chckbx3.isChecked() is True else ''
        print((' INFO: The Author Artist of this sound is: {}'.format(aut)))

        T = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
        tim = '--date {} '.format(T) if self.chckbx2.isChecked() is True else ''
        print((' INFO: The Date and Time of this sound is: {}'.format(tim)))

        vol = ' --disable-softvol' if self.chckbx0.isChecked() is True else ''
        print((' INFO: Software based Volume Control is: {}'.format(vol)))

        # make base directory
        try:
            mkdir(self.base)
            print((' INFO: Base Directory path created {}'.format(self.base)))
        except OSError:
            print((' INFO: Base Directory already exist {}'.format(self.base)))
        except:
            print((' ERROR: Can not create Directory ?, {}'.format(self.base)))

        # make directory tree
        try:
            for dr in range(1, 13):
                mkdir(path.abspath(path.join(self.base, str(dr))))
                print((' INFO:Directory created {}/{}'.format(self.base, dr)))
        except OSError:
            print((' INFO: Directory already exist {}/1,12'.format(self.base)))
        except:
            print((' ERROR: Cant create Directory?, {}/1,12'.format(self.base)))

        # make new filename
        flnm = path.abspath(path.join(self.base, str(datetime.now().month),
                   datetime.now().strftime("%Y-%m-%d_%H:%M:%S.ogg")))
        self.actual_file = flnm
        print((' INFO: Recording on the file {}'.format(flnm)))

        # make custom commands
        cmd1 = self.cmd1.format(n=prio, f=frmt, c=chnl, b=btrt, v=vol)
        cmd2 = self.cmd2.format(c=chnl, b=btrt, q=qlt,
                                d=downmix, o=flnm, a=aut, t=tim)
        print((cmd1, cmd2))
        #  multiprocess recording loop pipe
        self.process1 = QProcess(self)
        self.process2 = QProcess(self)
        self.process1.setStandardOutputProcess(self.process2)
        self.process1.start(cmd1)
        if not self.process1.waitForStarted():
            print((" ERROR: RECORDER QProcess 1 Failed: \n {}   ".format(cmd1)))
        self.process2.start(cmd2)
        if not self.process2.waitForStarted():
            print((" ERROR: ENCODER QProcess 2 Failed: \n   {} ".format(cmd2)))
        self.nepomuk_set(flnm, 'testigo', 'testigo', 'AutoTag by Cinta-Testigo')

    def spectro(self):
        ' spectrometer '
        wid = self.spec.size().width()
        hei = self.spec.size().height()
        command = self.cmd3.format(o=self.actual_file, x=wid, y=hei)
        print(' INFO: Spectrometer is deleting OLD .ogg.png Files on target ')
        call('rm --verbose --force {}/*/*.ogg.png'.format(self.base), shell=1)
        print(' INFO: Spectrometer finished Deleting Files, Starting Render ')
        call(command, shell=True)
        print((''' INFO: Spectrometer finished Rendering Sound using:
               {}{}   OutPut: {}'''.format(command, linesep, self.actual_file)))
        self.spec.setIcon(QIcon('{o}.png'.format(o=self.actual_file)))
        self.spec.setIconSize(QSize(wid, hei))
        self.spec.resize(wid, hei)

    ###########################################################################

    def paintEvent(self, event):
        'Paint semi-transparent background, animated pattern, background text'
        QWidget.paintEvent(self, event)
        # make a painter
        p = QPainter(self)
        p.setRenderHint(QPainter.TextAntialiasing)
        p.setRenderHint(QPainter.HighQualityAntialiasing)
        # fill a rectangle with transparent painting
        p.fillRect(event.rect(), Qt.transparent)
        # animated random dots background pattern
        for i in range(4096):
            x = randint(9, self.size().width() - 9)
            y = randint(9, self.size().height() - 9)
            p.setPen(QPen(QColor(randint(200, 255), randint(200, 255), 255), 1))
            p.drawPoint(x, y)
        # set pen to use white color
        p.setPen(QPen(QColor(randint(9, 255), randint(9, 255), 255), 1))
        # Rotate painter 45 Degree
        p.rotate(35)
        # Set painter Font for text
        p.setFont(QFont('Ubuntu', 300))
        # draw the background text, with antialiasing
        p.drawText(99, 199, "Radio")
        # Rotate -45 the QPen back !
        p.rotate(-35)
        # set the pen to no pen
        p.setPen(Qt.NoPen)
        # Background Color
        p.setBrush(QColor(0, 0, 0))
        # Background Opacity
        p.setOpacity(0.75)
        # Background Rounded Borders
        p.drawRoundedRect(self.rect(), 50, 50)
        # finalize the painter
        p.end()

    def seTitle(self):
        ' set the title of the main window '
        dialog = QDialog(self)
        textEditInput = QLineEdit(' Type Title Here ')
        ok = QPushButton(' O K ')
        ok.clicked.connect(lambda: self.setWindowTitle(textEditInput.text()))
        ly = QVBoxLayout()
        [ly.addWidget(wdgt) for wdgt in (QLabel('Title:'), textEditInput, ok)]
        dialog.setLayout(ly)
        dialog.exec_()

    def timedate(self):
        ' get the time and date '
        dialog = QDialog(self)
        clock = QLCDNumber()
        clock.setNumDigits(24)
        timer = QTimer()
        timer.timeout.connect(lambda: clock.display(
            datetime.now().strftime("%d-%m-%Y %H:%M:%S %p")))
        timer.start(1000)
        clock.setToolTip(datetime.now().strftime("%c %x"))
        ok = QPushButton(' O K ')
        ok.clicked.connect(dialog.close)
        ly = QVBoxLayout()
        [ly.addWidget(wdgt) for wdgt in (QCalendarWidget(), clock, ok)]
        dialog.setLayout(ly)
        dialog.exec_()

    def closeEvent(self, event):
        ' Ask to Quit '
        if QMessageBox.question(self, ' Close ', ' Quit ? ',
           QMessageBox.Yes | QMessageBox.No, QMessageBox.No) == QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()

    def center(self):
        ' Center and resize the window '
        self.showNormal()
        self.resize(QDesktopWidget().screenGeometry().width() // 1.25,
                    QDesktopWidget().screenGeometry().height() // 1.25)
        qr = self.frameGeometry()
        qr.moveCenter(QDesktopWidget().availableGeometry().center())
        self.move(qr.topLeft())

    def nepomuk_set(self, file_tag=None, __tag='', _label='', _description=''):
        ' Quick and Easy Nepomuk Taggify for Files '
        print((''' INFO: Semantic Desktop Experience is Tagging Files :
              {}, {}, {}, {})'''.format(file_tag, __tag, _label, _description)))
        if Nepomuk.ResourceManager.instance().init() is 0:
            fle = Nepomuk.Resource(KUrl(QFileInfo(file_tag).absoluteFilePath()))
            _tag = Nepomuk.Tag(__tag)
            _tag.setLabel(_label)
            fle.addTag(_tag)
            fle.setDescription(_description)
            print(([str(a.label()) for a in fle.tags()], fle.description()))
            return ([str(a.label()) for a in fle.tags()], fle.description())
        else:
            print(" ERROR: FAIL: Nepomuk is not running ! ")

    def nepomuk_get(self, query_to_search):
        ' Quick and Easy Nepomuk Query for Files '
        print((''' INFO: Semantic Desktop Experience is Quering Files :
              {} '''.format(query_to_search)))
        results = []
        nepo = Nepomuk.Query.QueryServiceClient()
        nepo.desktopQuery("hasTag:{}".format(query_to_search))

        def _query(data):
            ''' ('filename.ext', 'file description', ['list', 'of', 'tags']) '''
            results.append(([str(a.resource().genericLabel()) for a in data][0],
                            [str(a.resource().description()) for a in data][0],
            [str(a.label()) for a in iter([a.resource().tags() for a in data][0]
            )]))
        nepo.newEntries.connect(_query)

        def _end():
            '''
            [  ('filename.ext', 'file description', ['list', 'of', 'tags']),
               ('filename.ext', 'file description', ['list', 'of', 'tags']),
               ('filename.ext', 'file description', ['list', 'of', 'tags'])  ]
            '''
            nepo.newEntries.disconnect
            print(results)
            return results
        nepo.finishedListing.connect(_end)
Exemplo n.º 40
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()
Exemplo n.º 41
0
class Main(plugin.Plugin):
    " Main Class "

    def initialize(self, *args, **kwargs):
        " Init Main Class "
        super(Main, self).initialize(*args, **kwargs)
        self.process = QProcess()
        self.process.readyReadStandardOutput.connect(self.readOutput)
        self.process.readyReadStandardError.connect(self.readErrors)
        self.process.finished.connect(self._process_finished)
        self.process.error.connect(self._process_finished)
        # directory auto completer
        self.completer, self.dirs = QCompleter(self), QDirModel(self)
        self.dirs.setFilter(QDir.AllEntries | QDir.NoDotAndDotDot)
        self.completer.setModel(self.dirs)
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setCompletionMode(QCompleter.PopupCompletion)

        self.group0 = QGroupBox()
        self.group0.setTitle(' Source ')
        self.source, self.infile = QComboBox(), QLineEdit(path.expanduser("~"))
        self.source.addItems(['Local File', 'Remote URL'])
        self.source.currentIndexChanged.connect(self.on_source_changed)
        self.infile.setPlaceholderText(' /full/path/to/file.html ')
        self.infile.setCompleter(self.completer)
        self.open = QPushButton(QIcon.fromTheme("folder-open"), 'Open')
        self.open.setCursor(QCursor(Qt.PointingHandCursor))
        self.open.clicked.connect(lambda: self.infile.setText(
            str(
                QFileDialog.getOpenFileName(
                    self.dock, "Open a File to read from", path.expanduser(
                        "~"), ';;'.join([
                            '{}(*.{})'.format(e.upper(), e) for e in
                            ['html', 'webp', 'webm', 'svg', 'css', 'js', '*']
                        ])))))
        self.inurl, self.output = QLineEdit('http://www.'), QTextEdit()
        self.inurl.setPlaceholderText(
            'http://www.full/url/to/remote/file.html')
        self.inurl.hide()
        vboxg0 = QVBoxLayout(self.group0)
        for each_widget in (self.source, self.infile, self.open, self.inurl):
            vboxg0.addWidget(each_widget)

        self.group1 = QGroupBox()
        self.group1.setTitle(' Mobile ')
        self.ckcss1 = QCheckBox('Run in full screen using current resolution')
        self.ckcss2 = QCheckBox('Disable touch mode and use keypad mode')
        self.ckcss3 = QCheckBox(
            'Disable touch mode but allow to use the mouse')
        self.ckcss4 = QCheckBox(
            'Enable mouse,disable pointer & zoom emulation')
        self.ckcss5 = QCheckBox('Start the Mobile version of the browser')
        self.ckcss6 = QCheckBox('Start the Tablet version of the browser')
        self.ckcss7 = QCheckBox('Emulate hardware with Menu and Back keys')
        self.ckcss8 = QCheckBox('Start the browser in Kiosk mode')
        self.width, self.height = QSpinBox(), QSpinBox()
        self.zoom, self.ram, self.dpi = QSpinBox(), QSpinBox(), QSpinBox()
        self.cpulag, self.gpulag = QSpinBox(), QSpinBox()
        self.lang, self.agent = QComboBox(), QComboBox()
        self.lang.addItems(['EN', 'ES', 'PT', 'JA', 'ZH', 'DE', 'RU', 'FR'])
        self.agent.addItems(['Default', 'Android', 'MeeGo', 'Desktop'])
        self.fonts = QLineEdit()
        self.width.setMaximum(9999)
        self.width.setMinimum(100)
        self.width.setValue(480)
        self.height.setMaximum(9999)
        self.height.setMinimum(100)
        self.height.setValue(800)
        self.zoom.setMaximum(999)
        self.zoom.setMinimum(1)
        self.zoom.setValue(100)
        self.ram.setMaximum(999)
        self.ram.setMinimum(1)
        self.ram.setValue(100)
        self.dpi.setMaximum(200)
        self.dpi.setMinimum(50)
        self.dpi.setValue(96)
        self.cpulag.setMaximum(9999)
        self.cpulag.setMinimum(0)
        self.cpulag.setValue(1)
        self.gpulag.setMaximum(9999)
        self.gpulag.setMinimum(0)
        self.gpulag.setValue(1)
        vboxg1 = QVBoxLayout(self.group1)
        for each_widget in (
                self.ckcss1, self.ckcss2, self.ckcss3, self.ckcss4,
                self.ckcss5, self.ckcss6, self.ckcss7, self.ckcss8,
                QLabel('Width Pixels of the emulated device screen'),
                self.width,
                QLabel('Height Pixels of the emulated device screen'),
                self.height,
                QLabel('Zoom Percentage of emulated screen'), self.zoom,
                QLabel('RAM MegaBytes of the emulated device'), self.ram,
                QLabel('Language of the emulated device'), self.lang,
                QLabel('D.P.I. of the emulated device'), self.dpi,
                QLabel('User-Agent of the emulated device'), self.agent,
                QLabel('CPU Core Lag Miliseconds of emulated device'),
                self.cpulag,
                QLabel('GPU Video Lag Miliseconds of emulated device'),
                self.gpulag, QLabel('Extra Fonts Directory Full Path'),
                self.fonts):
            vboxg1.addWidget(each_widget)

        self.group2 = QGroupBox()
        self.group2.setTitle(' General ')
        self.nice, self.opera = QSpinBox(), QLineEdit(path.expanduser("~"))
        self.nice.setValue(20)
        self.nice.setMaximum(20)
        self.nice.setMinimum(0)
        self.opera.setCompleter(self.completer)
        if path.exists(CONFIG_FILE):
            with codecs.open(CONFIG_FILE, encoding='utf-8') as fp:
                self.opera.setText(fp.read())
        self.open2 = QPushButton(QIcon.fromTheme("folder-open"), 'Open')
        self.open2.setCursor(QCursor(Qt.PointingHandCursor))
        self.open2.clicked.connect(lambda: self.opera.setText(
            str(
                QFileDialog.getOpenFileName(
                    self.dock, "Open Opera Mobile Emulator",
                    path.expanduser("~"),
                    'Opera Mobile Emulator Executable(opera-mobile-emulator)'))
        ))
        self.help1 = QLabel('''<a href=
            "http://www.opera.com/developer/mobile-emulator">
            <small><center>Download Opera Mobile Emulator !</a>''')
        self.help1.setTextInteractionFlags(Qt.LinksAccessibleByMouse)
        self.help1.setOpenExternalLinks(True)
        vboxg4 = QVBoxLayout(self.group2)
        for each_widget in (QLabel(' Backend CPU priority: '), self.nice,
                            QLabel(' Opera Mobile Emulator Full Path: '),
                            self.opera, self.open2, self.help1):
            vboxg4.addWidget(each_widget)

        self.button = QPushButton('Preview on Mobile')
        self.button.setCursor(QCursor(Qt.PointingHandCursor))
        self.button.setMinimumSize(100, 50)
        self.button.clicked.connect(self.run)
        glow = QGraphicsDropShadowEffect(self)
        glow.setOffset(0)
        glow.setBlurRadius(99)
        glow.setColor(QColor(99, 255, 255))
        self.button.setGraphicsEffect(glow)
        glow.setEnabled(True)

        class TransientWidget(QWidget):
            ' persistant widget thingy '

            def __init__(self, widget_list):
                ' init sub class '
                super(TransientWidget, self).__init__()
                vbox = QVBoxLayout(self)
                for each_widget in widget_list:
                    vbox.addWidget(each_widget)

        tw = TransientWidget((
            QLabel('<b>Mobile Browser Emulator'),
            self.group0,
            self.group1,
            self.group2,
            self.output,
            self.button,
        ))
        self.scrollable, self.dock = QScrollArea(), QDockWidget()
        self.scrollable.setWidgetResizable(True)
        self.scrollable.setWidget(tw)
        self.dock.setWindowTitle(__doc__)
        self.dock.setStyleSheet('QDockWidget::title{text-align: center;}')
        self.dock.setWidget(self.scrollable)
        ExplorerContainer().addTab(self.dock, "Mobile")
        QPushButton(
            QIcon.fromTheme("help-about"), 'About', self.dock).clicked.connect(
                lambda: QMessageBox.information(self.dock, __doc__, HELPMSG))

    def run(self):
        ' run the string replacing '
        self.output.clear()
        self.button.setEnabled(False)
        self.output.append(self.formatInfoMsg('INFO:{}'.format(
            datetime.now())))
        if self.source.currentText() == 'Local File':
            target = 'file://' + str(self.infile.text()).strip()
        else:
            target = self.inurl.text()
        self.output.append(self.formatInfoMsg(' INFO: OK: Parsing Arguments'))
        cmd = ' '.join(
            ('nice --adjustment={}'.format(self.nice.value()), '"{}"'.format(
                self.opera.text()),
             '-fullscreen' if self.ckcss1.isChecked() is True else '',
             '-notouch' if self.ckcss2.isChecked() is True else '',
             '-notouchwithtouchevents' if self.ckcss3.isChecked() is True else
             '', '-usemouse' if self.ckcss4.isChecked() is True else '',
             '-mobileui' if self.ckcss5.isChecked() is True else '',
             '-tabletui' if self.ckcss6.isChecked() is True else '',
             '-hasmenuandback' if self.ckcss7.isChecked() is True else '',
             '-k' if self.ckcss8.isChecked() is True else '',
             '-displaysize {}x{}'.format(
                 self.width.value(),
                 self.height.value()), '-displayzoom {}'.format(
                     self.zoom.value()), '-mem {}M'.format(self.ram.value()),
             '-lang {}'.format(self.lang.currentText()), '-ppi {}'.format(
                 self.dpi.value()), '-extra-fonts {}'.format(self.fonts.text())
             if str(self.fonts.text()).strip() is not '' else '',
             '-user-agent-string {}'.format(
                 self.agent.currentText()), '-delaycorethread {}'.format(
                     self.cpulag.value()), '-delayuithread {}'.format(
                         self.gpulag.value()), '-url "{}"'.format(target)))
        self.output.append(self.formatInfoMsg(
            'INFO:OK:Command:{}'.format(cmd)))
        self.process.start(cmd)
        if not self.process.waitForStarted():
            self.output.append(self.formatErrorMsg(' ERROR: FAIL: Meh. '))
            self.output.append(
                self.formatErrorMsg(
                    'ERROR: FAIL: Failed with Arguments: {} '.format(cmd)))
            self.button.setEnabled(True)
            return
        self.output.setFocus()
        self.output.selectAll()
        self.button.setEnabled(True)

    def on_source_changed(self):
        ' do something when the desired source has changed '
        if self.source.currentText() == 'Local File':
            self.open.show()
            self.infile.show()
            self.inurl.hide()
        else:
            self.inurl.show()
            self.open.hide()
            self.infile.hide()

    def _process_finished(self):
        """ finished sucessfully """
        self.output.append(self.formatInfoMsg('INFO:{}'.format(
            datetime.now())))
        self.output.selectAll()
        self.output.setFocus()

    def readOutput(self):
        """Read and append output to the logBrowser"""
        self.output.append(str(self.process.readAllStandardOutput()).strip())

    def readErrors(self):
        """Read and append errors to the logBrowser"""
        self.output.append(
            self.formatErrorMsg(str(self.process.readAllStandardError())))

    def formatErrorMsg(self, msg):
        """Format error messages in red color"""
        return self.formatMsg(msg, 'red')

    def formatInfoMsg(self, msg):
        """Format informative messages in blue color"""
        return self.formatMsg(msg, 'green')

    def formatMsg(self, msg, color):
        """Format message with the given color"""
        return '<font color="{}">{}</font>'.format(color, msg)

    def finish(self):
        ' save when finish '
        with codecs.open(CONFIG_FILE, "w", encoding='utf-8') as fp:
            fp.write(self.opera.text())
Exemplo n.º 42
0
class Main(plugin.Plugin):
    " Main Class "
    def initialize(self, *args, **kwargs):
        " Init Main Class "
        super(Main, self).initialize(*args, **kwargs)
        self.process = QProcess()
        self.process.readyReadStandardOutput.connect(self.readOutput)
        self.process.readyReadStandardError.connect(self.readErrors)
        self.process.finished.connect(self._process_finished)
        # self.process.error.connect(self._process_error)

        self.sourceDirectory, self.outputDirectory = None, None

        self.group2 = QGroupBox()
        self.group2.setTitle(' Paths ')
        self.inf = QLineEdit(path.expanduser("~"))
        self.inf.setPlaceholderText(' /full/path/to/directory ')
        self.out, self.fle = QLineEdit(path.expanduser("~")), QLineEdit()
        self.out.setPlaceholderText(' /full/path/to/directory ')
        self.fle.setPlaceholderText(' /full/path/to/single/file ')
        self.completer, self.dirs = QCompleter(self), QDirModel(self)
        self.dirs.setFilter(QDir.AllEntries | QDir.NoDotAndDotDot)
        self.completer.setModel(self.dirs)
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setCompletionMode(QCompleter.PopupCompletion)
        self.inf.setCompleter(self.completer)
        self.out.setCompleter(self.completer)
        self.fle.setCompleter(self.completer)
        self.open1 = QPushButton(QIcon.fromTheme("folder-open"), 'Open')
        self.open1.setCursor(QCursor(Qt.PointingHandCursor))
        self.open1.clicked.connect(lambda: self.inf.setText(str(
            QFileDialog.getExistingDirectory(self.dock, "Open Source Directory",
            path.expanduser("~")))))
        self.open2 = QPushButton(QIcon.fromTheme("folder-open"), 'Open')
        self.open2.setCursor(QCursor(Qt.PointingHandCursor))
        self.open2.clicked.connect(lambda: self.out.setText(str(
            QFileDialog.getExistingDirectory(self.dock, "Open Target Directory",
            path.expanduser("~")))))
        self.open3 = QPushButton(QIcon.fromTheme("folder-open"), 'Open')
        self.open3.setCursor(QCursor(Qt.PointingHandCursor))
        self.open3.clicked.connect(lambda: self.fle.setText(str(
            QFileDialog.getOpenFileName(self.dock, "Open a Target File...",
            path.expanduser("~"), ';;'.join(['{}(*.{})'.format(e.upper(), e)
                for e in ['py', 'pyw', '*']])))))
        vboxg2 = QVBoxLayout(self.group2)
        for each_widget in (
            QLabel('Source Directory Project:'), self.inf, self.open1,
            QLabel(' Target Directory Outputs: '), self.out, self.open2,
            QLabel(' Source Single File (Optional):'), self.fle, self.open3, ):
            vboxg2.addWidget(each_widget)

        self.group1 = QGroupBox()
        self.group1.setTitle(' Options ')
        self.chckbx1 = QCheckBox(' Inject Twitter Bootstrap CSS3 ')
        self.chckbx1.toggled.connect(self.toggle_styles_group)
        self.chckbx2 = QCheckBox(' Warn all missing references ')
        self.chckbx3 = QCheckBox(' Open Docs when done building ')
        self.chckbx4 = QCheckBox('Save Bash script to reproduce Sphinx Builds')
        vboxg1 = QVBoxLayout(self.group1)
        for each_widget in (self.chckbx1, self.chckbx2,
                            self.chckbx3, self.chckbx4):
            vboxg1.addWidget(each_widget)
            each_widget.setChecked(True)

        self.group3 = QGroupBox()
        self.group3.setTitle(' Styles ')
        self.group3.setGraphicsEffect(QGraphicsBlurEffect(self))
        self.group3.graphicsEffect().setEnabled(False)
        self.basecss, self.fontcss = QComboBox(), QComboBox()
        self.basecss.addItems(['slate', 'united', 'spacelab', 'superhero',
            'simplex', 'journal', 'flatly', 'cyborg', 'cosmo', 'cerulean'])
        self.fontcss.addItems(['Ubuntu Light', 'Oxygen', 'Roboto', 'Droid Sans',
            'Open Sans', 'Pacifico', 'Rancho', 'Arvo', 'Fresca', 'Graduate'])
        self.backcss = QComboBox()
        self.backcss.addItems(['shattered', 'retina_wood', 'ricepaper',
            'brickwall', 'sneaker_mesh_fabric', 'diagonales_decalees',
            'noisy_grid', 'pw_pattern', 'escheresque', 'diamond_upholstery'])
        vboxg3 = QVBoxLayout(self.group3)
        for each_widget in (QLabel('<b>Twitter Bootstrap Theme'), self.basecss,
            QLabel('<b>Fonts Family'), self.fontcss,
            QLabel('<b>Background Seamless Tiled Pattern'), self.backcss):
            vboxg3.addWidget(each_widget)

        self.output = QTextEdit('''
        My brain is something more than merely mortal; As time will show.
        - Ada Lovelace ''')
        self.output.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        self.button = QPushButton('Document My Code')
        self.button.setCursor(QCursor(Qt.PointingHandCursor))
        self.button.setMinimumSize(75, 50)
        self.button.clicked.connect(self.build)
        glow = QGraphicsDropShadowEffect(self)
        glow.setOffset(0)
        glow.setBlurRadius(99)
        glow.setColor(QColor(99, 255, 255))
        self.button.setGraphicsEffect(glow)

        class TransientWidget(QWidget):
            ' persistant widget thingy '
            def __init__(self, widget_list):
                ' init sub class '
                super(TransientWidget, self).__init__()
                vbox = QVBoxLayout(self)
                for each_widget in widget_list:
                    vbox.addWidget(each_widget)

        tw = TransientWidget((self.group2, self.group1, self.group3,
            QLabel(linesep + ' Logs: '), self.output, self.button))
        self.scrollable, self.dock = QScrollArea(), QDockWidget()
        self.scrollable.setWidgetResizable(True)
        self.scrollable.setWidget(tw)
        self.dock.setWindowTitle(__doc__)
        self.dock.setStyleSheet('QDockWidget::title{text-align: center;}')
        self.dock.setWidget(self.scrollable)
        ExplorerContainer().addTab(self.dock, "Sphinx")
        QPushButton(QIcon.fromTheme("help-about"), 'About', self.dock
            ).clicked.connect(lambda:
            QMessageBox.information(self.dock, __doc__, HELPMSG))

    def readOutput(self):
        """Read and append sphinx-build output to the logBrowser"""
        self.output.append(str(self.process.readAllStandardOutput()))

    def readErrors(self):
        """Read and append sphinx-build errors to the logBrowser"""
        self.output.append(self.formatErrorMsg(str(
                                        self.process.readAllStandardError())))

    def formatErrorMsg(self, msg):
        """Format error messages in red color"""
        return self.formatMsg(msg, 'red')

    def formatInfoMsg(self, msg):
        """Format informative messages in blue color"""
        return self.formatMsg(msg, 'green')

    def formatMsg(self, msg, color):
        """Format message with the given color"""
        return '<font color="{}">{}</font>'.format(color, msg)

    def build(self):
        """Main function calling sphinx-build to generate the project"""
        self.output.setText('')
        self.output.append(self.formatInfoMsg(
                            'INFO: OK: Starting at {}'.format(datetime.now())))
        self.button.setDisabled(True)
        self.sourceDirectory = str(self.inf.text()).strip()
        self.outputDirectory = str(self.out.text()).strip()
        if not len(self.sourceDirectory):
            self.output.append(' ERROR: FAIL: Source directory cannot be empty')
        else:
            self.output.append(self.formatInfoMsg(
            'INFO: OK: Source Directory is {}'.format(self.sourceDirectory)))
        if not len(self.outputDirectory):
            self.output.append(' ERROR: FAIL: Output directory cannot be empty')
        else:
            self.output.append(self.formatInfoMsg(
            'INFO: OK: Output Directory is {}'.format(self.outputDirectory)))
        if not(len(self.sourceDirectory) or len(self.outputDirectory)):
            self.button.setDisabled(False)
            return
        self.output.append(self.formatInfoMsg('INFO:OK: Building. Please wait'))

        args = ['-n' if self.chckbx2.isChecked() is True else '',
                '-b', 'html', self.sourceDirectory, self.outputDirectory]
        if len(self.fle.text()):
            args.append(str(self.fle.text()).strip().replace('file:///', '/'))
            self.output.append(self.formatInfoMsg(
                'INFO: OK: Source Single File is {}'.format(self.fle.text())))
        self.output.append(self.formatInfoMsg('INFO:OK: Running sphinx-build!'))

        self.process.start('sphinx-build', args)
        if not self.process.waitForStarted():
            self.output.append(self.formatErrorMsg('ERROR: FAIL: Build Failed'))
            self.output.append(self.formatErrorMsg(
                'ERROR: FAIL: Failed with Arguments: {} '.format(args)))
            self.button.setEnabled(True)
            return
        # write a .sh bash script file on target
        if self.chckbx4.isChecked() is True:
            sh_file = 'build_sphinx_documentation.sh'
            with open(path.join(self.sourceDirectory, sh_file), 'w') as _sh:
                self.output.append(self.formatInfoMsg('''INFO: OK: Writing Bash:
                    {}'''.format(path.join(self.sourceDirectory, sh_file))))
                _sh.write('#!/usr/bin/env bash {}'.format(linesep) +
                          'sphinx-build {}'.format(' '.join(args)))
                _sh.close()
            self.output.append(self.formatInfoMsg('INFO: OK: Bash chmod: 775'))
            try:
                chmod(path.join(self.sourceDirectory, sh_file), 0775)  # Py2
            except:
                chmod(path.join(self.sourceDirectory, sh_file), 0o775)  # Py3
        self.button.setEnabled(True)

    def _process_finished(self):
        """sphinx-build finished sucessfully"""
        self.output.append(self.formatInfoMsg(
                            'INFO: OK: Finished at {}'.format(datetime.now())))
        if self.chckbx1.isChecked() is True:
            with open(path.join(self.outputDirectory, '_static', 'default.css'),
                'a') as f:
                css = CSS3.replace('CSSWEBFONT', str(self.fontcss.currentText())
                      ).replace('CSSBACKGR', str(self.backcss.currentText())
                      ).replace('CSSCUSTOM', str(self.basecss.currentText()))
                f.write(css)
                f.close()
        if self.chckbx3.isChecked() is True:
            call('xdg-open ' + path.join(self.outputDirectory, 'index.html'),
                 shell=True)

    def toggle_styles_group(self):
        ' toggle on or off the styles checkboxes '
        try:
            if self.chckbx1.isChecked() is True:
                self.group3.graphicsEffect().setEnabled(False)
                self.group3.setEnabled(True)
            else:
                self.group3.graphicsEffect().setEnabled(True)
                self.group3.setEnabled(False)
        except:
            pass
    def __init__(self, item, parent=None):
        QDialog.__init__(self, parent, Qt.Dialog)
        self.setModal(True)
        self._item = item
        self.setWindowTitle(self.tr("Project Properties"))
        grid = QGridLayout(self)
        grid.addWidget(QLabel(self.tr("Name:")), 0, 0)
        self.name = QLineEdit()
        if self._item.name == '':
            self.name.setText(file_manager.get_basename(self._item.path))
        else:
            self.name.setText(self._item.name)
        grid.addWidget(self.name, 0, 1)
        grid.addWidget(QLabel(self.tr("Project Type:")), 1, 0)
        self.txtType = QLineEdit()
        completer = QCompleter(sorted(settings.PROJECT_TYPES))
        completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.txtType.setCompleter(completer)
        self.txtType.setText(self._item.projectType)
        grid.addWidget(self.txtType, 1, 1)
        grid.addWidget(QLabel(self.tr("Description:")), 2, 0)
        self.description = QPlainTextEdit()
        self.description.setPlainText(self._item.description)
        grid.addWidget(self.description, 2, 1)
        grid.addWidget(QLabel(self.tr("URL:")), 3, 0)
        self.url = QLineEdit()
        self.url.setText(self._item.url)
        grid.addWidget(self.url, 3, 1)
        grid.addWidget(QLabel(self.tr("Licence:")), 4, 0)
        self.cboLicense = QComboBox()
        self.cboLicense.addItem('Apache License 2.0')
        self.cboLicense.addItem('Artistic License/GPL')
        self.cboLicense.addItem('Eclipse Public License 1.0')
        self.cboLicense.addItem('GNU General Public License v2')
        self.cboLicense.addItem('GNU General Public License v3')
        self.cboLicense.addItem('GNU Lesser General Public License')
        self.cboLicense.addItem('MIT License')
        self.cboLicense.addItem('Mozilla Public License 1.1')
        self.cboLicense.addItem('New BSD License')
        self.cboLicense.addItem('Other Open Source')
        self.cboLicense.addItem('Other')
        self.cboLicense.setCurrentIndex(4)
        index = self.cboLicense.findText(self._item.license)
        self.cboLicense.setCurrentIndex(index)
        grid.addWidget(self.cboLicense, 4, 1)
        grid.addWidget(QLabel(self.tr("Main File:")), 5, 0)
        self.path = QLineEdit()
        ui_tools.LineEditButton(self.path, self.path.clear,
            self.style().standardPixmap(self.style().SP_TrashIcon))
        self.path.setText(self._item.mainFile)
        self.path.setReadOnly(True)
        self.btnBrowse = QPushButton(QIcon(
            self.style().standardPixmap(self.style().SP_FileIcon)), '')
        hbox = QHBoxLayout()
        hbox.addWidget(self.path)
        hbox.addWidget(self.btnBrowse)
        grid.addLayout(hbox, 5, 1)

        self.txtExtensions = QLineEdit()
        self.txtExtensions.setText(str(', '.join(self._item.extensions)))
        grid.addWidget(QLabel(self.tr("Supported Extensions:")), 6, 0)
        grid.addWidget(self.txtExtensions, 6, 1)

        self.txtPythonPath = QLineEdit()
        self.txtPythonPath.setText(self._item.pythonPath)
        self.btnPythonPath = QPushButton(QIcon(resources.IMAGES['open']), '')
        grid.addWidget(QLabel(self.tr("Python Path:")), 7, 0)
        grid.addWidget(self.txtPythonPath, 7, 1)
        grid.addWidget(self.btnPythonPath, 7, 2)

        self.txtParams = QLineEdit()
        self.txtParams.setToolTip(
            self.tr("Separate the params with commas (ie: help, verbose)"))
        self.txtParams.setText(self._item.programParams)
        grid.addWidget(QLabel(self.tr("Params (comma separated):")), 8, 0)
        grid.addWidget(self.txtParams, 8, 1)

        #Widgets for virtualenv properties
        self.txtVenvPath = QLineEdit()
        ui_tools.LineEditButton(self.txtVenvPath, self.txtVenvPath.clear,
            self.style().standardPixmap(self.style().SP_TrashIcon))
        self.txtVenvPath.setText(self._item.venv)
        self.txtVenvPath.setReadOnly(True)
        self.btnVenvPath = QPushButton(QIcon(resources.IMAGES['open']), '')
        grid.addWidget(QLabel(self.tr("Virtualenv Folder:")), 9, 0)
        grid.addWidget(self.txtVenvPath, 9, 1)
        grid.addWidget(self.btnVenvPath, 9, 2)

        self.btnSave = QPushButton(self.tr("Save"))
        self.btnCancel = QPushButton(self.tr("Cancel"))
        hbox3 = QHBoxLayout()
        hbox3.addWidget(self.btnCancel)
        hbox3.addWidget(self.btnSave)
        grid.addLayout(hbox3, 10, 1)

        self.connect(self.btnBrowse, SIGNAL("clicked()"), self.select_file)
        self.connect(self.btnCancel, SIGNAL("clicked()"), self.close)
        self.connect(self.btnSave, SIGNAL("clicked()"), self.save_properties)
        self.connect(self.btnPythonPath, SIGNAL("clicked()"),
            self._load_python_path)
        self.connect(self.btnVenvPath, SIGNAL("clicked()"),
            self._load_python_venv)
Exemplo n.º 44
0
class DiffGUI(object):
    ' diff gui class '
    def __init__(self):
        ' make a diff method with GUI '
        self.dialog = QDialog()
        self.diff_path = None

        # directory auto completer
        self.completer = QCompleter(self.dialog)
        self.dirs = QDirModel(self.dialog)
        self.dirs.setFilter(QDir.AllEntries | QDir.NoDotAndDotDot)
        self.completer.setModel(self.dirs)
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setCompletionMode(QCompleter.PopupCompletion)

        self.group1 = QGroupBox()
        self.group1.setTitle('Diff')
        self.frmt = QComboBox(self.group1)
        self.frmt.addItems(['Unified', 'Normal', 'Context'])
        self.file1 = QLineEdit()
        self.file1.setPlaceholderText('/full/path/to/one_file.py')
        self.file1.setCompleter(self.completer)
        self.file2 = QLineEdit()
        self.file2.setPlaceholderText('/full/path/to/another_file.py')
        self.file2.setCompleter(self.completer)
        self.fout = QLineEdit()
        self.fout.setText(''.join((path.join(gettempdir(),
                     datetime.now().strftime('%d-%b-%Y_%H:%M:%S.diff')))))
        self.fout.setPlaceholderText('/full/path/to/output_file.diff')
        self.fout.setCompleter(self.completer)
        self.regex = QLineEdit()
        self.regex.setPlaceholderText('DONT use unless you know what are doing')
        self.regex.setToolTip('Do NOT use unless you know what you are doing !')
        self.borig = QPushButton(QIcon.fromTheme("folder-open"), 'Open')
        self.borig.clicked.connect(lambda: self.file1.setText(str(
            QFileDialog.getOpenFileName(self.dialog, 'Open file to compare',
                                           path.expanduser("~"), ';;(*.*)'))))

        self.bmodi = QPushButton(QIcon.fromTheme("folder-open"), 'Open')
        self.bmodi.clicked.connect(lambda: self.file2.setText(str(
            QFileDialog.getOpenFileName(self.dialog, 'Open file to compare',
                                           path.expanduser("~"), ';;(*.*)'))))
        self.bout = QPushButton(QIcon.fromTheme("folder-open"), 'Open')
        self.bout.clicked.connect(lambda: self.fout.setText(str(
            QFileDialog.getSaveFileName(self.dialog, 'Save a Diff file',
                                        path.expanduser("~"), ';;(*.diff)'))))
        vboxg1 = QVBoxLayout(self.group1)
        for each_widget in (QLabel('Original file full path'),
                            self.file1, self.borig,
                            QLabel('Modified file full path'),
                            self.file2, self.bmodi,
                            QLabel('Output file full Path'),
                            self.fout, self.bout,
                            QLabel('Diff Output Format'), self.frmt,
                            QLabel('Diff REGEX to Ignore (ADVANCED)'),
                            self.regex):
            vboxg1.addWidget(each_widget)

        self.group2 = QGroupBox()
        self.group2.setTitle('Options')
        self.nwfl = QCheckBox('Treat new files as Empty')
        self.smll = QCheckBox('Look for smaller changes')
        self.lrgf = QCheckBox('Optimize for large files')
        self.case = QCheckBox('Ignore case changes on content')
        self.cnvt = QCheckBox('Convert Tabs to Spaces')
        self.blnk = QCheckBox('Ignore added or removed Blank lines')
        self.spac = QCheckBox('Ignore changes in amount of Spaces')
        self.whit = QCheckBox('Ignore ALL white Spaces')
        self.tabz = QCheckBox('Ignore changes by Tab expansions')
        self.sprs = QCheckBox('Remove Space or Tab before empty lines')
        self.filn = QCheckBox('Ignore case when comparing file names')
        self.tbs = QComboBox(self.group2)
        self.tbs.addItems(['4', '6', '8', '10', '2'])
        self.nice = QComboBox(self.group2)
        self.nice.addItems(['20', '15', '10', '5', '0'])
        vboxg2 = QVBoxLayout(self.group2)
        for each_widget in (self.nwfl, self.smll, self.lrgf, self.case,
                            self.cnvt, self.blnk, self.spac, self.whit,
                            self.tabz, self.sprs, self.filn,
                            QLabel('Diff Tabs-to-Spaces Size'), self.tbs,
                            QLabel('Diff Backend CPU Priority'), self.nice):
            vboxg2.addWidget(each_widget)
            try:
                each_widget.setToolTip(each_widget.text())
            except:
                each_widget.setToolTip(each_widget.currentText())
            each_widget.setCursor(QCursor(Qt.PointingHandCursor))

        group3 = QGroupBox()
        group3.setTitle('Even More Options')
        self.plai = QCheckBox('Force treat all files as plain text')
        self.nocr = QCheckBox('Force strip trailing carriage return')
        self.ridt = QCheckBox('Report when two files are identical')
        self.nocm = QCheckBox('Do not output common lines')
        self.rdif = QCheckBox('Report only when files differ')
        self.clip = QCheckBox('Copy Diff to Clipboard when done')
        self.noti = QCheckBox('Use system Notification when done')
        self.pret = QCheckBox('Align all Tabs by prepending a Tab')
        self.lolz = QCheckBox('Output Diff in two equal columns')
        self.odif = QCheckBox('Open Diff with Ninja-IDE when done')
        self.plac = QCheckBox('Make an Awesome Diff view when done')
        self.wdth = QComboBox(group3)
        self.wdth.addItems(['80', '100', '120', '130', '250', '500', '9999999'])
        self.bcknd = QComboBox(group3)
        self.bcknd.addItems(['diff', 'diff.py'])
        self.bcknd.setDisabled(True)  # TODO this feature needs work
        vboxg3 = QVBoxLayout(group3)
        for each_widget in (self.plai, self.nocr, self.ridt, self.nocm,
                            self.rdif, self.pret, self.clip, self.noti,
                            self.lolz, self.odif, self.plac,
                            QLabel('Diff Maximum Total Width'), self.wdth,
                            QLabel('Diff Backend (EXPERIMENTAL)'), self.bcknd):
            vboxg3.addWidget(each_widget)
            try:
                each_widget.setToolTip(each_widget.text())
            except:
                each_widget.setToolTip(each_widget.currentText())
            each_widget.setCursor(QCursor(Qt.PointingHandCursor))

        for widget_should_be_checked in (self.nwfl, self.smll, self.lrgf,
                                   self.clip, self.cnvt, self.plai, self.noti):
            widget_should_be_checked.setChecked(True)

        container = QWidget()
        hbox = QHBoxLayout(container)
        for each_widget in (self.group2, self.group1, group3):
            hbox.addWidget(each_widget)

        buttons = QDialogButtonBox()
        buttons.resize(self.dialog.size().width(), buttons.size().height() * 2)
        buttons.setOrientation(Qt.Horizontal)
        buttons.setStandardButtons(
            QDialogButtonBox.Ok |
            QDialogButtonBox.Cancel |
            QDialogButtonBox.Close |
            QDialogButtonBox.Help)
        buttons.setCenterButtons(False)
        buttons.helpRequested.connect(lambda: QMessageBox.about(
            self.dialog, __doc__,
            ''.join((__doc__, ' GUI and Visualizer Plugin,', linesep,
            'version ', __version__, ', (', __license__, '), by ', linesep,
            __author__, ', ( ', __email__, ' ).', linesep))))
        buttons.rejected.connect(self.dialog.close)
        buttons.accepted.connect(self.make_diff)

        info = QLabel(''.join(('<b> Current Backend Diff Engine: </b>',
                      getoutput('diff --version').split(linesep)[0])))

        vbox = QVBoxLayout(self.dialog)
        for each_widget in (
                QLabel('<center><h2> Ninja IDE Diff and Patch </h2></center>'),
                container, info, buttons):
            vbox.addWidget(each_widget)

        self.dialog.resize(1024, self.dialog.size().height())
        self.dialog.exec_()

    def make_diff(self):
        ' make the diff '
        diff_command = ''.join((
        'nice --adjustment=', str(self.nice.currentText()).strip(), ' ',
        str(self.bcknd.currentText()).strip(), ' --',
        str(self.frmt.currentText()).strip().lower(),

        ' --new-file ' if self.nwfl.isChecked() is True else '',
        ' --minimal ' if self.smll.isChecked() is True else '',
        ' --speed-large-files ' if self.lrgf.isChecked() is True else '',
        ' --ignore-self.case ' if self.case.isChecked() is True else '',
        ' --expand-tabs ' if self.cnvt.isChecked() is True else '',
        ' --ignore-blank-lines ' if self.blnk.isChecked() is True else '',
        ' --ignore-space-change ' if self.spac.isChecked() is True else '',
        ' --ignore-all-space ' if self.whit.isChecked() is True else '',
        ' --ignore-tab-expansion ' if self.tabz.isChecked() is True else '',
        ' --suppress-blank-empty ' if self.sprs.isChecked() is True else '',
        ' --ignore-file-name-case ' if self.filn.isChecked() is True else '',
        ' --text ' if self.plai.isChecked() is True else '',
        ' --strip-trailing-cr ' if self.nocr.isChecked() is True else '',
        ' --suppress-common-lines ' if self.nocm.isChecked() is True else '',
        ' --initial-tab ' if self.pret.isChecked() is True else '',
        ' --side-by-side ' if self.lolz.isChecked() is True else '',

        ' --tabsize=', str(self.tbs.currentText()).strip(),
        ' --width=', str(self.wdth.currentText()).strip(),

        str(' --ignore-matching-lines=' + str(self.regex.text()).strip())
                           if str(self.regex.text()).strip() is not '' else '',
        ' ',
        path.abspath(str(self.file1.text()))
                    if str(self.file1.text()).strip() is not '' else __file__,
        ' ',
        path.abspath(str(self.file2.text()))
                    if str(self.file2.text()).strip() is not '' else __file__
        ))

        print(diff_command)
        diff_output = getoutput(diff_command)
        try:
            print(' INFO: OK, Saving new Diff to disk...')
            output_file = file(path.abspath(str(self.fout.text())), 'w')
            output_file.write(diff_output)
            output_file.close()
        except:
            print(' ERROR: FAIL, Can not save Diff to disk!')
        if self.clip.isChecked() is True:
            print(' INFO: OK, Diff Copied to Clipboard...')
            QApplication.clipboard().setText(diff_output)
        if self.noti.isChecked() is True:
            call('notify-send [Ninja-IDE] ¡Diff_is_Ready!', shell=True)
        if self.odif.isChecked() is True:
            print(' INFO: OK, Opening Diff with Ninja-IDE')
            call('ninja-ide ' + path.abspath(str(self.fout.text())), shell=True)

        self.diff_path = path.abspath(str(self.fout.text()))
        return self.diff_path
Exemplo n.º 45
0
class SearchPanel(QComboBox):
    def __init__(self, model, parent=None, showTable=False):
        super(SearchPanel, self).__init__(parent)

        self.tabla = None
        self.setFocusPolicy(Qt.StrongFocus)
        self.setEditable(True)
        #        self.setModel( model )
        self.setEditable(True)
        self.completer = QCompleter(self)
        # always show all completions
        self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.pFilterModel = QSortFilterProxyModel(self)
        self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.showTable = showTable

        if model != None:
            self.setModel(model)
        #        self.pFilterModel.setSourceModel( model );

        self.completer.setModel(self.pFilterModel)
        self.completerTable = SearchPanelView()
        self.completer.setPopup(self.completerTable)
        # Mostrar el Popup en forma de Tabla
        if self.showTable:
            self.tabla = SearchPanelView()
            self.setView(self.tabla)

        self.setCompleter(self.completer)

        self.setColumn(1)

        self.lineEdit().textEdited[unicode].connect(
            self.pFilterModel.setFilterFixedString if not showTable else self.pFilterModel.setFilterWildcard
        )

    def setModel(self, model):
        QComboBox.setModel(self, model)
        self.pFilterModel.setSourceModel(model)

    def setColumn(self, column):
        self.setModelColumn(1)
        self.completer.setCompletionColumn(column)
        self.pFilterModel.setFilterKeyColumn(column)
        self.setModelColumn(column)

    def view(self):
        return self.completer.popup()

    def data(self):
        return self.currentIndex()

    def index(self):
        return self.currentIndex()

    def setColumnHidden(self, col):
        self.completerTable.hiddenColumns.append(col)
        if self.showTable:
            self.tabla.hiddenColumns.append(col)

    def setMinimumWidth(self, width):
        self.completerTable.setMinimumWidth(width)
        if self.showTable:
            self.tabla.setMinimumWidth(width)
Exemplo n.º 46
0
class SpellcheckEdit(QTextEdit, BaseEdit):
    def __init__(self, spell_dict):
        QTextEdit.__init__(self)
        BaseEdit.__init__(self)
        self.spell_dict = spell_dict
        self.highlighter = Highlighter(self.document(), self.spell_dict)
        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.customContextMenu)
        self.found = False
        self.edit_id = "spellcheck"
        self.completer = QCompleter(self.text())
        self.completer.setCompletionMode(QCompleter.PopupCompletion)

        self.setAcceptRichText(False)

    def text(self):
        return self.toPlainText()

    def set_dict(self, spell_dict):
        self.spell_dict = spell_dict
        self.highlighter = Highlighter(self.document(), self.spell_dict)

    def _search(self, search_string):
        if self.search_string != search_string:
            self.found = False
            self.search_string = search_string
        found = self.find(self.search_string)
        if not found and self.found:
            self._get_first(False)
            self._search(search_string)
        else:
            self.found = found

    def _get_first(self, select=True):
        cursor = self.textCursor()
        cursor.setPosition(0)
        self.setTextCursor(cursor)
        cursor.select(QTextCursor.WordUnderCursor)
        if select:
            self.setTextCursor(cursor)
        return cursor.selectedText()

    def _iterate(self):
        cursor = self.textCursor()
        cursor.movePosition(QTextCursor.WordRight)
        cursor.select(QTextCursor.WordUnderCursor)
        self.setTextCursor(cursor)
        return cursor.selectedText()

    def _replace(self, word):
        self.correctWord(word)

    @pyqtSignature("QPointF")
    def customContextMenu(self, point):
        popup_menu = self.createStandardContextMenu()

        # Select the word under the cursor.
        cursor = self.cursorForPosition(point)
        cursor.select(QTextCursor.WordUnderCursor)
        self.setTextCursor(cursor)

        # Check if the selected word is misspelled and offer spelling
        # suggestions if it is.
        if self.textCursor().hasSelection():
            text = unicode(self.textCursor().selectedText())
            if not self.spell_dict.check(text):
                spell_menu = QMenu('Spelling Suggestions')
                for word in self.spell_dict.suggest(text):
                    action = SpellAction(word, spell_menu)
                    action.correct.connect(self.correctWord)
                    spell_menu.addAction(action)
                # Only add the spelling suggests to the menu if there are
                # suggestions.
                if len(spell_menu.actions()) != 0:
                    popup_menu.insertSeparator(popup_menu.actions()[0])
                    popup_menu.insertMenu(popup_menu.actions()[0], spell_menu)

        popup_menu.exec_(self.mapToGlobal(point))

    def correctWord(self, word):
        '''
        Replaces the selected text with word.
        '''
        cursor = self.textCursor()
        cursor.beginEditBlock()

        cursor.removeSelectedText()
        cursor.insertText(word)

        cursor.endEditBlock()
Exemplo n.º 47
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()
    def __init__(self, parent):
        super(ProjectData, self).__init__()
        self._parent = parent
        grid = QGridLayout(self)
        grid.addWidget(QLabel(translations.TR_PROJECT_NAME), 0, 0)
        self.name = QLineEdit()
        if self._parent.project.name == '':
            self.name.setText(file_manager.get_basename(
                self._parent.project.path))
        else:
            self.name.setText(self._parent.project.name)
        grid.addWidget(self.name, 0, 1)
        grid.addWidget(QLabel(translations.TR_PROJECT_LOCATION), 1, 0)
        self.txtPath = QLineEdit()
        self.txtPath.setReadOnly(True)
        self.txtPath.setText(self._parent.project.path)
        grid.addWidget(self.txtPath, 1, 1)
        grid.addWidget(QLabel(translations.TR_PROJECT_TYPE), 2, 0)
        self.txtType = QLineEdit()
        completer = QCompleter(sorted(settings.PROJECT_TYPES))
        completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.txtType.setCompleter(completer)
        self.txtType.setText(self._parent.project.project_type)
        grid.addWidget(self.txtType, 2, 1)
        grid.addWidget(QLabel(translations.TR_PROJECT_DESCRIPTION), 3, 0)
        self.description = QPlainTextEdit()
        self.description.setPlainText(self._parent.project.description)
        grid.addWidget(self.description, 3, 1)
        grid.addWidget(QLabel(translations.TR_PROJECT_URL), 4, 0)
        self.url = QLineEdit()
        self.url.setText(self._parent.project.url)
        grid.addWidget(self.url, 4, 1)
        grid.addWidget(QLabel(translations.TR_PROJECT_LICENSE), 5, 0)
        self.cboLicense = QComboBox()
        self.cboLicense.addItem('Apache License 2.0')
        self.cboLicense.addItem('Artistic License/GPL')
        self.cboLicense.addItem('Eclipse Public License 1.0')
        self.cboLicense.addItem('GNU General Public License v2')
        self.cboLicense.addItem('GNU General Public License v3')
        self.cboLicense.addItem('GNU Lesser General Public License')
        self.cboLicense.addItem('MIT License')
        self.cboLicense.addItem('Mozilla Public License 1.1')
        self.cboLicense.addItem('Mozilla Public License 2.0')
        self.cboLicense.addItem('New BSD License')
        self.cboLicense.addItem('Other Open Source')
        self.cboLicense.addItem('Other')
        self.cboLicense.setCurrentIndex(4)
        index = self.cboLicense.findText(self._parent.project.license)
        self.cboLicense.setCurrentIndex(index)
        grid.addWidget(self.cboLicense, 5, 1)

        self.txtExtensions = QLineEdit()
        self.txtExtensions.setText(', '.join(self._parent.project.extensions))
        grid.addWidget(QLabel(translations.TR_PROJECT_EXTENSIONS), 6, 0)
        grid.addWidget(self.txtExtensions, 6, 1)

        grid.addWidget(QLabel(translations.TR_PROJECT_INDENTATION), 7, 0)
        self.spinIndentation = QSpinBox()
        self.spinIndentation.setValue(self._parent.project.indentation)
        self.spinIndentation.setMinimum(1)
        grid.addWidget(self.spinIndentation, 7, 1)
        self.checkUseTabs = QCheckBox(translations.TR_PROJECT_USE_TABS)
        self.checkUseTabs.setChecked(self._parent.project.use_tabs)
        grid.addWidget(self.checkUseTabs, 7, 2)
Exemplo n.º 49
0
class MainWindow(QMainWindow, Ui_MainWindow):
    """
    Class documentation goes here.
    """
    def __init__(self,argv=[], parent = None):
        """
        Constructor
        """
        self.conn=requests.Session()
        self.login_form=dlgLogin(self.conn)
        if len(argv)==3:
            self.login_form.txtUsername.setText(argv[1])
            self.login_form.txtPasswd.setText(argv[2])
        self.login_form.first_time_called=True;
        self.booking_form=dlgBooking(self.conn)
        QMainWindow.__init__(self, parent)
        self.setupUi(self)
        #set the table column width
        self.tableTickets.resizeColumnsToContents()
        header=self.tableTickets.horizontalHeader()
        header.setResizeMode(QtGui.QHeaderView.Stretch)
        #set the date to current date
        self.dateStart.setDateTime(QtCore.QDateTime.currentDateTime())
        #set the request headers
        self.headers={
                      "Host":"kyfw.12306.cn",
                      "User-Agent":"Mozilla/5.0 (X11; Linux i686; rv:38.0) Gecko/20100101 Firefox/38.0",
                      "Connection":"keep-alive"}
        #initial the combobox
        self.station_url="https://kyfw.12306.cn/otn/resources/js/framework/station_name.js"
        self.log_url="https://kyfw.12306.cn/otn/leftTicket/log"
        self.confirm_url="https://kyfw.12306.cn/otn/confirmPassenger/initDc"
        self.queryT_url="https://kyfw.12306.cn/otn/leftTicket/query"
        self.check_user_url="https://kyfw.12306.cn/otn/login/checkUser"
        self.submit_order_url="https://kyfw.12306.cn/otn/leftTicket/submitOrderRequest"
        self.repeat_init_url="https://kyfw.12306.cn/otn/leftTicket/init?random="
        self.passengers_info_url="https://kyfw.12306.cn/otn/passengers/init"
        self.init_station_name()
        self.cmbFrom.setStyleSheet("combobox-popup: 0;"); #make  maxVisibleItems property available in GTK+
        self.cmbTo.setStyleSheet("combobox-popup: 0;");
        self.cmbFrom.setFocusPolicy(Qt.StrongFocus)
        self.cmbTo.setFocusPolicy(Qt.StrongFocus)
        self.cmbFrom.setCurrentIndex(-1)
        self.cmbTo.setCurrentIndex(-1)
        self.filtermodFrom=StationNameFilterProxy(self.station_name_dict, self.cmbFrom)
        self.filtermodFrom.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.filtermodFrom.setSourceModel(self.cmbFrom.model())
        self.completerFrom=QCompleter(self.filtermodFrom, self.cmbFrom)
        self.completerFrom.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.cmbFrom.setCompleter(self.completerFrom)
        self.cmbFrom.lineEdit().textEdited[unicode].connect(self.filtermodFrom.setFilterFixedString)
        self.completerFrom.activated.connect(self.on_completerFrom_activated)
        #-------------
        self.filtermodTo=StationNameFilterProxy(self.station_name_dict, self.cmbTo)
        self.filtermodTo.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.filtermodTo.setSourceModel(self.cmbTo.model())
        self.completerTo=QCompleter(self.filtermodTo, self.cmbTo)
        self.completerTo.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.cmbTo.setCompleter(self.completerTo)
        self.cmbTo.lineEdit().textEdited[unicode].connect(self.filtermodTo.setFilterFixedString)
        self.completerTo.activated.connect(self.on_completerTo_activated)
        #initial tableview's context menu and mainwindow's menu
        self.menuBar().setNativeMenuBar(False)
        self.tableTickets.addAction(self.action_login)#用户登录
        self.menuBar().addAction(self.action_login)
        self.tableTickets.addAction(self.action_tickets)#定时抢票
        self.menuBar().addAction(self.action_tickets)
        self.tableTickets.addAction(self.action_fresh_tickets)#自动刷票
        self.menuBar().addAction(self.action_fresh_tickets)
        if self.login_form.islogin : 
            self.action_login.setEnabled (False)
            self.get_passengers()
            self.booking_form.set_passenger_list(self.passengers_info)
        #initial tableview's column name
        self.dict_table_column={
            0:("station_train_code",_fromUtf8(u"车次")), 
            1:("from_station_name",_fromUtf8(u"出发站")), 
            2:("to_station_name",_fromUtf8(u"到达站")), 
            3:("start_time",_fromUtf8(u"出发时间")), 
            4:("arrive_time",_fromUtf8(u"达到时间")), 
            5:("lishi",_fromUtf8(u"历时")), 
            6:("swz_num",_fromUtf8(u"商务座")), 
            7:("tz_num",_fromUtf8(u"特等座")), 
            8:("zy_num",_fromUtf8(u"一等座")), 
            9:("ze_num",_fromUtf8(u"二等座")), 
            10:("gr_num",_fromUtf8(u"高级软卧")), 
            11:("rw_num",_fromUtf8(u"软卧")), 
            12:("yw_num",_fromUtf8(u"硬卧")), 
            13:("rz_num",_fromUtf8(u"软座")), 
            14:("yz_num",_fromUtf8(u"硬座")), 
            15:("wz_num",_fromUtf8(u"无座"))}
        self.monitor_list={}
        self.query_date=""
        self.from_station=""
        self.to_station=""
        self.conn.get("https://kyfw.12306.cn/otn/resources/js/query/qss.js", 
                      headers=self.headers,verify=False)
        
            
    def showEvent(self, event):
        super(MainWindow, self).showEvent(event)
        if self.login_form.first_time_called==False:return
        self.login_form.first_time_called=False
        self.login_form.exec_()
        if self.login_form.islogin : 
            self.action_login.setEnabled (False)
            self.get_passengers()
            self.booking_form.set_passenger_list(self.passengers_info)
    def closeEvent(self, event):
        if self.login_form.islogin==True:
            self.conn.get("https://kyfw.12306.cn/otn/login/loginOut", headers=self.headers, verify=False)
            print "Exit"
        
    def on_completerTo_activated(self, text):
        if text:
            index = self.cmbTo.findText(text)
            self.cmbTo.setCurrentIndex(index)
        
    def on_completerFrom_activated(self, text):
        if text:
            index = self.cmbFrom.findText(text)
            self.cmbFrom.setCurrentIndex(index)
        
    def init_station_name(self):
        self.print_log(u"获取站点信息")
        init_page_url="https://kyfw.12306.cn/otn/lcxxcx/init"
        init_page=requests.get(init_page_url, headers=self.headers,verify=False)
        init_str=init_page.text
        start=init_str.find("?station_version=")
        end=init_str.find("\"", start)
        station_version=init_str[start:end]
        station_page=requests.get(self.station_url+station_version, headers=self.headers, verify=False)
        station_str=station_page.text
        start=station_str.find("@", 0)+1
        end=station_str.find("@", start)
        self.station_name_dict={}
        self.station_name_index=0
        while end>0:
            str_tmp=station_str[start:end]
            token_tmp=str_tmp.split('|')
            self.cmbFrom.addItem(token_tmp[1])
            self.cmbTo.addItem(token_tmp[1])
            self.station_name_dict[self.station_name_index]=(token_tmp[0], token_tmp[3], token_tmp[4], token_tmp[2], token_tmp[1])
            self.station_name_index=self.station_name_index+1
            start=end+1
            end=station_str.find("@", start)
        end=station_str.find("\'", start)
        str_tmp=station_str[start:end]
        token_tmp=str_tmp.split('|')
        self.cmbFrom.addItem(token_tmp[1])
        self.cmbTo.addItem(token_tmp[1])
        self.station_name_dict[self.station_name_index]= (token_tmp[0], token_tmp[3], token_tmp[4], token_tmp[2], token_tmp[1])
        self.station_name_index=self.station_name_index+1
        
    def get_passengers(self):
        self.print_log(u"获取乘客信息")
        header=self.headers
        header["Referer"]="https://kyfw.12306.cn/otn/index/initMy12306"
        payload={"_json_att":""}
        passenger_page=self.conn.post(self.passengers_info_url, data=payload, headers=header, verify=False)
        passenger_text=passenger_page.text
        start_str="var passengers="
        start_index=passenger_text.find(start_str)
        start_index=start_index+len(start_str)
        end_index=passenger_text.find(";", start_index)
        passengers_info=passenger_text[start_index:end_index].replace("\'", "\"")
        self.passengers_info=json.loads(passengers_info)
        self.tableTickets.passengers_menu=QtGui.QMenu(_fromUtf8("乘客选择"), self.tableTickets)
        self.passengers_menu_actions=[]
        for p in self.passengers_info:
            self.passengers_menu_actions.append(QtGui.QAction(_fromUtf8(p['passenger_name']), self.tableTickets))
            actions_len=len(self.passengers_menu_actions)
            self.passengers_menu_actions[actions_len-1].setCheckable(True)
            if p['total_times']=='98':
                self.passengers_menu_actions[actions_len-1].setEnabled(False)
            self.tableTickets.passengers_menu.addAction(self.passengers_menu_actions[actions_len-1])
        self.tableTickets.addAction(self.tableTickets.passengers_menu.menuAction())
        self.menuBar().addAction(self.tableTickets.passengers_menu.menuAction())
        
    def query_tickets(self):
        query_date="{0:04}-{1:02}-{2:02}".format(self.dateStart.date().year(), self.dateStart.date().month(), self.dateStart.date().day())
        from_station=self.station_name_dict[self.cmbFrom.currentIndex()][3]
        to_station=self.station_name_dict[self.cmbTo.currentIndex()][3]
        if query_date!=self.query_date or from_station!=self.from_station or to_station!=self.to_station:
            self.monitor_list.clear()
            self.query_date=query_date
            self.from_station=from_station
            self.to_station=to_station
        query_params="?leftTicketDTO.train_date="+query_date
        query_params=query_params+"&leftTicketDTO.from_station="+from_station
        query_params=query_params+"&leftTicketDTO.to_station="+to_station
        query_params=query_params+"&purpose_codes=ADULT"
        log_page=self.conn.get(self.log_url+query_params+"A=T", headers=self.headers,verify=False)
        log_page_json=log_page.json()
        if log_page_json["status"] != True:
            return None
        query_page=self.conn.get(self.queryT_url+query_params, headers=self.headers,verify=False)
        query_page_json=query_page.json()
        if query_page_json["status"] == True and query_page_json.has_key('data'):
            return query_page_json['data']
        else:
            return None
    
    def fetch_tickes(self, station_from, station_to, query_date):
        tickets_url="https://kyfw.12306.cn/otn/lcxxcx/query?purpose_codes=ADULT&queryDate="+query_date
        tickets_url=tickets_url+"&from_station="+station_from
        tickets_url=tickets_url+"&to_station="+station_to
        tickets_page=requests.get(tickets_url, headers=self.headers,verify=False)
        tickets_dict=tickets_page.json()
        if tickets_dict["data"]["flag"]:
            return tickets_dict["data"]["datas"]
        else:return None
        
    def show_tickets(self, tickets):
        if not tickets:
            self.print_log(u"没有符合条件的数据")
            self.clear_table_content()
            return False
        col=0
        index=self.tableTickets.rowCount()
        if index!=len(tickets):
            self.tableTickets.setRowCount(len(tickets))
            index=0
            while index<len(tickets):
                col=0
                while col<len(self.dict_table_column):
                    item=QtGui.QTableWidgetItem(QtCore.QString(u""))
                    item.setFlags(QtCore.Qt.ItemIsEnabled)
                    self.tableTickets.setItem(index, col,item)
                    col=col+1
                index=index+1
        index=0
        for t in tickets:
            col=0
            if self.monitor_list.has_key(t['queryLeftNewDTO']['station_train_code']):
                red_col=self.monitor_list[t['queryLeftNewDTO']['station_train_code']]
            else:
                red_col=None
            while col<len(self.dict_table_column):
                item=self.tableTickets.item(index, col)
                item.setText(QtCore.QString(t['queryLeftNewDTO'][self.dict_table_column[col][0]]))
                if red_col and col in red_col:
                    item.setBackground(Qt.red)
                else:
                    item.setBackground(Qt.transparent)
                col=col+1
            index=index+1
        return True
            
    def print_log(self, text):
        str=QtCore.QString(datetime.datetime.now().strftime('%H:%M:%S')) + QtCore.QString(" - ") + QtCore.QString(_fromUtf8(text))
        self.plainTextEdit.appendPlainText(str)
    
    def print_session_info(self, conn):
        print"Headers:"
        for (k, v) in conn.headers.iteritems():
            print "\t%s:%s" %(k, v)
        print"Cookies:"
        for (k, v) in conn.cookies.iteritems():
            print "\t%s:%s" %(k, v)
    
    #action slots
    @pyqtSignature("")
    def on_action_login_triggered(self):
        print "on login triggered"
        self.login_form.on_btnRefresh_released()
        self.login_form.exec_()
        if self.login_form.islogin : 
            self.action_login.setEnabled (False)
            self.get_passengers()
            self.booking_form.set_passenger_list(self.passengers_info)
        
    @pyqtSignature("")
    def on_action_tickets_triggered(self):
        print "on tickets triggered"
        
    @pyqtSignature("")
    def on_action_fresh_tickets_triggered(self):
        print "on fresh triggered"
        
    @pyqtSignature("")
    def on_btnQuery_clicked(self):
        self.print_log(u"查询车次信息。。。")
        if self.cmbFrom.currentIndex()<0:
            self.print_log(u"请选择始发站点")
            self.clear_table_content()
            return
        if self.cmbTo.currentIndex()<0:
            self.print_log(u"请选择终点站")
            self.clear_table_content()
            return
        if self.dateStart.date() < QtCore.QDateTime.currentDateTime().date():
            self.print_log(u"请选择正确的乘车日期")
            self.clear_table_content()
            return
        if self.login_form.islogin==False:
            self.print_log("请先登录")
            self.clear_table_content()
            return
        self.print_log(u"正在获取车票信息。。。")
        self.current_tickets=self.query_tickets()
        #self.current_tickets=self.fetch_tickes(station_from, station_to, query_date)
        if self.show_tickets(self.current_tickets):
            self.print_log(u"获取车票信息完成")
            self.print_log(u"双击剩余票数,即可订票")
        #del self.monitor_list[:]
        
    def check_the_user(self):
        payload={"_json_att":""}
        self.print_log(u"执行用户认证。。。")
        check_page=self.conn.post(self.check_user_url,data=payload,headers=self.headers, verify=False)
        check_page_json = check_page.json()
        if check_page_json["data"]["flag"]==False:
            self.login_form.islogin=False
        if self.login_form.islogin==False:
            self.action_login.setEnabled (True)
            #self.clear_table_content()
            return False
        return True
        
    def submit_ticket(self, ticket_info):
        payload={
                 "secretStr":urllib.unquote(ticket_info["secretStr"]), 
                 "train_date":'{0:04}-{1:02}-{2:02}'.format(self.dateStart.date().year(), self.dateStart.date().month(), self.dateStart.date().day()),  
                 "back_train_date":'{0:04}-{1:02}-{2:02}'.format(self.dateStart.date().year(), self.dateStart.date().month(), self.dateStart.date().day()), 
                 "tour_flag":"dc", 
                 "purpose_codes":"ADULT", 
                 "query_from_station_name":self.station_name_dict[self.cmbFrom.currentIndex()][4].encode("utf-8"), 
                 "query_to_station_name":self.station_name_dict[self.cmbTo.currentIndex()][4].encode("utf-8"), 
                 "undefined":""
                 }
        self.print_log(u"提交订票信息。。。")
        submit_page=self.conn.post(self.submit_order_url, data=payload,headers=self.headers, verify=False)
        submit_page_json=submit_page.json()
        if submit_page_json["status"]==False:
            return False
        return True
        
    def load_confirm_page(self):
        payload={"_json_att":""}
        confirm_page=self.conn.post(self.confirm_url, data=payload,headers=self.headers, verify=False)
        confirm_page_text=confirm_page.text
        start_index=confirm_page_text.find("var globalRepeatSubmitToken = \'")+len("var globalRepeatSubmitToken = \'");
        end_index=confirm_page_text.find("\'", start_index);
        self.repeatToken=confirm_page_text[start_index:end_index]
        return confirm_page_text

    def clear_table_content(self):
        row=0
        col=0
        rowCount=self.tableTickets.rowCount()
        columnCount=self.tableTickets.columnCount()
        while row<rowCount:
            col=0
            while col<columnCount:
                item=self.tableTickets.item(row, col)
                item.setText(QtCore.QString(u""))
                item.setBackground(Qt.transparent)
                col=col+1
            row=row+1
        
    @pyqtSignature("int,int")
    def on_tableTickets_cellDoubleClicked(self, row, column):
        if column<5:return
        item=self.tableTickets.item(row, column)
        if item.text()==_fromUtf8(u"--"):
            msg=QtGui.QMessageBox()
            msg.setText(_fromUtf8(u"当前车次不发售")+self.dict_table_column[column][1])
            msg.exec_()
            return
        if item.text()==_fromUtf8(u"无"):
            train_code=self.current_tickets[row]["queryLeftNewDTO"]["station_train_code"]
            if self.monitor_list.has_key(train_code):
                if column in self.monitor_list[train_code]:
                    self.monitor_list[train_code].remove(column)
                    if len(self.monitor_list[train_code])==0:
                        del self.monitor_list[train_code]
                    item.setBackground(Qt.transparent)
                else:
                    self.monitor_list[train_code].add(column)
                    item.setBackground(Qt.red)
            else:
                self.monitor_list[train_code]=set([column])
                item.setBackground(Qt.red)
            return
        self.print_log(u"开始订票")
        #check the user
        if self.check_the_user()==False:
            msg=QtGui.QMessageBox()
            msg.setText(_fromUtf8(u"用户认证失败,请登录"))
            msg.exec_()
            return
        #submit tickets
        if self.submit_ticket(self.current_tickets[row])==False:
            msg=QtGui.QMessageBox()
            msg.setText(_fromUtf8(submit_page_json["messages"][0]))
            msg.exec_()
            return
        #load confirm page
        self.booking_form.confirm_page_text=self.load_confirm_page()
        self.booking_form.isDone=False
        self.booking_form.repeatToken=self.repeatToken
        index=0
        #set passengers checked in the booking form
        while index<len(self.passengers_menu_actions):
            if self.passengers_menu_actions[index].isChecked():
                self.booking_form.set_passenger_check_status(index, True)
            else:
                self.booking_form.set_passenger_check_status(index, False)
            index=index+1
        self.booking_form.ticket_infos=self.current_tickets[row]
        self.booking_form.set_train_info(self.current_tickets[row]["queryLeftNewDTO"], self.dateStart.date(), 
                                         self.dict_table_column[column][1], item.text())
        #start booking form
        self.booking_form.exec_()
        if self.booking_form.fresh_status==False:
            self.login_form.islogin=False
            self.action_login.setEnabled(True)
        #if booking failed, reload tickets infos
        if self.booking_form.isDone==False:
            t=datetime.datetime.now()
            posix_ms=int(time.mktime(t.timetuple()))*1000+(t.microsecond/1000)
            payload={"REPEAT_SUBMIT_TOKEN":self.repeatToken, 
                     "_json_att":"", 
                     "pre_step_flag":"preStep"}
            init_page=self.conn.post(self.repeat_init_url+str(posix_ms), data=payload, 
                                   headers=self.headers, verify=False)
            self.on_btnQuery_clicked()
        else:
            self.print_log(u"订票成功,请登录12306完成支付")
Exemplo n.º 50
0
class Main(plugin.Plugin):
    ' main class for plugin '
    def initialize(self, *args, **kwargs):
        ' class init '
        super(Main, self).initialize(*args, **kwargs)
        self.process = QProcess()
        self.process.readyReadStandardOutput.connect(self.readOutput)
        self.process.readyReadStandardError.connect(self.readErrors)
        self.process.finished.connect(self._process_finished)
        self.process.error.connect(self._process_finished)
        # directory auto completer
        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)

        menu = QMenu('Clones')
        menu.addAction('Analyze for Code Clones here', lambda: self.make_clon())
        self.locator.get_service('explorer').add_project_menu(menu, lang='all')

        self.group1 = QGroupBox()
        self.group1.setTitle(' Target ')
        self.outdir, self.igndir = QLineEdit(path.expanduser("~")), QLineEdit()
        self.outdir.setCompleter(self.completer)
        self.btn1 = QPushButton(QIcon.fromTheme("document-open"), ' Open ')
        self.btn1.clicked.connect(lambda: self.outdir.setText(str(
            QFileDialog.getExistingDirectory(self.dock,
            'Please, Open a Target Directory...', path.expanduser("~")))))
        self.btn1a = QPushButton(QIcon.fromTheme("face-smile"),
                                 'Get from Ninja active project')
        self.btn1a.clicked.connect(lambda: self.outdir.setText(
          self.locator.get_service('explorer').get_current_project_item().path))

        self.ignckb, self.ignmor = QComboBox(), QTextEdit()
        self.ignckb.addItems(['Single Directory', 'Multiple Directories CSV'])
        self.ignckb.currentIndexChanged.connect(self.on_ignore_changed)
        self.ignmor.hide()
        self.igndir.setPlaceholderText('Exclude directory')
        self.igndir.setCompleter(self.completer)
        self.btn2 = QPushButton(QIcon.fromTheme("document-open"), ' Open ')
        self.btn2.clicked.connect(lambda: self.igndir.setText(str(
            QFileDialog.getExistingDirectory(self.dock,
            'Please, Open a Ignore Directory...', path.expanduser("~")))))
        vboxg1 = QVBoxLayout(self.group1)
        for each_widget in (QLabel('<b>Target directory path: '), self.outdir,
            self.btn1, self.btn1a, QLabel('<b>Ignore directory path: '),
            self.ignckb, self.ignmor, self.igndir, self.btn2, ):
            vboxg1.addWidget(each_widget)

        self.group2 = QGroupBox()
        self.group2.setTitle(' Output ')
        self.outfle = QLineEdit(path.join(path.expanduser("~"), 'output.html'))
        self.outfle.setPlaceholderText('Exclude directory')
        self.outfle.setCompleter(self.completer)
        self.btn3 = QPushButton(QIcon.fromTheme("document-save"), ' Save ')
        self.btn3.clicked.connect(lambda: self.outfle.setText(
            QFileDialog.getSaveFileName(self.dock, 'Save', path.expanduser("~"),
            'XML(*.xml)' if self.xmlo.isChecked() is True else 'HTML(*.html)')))
        vboxg2 = QVBoxLayout(self.group2)
        for each_widget in (QLabel('<b>Output report file path:'),
            self.outfle, self.btn3):
            vboxg2.addWidget(each_widget)

        self.group3 = QGroupBox()
        self.group3.setTitle(' Options ')
        self.group3.setCheckable(True)
        self.group3.setGraphicsEffect(QGraphicsBlurEffect(self))
        self.group3.graphicsEffect().setEnabled(False)
        self.group3.toggled.connect(self.toggle_options_group)
        self.qckb1, self.qckb2 = QCheckBox('Recursive'), QCheckBox('Time-less')
        self.qckb3, self.qckb4 = QCheckBox('Force Diff'), QCheckBox('Fast Mode')
        self.qckb5, self.tm = QCheckBox('Save a LOG file to target'), QLabel('')
        self.xmlo = QCheckBox('XML Output instead of HTML')
        self.opeo = QCheckBox('Open Clones Report when done')
        self.chrt = QCheckBox('LOW CPU priority for Backend Process')
        self.mdist, self.hdep, self.output = QSpinBox(), QSpinBox(), QTextEdit()
        self.ign_func = QLineEdit('test, forward, backward, Migration')
        self.mdist.setValue(5)
        self.hdep.setValue(1)
        self.mdist.setToolTip('''<b>Maximum amount of difference between pair of
        sequences in clone pair (5 default).Larger value more false positive''')
        self.hdep.setToolTip('''<b>Computation can be speeded up by increasing
                       this value, but some clones can be missed (1 default)''')
        [a.setChecked(True) for a in (self.qckb1, self.qckb3, self.qckb5,
                                      self.chrt, self.opeo)]
        vboxg3 = QVBoxLayout(self.group3)
        for each_widget in (self.qckb1, self.qckb2, self.qckb3, self.qckb4,
            self.qckb5, self.chrt, self.xmlo, self.opeo,
            QLabel('<b>Max Distance Threshold:'), self.mdist,
            QLabel('<b>Max Hashing Depth:'), self.hdep,
            QLabel('<b>Ignore code block prefix:'), self.ign_func):
            vboxg3.addWidget(each_widget)

        self.group4, self.auto = QGroupBox(), QComboBox()
        self.group4.setTitle(' Automation ')
        self.group4.setCheckable(True)
        self.group4.setToolTip('<font color="red"><b>WARNING:Advanced Setting!')
        self.group4.toggled.connect(lambda: self.group4.hide())
        self.auto.addItems(['Never run automatically', 'Run when File Saved',
            'Run when File Executed', 'Run when Tab Changed',
            'Run when File Opened', 'Run before File Saved'])
        self.auto.currentIndexChanged.connect(self.on_auto_changed)
        QVBoxLayout(self.group4).addWidget(self.auto)

        self.button = QPushButton(' Analyze for Clones ')
        self.button.setMinimumSize(75, 50)
        self.button.clicked.connect(self.run)
        glow = QGraphicsDropShadowEffect(self)
        glow.setOffset(0)
        glow.setBlurRadius(99)
        glow.setColor(QColor(99, 255, 255))
        self.button.setGraphicsEffect(glow)

        self.butkil = QPushButton(' Force Kill Clones ')
        self.butkil.clicked.connect(lambda: self.process.kill())

        class TransientWidget(QWidget):
            ' persistant widget thingy '
            def __init__(self, widget_list):
                ' init sub class '
                super(TransientWidget, self).__init__()
                vbox = QVBoxLayout(self)
                for each_widget in widget_list:
                    vbox.addWidget(each_widget)

        tw = TransientWidget((QLabel('<i>D.R.Y. principle analyzer'),
            self.group1, self.group2, self.group3, self.group4,
            QLabel('<b>Backend Logs'), self.output, self.tm, self.button,
            self.butkil))
        self.scrollable, self.dock = QScrollArea(), QDockWidget()
        self.scrollable.setWidgetResizable(True)
        self.scrollable.setWidget(tw)
        self.dock.setWindowTitle(__doc__)
        self.dock.setStyleSheet('QDockWidget::title{text-align: center;}')
        self.dock.setWidget(self.scrollable)
        ExplorerContainer().addTab(self.dock, "Clones")
        QPushButton(QIcon.fromTheme("help-about"), 'About', self.dock
            ).clicked.connect(lambda:
            QMessageBox.information(self.dock, __doc__, HELPMSG))

    def readOutput(self):
        """Read and append output to the logBrowser"""
        self.output.append(str(self.process.readAllStandardOutput()).strip())

    def readErrors(self):
        """Read and append errors to the logBrowser"""
        self.output.append(self.formatErrorMsg(str(
                                        self.process.readAllStandardError())))

    def formatErrorMsg(self, msg):
        """Format error messages in red color"""
        return self.formatMsg(msg, 'red')

    def formatInfoMsg(self, msg):
        """Format informative messages in blue color"""
        return self.formatMsg(msg, 'green')

    def formatMsg(self, msg, color):
        """Format message with the given color"""
        return '<font color="{}">{}</font>'.format(color, msg)

    def make_clon(self):
        ' make clones analyze from contextual sub menu '
        self.outdir.setText(
          self.locator.get_service('explorer').get_current_project_item().path)
        self.run()

    def run(self):
        ' run the actions '
        self.output.clear()
        self.output.append(self.formatInfoMsg('INFO:{}'.format(datetime.now())))
        self.tm.setText('<center><b>Last Clone: </b>' +
                        datetime.now().isoformat().split('.')[0])
        self.button.setDisabled(True)
        if not len(self.outdir.text()) and not len(self.outfle.text()):
            self.output.append(self.formatErrorMsg('ERROR: FAIL: Target empty'))
            self.button.setEnabled(True)
            return
        # run the subprocesses
        cmd = ' '.join((
            'chrt -i 0' if self.chrt.isChecked() is True else '', 'clonedigger',
            '' if self.qckb1.isChecked() is True else '--no-recursion',
            '--dont-print-time' if self.qckb2.isChecked() is True else '',
            '--force' if self.qckb3.isChecked() is True else '',
            '--fast' if self.qckb4.isChecked() is True else '',
            '--cpd-output' if self.xmlo.isChecked() is True else '',
            '' if self.xmlo.isChecked() is True else '--report-unifiers',
            '--distance-threshold={}'.format(self.mdist.value()),
            '--hashing-depth={}'.format(self.hdep.value()),
            '--ignore-dir="{}"'.format(self.igndir.text()
                if self.ignckb.currentIndex() is 0
                else self.ignmor.toPlainText()),
            '--func-prefixes="{}"'.format(self.ign_func.text()),
            '--output="{}"'.format(self.outfle.text()),
            '--language=python', path.abspath(self.outdir.text()),
        ))
        self.output.append(self.formatInfoMsg('INFO:OK:Command:{}'.format(cmd)))
        self.process.start(cmd)
        if not self.process.waitForStarted():
            self.output.append(self.formatErrorMsg(' ERROR: FAIL: Meh. '))
            self.output.append(self.formatErrorMsg('ERROR:FAIL:{}'.format(cmd)))
            self.button.setEnabled(True)
            return
        self.readOutput()
        self.readErrors()
        self.button.setEnabled(True)

    def _process_finished(self):
        """ finished sucessfully """
        self.output.append(self.formatInfoMsg('INFO:{}'.format(datetime.now())))
        # write a .log file on target
        if self.qckb5.isChecked() is True:
            log_file = 'ninja_clones.log'
            with open(path.join(str(self.outdir.text()), log_file), 'w') as log:
                self.output.append(self.formatInfoMsg('''INFO: OK: Writing Logs:
                    {}'''.format(path.join(str(self.outdir.text()), log_file))))
                log.write(self.output.toPlainText())
                log.close()
        # open target output
        if self.opeo.isChecked() is True and self.xmlo.isChecked() is False:
            try:
                startfile(self.outfle.text())
            except:
                Popen(["xdg-open", self.outfle.text()])
        self.output.selectAll()
        self.output.setFocus()

    def toggle_options_group(self):
        ' toggle on off the options group '
        if self.group3.isChecked() is True:
            [a.setChecked(True) for a in (self.qckb1, self.qckb3, self.qckb5,
                                          self.chrt, self.opeo)]
            self.mdist.setValue(5)
            self.hdep.setValue(1)
            self.group3.graphicsEffect().setEnabled(False)
        else:
            [a.setChecked(False) for a in (self.qckb1, self.qckb3, self.qckb5,
                                           self.chrt, self.opeo)]
            self.group3.graphicsEffect().setEnabled(True)

    def on_ignore_changed(self):
        'hide or show one widget or another depending what kind of input need'
        if self.ignckb.currentIndex() is 0:
            self.igndir.show()
            self.btn2.show()
            self.ignmor.hide()
        else:
            self.igndir.hide()
            self.btn2.hide()
            self.ignmor.show()

    def on_auto_changed(self):
        ' automation connects '
        if self.auto.currentIndex() is 1:
            self.locator.get_service('editor').fileSaved.connect(lambda:
                self.run())
            QMessageBox.information(self.dock, __doc__,
            '<b>Now Actions will Run Automatically when any File is Saved !')
        elif self.auto.currentIndex() is 2:
            self.locator.get_service('editor').fileExecuted.connect(lambda:
                self.run())
            QMessageBox.information(self.dock, __doc__,
            '<b>Now Actions will Run Automatically when any File is Executed !')
        elif self.auto.currentIndex() is 3:
            self.locator.get_service('editor').currentTabChanged.connect(lambda:
                self.run())
            QMessageBox.information(self.dock, __doc__,
            '<b>Now Actions will Run Automatically when current Tab is Changed')
        elif self.auto.currentIndex() is 4:
            self.locator.get_service('editor').fileOpened.connect(lambda:
                self.run())
            QMessageBox.information(self.dock, __doc__,
            '<b>Now Actions will Run Automatically when any File is Opened !')
        elif self.auto.currentIndex() is 5:
            self.locator.get_service('editor').beforeFileSaved.connect(lambda:
                self.run())
            QMessageBox.information(self.dock, __doc__,
            '<b>Now Actions will Run Automatically before any File is Saved !')
        self.group4.setDisabled(True)

    def finish(self):
        ' clear when finish '
        self.process.kill()
Exemplo n.º 51
0
    def __init__(self, item, parent=None):
        QDialog.__init__(self, parent, Qt.Dialog)
        self.setModal(True)
        self._item = item
        self.setWindowTitle(self.tr("Project Properties"))
        grid = QGridLayout(self)
        grid.addWidget(QLabel(self.tr("Name:")), 0, 0)
        self.name = QLineEdit()
        if self._item.name == '':
            self.name.setText(file_manager.get_basename(self._item.path))
        else:
            self.name.setText(self._item.name)
        grid.addWidget(self.name, 0, 1)
        grid.addWidget(QLabel(self.tr("Project Type:")), 1, 0)
        self.txtType = QLineEdit()
        completer = QCompleter(sorted(settings.PROJECT_TYPES))
        completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.txtType.setCompleter(completer)
        self.txtType.setText(self._item.projectType)
        grid.addWidget(self.txtType, 1, 1)
        grid.addWidget(QLabel(self.tr("Description:")), 2, 0)
        self.description = QPlainTextEdit()
        self.description.setPlainText(self._item.description)
        grid.addWidget(self.description, 2, 1)
        grid.addWidget(QLabel(self.tr("URL:")), 3, 0)
        self.url = QLineEdit()
        self.url.setText(self._item.url)
        grid.addWidget(self.url, 3, 1)
        grid.addWidget(QLabel(self.tr("Licence:")), 4, 0)
        self.cboLicense = QComboBox()
        self.cboLicense.addItem('Apache License 2.0')
        self.cboLicense.addItem('Artistic License/GPL')
        self.cboLicense.addItem('Eclipse Public License 1.0')
        self.cboLicense.addItem('GNU General Public License v2')
        self.cboLicense.addItem('GNU General Public License v3')
        self.cboLicense.addItem('GNU Lesser General Public License')
        self.cboLicense.addItem('MIT License')
        self.cboLicense.addItem('Mozilla Public License 1.1')
        self.cboLicense.addItem('New BSD License')
        self.cboLicense.addItem('Other Open Source')
        self.cboLicense.addItem('Other')
        self.cboLicense.setCurrentIndex(4)
        index = self.cboLicense.findText(self._item.license)
        self.cboLicense.setCurrentIndex(index)
        grid.addWidget(self.cboLicense, 4, 1)
        grid.addWidget(QLabel(self.tr("Main File:")), 5, 0)
        self.path = QLineEdit()
        ui_tools.LineEditButton(
            self.path, self.path.clear,
            self.style().standardPixmap(self.style().SP_TrashIcon))
        self.path.setText(self._item.mainFile)
        self.path.setReadOnly(True)
        self.btnBrowse = QPushButton(
            QIcon(self.style().standardPixmap(self.style().SP_FileIcon)), '')
        hbox = QHBoxLayout()
        hbox.addWidget(self.path)
        hbox.addWidget(self.btnBrowse)
        grid.addLayout(hbox, 5, 1)

        self.txtExtensions = QLineEdit()
        self.txtExtensions.setText(str(', '.join(self._item.extensions)))
        grid.addWidget(QLabel(self.tr("Supported Extensions:")), 6, 0)
        grid.addWidget(self.txtExtensions, 6, 1)

        self.txtPythonPath = QLineEdit()
        self.txtPythonPath.setText(self._item.pythonPath)
        self.btnPythonPath = QPushButton(QIcon(resources.IMAGES['open']), '')
        grid.addWidget(QLabel(self.tr("Python Path:")), 7, 0)
        grid.addWidget(self.txtPythonPath, 7, 1)
        grid.addWidget(self.btnPythonPath, 7, 2)

        self.txtParams = QLineEdit()
        self.txtParams.setToolTip(
            self.tr("Separate the params with commas (ie: help, verbose)"))
        self.txtParams.setText(self._item.programParams)
        grid.addWidget(QLabel(self.tr("Params (comma separated):")), 8, 0)
        grid.addWidget(self.txtParams, 8, 1)

        #Widgets for virtualenv properties
        self.txtVenvPath = QLineEdit()
        ui_tools.LineEditButton(
            self.txtVenvPath, self.txtVenvPath.clear,
            self.style().standardPixmap(self.style().SP_TrashIcon))
        self.txtVenvPath.setText(self._item.venv)
        self.txtVenvPath.setReadOnly(True)
        self.btnVenvPath = QPushButton(QIcon(resources.IMAGES['open']), '')
        grid.addWidget(QLabel(self.tr("Virtualenv Folder:")), 9, 0)
        grid.addWidget(self.txtVenvPath, 9, 1)
        grid.addWidget(self.btnVenvPath, 9, 2)

        self.btnSave = QPushButton(self.tr("Save"))
        self.btnCancel = QPushButton(self.tr("Cancel"))
        hbox3 = QHBoxLayout()
        hbox3.addWidget(self.btnCancel)
        hbox3.addWidget(self.btnSave)
        grid.addLayout(hbox3, 10, 1)

        self.connect(self.btnBrowse, SIGNAL("clicked()"), self.select_file)
        self.connect(self.btnCancel, SIGNAL("clicked()"), self.close)
        self.connect(self.btnSave, SIGNAL("clicked()"), self.save_properties)
        self.connect(self.btnPythonPath, SIGNAL("clicked()"),
                     self._load_python_path)
        self.connect(self.btnVenvPath, SIGNAL("clicked()"),
                     self._load_python_venv)
Exemplo n.º 52
0
class ReciboDelegate( QStyledItemDelegate ):

    def __init__( self, parent = None ):
        super( ReciboDelegate, self ).__init__( parent )

        query = QSqlQuery( """
            SELECT
                idtipomovimiento,
                CONCAT(descripcion, ' ' , moneda) as tipopago,
                idtipomoneda,
                m.simbolo
                FROM tiposmoneda m
            JOIN tiposmovimientocaja p
            ;
        """ )
        self.filtrados = []
        query.exec_()
        while query.next():
            self.filtrados.append( query.value( 1 ).toString() )

        self.abonosmodel = QSqlQueryModel()
        self.abonosmodel.setQuery( query )
        self.proxymodel = QSortFilterProxyModel()
        self.proxymodel.setSourceModel( self.abonosmodel )
        self.proxymodel.setFilterKeyColumn( 1 )
        self.completer = QCompleter()
        self.completer.setModel( self.proxymodel )

        self.completer.setCompletionColumn( 1 )
        self.completer.setCaseSensitivity( Qt.CaseInsensitive )
        self.completer.setCompletionMode( QCompleter.UnfilteredPopupCompletion )

        query = QSqlQuery( """
            SELECT idbanco,descripcion FROM bancos;
            """ )
        self.bancosmodel = QSqlQueryModel()
        self.bancosmodel.setQuery( query )



    def createEditor( self, parent, option, index ):
        if index.column() == DESCRIPCION:
            combo = QComboBox( parent )
            combo.setEditable( True )
            value = index.data().toString()
            self.filtrados.append( value )
            self.proxymodel.setFilterRegExp( self.filter() )
            combo.setModel( self.proxymodel )
            combo.setModelColumn( 1 )
            combo.setCompleter( self.completer )
            return combo
        elif index.column() == BANCO:
            combo = QComboBox( parent )
            #combo.setEditable(True)
            combo.setModel( self.bancosmodel )
            combo.setModelColumn( 1 )
            #combo.setCompleter(self.completer)
            return combo
        elif index.column() == MONTO:
            doublespinbox = QDoubleSpinBox( parent )
            doublespinbox.setMinimum( -1000000 )
            doublespinbox.setMaximum( 1000000 )
            doublespinbox.setDecimals( 4 )
            doublespinbox.setAlignment( Qt.AlignHCenter )
            return doublespinbox
        elif index.column() == REFERENCIA:
            textbox = QStyledItemDelegate.createEditor( self, parent, option, index )
            textbox.setAlignment( Qt.AlignHCenter )
            return textbox

#FIXME: Se deberia de especificar siempre el tipo de excepción que se esta atrapando
    def removeFromFilter( self, value ):
        try:
            self.filtrados.remove( value )
            return True
        except:
            #FIXME: Se deberia de especificar siempre el tipo de excepción que se esta atrapando
            return False

    def filter( self ):
        filtro = "$|^".join( self.filtrados )
        if filtro != "":
            filtro = "^" + filtro + "$"
        return filtro

    def setEditorData( self, editor, index ):
        data = index.data()
        if index.column() in ( BANCO, DESCRIPCION ):
            i = editor.findText( data if type( data ) != QVariant else data.toString() )
            if i == -1:
                i = 0
            editor.setCurrentIndex( i )
        elif index.column() == MONTO:
            editor.setValue( index.model().data( index, Qt.EditRole ) if index.model().data( index, Qt.EditRole ) != "" else 0 )
        else:
            QStyledItemDelegate.setEditorData( self, editor, index )

    def setModelData( self, editor, model, index ):

        if index.column() == DESCRIPCION:
            modelo = self.proxymodel
            if modelo.rowCount() > 0:
                fila = editor.currentIndex()
                model.setData( index, [
                                           modelo.index( fila, 0 ).data().toInt()[0],
                                           modelo.index( fila, 1 ).data().toString(),
                                           modelo.index( fila, 2 ).data().toInt()[0],
                                           modelo.index( fila, 3 ).data().toString()
                    ] )
                self.removeFromFilter( modelo.index( fila, 1 ).data().toString() )
                self.proxymodel.setFilterRegExp( self.filter() )
        elif index.column() == BANCO:
            modelo = self.bancosmodel
            if modelo.rowCount() == 0 :
                model.setData( index, [-1, ""] )
            else:
                fila = editor.currentIndex()
                model.setData( index, [
                                               modelo.index( fila, 0 ).data().toInt()[0],
                                               modelo.index( fila, 1 ).data().toString()
                        ] )
        else:
            QStyledItemDelegate.setModelData( self, editor, model, index )

    def sizeHint( self, option, index ):
        u"""
        El tamaño sugerido de los datos en el modelo
        """
        fm = option.fontMetrics
        if index.column() == DESCRIPCION:
            return QSize( 250, fm.height() )
        else:
            return QSize( 150, fm.height() )

        return QStyledItemDelegate.sizeHint( self, option, index )