Beispiel #1
0
class LayerListDialog(QDialog):
    def __init__(self, parent):
        QDialog.__init__(self, parent)

        # add a button box
        self.layout = QVBoxLayout()

        self.layer_list = LayerListWidget(self)
        self.button_box = QDialogButtonBox(self)
        self.button_box.setOrientation(Qt.Horizontal)
        self.button_box.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok)
        self.button_box.accepted.connect(self.accept)
        self.button_box.rejected.connect(self.reject)

        self.layout.addWidget(self.layer_list)
        self.layout.addWidget(self.button_box)

        self.setLayout(self.layout)

    def set_labeling_model(self, model):
        self.layer_list.set_model(model)

    def exec_(self):
        self.layer_list.update_from_layers()
        return QDialog.exec_(self)

    def accept(self):
        # update layers
        self.layer_list.update_labeling_from_list()
        QDialog.accept(self)
Beispiel #2
0
class AboutBox(QDialog):
    def __init__(self, parent, app, **kwargs):
        flags = Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowSystemMenuHint | Qt.MSWindowsFixedSizeDialogHint
        super().__init__(parent, flags, **kwargs)
        self.app = app
        self._setupUi()

        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)

    def _setupUi(self):
        self.setWindowTitle(tr("About {}").format(QCoreApplication.instance().applicationName()))
        self.resize(400, 190)
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth())
        self.setSizePolicy(sizePolicy)
        self.horizontalLayout = QHBoxLayout(self)
        self.logoLabel = QLabel(self)
        self.logoLabel.setPixmap(QPixmap(':/%s_big' % self.app.LOGO_NAME))
        self.horizontalLayout.addWidget(self.logoLabel)
        self.verticalLayout = QVBoxLayout()
        self.nameLabel = QLabel(self)
        font = QFont()
        font.setWeight(75)
        font.setBold(True)
        self.nameLabel.setFont(font)
        self.nameLabel.setText(QCoreApplication.instance().applicationName())
        self.verticalLayout.addWidget(self.nameLabel)
        self.versionLabel = QLabel(self)
        self.versionLabel.setText(tr("Version {}").format(QCoreApplication.instance().applicationVersion()))
        self.verticalLayout.addWidget(self.versionLabel)
        self.label_3 = QLabel(self)
        self.verticalLayout.addWidget(self.label_3)
        self.label_3.setText(tr("Licensed under GPLv3"))
        self.label = QLabel(self)
        font = QFont()
        font.setWeight(75)
        font.setBold(True)
        self.label.setFont(font)
        self.verticalLayout.addWidget(self.label)
        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Ok)
        self.verticalLayout.addWidget(self.buttonBox)
        self.horizontalLayout.addLayout(self.verticalLayout)
Beispiel #3
0
class BudgetPanel(Panel):
    FIELDS = [
        ('amountEdit', 'amount'),
        ('notesEdit', 'notes'),
    ]
    PERSISTENT_NAME = 'budgetPanel'

    def __init__(self, model, mainwindow):
        Panel.__init__(self, mainwindow)
        self.setAttribute(Qt.WA_DeleteOnClose)
        self._setupUi()
        self.model = model
        self.accountComboBox = ComboboxModel(model=self.model.account_list, view=self.accountComboBoxView)

        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)

    def _setupUi(self):
        self.setWindowTitle(tr("Budget Info"))
        self.resize(230, 230)
        self.setModal(True)
        self.verticalLayout = QVBoxLayout(self)
        self.formLayout = QFormLayout()
        self.formLayout.setFieldGrowthPolicy(QFormLayout.ExpandingFieldsGrow)
        self.accountComboBoxView = QComboBox(self)
        self.formLayout.setWidget(0, QFormLayout.FieldRole, self.accountComboBoxView)
        self.label_3 = QLabel(tr("Account:"))
        self.formLayout.setWidget(0, QFormLayout.LabelRole, self.label_3)
        self.amountEdit = QLineEdit(self)
        self.amountEdit.setMaximumWidth(120)
        self.formLayout.setWidget(1, QFormLayout.FieldRole, self.amountEdit)
        self.label_5 = QLabel(tr("Amount:"))
        self.formLayout.setWidget(1, QFormLayout.LabelRole, self.label_5)
        self.notesEdit = QPlainTextEdit(tr("Notes:"))
        self.formLayout.setWidget(2, QFormLayout.FieldRole, self.notesEdit)
        self.label = QLabel(self)
        self.formLayout.setWidget(2, QFormLayout.LabelRole, self.label)
        self.verticalLayout.addLayout(self.formLayout)
        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Save)
        self.verticalLayout.addWidget(self.buttonBox)
        self.label_3.setBuddy(self.accountComboBoxView)
        self.label_5.setBuddy(self.amountEdit)
Beispiel #4
0
class PasswordInputView(QWidget, Ui_PasswordInputWidget):
    """
    The model of Navigation component
    """
    def __init__(self, parent):
        # construct from qtDesigner
        super().__init__(parent)
        self.setupUi(self)
        self.button_box = QDialogButtonBox(self)
        self.button_box.setOrientation(Qt.Horizontal)
        self.button_box.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok)
        self.button_box.button(QDialogButtonBox.Ok).setEnabled(False)
        self.layout().addWidget(self.button_box)
        self.button_box.hide()

    def error(self, text):
        self.label_info.setText(text)
        self.button_box.button(QDialogButtonBox.Ok).setEnabled(False)

    def clear(self):
        self.edit_password.clear()
        self.edit_secret_key.clear()

    def valid(self):
        self.label_info.setText(self.tr("Password is valid"))
        self.button_box.button(QDialogButtonBox.Ok).setEnabled(True)

    def changeEvent(self, event):
        """
        Intercepte LanguageChange event to translate UI
        :param QEvent QEvent: Event
        :return:
        """
        if event.type() == QEvent.LanguageChange:
            self.retranslateUi(self)
        return super(PasswordInputView, self).changeEvent(event)
    def showDialog(self, currentCard=None):
        # Handle for dialog open without a current card from IR model
        did = None
        cid = None
        if not currentCard:
            deck = mw._selectedDeck()
            did = deck['id']
        else:
            did = currentCard.did
            cid = currentCard.id

        cardDataList = self.getCardDataList(did, cid)
        if not cardDataList:
            showInfo(_('Please select an Incremental Reading deck.'))
            return

        d = QDialog(mw)
        l = QVBoxLayout()
        w = AnkiWebView()
        l.addWidget(w)

        script = '''
        var cardList = new Array();
        '''
        index = 0
        for cardData in cardDataList:
            index += 1
            script += "card = new Object();"
            script += "card.id = " + str(cardData['id']) + ";"
            script += "card.title = '" + str(cardData['title']) + "';"
            script += "card.isCurrent = " + str(cardData['isCurrent']) + ";"
            script += "card.checkbox = document.createElement('input');"
            script += "card.checkbox.type = 'checkbox';"
            if cardData['isCurrent'] == 'true':
                script += "card.checkbox.setAttribute('checked', 'true');"
            script += "cardList[cardList.length] = card;"

        script += """
        function buildCardData() {
            var container = document.getElementById('cardList');
            container.innerHTML = '';
            var list = document.createElement('div');
            list.setAttribute('style','overflow:auto;');
            var table = document.createElement('table');
            list.appendChild(table);
            container.appendChild(list);
            var row;
            var col;
            var cardData;
            for (var i = 0; i < cardList.length; i++) {
                row = document.createElement('tr');
                row.setAttribute('id','row' + i);
                cardData = cardList[i];

                col = document.createElement('td');
                col.setAttribute('style','width:4em;');
                col.innerHTML = '' + i;
                row.appendChild(col);

                col = document.createElement('td');
                col.setAttribute('style','width:10em;');
                col.innerHTML = '' + cardData.id;
                row.appendChild(col);

                col = document.createElement('td');
                col.setAttribute('style','width:30em;');
                col.innerHTML = '' + cardData.title;
                row.appendChild(col);

                col = document.createElement('td');
                col.setAttribute('style','width:2em;');
                col.appendChild(cardData.checkbox);
                row.appendChild(col);

                table.appendChild(row);
            }
        }

        function reposition(origIndex, newIndex, isTopOfRange) {
            if (newIndex < 0 || newIndex > (cardList.length-1)) return -1;
            if (cardList[newIndex].checkbox.checked) return -1;

            if (isTopOfRange) {
                document.getElementById('newPos').value = newIndex;
            }
            var removedCards = cardList.splice(origIndex,1);
            cardList.splice(newIndex, 0, removedCards[0]);
            return newIndex;
        }

        function moveSelectedUp() {
            var topOfRange = -1;
            for (var i = 0; i < cardList.length; i++) {
                if (cardList[i].checkbox.checked) {
                    if (topOfRange == -1) {
                        topOfRange = i;
                    }
                    if (i == topOfRange) {
                        if (document.getElementById('anchor').checked) {
                            continue; //Don't move end of range if anchored.
                        } else {
                            reposition(i, i - 1, true);
                        }
                    } else {
                        reposition(i, i - 1, false);
                    }
                }
            }
            buildCardData();
        }

        function moveSelectedDown() {
            var topOfRange = -1;
            var bottomOfRange = -1;
            for (var i = 0; i < cardList.length; i++) {
                if (cardList[i].checkbox.checked) {
                    if (topOfRange == -1) {
                        topOfRange = i;
                    }
                    bottomOfRange = i;
                }
            }
            for (var i = cardList.length-1; i > -1; i--) {
                if (cardList[i].checkbox.checked) {
                    if (i == bottomOfRange &&
                            document.getElementById('anchor').checked) {
                        continue; //Don't move end of range if anchored.
                    }
                    if (i == topOfRange) {
                        reposition(i, i + 1, true);
                    } else {
                        reposition(i, i + 1, false);
                    }
                }
            }
            buildCardData();
        }

        function selectAll() {
            for (var i = 0; i < cardList.length; i++) {
                cardList[i].checkbox.checked = true;
            }
        }

        function selectNone() {
            for (var i = 0; i < cardList.length; i++) {
                cardList[i].checkbox.checked = false;
            }
        }

        function directMove() {
            var newIndex = document.getElementById('newPos').value;
            var topOfRange = -1;
            origIndex = -1;
            for (var i = 0; i < cardList.length; i++) {
                if (cardList[i].checkbox.checked) {
                    if (topOfRange == -1) {
                        topOfRange = i;
                    }
                    if (origIndex == -1) {
                        origIndex = i;
                        sizeOfMove = (newIndex - origIndex);
                    }
                }
            }
            if (sizeOfMove < 0) {
                for (var i = 0; i < cardList.length; i++) {
                    if (cardList[i].checkbox.checked) {
                        if (i == topOfRange) {
                            reposition(i, i + sizeOfMove, true);
                        } else {
                            reposition(i, i + sizeOfMove, false);
                        }
                    }
                }
            } else {
                for (var i = cardList.length-1; i > -1; i--) {
                    if (cardList[i].checkbox.checked) {
                        if (i == topOfRange) {
                            reposition(i, i + sizeOfMove, true);
                        } else {
                            reposition(i, i + sizeOfMove, false);
                        }
                    }
                }
            }
            buildCardData();
        }

        function updatePositions() {
            var cids = new Array();
            for (var i=0; i < cardList.length; i++) {
                cids[cids.length] = parseInt(cardList[i].id);
            }
            return cids.join();
        };
        """

        newPosField = "<span style='font-weight:bold'>Card Position: </span><input type='text' id='newPos' size='5' value='0' />&nbsp;<span style='font-weight:bold'>of " + str(
            len(cardDataList)) + "</span>&nbsp;&nbsp;"
        newPosField += "<input type='button' value='Apply' onclick='directMove()' />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style='font-weight:bold'>Pin Top/Bottom? </span><input type='checkbox' id='anchor'/>"

        upDownButtons = "<input type='button' value='Move Up' onclick='moveSelectedUp()'/><input type='button' value='Move Down' onclick='moveSelectedDown()'/>"
        upDownButtons += "<input type='button' value='Select All' onclick='selectAll()'/><input type='button' value='Select None' onclick='selectNone()'/>"

        html = "<html><head><script>" + script + "</script></head><body onLoad='buildCardData()'>"
        html += "<p>" + newPosField
        html += "<p>" + upDownButtons
        html += "<div id='cardList'></div>"
        html += "</body></html>"
        w.stdHtml(html)
        bb = QDialogButtonBox(QDialogButtonBox.Close | QDialogButtonBox.Save)
        bb.accepted.connect(d.accept)
        bb.rejected.connect(d.reject)
        bb.setOrientation(Qt.Horizontal)
        l.addWidget(bb)
        d.setLayout(l)
        d.setWindowModality(Qt.WindowModal)
        d.resize(500, 500)
        choice = d.exec_()
        if choice == 1:
            if ANKI_21:
                cids = w.page().runJavaScript('updatePositions()',
                                              self.callback)
            else:
                cids = w.page().mainFrame().evaluateJavaScript(
                    'updatePositions()')
                self.repositionCards(cids)
        elif currentCard:
            self.repositionCard(currentCard, -1)
Beispiel #6
0
class TransactionPanel(Panel):
    FIELDS = [
        ('dateEdit', 'date'),
        ('descriptionEdit', 'description'),
        ('payeeEdit', 'payee'),
        ('checkNoEdit', 'checkno'),
        ('notesEdit', 'notes'),
    ]
    PERSISTENT_NAME = 'transactionPanel'

    def __init__(self, model, mainwindow):
        Panel.__init__(self, mainwindow)
        self.setAttribute(Qt.WA_DeleteOnClose)
        self.model = model
        self._setupUi()
        self.splitTable = SplitTable(model=self.model.split_table,
                                     view=self.splitTableView)

        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)
        self.mctButton.clicked.connect(self.model.mct_balance)
        self.assignImbalanceButton.clicked.connect(self.model.assign_imbalance)
        self.addSplitButton.clicked.connect(self.splitTable.model.add)
        self.removeSplitButton.clicked.connect(self.splitTable.model.delete)

    def _setupUi(self):
        self.setWindowTitle(tr("Transaction Info"))
        self.resize(462, 329)
        self.setModal(True)
        self.mainLayout = QVBoxLayout(self)
        self.tabWidget = QTabWidget(self)
        self.infoTab = QWidget()
        self.infoLayout = QVBoxLayout(self.infoTab)
        self.formLayout = QFormLayout()
        self.formLayout.setFieldGrowthPolicy(QFormLayout.ExpandingFieldsGrow)
        self.dateEdit = DateEdit(self.infoTab)
        self.dateEdit.setMaximumSize(QSize(120, 16777215))
        self.formLayout.addRow(tr("Date:"), self.dateEdit)
        self.descriptionEdit = DescriptionEdit(self.model.completable_edit,
                                               self.infoTab)
        self.formLayout.addRow(tr("Description:"), self.descriptionEdit)
        self.payeeEdit = PayeeEdit(self.model.completable_edit, self.infoTab)
        self.formLayout.addRow(tr("Payee:"), self.payeeEdit)
        self.checkNoEdit = QLineEdit(self.infoTab)
        self.checkNoEdit.setMaximumSize(QSize(120, 16777215))
        self.formLayout.addRow(tr("Check #:"), self.checkNoEdit)
        self.infoLayout.addLayout(self.formLayout)
        self.amountLabel = QLabel(tr("Transfers:"), self.infoTab)
        self.infoLayout.addWidget(self.amountLabel)
        self.splitTableView = TableView(self.infoTab)
        self.splitTableView.setAcceptDrops(True)
        self.splitTableView.setEditTriggers(QAbstractItemView.DoubleClicked
                                            | QAbstractItemView.EditKeyPressed)
        self.splitTableView.setDragEnabled(True)
        self.splitTableView.setDragDropMode(QAbstractItemView.InternalMove)
        self.splitTableView.setSelectionMode(QAbstractItemView.SingleSelection)
        self.splitTableView.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.splitTableView.horizontalHeader().setDefaultSectionSize(40)
        self.splitTableView.verticalHeader().setVisible(False)
        self.splitTableView.verticalHeader().setDefaultSectionSize(18)
        self.infoLayout.addWidget(self.splitTableView)
        self.mctButtonsLayout = QHBoxLayout()
        self.mctButtonsLayout.setContentsMargins(0, 0, 0, 0)
        spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding,
                                 QSizePolicy.Minimum)
        self.mctButtonsLayout.addItem(spacerItem)
        self.mctButton = QPushButton(tr("&Multi-currency balance"),
                                     self.infoTab)
        self.mctButtonsLayout.addWidget(self.mctButton)
        self.assignImbalanceButton = QPushButton(tr("Assign &imbalance"),
                                                 self.infoTab)
        self.mctButtonsLayout.addWidget(self.assignImbalanceButton)
        self.addSplitButton = QPushButton(self.infoTab)
        icon = QIcon()
        icon.addPixmap(QPixmap(":/plus_8"), QIcon.Normal, QIcon.Off)
        self.addSplitButton.setIcon(icon)
        self.mctButtonsLayout.addWidget(self.addSplitButton)
        self.removeSplitButton = QPushButton(self.infoTab)
        icon1 = QIcon()
        icon1.addPixmap(QPixmap(":/minus_8"), QIcon.Normal, QIcon.Off)
        self.removeSplitButton.setIcon(icon1)
        self.mctButtonsLayout.addWidget(self.removeSplitButton)
        self.infoLayout.addLayout(self.mctButtonsLayout)
        self.tabWidget.addTab(self.infoTab, tr("Info"))
        self.notesTab = QWidget()
        self.notesLayout = QVBoxLayout(self.notesTab)
        self.notesEdit = QPlainTextEdit(self.notesTab)
        self.notesLayout.addWidget(self.notesEdit)
        self.tabWidget.addTab(self.notesTab, tr("Notes"))
        self.tabWidget.setCurrentIndex(0)
        self.mainLayout.addWidget(self.tabWidget)
        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel
                                          | QDialogButtonBox.Save)
        self.mainLayout.addWidget(self.buttonBox)

    def _loadFields(self):
        Panel._loadFields(self)
        self.tabWidget.setCurrentIndex(0)

    # --- model --> view
    def refresh_for_multi_currency(self):
        self.mctButton.setEnabled(self.model.is_multi_currency)
Beispiel #7
0
class MoveFileDialog(QDialog):
    '''移动文件对话框'''
    new_infos = pyqtSignal(object)

    def __init__(self, infos, all_dirs_dict, parent=None):
        super(MoveFileDialog, self).__init__(parent)
        self.infos = infos
        self.dirs = all_dirs_dict
        self.initUI()
        self.setStyleSheet(dialog_qss_style)

    def initUI(self):
        for i in self.infos:
            if not i[2]:  # 非文件
                self.infos.remove(i)
        self.setWindowTitle("移动文件")
        self.setWindowIcon(QIcon("./src/move.ico"))
        self.lb_name = QLabel()
        self.lb_name.setText("文件路径:")
        self.lb_name.setAlignment(Qt.AlignRight | Qt.AlignTrailing
                                  | Qt.AlignVCenter)
        self.tx_name = QLineEdit()
        names = " | ".join([i[1] for i in self.infos])
        names_tip = "\n".join([i[1] for i in self.infos])
        self.tx_name.setText(names)
        self.tx_name.setToolTip(names_tip)
        # 只读
        self.tx_name.setFocusPolicy(Qt.NoFocus)
        self.tx_name.setReadOnly(True)
        self.lb_new_path = QLabel()
        self.lb_new_path.setText("目标文件夹:")
        self.lb_new_path.setAlignment(Qt.AlignRight | Qt.AlignTrailing
                                      | Qt.AlignVCenter)
        self.tx_new_path = QComboBox()
        f_icon = QIcon("./src/folder.gif")
        for f_name, fid in self.dirs.items():
            if len(f_name) > 50:  # 防止文件夹名字过长?
                f_name = f_name[:47] + "..."
            self.tx_new_path.addItem(f_icon,
                                     "id:{:>8},name:{}".format(fid, f_name))

        self.buttonBox = QDialogButtonBox()
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Ok
                                          | QDialogButtonBox.Cancel)
        self.buttonBox.button(QDialogButtonBox.Ok).setText("确定")
        self.buttonBox.button(QDialogButtonBox.Cancel).setText("取消")

        self.grid = QGridLayout()
        self.grid.setSpacing(10)
        self.grid.addWidget(self.lb_name, 1, 0)
        self.grid.addWidget(self.tx_name, 1, 1)
        self.grid.addWidget(self.lb_new_path, 2, 0)
        self.grid.addWidget(self.tx_new_path, 2, 1)
        self.grid.addWidget(self.buttonBox, 3, 0, 1, 2)
        self.setLayout(self.grid)
        self.buttonBox.accepted.connect(self.btn_ok)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)
        self.setMinimumWidth(280)

    def btn_ok(self):
        selected = self.tx_new_path.currentText().split(",")[0].split(":")[1]
        self.new_infos.emit([(info[0], selected, info[1])
                             for info in self.infos])
Beispiel #8
0
class CityListDlg(QDialog):
    citieslist_signal = pyqtSignal([list])
    citiesdict_signal = pyqtSignal([dict])

    def __init__(
        self, citylist, accurate_url, appid, trans_cities_dict, parent=None
    ):
        super(CityListDlg, self).__init__(parent)
        self.settings = QSettings()
        self.citylist = citylist
        self.trans_cities_dict = trans_cities_dict
        self.accurate_url = accurate_url
        self.appid = appid
        self.listWidget = QListWidget()
        self.listWidget.itemDoubleClicked.connect(self.translate)
        cities_list = []
        for i in self.citylist:
            cities_list.append(self.trans_cities_dict.get(i, i))
        self.listWidget.addItems(cities_list)
        buttonLayout = QVBoxLayout()
        self.buttonBox = QDialogButtonBox()
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(
            QDialogButtonBox.Ok | QDialogButtonBox.Cancel
        )
        self.buttonBox.rejected.connect(self.reject)
        self.buttonBox.accepted.connect(self.accept)
        layoutT = QVBoxLayout()
        layout = QHBoxLayout()
        layout.addWidget(self.listWidget)
        layout.addLayout(buttonLayout)
        for text, slot in ((self.tr("&Add..."), self.add),
                           (self.tr("&Remove..."), self.remove),
                           (self.tr("&Up"), self.up),
                           (self.tr("&Down"), self.down),
                           (self.tr("De&fault"), self.default),
                           (self.tr("&Sort"), self.listWidget.sortItems)):
            button = QPushButton(text)
            buttonLayout.addWidget(button)
            button.clicked.connect(slot)
        self.translate_button = QPushButton(
            QCoreApplication.translate(
                'Button',
                '&Translate',
                'Edit cities name'
            )
        )
        buttonLayout.addWidget(self.translate_button)
        self.translate_button.clicked.connect(self.translate)
        buttonLayout.addWidget(self.buttonBox)
        self.status = QLabel()
        layoutT.addLayout(layout)
        layoutT.addWidget(self.status)
        self.setLayout(layoutT)
        self.setWindowTitle(
            QCoreApplication.translate(
                'Window title',
                'Cities',
                'Cities list dialogue'
            )
        )
        self.checklength()

    def add(self):
        self.status.setText('')
        lista = []
        newitem = ''
        self.citytoadd = ''
        self.countrytoadd = ''
        self._idtoadd = ''
        dialog = searchcity.SearchCity(self.accurate_url, self.appid, self)
        dialog.id_signal.connect(self.addcity)
        dialog.city_signal.connect(self.addcity)
        dialog.country_signal.connect(self.addcity)
        if dialog.exec_() == 1:
            newitem = (
                self.citytoadd + '_' + self.countrytoadd
                + '_' + self._idtoadd
            )
            for row in range(self.listWidget.count()):
                lista.append(self.listWidget.item(row).text())
            if newitem in lista:
                self.status.setText(
                    QCoreApplication.translate(
                        'Status bar message',
                        'The city already exists in the list',
                        'Cities list dialogue'
                    )
                )
                return
            else:
                self.listWidget.addItem(newitem)
                self.checklength()
                self.status.setText(
                    'ℹ ' + QCoreApplication.translate(
                        'Status bar message',
                        'Toggle cities with mouse scroll on the weather window',
                        'Cities list dialogue'
                    )
                )

    def addcity(self, what):
        self.status.setText('')
        if what[0] == 'ID':
            self._idtoadd = what[1]
        elif what[0] == 'City':
            self.citytoadd = what[1]
        elif what[0] == 'Country':
            self.countrytoadd = what[1]

    def remove(self):
        self.status.setText('')
        if self.listWidget.count() == 1:
            self.status.setText(
                QCoreApplication.translate(
                    'Message when trying to remove the'
                    'last and unique city in the list',
                    'This is the default city !',
                    'Cities list dialogue'
                )
            )
            return
        row = self.listWidget.currentRow()
        item = self.listWidget.item(row)
        if item is None:
            return
        message = self.tr('The city "{0}" has been removed').format(
            self.listWidget.item(row).text())
        item = self.listWidget.takeItem(row)
        del item
        self.status.setText(message)

    def up(self):
        self.status.setText('')
        row = self.listWidget.currentRow()
        if row >= 1:
            item = self.listWidget.takeItem(row)
            self.listWidget.insertItem(row - 1, item)
            self.listWidget.setCurrentItem(item)

    def down(self):
        self.status.setText('')
        row = self.listWidget.currentRow()
        if row < self.listWidget.count() - 1:
            item = self.listWidget.takeItem(row)
            self.listWidget.insertItem(row + 1, item)
            self.listWidget.setCurrentItem(item)

    def default(self):
        self.status.setText('')
        row = self.listWidget.currentRow()
        if row >= 1:
            item = self.listWidget.takeItem(row)
            self.listWidget.insertItem(0, item)
            self.listWidget.setCurrentItem(item)

    def checklength(self):
        if self.listWidget.count() == 1:
            # After adding the first city the entry is not activated
            self.listWidget.setCurrentRow(0)
        if self.listWidget.count() > 0:
            self.translate_button.setEnabled(True)
            self.listWidget.setMinimumWidth(
                self.listWidget.sizeHintForColumn(0)
            )
        else:
            self.translate_button.setEnabled(False)

    def translate(self):
        city = self.listWidget.currentItem().text()
        dialog = citytranslate.CityTranslate(
            city, self.trans_cities_dict, self
        )
        dialog.city_signal.connect(self.current_translation)
        if dialog.exec_() == 1:
            row = self.listWidget.currentRow()
            item = self.listWidget.takeItem(row)
            del item
            self.listWidget.insertItem(row, self.current_translated_city)
            self.listWidget.setCurrentRow(row)

    def current_translation(self, translated_city):
        for city, translated in translated_city.items():
            if translated == '':
                translated = city
            self.trans_cities_dict[city] = translated
            self.current_translated_city = translated

    def accept(self):
        listtosend = []
        for row in range(self.listWidget.count()):
            city = self.find_city_key(self.listWidget.item(row).text())
            listtosend.append(city)
        if self.listWidget.count() == 0:
            return
        self.citieslist_signal[list].emit(listtosend)
        self.citiesdict_signal[dict].emit(self.trans_cities_dict)
        QDialog.accept(self)

    def find_city_key(self, city):
        for key, value in self.trans_cities_dict.items():
            if value == city:
                return key
        return city
Beispiel #9
0
class TorrentCreatingDialog(QDialog):
    SELECTION_LABEL_FORMAT = 'Selected {} files ({})'

    def _get_directory_browse_widget(self):
        widget = QWidget()
        hbox = QHBoxLayout(widget)
        hbox.setContentsMargins(0, 0, 0, 0)

        self._path_edit = QLineEdit(self)
        self._path_edit.setReadOnly(True)
        hbox.addWidget(self._path_edit, 4)

        browse_button = QPushButton('Browse...')
        browse_button.clicked.connect(self._browse)
        hbox.addWidget(browse_button, 1)

        widget.setLayout(hbox)
        return widget

    def _browse(self):
        new_download_dir = QFileDialog.getExistingDirectory(
            self, 'Select download directory', self.path)
        if not new_download_dir:
            return

        self._download_dir = new_download_dir
        self._path_edit.setText(new_download_dir)

    def __init__(self, parent: QWidget, path):
        super().__init__(parent)
        # download_info = torrent_info.download_info
        vbox = QVBoxLayout(self)

        vbox.addWidget(QLabel('Path to file:'))
        vbox.addWidget(self._get_directory_browse_widget())

        vbox.addWidget(QLabel('Tracker:'))
        self._path_edit = QLineEdit(self)
        self._path_edit.setReadOnly(False)
        vbox.addWidget(self._path_edit, 4)

        self._button_box = QDialogButtonBox(self)
        self._button_box.setOrientation(Qt.Horizontal)
        self._button_box.setStandardButtons(QDialogButtonBox.Cancel
                                            | QDialogButtonBox.Ok)
        self._button_box.button(QDialogButtonBox.Ok).clicked.connect(
            self.submit_torrent)
        self._button_box.button(QDialogButtonBox.Cancel).clicked.connect(
            self.close)
        vbox.addWidget(self._button_box)

        # self.setFixedSize(250, 200)
        self.setWindowTitle('Create torrent')
        self.path = path

    def _set_check_state_to_tree(self, item: QTreeWidgetItem,
                                 check_state: Qt.CheckState):
        for i in range(item.childCount()):
            child = item.child(i)
            child.setCheckState(0, check_state)
            self._set_check_state_to_tree(child, check_state)

    def _update_checkboxes(self, item: QTreeWidgetItem, column: int):
        if column != 0:
            return

        new_check_state = item.checkState(0)
        self._set_check_state_to_tree(item, new_check_state)

        while True:
            item = item.parent()
            if item is None:
                break

            has_checked_children = False
            has_partially_checked_children = False
            has_unchecked_children = False
            for i in range(item.childCount()):
                state = item.child(i).checkState(0)
                if state == Qt.Checked:
                    has_checked_children = True
                elif state == Qt.PartiallyChecked:
                    has_partially_checked_children = True
                else:
                    has_unchecked_children = True

            if not has_partially_checked_children and not has_unchecked_children:
                new_state = Qt.Checked
            elif has_checked_children or has_partially_checked_children:
                new_state = Qt.PartiallyChecked
            else:
                new_state = Qt.Unchecked
            item.setCheckState(0, new_state)

        self._update_selection_label()

    def _update_selection_label(self):
        selected_file_count = 0
        selected_size = 0
        for node, item in self._file_items:
            if item.checkState(0) == Qt.Checked:
                selected_file_count += 1
                selected_size += node.length

        ok_button = self._button_box.button(QDialogButtonBox.Ok)
        if not selected_file_count:
            ok_button.setEnabled(False)
            self._selection_label.setText('Nothing to download')
        else:
            ok_button.setEnabled(True)
            # self._selection_label.setText(TorrentAddingDialog.SELECTION_LABEL_FORMAT.format(
            # selected_file_count, humanize_size(selected_size)))

    def submit_torrent(self):
        # self._torrent_info.download_dir = self._download_dir
        # self._control.last_download_dir = os.path.abspath(self._download_dir)
        #
        # file_paths = []
        # for node, item in self._file_items:
        #     if item.checkState(0) == Qt.Checked:
        #         file_paths.append(node.path)
        # if not self._torrent_info.download_info.single_file_mode:
        #     self._torrent_info.download_info.select_files(file_paths, 'whitelist')
        #
        # self._control_thread.loop.call_soon_threadsafe(self._control.add, self._torrent_info)
        #
        # self.close()
        pass
Beispiel #10
0
class UploadDialog(QDialog):
    """文件上传对话框"""
    new_infos = pyqtSignal(object)

    def __init__(self):
        super().__init__()
        self.cwd = os.getcwd()
        self.selected = []
        self.max_len = 400
        self.initUI()
        self.set_size()
        self.setStyleSheet(dialog_qss_style)

    def set_values(self, folder_name):
        self.setWindowTitle("上传文件至 ➩ " + str(folder_name))

    def initUI(self):
        self.setWindowTitle("上传文件")
        self.setWindowIcon(QIcon("./icon/upload.ico"))
        self.logo = QLabel()
        self.logo.setPixmap(QPixmap("./icon/logo3.gif"))
        self.logo.setStyleSheet("background-color:rgb(0,153,255);")
        self.logo.setAlignment(Qt.AlignCenter)

        # btn 1
        self.btn_chooseDir = QPushButton("选择文件夹", self)
        self.btn_chooseDir.setObjectName("btn_chooseDir")
        self.btn_chooseDir.setObjectName("btn_chooseDir")
        self.btn_chooseDir.setIcon(QIcon("./icon/folder.gif"))

        # btn 2
        self.btn_chooseMutiFile = QPushButton("选择多文件", self)
        self.btn_chooseDir.setObjectName("btn_chooseMutiFile")
        self.btn_chooseMutiFile.setObjectName("btn_chooseMutiFile")
        self.btn_chooseMutiFile.setIcon(QIcon("./icon/file.ico"))

        # btn 3
        self.btn_deleteSelect = QPushButton("删除", self)
        self.btn_deleteSelect.setObjectName("btn_deleteSelect")
        self.btn_deleteSelect.setIcon(QIcon("./icon/delete.ico"))

        # 列表
        self.list_view = QListView(self)
        self.list_view.setViewMode(QListView.ListMode)
        self.slm = QStandardItem()
        self.model = QStandardItemModel()
        self.list_view.setModel(self.model)
        self.model.removeRows(0, self.model.rowCount())  # 清除旧的选择
        self.list_view.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.list_view.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.list_view.setSelectionMode(QAbstractItemView.ExtendedSelection)

        self.buttonBox = QDialogButtonBox()
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Ok
                                          | QDialogButtonBox.Cancel)

        grid = QGridLayout()
        grid.setSpacing(10)
        grid.addWidget(self.logo, 1, 0, 1, 3)
        grid.addWidget(self.btn_chooseDir, 2, 0)
        grid.addWidget(self.btn_chooseMutiFile, 2, 2)
        grid.addWidget(self.list_view, 3, 0, 2, 3)
        grid.addWidget(self.btn_deleteSelect, 5, 0)
        grid.addWidget(self.buttonBox, 5, 1, 1, 2)
        self.setLayout(grid)

        self.setMinimumWidth(350)

        # 设置信号
        self.btn_chooseDir.clicked.connect(self.slot_btn_chooseDir)
        self.btn_chooseMutiFile.clicked.connect(self.slot_btn_chooseMutiFile)
        self.btn_deleteSelect.clicked.connect(self.slot_btn_deleteSelect)

        self.buttonBox.accepted.connect(self.slot_btn_ok)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.clear_old)
        self.buttonBox.rejected.connect(self.reject)

    def set_size(self):
        rows = self.model.rowCount()
        for i in range(rows):
            m_len = int(len(self.model.item(i, 0).text()) * 4)
            if m_len > self.max_len:
                self.max_len = m_len
        rows = 10 if rows >= 10 else rows  # 限制最大高度
        self.resize(self.max_len, 250 + rows * 28)

    def clear_old(self):
        self.selected = []
        self.model.removeRows(0, self.model.rowCount())
        self.set_size()

    def slot_btn_ok(self):
        if self.selected:
            self.new_infos.emit(self.selected)
            self.clear_old()

    def slot_btn_deleteSelect(self):
        _indexes = self.list_view.selectionModel().selection().indexes()
        if not _indexes:
            return
        indexes = []
        for i in _indexes:  # 获取所选行号
            indexes.append(i.row())
        indexes = set(indexes)
        for i in sorted(indexes, reverse=True):
            self.selected.remove(self.model.item(i, 0).text())
            self.model.removeRow(i)
        self.set_size()

    def slot_btn_chooseDir(self):
        dir_choose = QFileDialog.getExistingDirectory(self, "选择文件夹",
                                                      self.cwd)  # 起始路径

        if dir_choose == "":
            return
        if dir_choose not in self.selected:
            self.selected.append(dir_choose)
            self.model.appendRow(
                QStandardItem(QIcon("./icon/folder.gif"), dir_choose))
            self.set_size()

    def slot_btn_chooseMutiFile(self):
        files, _ = QFileDialog.getOpenFileNames(self, "选择多文件", self.cwd,
                                                "All Files (*)")
        if len(files) == 0:
            return

        for _file in files:
            if _file not in self.selected:
                self.selected.append(_file)
                self.model.appendRow(
                    QStandardItem(QIcon("./icon/file.ico"), _file))
        self.set_size()
class TransactionPanel(Panel):
    FIELDS = [
        ('dateEdit', 'date'),
        ('descriptionEdit', 'description'),
        ('payeeEdit', 'payee'),
        ('checkNoEdit', 'checkno'),
        ('notesEdit', 'notes'),
    ]
    PERSISTENT_NAME = 'transactionPanel'

    def __init__(self, model, mainwindow):
        Panel.__init__(self, mainwindow)
        self.setAttribute(Qt.WA_DeleteOnClose)
        self.model = model
        self._setupUi()
        self.splitTable = SplitTable(model=self.model.split_table, view=self.splitTableView)

        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)
        self.mctButton.clicked.connect(self.model.mct_balance)
        self.assignImbalanceButton.clicked.connect(self.model.assign_imbalance)
        self.addSplitButton.clicked.connect(self.splitTable.model.add)
        self.removeSplitButton.clicked.connect(self.splitTable.model.delete)

    @pyqtSlot()
    def on_focus_transactions(self):
        self.splitTableView.setFocus()

    def _setupUi(self):
        self.setWindowTitle(tr("Transaction Info"))
        self.resize(462, 329)
        self.setModal(True)
        self.mainLayout = QVBoxLayout(self)
        self.tabWidget = QTabWidget(self)
        self.infoTab = QWidget()
        self.infoLayout = QVBoxLayout(self.infoTab)
        self.formLayout = QFormLayout()
        self.formLayout.setFieldGrowthPolicy(QFormLayout.ExpandingFieldsGrow)
        self.dateEdit = DateEdit(self.infoTab)
        self.dateEdit.setMaximumSize(QSize(120, 16777215))
        self.formLayout.addRow(tr("Date:"), self.dateEdit)
        self.descriptionEdit = DescriptionEdit(self.model.completable_edit, self.infoTab)
        self.formLayout.addRow(tr("Description:"), self.descriptionEdit)
        self.payeeEdit = PayeeEdit(self.model.completable_edit, self.infoTab)
        self.formLayout.addRow(tr("Payee:"), self.payeeEdit)
        self.checkNoEdit = QLineEdit(self.infoTab)
        self.checkNoEdit.setMaximumSize(QSize(120, 16777215))
        self.formLayout.addRow(tr("Check #:"), self.checkNoEdit)
        self.infoLayout.addLayout(self.formLayout)
        self.amountLabel = QLabel(tr("Transfers:"), self.infoTab)
        self.infoLayout.addWidget(self.amountLabel)
        self.splitTableView = TableView(self.infoTab)
        self.splitTableView.setAcceptDrops(True)
        self.splitTableView.setEditTriggers(QAbstractItemView.DoubleClicked|QAbstractItemView.EditKeyPressed)
        self.splitTableView.setDragEnabled(True)
        self.splitTableView.setDragDropMode(QAbstractItemView.InternalMove)
        self.splitTableView.setSelectionMode(QAbstractItemView.SingleSelection)
        self.splitTableView.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.splitTableView.horizontalHeader().setDefaultSectionSize(40)
        self.splitTableView.verticalHeader().setVisible(False)
        self.splitTableView.verticalHeader().setDefaultSectionSize(18)
        self.tvShortcut = QShortcut(QKeySequence("Alt+T"), self)
        self.tvShortcut.activated.connect(self.on_focus_transactions)
        self.infoLayout.addWidget(self.splitTableView)
        self.mctButtonsLayout = QHBoxLayout()
        self.mctButtonsLayout.setContentsMargins(0, 0, 0, 0)
        spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.mctButtonsLayout.addItem(spacerItem)
        self.mctButton = QPushButton(tr("&Multi-currency balance"), self.infoTab)
        self.mctButtonsLayout.addWidget(self.mctButton)
        self.assignImbalanceButton = QPushButton(tr("Assign &imbalance"), self.infoTab)
        self.mctButtonsLayout.addWidget(self.assignImbalanceButton)
        self.addSplitButton = QPushButton(self.infoTab)
        icon = QIcon()
        icon.addPixmap(QPixmap(":/plus_8"), QIcon.Normal, QIcon.Off)
        self.addSplitButton.setIcon(icon)
        self.mctButtonsLayout.addWidget(self.addSplitButton)
        self.removeSplitButton = QPushButton(self.infoTab)
        icon1 = QIcon()
        icon1.addPixmap(QPixmap(":/minus_8"), QIcon.Normal, QIcon.Off)
        self.removeSplitButton.setIcon(icon1)
        self.mctButtonsLayout.addWidget(self.removeSplitButton)
        self.infoLayout.addLayout(self.mctButtonsLayout)
        self.tabWidget.addTab(self.infoTab, tr("Info"))
        self.notesTab = QWidget()
        self.notesLayout = QVBoxLayout(self.notesTab)
        self.notesEdit = QPlainTextEdit(self.notesTab)
        self.notesLayout.addWidget(self.notesEdit)
        self.tabWidget.addTab(self.notesTab, tr("Notes"))
        self.tabWidget.setCurrentIndex(0)
        self.mainLayout.addWidget(self.tabWidget)
        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.addButton(tr("&Save"), QDialogButtonBox.AcceptRole)
        self.buttonBox.addButton(tr("Cancel"), QDialogButtonBox.RejectRole)
        self.mainLayout.addWidget(self.buttonBox)

    def _loadFields(self):
        Panel._loadFields(self)
        self.tabWidget.setCurrentIndex(0)

    # --- model --> view
    def refresh_for_multi_currency(self):
        self.mctButton.setEnabled(self.model.is_multi_currency)
Beispiel #12
0
class HighpassExtension(Extension):
    def __init__(self, parent):
        super().__init__(parent)

    def setup(self):
        pass

    def createActions(self, window):
        action = window.createAction("high_pass_filter", i18n("High Pass"))
        action.triggered.connect(self.showDialog)

    def showDialog(self):
        doc = Application.activeDocument()
        if doc is None:
            QMessageBox.information(Application.activeWindow().qwindow(),
                                    i18n("High Pass Filter"),
                                    i18n("There is no active image."))
            return

        self.dialog = QDialog(Application.activeWindow().qwindow())

        self.intRadius = QSpinBox()
        self.intRadius.setValue(10)
        self.intRadius.setRange(2, 200)

        self.cmbMode = QComboBox()
        self.cmbMode.addItems([
            "Color", "Preserve DC", "Greyscale", "Greyscale, Apply Chroma",
            "Redrobes"
        ])
        self.keepOriginal = QCheckBox(i18n("Keep original layer"))
        self.keepOriginal.setChecked(True)
        form = QFormLayout()
        form.addRow(
            i18nc("Filter radius in Highpass filter settings",
                  "Filter radius:"), self.intRadius)
        form.addRow(i18n("Mode:"), self.cmbMode)
        form.addRow("", self.keepOriginal)

        self.buttonBox = QDialogButtonBox(self.dialog)
        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Ok
                                          | QDialogButtonBox.Cancel)
        self.buttonBox.accepted.connect(self.dialog.accept)
        self.buttonBox.accepted.connect(self.highpass)
        self.buttonBox.rejected.connect(self.dialog.reject)

        vbox = QVBoxLayout(self.dialog)
        vbox.addLayout(form)
        vbox.addWidget(self.buttonBox)

        self.dialog.show()
        self.dialog.activateWindow()
        self.dialog.exec_()

    def highpass(self):
        # XXX: Start undo macro
        image = Application.activeDocument()
        original = image.activeNode()
        working_layer = original

        # We can only highpass on paint layers
        if self.keepOriginal.isChecked() or original.type() != "paintlayer":
            working_layer = image.createNode("working", "paintlayer")
            working_layer.setColorSpace(original.colorModel(),
                                        original.colorSpace(),
                                        original.profile())
            working_layer.writeBytes(
                original.readBytes(0, 0, image.width(), image.height()), 0, 0,
                image.width(), image.height())

            # XXX: Unimplemented:
            original.parentNode().addChildNode(working_layer, original)

        image.setActiveNode(working_layer)
        colors_layer = None

        # if keeping colors
        if (self.cmbMode.currentIndex() == 1
                or self.cmbMode.currentIndex() == 3):
            # XXX: Unimplemented:
            colors_layer = working_layer.duplicate()
            colors_layer.setName("colors")
            # XXX: Unimplemented:
            original.parentNode().addChildNode(working_layer, colors_layer)

        # if greyscale, desature
        if (self.cmbMode.currentIndex() == 2
                or self.cmbMode.currentIndex() == 3):
            filter = Application.filter("desaturate")
            filter.apply(working_layer, 0, 0, image.width(), image.height())

        # Duplicate on top and blur
        blur_layer = working_layer.duplicate()
        blur_layer.setName("blur")
        # XXX: Unimplemented:
        original.parentNode().addChildNode(blur_layer, working_layer)

        # blur
        filter = Application.filter("gaussian blur")
        filter_configuration = filter.configuration()
        filter_configuration.setProperty("horizRadius", self.intRadius.value())
        filter_configuration.setProperty("vertRadius", self.intRadius.value())
        filter_configuration.setProperty("lockAspect", True)
        filter.setConfiguration(filter_configuration)
        filter.apply(blur_layer, 0, 0, image.width(), image.height())

        if self.cmbMode.currentIndex() <= 3:
            blur_layer.setBlendingMode("grain_extract")
            working_layer = image.mergeDown(blur_layer)

            # if preserve chroma, change set the mode to value and
            # merge down with the layer we kept earlier.
            if self.cmbMode.currentIndex() == 3:
                working_layer.setBlendingMode("value")
                working_layer = image.mergeDown(working_layer)

            # if preserve DC, change set the mode to overlay and merge
            # down with the average color of the layer we kept
            # earlier.
            if self.cmbMode.currentIndex() == 1:
                # get the average color of the entire image
                # clear the colors layer to the given color
                working_layer = image.mergeDown(working_layer)

        else:  # Mode == 4, RedRobes
            image.setActiveNode(blur_layer)
Beispiel #13
0
class PreferencesPanel(QDialog):
    def __init__(self, parent, app):
        # The flags we pass are that so we don't get the "What's this" button in the title bar
        QDialog.__init__(self, parent, Qt.WindowTitleHint | Qt.WindowSystemMenuHint)
        self.app = app
        self._setupUi()

        self.dateFormatEdit.editingFinished.connect(self.dateFormatEdited)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)

    def _setupUi(self):
        self.setWindowTitle(tr("Preferences"))
        self.resize(332, 170)
        self.verticalLayout = QVBoxLayout(self)
        self.formLayout = QFormLayout()

        self.autoSaveIntervalSpinBox = QSpinBox(self)
        self.autoSaveIntervalSpinBox.setMaximumSize(QSize(70, 0xffffff))
        self.label_5 = QLabel(tr("step(s) (0 for none)"), self)
        self.formLayout.addRow(
            tr("Auto-save interval:"),
            horizontalWrap([self.autoSaveIntervalSpinBox, self.label_5])
        )

        self.dateFormatEdit = QLineEdit(self)
        self.dateFormatEdit.setMaximumSize(QSize(140, 0xffffff))
        self.formLayout.addRow(tr("Date format:"), self.dateFormatEdit)

        self.fontSizeSpinBox = QSpinBox()
        self.fontSizeSpinBox.setMinimum(5)
        self.fontSizeSpinBox.setMaximumSize(QSize(70, 0xffffff))
        self.formLayout.addRow(tr("Font size:"), self.fontSizeSpinBox)

        self.verticalLayout.addLayout(self.formLayout)

        self.scopeDialogCheckBox = QCheckBox(tr("Show scope dialog when modifying a scheduled transaction"), self)
        self.verticalLayout.addWidget(self.scopeDialogCheckBox)
        self.autoDecimalPlaceCheckBox = QCheckBox(tr("Automatically place decimals when typing"), self)
        self.verticalLayout.addWidget(self.autoDecimalPlaceCheckBox)
        self.dateEntryBox = QCheckBox(tr("Enter dates in day → month → year order"), self)
        self.verticalLayout.addWidget(self.dateEntryBox)
        self.verticalLayout.addItem(verticalSpacer())
        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Ok)
        self.verticalLayout.addWidget(self.buttonBox)

    def load(self):
        appm = self.app.model
        self.autoSaveIntervalSpinBox.setValue(appm.autosave_interval)
        self.dateFormatEdit.setText(self.app.prefs.dateFormat)
        self.fontSizeSpinBox.setValue(self.app.prefs.tableFontSize)
        self.scopeDialogCheckBox.setChecked(appm.show_schedule_scope_dialog)
        self.autoDecimalPlaceCheckBox.setChecked(appm.auto_decimal_place)
        self.dateEntryBox.setChecked(appm.day_first_date_entry)

    def save(self):
        restartRequired = False
        appm = self.app.model
        appm.autosave_interval = self.autoSaveIntervalSpinBox.value()
        if self.dateFormatEdit.text() != self.app.prefs.dateFormat:
            restartRequired = True
        self.app.prefs.dateFormat = self.dateFormatEdit.text()
        self.app.prefs.tableFontSize = self.fontSizeSpinBox.value()
        appm.show_schedule_scope_dialog = self.scopeDialogCheckBox.isChecked()
        appm.auto_decimal_place = self.autoDecimalPlaceCheckBox.isChecked()
        appm.day_first_date_entry = self.dateEntryBox.isChecked()
        if restartRequired:
            QMessageBox.information(self, "", tr("moneyGuru has to restart for these changes to take effect"))

    # --- Signals
    def dateFormatEdited(self):
        self.dateFormatEdit.setText(clean_format(self.dateFormatEdit.text()))
class BudgetPanel(Panel):
    FIELDS = [
        ('startDateEdit', 'start_date'),
        ('repeatEverySpinBox', 'repeat_every'),
        ('stopDateEdit', 'stop_date'),
        ('amountEdit', 'amount'),
        ('notesEdit', 'notes'),
    ]
    PERSISTENT_NAME = 'budgetPanel'

    def __init__(self, model, mainwindow):
        Panel.__init__(self, mainwindow)
        self.setAttribute(Qt.WA_DeleteOnClose)
        self._setupUi()
        self.model = model
        self.repeatTypeComboBox = ComboboxModel(model=self.model.repeat_type_list, view=self.repeatTypeComboBoxView)
        self.accountComboBox = ComboboxModel(model=self.model.account_list, view=self.accountComboBoxView)
        self.targetComboBox = ComboboxModel(model=self.model.target_list, view=self.targetComboBoxView)

        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)

    def _setupUi(self):
        self.setWindowTitle(tr("Budget Info"))
        self.resize(230, 369)
        self.setModal(True)
        self.verticalLayout = QVBoxLayout(self)
        self.formLayout = QFormLayout()
        self.formLayout.setFieldGrowthPolicy(QFormLayout.ExpandingFieldsGrow)
        self.label_2 = QLabel(tr("Start Date:"))
        self.formLayout.setWidget(0, QFormLayout.LabelRole, self.label_2)
        self.startDateEdit = DateEdit(self)
        self.startDateEdit.setMaximumSize(QSize(120, 16777215))
        self.formLayout.setWidget(0, QFormLayout.FieldRole, self.startDateEdit)
        self.label_7 = QLabel(tr("Repeat Type:"))
        self.formLayout.setWidget(1, QFormLayout.LabelRole, self.label_7)
        self.repeatTypeComboBoxView = QComboBox(self)
        self.formLayout.setWidget(1, QFormLayout.FieldRole, self.repeatTypeComboBoxView)
        self.label_8 = QLabel(tr("Every:"))
        self.formLayout.setWidget(2, QFormLayout.LabelRole, self.label_8)
        self.horizontalLayout_2 = QHBoxLayout()
        self.repeatEverySpinBox = QSpinBox(self)
        self.repeatEverySpinBox.setMinimum(1)
        self.horizontalLayout_2.addWidget(self.repeatEverySpinBox)
        self.repeatEveryDescLabel = QLabel(self)
        self.horizontalLayout_2.addWidget(self.repeatEveryDescLabel)
        self.formLayout.setLayout(2, QFormLayout.FieldRole, self.horizontalLayout_2)
        self.label_9 = QLabel(tr("Stop Date:"))
        self.formLayout.setWidget(3, QFormLayout.LabelRole, self.label_9)
        self.stopDateEdit = DateEdit(self)
        self.stopDateEdit.setMaximumSize(QSize(120, 16777215))
        self.formLayout.setWidget(3, QFormLayout.FieldRole, self.stopDateEdit)
        self.accountComboBoxView = QComboBox(self)
        self.formLayout.setWidget(4, QFormLayout.FieldRole, self.accountComboBoxView)
        self.label_3 = QLabel(tr("Account:"))
        self.formLayout.setWidget(4, QFormLayout.LabelRole, self.label_3)
        self.targetComboBoxView = QComboBox(self)
        self.formLayout.setWidget(5, QFormLayout.FieldRole, self.targetComboBoxView)
        self.label_4 = QLabel(tr("Target:"))
        self.formLayout.setWidget(5, QFormLayout.LabelRole, self.label_4)
        self.amountEdit = QLineEdit(self)
        self.amountEdit.setMaximumSize(QSize(120, 16777215))
        self.formLayout.setWidget(6, QFormLayout.FieldRole, self.amountEdit)
        self.label_5 = QLabel(tr("Amount:"))
        self.formLayout.setWidget(6, QFormLayout.LabelRole, self.label_5)
        self.notesEdit = QPlainTextEdit(tr("Notes:"))
        self.formLayout.setWidget(7, QFormLayout.FieldRole, self.notesEdit)
        self.label = QLabel(self)
        self.formLayout.setWidget(7, QFormLayout.LabelRole, self.label)
        self.verticalLayout.addLayout(self.formLayout)
        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Save)
        self.verticalLayout.addWidget(self.buttonBox)
        self.label_2.setBuddy(self.startDateEdit)
        self.label_7.setBuddy(self.repeatTypeComboBoxView)
        self.label_8.setBuddy(self.repeatEverySpinBox)
        self.label_9.setBuddy(self.stopDateEdit)
        self.label_3.setBuddy(self.accountComboBoxView)
        self.label_4.setBuddy(self.targetComboBoxView)
        self.label_5.setBuddy(self.amountEdit)

    #--- model --> view
    def refresh_repeat_every(self):
        self.repeatEveryDescLabel.setText(self.model.repeat_every_desc)
Beispiel #15
0
class TorrentAddingDialog(QDialog):
    SELECTION_LABEL_FORMAT = 'Selected {} files ({})'

    def _traverse_file_tree(self, name: str, node: FileTreeNode, parent: QWidget):
        item = QTreeWidgetItem(parent)
        item.setCheckState(0, Qt.Checked)
        item.setText(0, name)
        if isinstance(node, FileInfo):
            item.setText(1, humanize_size(node.length))
            item.setIcon(0, file_icon)
            self._file_items.append((node, item))
            return

        item.setIcon(0, directory_icon)
        for name, child in node.items():
            self._traverse_file_tree(name, child, item)

    def _get_directory_browse_widget(self):
        widget = QWidget()
        hbox = QHBoxLayout(widget)
        hbox.setContentsMargins(0, 0, 0, 0)

        self._path_edit = QLineEdit(self._download_dir)
        self._path_edit.setReadOnly(True)
        hbox.addWidget(self._path_edit, 3)

        browse_button = QPushButton('Browse...')
        browse_button.clicked.connect(self._browse)
        hbox.addWidget(browse_button, 1)

        widget.setLayout(hbox)
        return widget

    def _browse(self):
        new_download_dir = QFileDialog.getExistingDirectory(self, 'Select download directory', self._download_dir)
        if not new_download_dir:
            return

        self._download_dir = new_download_dir
        self._path_edit.setText(new_download_dir)

    def __init__(self, parent: QWidget, filename: str, torrent_info: TorrentInfo,
                 control_thread: 'ControlManagerThread'):
        super().__init__(parent)
        self._torrent_info = torrent_info
        download_info = torrent_info.download_info
        self._control_thread = control_thread
        self._control = control_thread.control

        vbox = QVBoxLayout(self)

        self._download_dir = get_directory(self._control.last_download_dir)
        vbox.addWidget(QLabel('Download directory:'))
        vbox.addWidget(self._get_directory_browse_widget())

        vbox.addWidget(QLabel('Announce URLs:'))

        url_tree = QTreeWidget()
        url_tree.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel)
        url_tree.header().close()
        vbox.addWidget(url_tree)
        for i, tier in enumerate(torrent_info.announce_list):
            tier_item = QTreeWidgetItem(url_tree)
            tier_item.setText(0, 'Tier {}'.format(i + 1))
            for url in tier:
                url_item = QTreeWidgetItem(tier_item)
                url_item.setText(0, url)
        url_tree.expandAll()
        vbox.addWidget(url_tree, 1)

        file_tree = QTreeWidget()
        file_tree.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel)
        file_tree.setHeaderLabels(('Name', 'Size'))
        file_tree.header().setSectionResizeMode(0, QHeaderView.ResizeToContents)
        self._file_items = []
        self._traverse_file_tree(download_info.suggested_name, download_info.file_tree, file_tree)
        file_tree.sortItems(0, Qt.AscendingOrder)
        file_tree.expandAll()
        file_tree.itemClicked.connect(self._update_checkboxes)
        vbox.addWidget(file_tree, 3)

        self._selection_label = QLabel(TorrentAddingDialog.SELECTION_LABEL_FORMAT.format(
            len(download_info.files), humanize_size(download_info.total_size)))
        vbox.addWidget(self._selection_label)

        self._button_box = QDialogButtonBox(self)
        self._button_box.setOrientation(Qt.Horizontal)
        self._button_box.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok)
        self._button_box.button(QDialogButtonBox.Ok).clicked.connect(self.submit_torrent)
        self._button_box.button(QDialogButtonBox.Cancel).clicked.connect(self.close)
        vbox.addWidget(self._button_box)

        self.setFixedSize(450, 550)
        self.setWindowTitle('Adding "{}"'.format(filename))

    def _set_check_state_to_tree(self, item: QTreeWidgetItem, check_state: Qt.CheckState):
        for i in range(item.childCount()):
            child = item.child(i)
            child.setCheckState(0, check_state)
            self._set_check_state_to_tree(child, check_state)

    def _update_checkboxes(self, item: QTreeWidgetItem, column: int):
        if column != 0:
            return

        new_check_state = item.checkState(0)
        self._set_check_state_to_tree(item, new_check_state)

        while True:
            item = item.parent()
            if item is None:
                break

            has_checked_children = False
            has_partially_checked_children = False
            has_unchecked_children = False
            for i in range(item.childCount()):
                state = item.child(i).checkState(0)
                if state == Qt.Checked:
                    has_checked_children = True
                elif state == Qt.PartiallyChecked:
                    has_partially_checked_children = True
                else:
                    has_unchecked_children = True

            if not has_partially_checked_children and not has_unchecked_children:
                new_state = Qt.Checked
            elif has_checked_children or has_partially_checked_children:
                new_state = Qt.PartiallyChecked
            else:
                new_state = Qt.Unchecked
            item.setCheckState(0, new_state)

        self._update_selection_label()

    def _update_selection_label(self):
        selected_file_count = 0
        selected_size = 0
        for node, item in self._file_items:
            if item.checkState(0) == Qt.Checked:
                selected_file_count += 1
                selected_size += node.length

        ok_button = self._button_box.button(QDialogButtonBox.Ok)
        if not selected_file_count:
            ok_button.setEnabled(False)
            self._selection_label.setText('Nothing to download')
        else:
            ok_button.setEnabled(True)
            self._selection_label.setText(TorrentAddingDialog.SELECTION_LABEL_FORMAT.format(
                selected_file_count, humanize_size(selected_size)))

    def submit_torrent(self):
        self._torrent_info.download_dir = self._download_dir
        self._control.last_download_dir = os.path.abspath(self._download_dir)

        file_paths = []
        for node, item in self._file_items:
            if item.checkState(0) == Qt.Checked:
                file_paths.append(node.path)
        if not self._torrent_info.download_info.single_file_mode:
            self._torrent_info.download_info.select_files(file_paths, 'whitelist')

        self._control_thread.loop.call_soon_threadsafe(self._control.add, self._torrent_info)

        self.close()
class MassEditionPanel(Panel):
    FIELDS = [
        ('dateCheckBox', 'date_enabled'),
        ('descriptionCheckBox', 'description_enabled'),
        ('payeeCheckBox', 'payee_enabled'),
        ('checknoCheckBox', 'checkno_enabled'),
        ('fromCheckBox', 'from_enabled'),
        ('toCheckBox', 'to_enabled'),
        ('amountCheckBox', 'amount_enabled'),
        ('currencyCheckBox', 'currency_enabled'),
    ]
    PERSISTENT_NAME = 'massEditionPanel'

    def __init__(self, model, mainwindow):
        Panel.__init__(self, mainwindow)
        self.setAttribute(Qt.WA_DeleteOnClose)
        self.mainwindow = mainwindow
        self.model = model
        self._setupUi()
        self.dateEdit = TextField(model=self.model.date_field, view=self.dateEditView)
        self.descriptionEdit = TextField(model=self.model.description_field, view=self.descriptionEditView)
        self.payeeEdit = TextField(model=self.model.payee_field, view=self.payeeEditView)
        self.checknoEdit = TextField(model=self.model.checkno_field, view=self.checknoEditView)
        self.fromEdit = TextField(model=self.model.from_field, view=self.fromEditView)
        self.toEdit = TextField(model=self.model.to_field, view=self.toEditView)
        self.amountEdit = TextField(model=self.model.amount_field, view=self.amountEditView)
        self.currencyComboBox = ComboboxModel(model=self.model.currency_list, view=self.currencyComboBoxView)

        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)

    def _setupUi(self):
        self.resize(314, 267)
        self.setModal(True)
        self.verticalLayout = QVBoxLayout(self)
        self.formLayout = QFormLayout()
        self.formLayout.setFieldGrowthPolicy(QFormLayout.ExpandingFieldsGrow)
        self.label = QLabel(tr("Date:"), self)
        self.formLayout.setWidget(0, QFormLayout.LabelRole, self.label)
        self.horizontalLayout = QHBoxLayout()
        self.dateCheckBox = QCheckBox(self)
        self.horizontalLayout.addWidget(self.dateCheckBox)
        self.dateEditView = DateEdit(self)
        self.horizontalLayout.addWidget(self.dateEditView)
        self.formLayout.setLayout(0, QFormLayout.FieldRole, self.horizontalLayout)
        self.label_2 = QLabel(tr("Description:"), self)
        self.formLayout.setWidget(1, QFormLayout.LabelRole, self.label_2)
        self.horizontalLayout_2 = QHBoxLayout()
        self.descriptionCheckBox = QCheckBox(self)
        self.horizontalLayout_2.addWidget(self.descriptionCheckBox)
        self.descriptionEditView = DescriptionEdit(self.model.completable_edit, self)
        self.horizontalLayout_2.addWidget(self.descriptionEditView)
        self.formLayout.setLayout(1, QFormLayout.FieldRole, self.horizontalLayout_2)
        self.label_3 = QLabel(tr("Payee:"), self)
        self.formLayout.setWidget(2, QFormLayout.LabelRole, self.label_3)
        self.horizontalLayout_3 = QHBoxLayout()
        self.payeeCheckBox = QCheckBox(self)
        self.horizontalLayout_3.addWidget(self.payeeCheckBox)
        self.payeeEditView = PayeeEdit(self.model.completable_edit, self)
        self.horizontalLayout_3.addWidget(self.payeeEditView)
        self.formLayout.setLayout(2, QFormLayout.FieldRole, self.horizontalLayout_3)
        self.label_4 = QLabel(tr("Check #"), self)
        self.formLayout.setWidget(3, QFormLayout.LabelRole, self.label_4)
        self.horizontalLayout_4 = QHBoxLayout()
        self.checknoCheckBox = QCheckBox(self)
        self.horizontalLayout_4.addWidget(self.checknoCheckBox)
        self.checknoEditView = QLineEdit(self)
        self.horizontalLayout_4.addWidget(self.checknoEditView)
        self.formLayout.setLayout(3, QFormLayout.FieldRole, self.horizontalLayout_4)
        self.label_5 = QLabel(tr("From:"), self)
        self.formLayout.setWidget(4, QFormLayout.LabelRole, self.label_5)
        self.horizontalLayout_5 = QHBoxLayout()
        self.fromCheckBox = QCheckBox(self)
        self.horizontalLayout_5.addWidget(self.fromCheckBox)
        self.fromEditView = AccountEdit(self.model.completable_edit, self)
        self.horizontalLayout_5.addWidget(self.fromEditView)
        self.formLayout.setLayout(4, QFormLayout.FieldRole, self.horizontalLayout_5)
        self.label_6 = QLabel(tr("To:"), self)
        self.formLayout.setWidget(5, QFormLayout.LabelRole, self.label_6)
        self.horizontalLayout_6 = QHBoxLayout()
        self.toCheckBox = QCheckBox(self)
        self.horizontalLayout_6.addWidget(self.toCheckBox)
        self.toEditView = AccountEdit(self.model.completable_edit, self)
        self.horizontalLayout_6.addWidget(self.toEditView)
        self.formLayout.setLayout(5, QFormLayout.FieldRole, self.horizontalLayout_6)
        self.label_7 = QLabel(tr("Amount:"), self)
        self.formLayout.setWidget(6, QFormLayout.LabelRole, self.label_7)
        self.horizontalLayout_7 = QHBoxLayout()
        self.amountCheckBox = QCheckBox(self)
        self.horizontalLayout_7.addWidget(self.amountCheckBox)
        self.amountEditView = QLineEdit(self)
        self.horizontalLayout_7.addWidget(self.amountEditView)
        self.formLayout.setLayout(6, QFormLayout.FieldRole, self.horizontalLayout_7)
        self.label_8 = QLabel(tr("Currency:"), self)
        self.formLayout.setWidget(7, QFormLayout.LabelRole, self.label_8)
        self.horizontalLayout_8 = QHBoxLayout()
        self.currencyCheckBox = QCheckBox(self)
        self.horizontalLayout_8.addWidget(self.currencyCheckBox)
        self.currencyComboBoxView = QComboBox(self)
        self.currencyComboBoxView.setEditable(True)
        self.horizontalLayout_8.addWidget(self.currencyComboBoxView)
        self.formLayout.setLayout(7, QFormLayout.FieldRole, self.horizontalLayout_8)
        self.verticalLayout.addLayout(self.formLayout)
        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Save)
        self.verticalLayout.addWidget(self.buttonBox)
        self.label.setBuddy(self.dateEditView)
        self.label_2.setBuddy(self.descriptionEditView)
        self.label_3.setBuddy(self.payeeEditView)
        self.label_4.setBuddy(self.checknoEditView)
        self.label_5.setBuddy(self.fromEditView)
        self.label_6.setBuddy(self.toEditView)
        self.label_7.setBuddy(self.amountEditView)
        self.label_8.setBuddy(self.currencyComboBoxView)

    def _loadFields(self):
        Panel._loadFields(self)
        disableableWidgets = [self.fromCheckBox, self.fromEdit, self.toCheckBox, self.toEdit]
        for widget in disableableWidgets:
            self.fromCheckBox.setEnabled(self.model.can_change_accounts)
        disableableWidgets = [self.amountCheckBox, self.amountEdit]
        for widget in disableableWidgets:
            self.fromCheckBox.setEnabled(self.model.can_change_amount)

    # --- model --> view
    def refresh(self):
        # We have to refresh the checkboxes' state.
        self._loadFields()
Beispiel #17
0
class MeteoSettings(QDialog):
    applied_signal = pyqtSignal()

    def __init__(self, accurate_url, appid, parent=None):
        super(MeteoSettings, self).__init__(parent)
        self.layout = QVBoxLayout()
        self.accurate_url = accurate_url
        self.appid = appid
        self.settings = QSettings()
        self.set_city = self.settings.value("City") or "?"
        locale = QLocale.system().name()
        locale_long = ["pt_BR", "zh_CN", "zh_TW"]
        if locale not in locale_long:
            locale = locale[:2]
        self.interval_set = self.settings.value("Interval") or "30"
        self.temp_tray_color = self.settings.value("TrayColor") or ""
        # -----Cities comboBox------------------------
        self.first = True
        self.clear_combo = False
        self.city_list_before = []
        self.citylist = []
        self.city_combo = QComboBox()
        if self.set_city != "?":
            self.add_cities_incombo()
        self.city_combo.currentIndexChanged.connect(self.city_default)
        self.city_title = QLabel(self.tr("City"))
        self.city_button = QPushButton()
        self.city_button.setIcon(QIcon(":/configure"))
        self.city_button.setToolTip(self.tr("Click to edit the cities list"))
        self.city_button.clicked.connect(self.edit_cities_list)
        # ------Language------------------------------
        self.language_label = QLabel(self.tr("Language"))
        self.language_combo = QComboBox()
        self.language_combo.setToolTip(
            QCoreApplication.translate(
                "Tooltip", "The application has to be restared to apply the language setting", "Settings dialogue"
            )
        )
        self.language_dico = {
            "bg": self.tr("Bulgarian"),
            "ca": self.tr("Catalan"),
            "cs": self.tr("Czech"),
            "da": self.tr("Danish"),
            "de": self.tr("German"),
            "el": self.tr("Greek"),
            "en": self.tr("English"),
            "es": self.tr("Spanish"),
            "fi": self.tr("Finnish"),
            "fr": self.tr("French"),
            "he": self.tr("Hebrew"),
            "hr": self.tr("Croatian"),
            "hu": self.tr("Hungarian"),
            "it": self.tr("Italian"),
            "ja": self.tr("Japanese"),
            "lt": self.tr("Lithuanian"),
            "nb": self.tr("Norwegian (Bokmaal)"),
            "nl": self.tr("Dutch"),
            "pl": self.tr("Polish"),
            "pt": self.tr("Portuguese"),
            "pt_BR": self.tr("Brazil Portuguese"),
            "ro": self.tr("Romanian"),
            "ru": self.tr("Russian"),
            "sk": self.tr("Slovak"),
            "sv": self.tr("Swedish"),
            "tr": self.tr("Turkish"),
            "uk": self.tr("Ukrainian"),
            "zh_TW": self.tr("Chinese Traditional"),
            "zh_CN": self.tr("Chinese Simplified"),
        }
        lang_list = sorted(self.language_dico.values())
        # English as fallback language
        if locale not in self.language_dico:
            locale = "en"
        self.setLanguage = self.settings.value("Language") or locale
        self.language_combo.addItems(lang_list)
        self.language_combo.setCurrentIndex(self.language_combo.findText(self.language_dico[self.setLanguage]))
        self.language_combo.currentIndexChanged.connect(self.language)
        self.lang_changed = False
        # Unit system
        self.units_changed = False
        self.temp_unit = self.settings.value("Unit")
        if self.temp_unit is None or self.temp_unit == "":
            self.temp_unit = "metric"
            self.units_changed = True
        self.units_label = QLabel(self.tr("Temperature unit"))
        self.units_combo = QComboBox()
        self.units_dico = {"metric": "°C", "imperial": "°F", " ": "°K"}
        units_list = sorted(self.units_dico.values())
        self.units_combo.addItems(units_list)
        self.units_combo.setCurrentIndex(self.units_combo.findText(self.units_dico[self.temp_unit]))
        self.units_combo.currentIndexChanged.connect(self.units)
        # Decimal in trayicon
        self.temp_decimal_label = QLabel(
            QCoreApplication.translate(
                "If the temperature will be shown with a decimal or rounded in tray icon",
                "Temperature accuracy in system tray",
                "Settings dialogue",
            )
        )
        self.temp_decimal_combo = QComboBox()
        temp_decimal_combo_dico = {"False": "0°", "True": "0.1°"}
        temp_decimal_combo_list = [temp_decimal_combo_dico["False"], temp_decimal_combo_dico["True"]]
        self.temp_decimal_combo.addItems(temp_decimal_combo_list)
        temp_decimal_bool_str = self.settings.value("Decimal") or "False"
        self.temp_decimal_combo.setCurrentIndex(
            self.temp_decimal_combo.findText(temp_decimal_combo_dico[temp_decimal_bool_str])
        )
        self.temp_decimal_combo.currentIndexChanged.connect(self.temp_decimal)
        self.temp_decimal_changed = False
        # Interval of updates
        self.interval_label = QLabel(self.tr("Update interval"))
        self.interval_min = QLabel(self.tr("minutes"))
        self.interval_combo = QComboBox()
        self.interval_list = ["15", "30", "45", "60", "90", "120"]
        self.interval_combo.addItems(self.interval_list)
        self.interval_combo.setCurrentIndex(
            self.interval_combo.findText(self.interval_list[self.interval_list.index(self.interval_set)])
        )
        self.interval_combo.currentIndexChanged.connect(self.interval)
        self.interval_changed = False
        # OK Cancel Apply Buttons
        self.buttonLayout = QHBoxLayout()
        self.buttonLayout.addStretch()
        self.buttonBox = QDialogButtonBox()
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Ok | QDialogButtonBox.Apply | QDialogButtonBox.Cancel)
        self.buttonBox.setContentsMargins(0, 30, 0, 0)
        self.buttonLayout.addWidget(self.buttonBox)
        self.buttonBox.button(QDialogButtonBox.Apply).clicked.connect(self.apply_settings)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(False)
        # Autostart
        self.autostart_label = QLabel(self.tr("Launch at startup"))
        self.autostart_checkbox = QCheckBox()
        autostart_bool = self.settings.value("Autostart") or "False"
        autostart_bool = eval(autostart_bool)
        self.autostart_checkbox.setChecked(autostart_bool)
        self.autostart_checkbox.stateChanged.connect(self.autostart)
        self.autostart_changed = False
        # Tray temp° color
        self.temp_colorLabel = QLabel(self.tr("Font colour in the tray"))
        self.temp_colorButton = QPushButton()
        self.temp_colorButton.setStyleSheet("QWidget {{ background-color: {0} }}".format(self.temp_tray_color))
        self.temp_colorButton.setMaximumSize(QSize(44, 24))
        self.temp_colorButton.clicked.connect(self.color_chooser)
        self.temp_color_resetButton = QPushButton(self.tr("Reset"))
        self.temp_color_resetButton.setToolTip(self.tr("Reset font colour to system default"))
        self.temp_color_resetButton.clicked.connect(self.color_reset)
        # Display notifications
        self.notifier_label = QLabel(self.tr("Notification on weather update"))
        self.notifier_checkbox = QCheckBox()
        notifier_bool = self.settings.value("Notifications") or "True"
        notifier_bool = eval(notifier_bool)
        self.notifier_checkbox.setChecked(notifier_bool)
        self.notifier_checkbox.stateChanged.connect(self.notifier)
        self.notifier_changed = False
        # Icon & Temp
        self.tray_icon_temp_label = QLabel(
            QCoreApplication.translate(
                "Settings dialogue",
                "System tray icon",
                """Setting to choose the type of the icon on the tray (only icon,
            only text, icon&text""",
            )
        )
        self.tray_icon_combo = QComboBox()
        tray_icon_temp = QCoreApplication.translate(
            "Settings dialogue", "Icon & temperature", "Setting to choose the type of the icon on the tray"
        )
        tray_icon = QCoreApplication.translate(
            "Settings dialogue", "Icon", "Setting to choose the type of the icon on the tray"
        )
        tray_temp = QCoreApplication.translate(
            "Settings dialogue", "Temperature", "Setting to choose the type of the icon on the tray"
        )
        self.tray_dico = {"icon&temp": tray_icon_temp, "icon": tray_icon, "temp": tray_temp}
        set_tray_icon = self.settings.value("TrayType") or "icon&temp"
        tray_icon_list = sorted(self.tray_dico.values())
        self.tray_icon_combo.addItems(tray_icon_list)
        self.tray_icon_combo.setCurrentIndex(self.tray_icon_combo.findText(self.tray_dico[set_tray_icon]))
        self.tray_icon_combo.currentIndexChanged.connect(self.tray)
        self.tray_changed = False
        # Font size
        fontsize = self.settings.value("FontSize") or "18"
        self.fontsize_label = QLabel(
            QCoreApplication.translate(
                "Settings dialog", "Font size in tray", "Setting for the font size of the temperature in the tray icon"
            )
        )
        self.fontsize_spinbox = QSpinBox()
        self.fontsize_spinbox.setRange(12, 32)
        self.fontsize_spinbox.setValue(int(fontsize))
        if fontsize is None or fontsize == "":
            self.settings.setValue("FontSize", "18")
        self.fontsize_changed = False
        self.fontsize_spinbox.valueChanged.connect(self.fontsize_change)
        # Proxy
        self.proxy_label = QLabel(QCoreApplication.translate("Checkbox", "Connection by proxy", "Settings dialogue"))
        self.proxy_chbox = QCheckBox()
        proxy_bool = self.settings.value("Proxy") or "False"
        self.proxy_bool = eval(proxy_bool)
        self.proxy_chbox.setChecked(self.proxy_bool)
        self.proxy_chbox.stateChanged.connect(self.proxy)
        self.proxy_changed = False
        self.proxy_button = QPushButton(
            QCoreApplication.translate("Label of button to open the proxy dialogue", "Settings", "Settings dialogue")
        )
        self.proxy_button.clicked.connect(self.proxy_settings)
        self.proxy_button.setEnabled(self.proxy_bool)
        # Openweathermap key
        self.owmkey_label = QLabel(
            QCoreApplication.translate(
                "The key that user can generate in his OpenWeatherMap profile",
                "OpenWeatherMap key",
                "Settings dialogue",
            )
        )
        self.owmkey_create = QLabel(
            QCoreApplication.translate(
                "Link to create a profile in OpenWeatherMap",
                '<a href="http://home.openweathermap.org/users/sign_up">Create key</a>',
                "Settings dialogue",
            )
        )
        self.owmkey_create.setOpenExternalLinks(True)
        apikey = self.settings.value("APPID") or ""
        self.owmkey_text = QLineEdit()
        self.owmkey_text.setText(apikey)
        self.owmkey_text.textChanged.connect(self.apikey_changed)
        # ----------
        self.panel = QGridLayout()
        self.panel.addWidget(self.city_title, 0, 0)
        self.panel.addWidget(self.city_combo, 0, 1)
        self.panel.addWidget(self.city_button, 0, 2)
        self.panel.addWidget(self.language_label, 1, 0)
        self.panel.addWidget(self.language_combo, 1, 1)
        self.panel.addWidget(self.units_label, 2, 0)
        self.panel.addWidget(self.units_combo, 2, 1)
        self.panel.addWidget(self.temp_decimal_label, 3, 0)
        self.panel.addWidget(self.temp_decimal_combo, 3, 1)
        self.panel.addWidget(self.interval_label, 4, 0)
        self.panel.addWidget(self.interval_combo, 4, 1)
        self.panel.addWidget(self.interval_min, 4, 2)
        self.panel.addWidget(self.autostart_label, 5, 0)
        self.panel.addWidget(self.autostart_checkbox, 5, 1)
        self.panel.addWidget(self.temp_colorLabel, 6, 0)
        self.panel.addWidget(self.temp_colorButton, 6, 1)
        self.panel.addWidget(self.temp_color_resetButton, 6, 2)
        self.panel.addWidget(self.notifier_label, 7, 0)
        self.panel.addWidget(self.notifier_checkbox, 7, 1)
        self.panel.addWidget(self.tray_icon_temp_label, 8, 0)
        self.panel.addWidget(self.tray_icon_combo, 8, 1)
        self.panel.addWidget(self.fontsize_label, 9, 0)
        self.panel.addWidget(self.fontsize_spinbox, 9, 1)
        self.panel.addWidget(self.proxy_label, 10, 0)
        self.panel.addWidget(self.proxy_chbox, 10, 1)
        self.panel.addWidget(self.proxy_button, 10, 2)
        self.panel.addWidget(self.owmkey_label, 11, 0)
        self.panel.addWidget(self.owmkey_text, 11, 1)
        self.panel.addWidget(self.owmkey_create, 11, 2)

        self.layout.addLayout(self.panel)
        self.layout.addLayout(self.buttonLayout)
        self.statusbar = QLabel()
        self.layout.addWidget(self.statusbar)
        self.nokey_message = QCoreApplication.translate(
            "Warning message after pressing Ok", "Please enter your OpenWeatherMap key", "Settings dialogue"
        )
        self.nocity_message = QCoreApplication.translate(
            "Warning message after pressing OK", "Please add a city", "Settings dialogue"
        )
        self.setLayout(self.layout)
        self.setWindowTitle(self.tr("Meteo-qt Configuration"))

    def units(self):
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)
        self.units_changed = True

    def language(self):
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)
        self.lang_changed = True

    def city_default(self):
        allitems = [self.city_combo.itemText(i) for i in range(self.city_combo.count())]
        city_name = self.city_combo.currentText()
        citytosave = city_name.split("_")
        if len(citytosave) < 3:
            return
        self.id_before = citytosave[2]
        self.city_before = citytosave[0]
        self.country_before = citytosave[1]
        self.city_list_before = allitems[:]
        self.city_list_before.pop(self.city_list_before.index(city_name))
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)

    def interval(self):
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)
        self.interval_changed = True

    def edit_cities_list(self):
        apikey = self.owmkey_text.text()
        apiid = "&APPID=" + apikey
        if apikey == "":
            self.statusbar.setText(self.nokey_message)
            return
        dialog = citylistdlg.CityListDlg(self.citylist, self.accurate_url, apiid, self)
        dialog.citieslist_signal.connect(self.cities_list)
        dialog.exec_()

    def cities_list(self, cit_list):
        if len(cit_list) > 0:
            citytosave = cit_list[0].split("_")
            self.id_before = citytosave[2]
            self.city_before = citytosave[0]
            self.country_before = citytosave[1]
            if len(cit_list) > 1:
                self.city_list_before = cit_list[1:]
            else:
                self.city_list_before = str("")
        else:
            self.id_before = ""
            self.city_before = ""
            self.country_before = ""
            self.city_list_before = []
            self.clear_combo = True
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)
        self.first = False
        self.add_cities_incombo()

    def autostart(self, state):
        self.autostart_state = state
        self.autostart_changed = True
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)

    def autostart_apply(self):
        dir_auto = "/.config/autostart/"
        d_file = "meteo-qt.desktop"
        home = os.getenv("HOME")
        total_path = home + dir_auto + d_file
        if self.autostart_state == 2:
            desktop_file = [
                "[Desktop Entry]\n",
                "Exec=meteo-qt\n",
                "Name=meteo-qt\n",
                "Type=Application\n",
                "Version=1.0\n",
                "X-LXQt-Need-Tray=true\n",
            ]
            if not os.path.exists(home + dir_auto):
                os.system("mkdir -p {}".format(os.path.dirname(total_path)))
            with open(total_path, "w") as out_file:
                out_file.writelines(desktop_file)
            self.settings.setValue("Autostart", "True")
            logging.debug("Write desktop file in ~/.config/autostart")
        elif self.autostart_state == 0:
            if os.path.exists(total_path):
                os.remove(total_path)
            self.settings.setValue("Autostart", "False")
            logging.debug("Remove desktop file from ~/.config/autostart")
        else:
            return

    def color_chooser(self):
        col = QColorDialog.getColor()
        if col.isValid():
            self.temp_colorButton.setStyleSheet("QWidget {{ background-color: {0} }}".format(col.name()))
            # focus to next elem to show immediatley the colour
            # in the button (in some DEs)
            self.temp_color_resetButton.setFocus()
            self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)
            self.color_before = col.name()
        else:
            logging.debug("Invalid color:" + str(col))

    def color_reset(self):
        self.temp_colorButton.setStyleSheet("QWidget { background-color:  }")
        self.color_before = ""
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)

    def notifier(self, state):
        self.notifier_state = state
        self.notifier_changed = True
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)

    def notifier_apply(self):
        if self.notifier_state == 2:
            self.settings.setValue("Notifications", "True")
            logging.debug("Write: Notifications = True")
        elif self.notifier_state == 0:
            self.settings.setValue("Notifications", "False")
            logging.debug("Write: Notifications = False")

    def temp_decimal(self, state):
        self.temp_decimal_state = state
        self.temp_decimal_changed = True
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)

    def tray(self):
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)
        self.tray_changed = True

    def tray_apply(self):
        tray = self.tray_icon_combo.currentText()
        self.settings.setValue("Tray", tray)
        logging.debug("Write >" + "Tray >" + str(tray))
        settray = [key for key, value in self.tray_dico.items() if value == tray]
        self.settings.setValue("TrayType", settray[0])

    def fontsize_change(self, size):
        self.fontsize_changed = True
        self.fontsize_value = size
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)

    def fontsize_apply(self):
        logging.debug("Apply fontsize: " + str(self.fontsize_value))
        self.settings.setValue("FontSize", str(self.fontsize_value))

    def proxy(self, state):
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)
        if state == 2:
            self.proxy_bool = True
            self.proxy_button.setEnabled(True)
        else:
            self.proxy_bool = False
            self.proxy_button.setEnabled(False)

    def proxy_settings(self):
        dialog = proxydlg.Proxy(self)
        dialog.exec_()

    def apikey_changed(self):
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)

    def apply_settings(self):
        self.accepted()

    def accepted(self):
        apikey = self.owmkey_text.text()
        city_name = self.city_combo.currentText()
        if apikey == "":
            self.statusbar.setText(self.nokey_message)
            return
        else:
            self.statusbar.setText("")
            self.settings.setValue("APPID", str(self.owmkey_text.text()))
        if city_name == "":
            self.statusbar.setText(self.nocity_message)
            return
        else:
            self.statusbar.setText("")
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(False)
        if hasattr(self, "id_before"):
            self.settings.setValue("ID", self.id_before)
            logging.debug("write " + "ID" + str(self.id_before))
        if hasattr(self, "city_before"):
            self.settings.setValue("City", self.city_before)
            logging.debug("write " + "City" + str(self.city_before))
        if hasattr(self, "country_before"):
            self.settings.setValue("Country", self.country_before)
            logging.debug("write " + "Country" + str(self.country_before))
        if hasattr(self, "city_list_before"):
            self.settings.setValue("CityList", str(self.city_list_before))
            logging.debug("write " + "CityList" + str(self.city_list_before))
        if hasattr(self, "color_before"):
            self.settings.setValue("TrayColor", self.color_before)
            if self.color_before == "":
                self.color_before = "None"
            logging.debug("Write font color for temp in tray: {0}".format(self.color_before))
        if self.autostart_changed:
            self.autostart_apply()
        if self.interval_changed:
            time = self.interval_combo.currentText()
            self.settings.setValue("Interval", time)
            logging.debug("Write " + "Interval " + str(time))
        if self.lang_changed:
            lang = self.language_combo.currentText()
            setlang = [key for key, value in self.language_dico.items() if value == lang]
            self.settings.setValue("Language", setlang[0])
            logging.debug("Write " + "Language " + str(setlang[0]))
        if self.units_changed:
            unit = self.units_combo.currentText()
            setUnit = [key for key, value in self.units_dico.items() if value == unit]
            self.settings.setValue("Unit", setUnit[0])
            logging.debug("Write " + "Unit " + str(setUnit[0]))
        if self.temp_decimal_changed:
            decimal = self.temp_decimal_combo.currentText()
            decimal_bool_str = "False"
            if decimal == "0.1°":
                decimal_bool_str = "True"
            self.settings.setValue("Decimal", decimal_bool_str)
            logging.debug("Write: Decimal in tray icon = " + decimal_bool_str)
        if self.notifier_changed:
            self.notifier_apply()
        if self.tray_changed:
            self.tray_apply()
        if self.fontsize_changed:
            self.fontsize_apply()
        proxy_url = self.settings.value("Proxy_url") or ""
        if proxy_url == "":
            self.proxy_bool = False
        self.settings.setValue("Proxy", str(self.proxy_bool))
        self.applied_signal.emit()

    def accept(self):
        self.accepted()
        apikey = self.owmkey_text.text()
        city_name = self.city_combo.currentText()
        if apikey == "":
            self.statusbar.setText(self.nokey_message)
            return
        if city_name == "":
            self.statusbar.setText(self.nocity_message)
            return
        QDialog.accept(self)

    def add_cities_incombo(self):
        list_cities = ""
        self.city_combo.clear()
        if self.clear_combo:
            return
        if self.first:
            list_cities = self.settings.value("CityList")
            if list_cities is not None:
                self.city_list_before = list_cities[:]
            self.citylist = [self.set_city + "_" + self.settings.value("Country") + "_" + self.settings.value("ID")]
        else:
            self.citylist = [self.city_before + "_" + self.country_before + "_" + self.id_before]
            list_cities = self.city_list_before[:]
        if list_cities is None:
            list_cities = []
        if list_cities != "" and list_cities is not None:
            if type(list_cities) is str:
                list_cities = eval(list_cities)
            self.citylist = self.citylist + list_cities
        duplicate = []
        for i in self.citylist:
            if i not in duplicate:
                duplicate.append(i)
        self.citylist = duplicate[:]
        self.city_combo.addItems(self.citylist)
        if len(list_cities) > 0:
            maxi = len(max(list_cities, key=len))
            self.city_combo.setMinimumSize(maxi * 8, 23)
Beispiel #18
0
    def initUI(self):
        self.setWindowTitle("设置")
        logo = QLabel()  # logo
        logo.setPixmap(QPixmap("./src/logo2.gif"))
        logo.setStyleSheet("background-color:rgb(255,255,255);")
        logo.setAlignment(Qt.AlignCenter)
        self.download_threads_lb = QLabel("同时下载文件数")  # about
        self.download_threads_var = QLineEdit()
        self.download_threads_var.setPlaceholderText("范围:1-9")
        self.download_threads_var.setToolTip("范围:1-9")
        self.download_threads_var.setInputMask("D")
        self.max_size_lb = QLabel("分卷大小(MB)")
        self.max_size_var = QLineEdit()
        self.max_size_var.setPlaceholderText("普通用户最大100,vip用户根据具体情况设置")
        self.max_size_var.setToolTip("普通用户最大100,vip用户根据具体情况设置")
        self.max_size_var.setInputMask("D99")
        self.timeout_lb = QLabel("请求超时(秒)")
        self.timeout_var = QLineEdit()
        self.timeout_var.setPlaceholderText("范围:1-99")
        self.timeout_var.setToolTip("范围:1-99")
        self.timeout_var.setInputMask("D9")
        self.upload_delay_lb = QLabel("上传延时(秒)")
        self.upload_delay_var = QLineEdit()
        self.upload_delay_var.setPlaceholderText("范围:1-99")
        self.upload_delay_var.setToolTip("范围:1-99")
        self.upload_delay_var.setInputMask("D9")
        self.dl_path_lb = QLabel("下载保存路径")
        self.dl_path_var = MyLineEdit(self)
        self.dl_path_var.clicked.connect(self.set_download_path)
        self.time_fmt_box = QCheckBox("使用[年-月-日]时间格式")
        self.to_tray_box = QCheckBox("关闭到系统托盘")
        self.watch_clipboard_box = QCheckBox("监听系统剪切板")
        self.debug_box = QCheckBox("开启调试日志")
        self.set_pwd_box = QCheckBox("上传文件自动设置密码")
        self.set_pwd_var = AutoResizingTextEdit()
        self.set_pwd_var.setPlaceholderText(" 2-8 位数字或字母")
        self.set_pwd_var.setToolTip("2-8 位数字或字母")
        self.set_desc_box = QCheckBox("上传文件自动设置描述")
        self.set_desc_var = AutoResizingTextEdit()
        self.big_file_box = QCheckBox(f"允许上传超过 {self.max_size}MB 的大文件")

        self.time_fmt_box.toggle()
        self.time_fmt_box.stateChanged.connect(self.change_time_fmt)
        self.to_tray_box.stateChanged.connect(self.change_to_tray)
        self.watch_clipboard_box.stateChanged.connect(
            self.change_watch_clipboard)
        self.debug_box.stateChanged.connect(self.change_debug)
        self.set_pwd_box.stateChanged.connect(self.change_set_pwd)
        self.set_pwd_var.editingFinished.connect(self.check_pwd)
        self.set_desc_box.stateChanged.connect(self.change_set_desc)
        self.big_file_box.stateChanged.connect(self.change_big_file)

        buttonBox = QDialogButtonBox()
        buttonBox.setOrientation(Qt.Horizontal)
        buttonBox.setStandardButtons(QDialogButtonBox.Reset
                                     | QDialogButtonBox.Save
                                     | QDialogButtonBox.Cancel)
        buttonBox.button(QDialogButtonBox.Reset).setText("重置")
        buttonBox.button(QDialogButtonBox.Save).setText("保存")
        buttonBox.button(QDialogButtonBox.Cancel).setText("取消")
        buttonBox.button(QDialogButtonBox.Reset).clicked.connect(
            lambda: self.set_values(reset=True))
        buttonBox.button(QDialogButtonBox.Save).clicked.connect(self.slot_save)
        buttonBox.rejected.connect(self.reject)

        form = QFormLayout()
        form.setLabelAlignment(Qt.AlignRight)
        form.setSpacing(10)
        form.addRow(self.download_threads_lb, self.download_threads_var)
        form.addRow(self.timeout_lb, self.timeout_var)
        form.addRow(self.upload_delay_lb, self.upload_delay_var)
        form.addRow(self.max_size_lb, self.max_size_var)
        form.addRow(self.dl_path_lb, self.dl_path_var)

        vbox = QVBoxLayout()
        vbox.addWidget(logo)
        vbox.addStretch(1)
        vbox.addLayout(form)
        vbox.addStretch(1)
        hbox = QHBoxLayout()
        hbox.addWidget(self.time_fmt_box)
        hbox.addWidget(self.to_tray_box)
        hbox.addWidget(self.watch_clipboard_box)
        hbox.addWidget(self.debug_box)
        vbox.addLayout(hbox)
        vbox.addStretch(1)
        hbox_2 = QHBoxLayout()
        hbox_2.addWidget(self.set_pwd_box)
        hbox_2.addWidget(self.set_pwd_var)
        vbox.addLayout(hbox_2)
        vbox.addStretch(1)
        hbox_3 = QHBoxLayout()
        hbox_3.addWidget(self.set_desc_box)
        hbox_3.addWidget(self.set_desc_var)
        vbox.addLayout(hbox_3)
        vbox.addWidget(self.big_file_box)
        vbox.addStretch(2)
        vbox.addWidget(buttonBox)
        self.setLayout(vbox)
        self.setMinimumWidth(500)
Beispiel #19
0
class DPlayerUI(QWidget):
    def __init__(self):
        """Initializes core and ui"""
        super().__init__()

        self.playerCore = DPlayerCore()
        self.player = self.playerCore.player
        self.playlist = self.playerCore.playlist
        self.initUI()
        self.connectSignals()

    def initUI(self):
        """Initialize user interface - buttons, sliders, labels, playlist."""
        self.grid = QGridLayout()

        self.initButtons()
        self.initVolumeSlider()
        self.initPositionSlider()
        self.initDurationLabel()
        self.initPlaylist()
        self.initSongLabel()

        self.setLayout(self.grid)
        self.setGeometry(0, 0, 700, 700)
        self.setWindowTitle('DPlayer')
        self.setWindowIcon(QIcon('icons/logo.png'))
        self.center()
        self.show()

    def connectSignals(self):
        """Connect player signals to functions."""
        self.player.durationChanged.connect(self.durationChanged)
        self.player.positionChanged.connect(self.positionChanged)
        self.player.stateChanged.connect(self.stateChanged)
        self.player.currentMediaChanged.connect(self.songChanged)

    def initButtons(self):
        """Create, set and connect buttons."""
        self.buttons = {}
        self.buttonNames = ['stop', 'previous', 'play', 'next', 'mute',
                            'addFiles', 'addFolder', 'shuffle',
                            'repeatPlaylist', 'repeatSong', 'Save playlist',
                            'Load playlist', 'Clear playlist', 'Find lyrics',
                            'Find info', 'Login', 'Logout', 'Love', 'Unlove']
        shortcuts = ['q', 'w', 'e', 'r', 't', 'a', 's', 'd', 'f', 'g', 'z',
                     'x', 'c', 'v', 'b', 'o', 'p', 'k', 'l']

        for name, cut in zip(self.buttonNames, shortcuts):
            button = QPushButton(self)
            button.setToolTip(name)
            button.setShortcut(QKeySequence(cut))
            self.buttons[name] = button

        for name in self.buttonNames[:10]:
            self.buttons[name].setIcon(QIcon('icons/{}.png'.format(name)))
            self.buttons[name].setIconSize(QSize(20, 20))

        for name, position in zip(self.buttonNames[:5], range(5)):
            self.grid.addWidget(self.buttons[name], 1, position)

        self.buttons['stop'].clicked.connect(self.stopClicked)
        self.buttons['previous'].clicked.connect(self.previousClicked)
        self.previousButtonClicked = False
        self.buttons['play'].clicked.connect(self.playClicked)
        self.buttons['play'].setFocus()
        self.buttons['next'].clicked.connect(self.nextClicked)
        self.buttons['mute'].clicked.connect(self.muteClicked)
        self.buttons['mute'].setIcon(QIcon('icons/volumeMiddle.png'))

        for name, position in zip(self.buttonNames[5:], range(5)):
            self.grid.addWidget(self.buttons[name], 3, position)

        self.buttons['addFiles'].clicked.connect(self.addFiles)
        self.buttons['addFolder'].clicked.connect(self.addFolder)
        self.buttons['shuffle'].clicked[bool].connect(self.playerCore.shuffle)
        self.buttons['shuffle'].setCheckable(True)
        self.buttons['repeatPlaylist'].clicked[bool].connect(
            self.playerCore.repeatPlaylist)
        self.buttons['repeatPlaylist'].setCheckable(True)
        self.buttons['repeatSong'].clicked[bool].connect(
            self.playerCore.repeatSong)
        self.buttons['repeatSong'].setCheckable(True)

        for name, position in zip(self.buttonNames[10:15], range(5)):
            self.buttons[name].setIcon(QIcon('icons/{}.png'.format(name)))
            self.buttons[name].setIconSize(QSize(120, 20))
            self.grid.addWidget(self.buttons[name], 4, position)

        self.buttons['Save playlist'].clicked.connect(self.savePlaylist)
        self.buttons['Load playlist'].clicked.connect(self.loadPlaylist)
        self.buttons['Clear playlist'].clicked.connect(self.clearPlaylist)
        self.buttons['Find lyrics'].clicked.connect(self.findLyrics)
        self.buttons['Find info'].clicked.connect(self.findInfo)

        self.lastFMbuttons = QDialogButtonBox()
        self.lastFMbuttons.setOrientation(Qt.Vertical)
        for name, position in zip(self.buttonNames[15:], range(4)):
            self.buttons[name].setIcon(QIcon('icons/{}.png'.format(name)))
            self.buttons[name].setIconSize(QSize(120, 20))
            self.lastFMbuttons.addButton(self.buttons[name],
                                         QDialogButtonBox.ActionRole)
        self.grid.addWidget(self.lastFMbuttons, 2, 4, Qt.AlignCenter)

        # self.userLabel = QLabel('Username:\n')
        # self.userLabel.setBuddy(self.buttons['Login'])
        # self.grid.addWidget(
        #     self.userLabel, 2, 4, Qt.AlignTop | Qt.AlignHCenter)
        self.buttons['Login'].clicked.connect(self.login)
        self.buttons['Logout'].clicked.connect(self.logout)
        self.buttons['Love'].clicked.connect(self.love)
        self.buttons['Unlove'].clicked.connect(self.unlove)

    def previousClicked(self):
        """Play previous song."""
        self.playerCore.songChanged = True
        self.previousButtonClicked = True
        self.playerCore.previous()
        self.stateChanged()

    def stopClicked(self):
        """Stop the player. Set icon to play button."""
        self.playerCore.stop()
        self.buttons['play'].setIcon(QIcon('icons/play.png'))
        self.buttons['play'].setToolTip('play')
        self.songLabel.setText('')

    def playClicked(self):
        """Play / Pause the player. Set icon to play button."""
        if self.player.state() in (QMediaPlayer.StoppedState,
                                   QMediaPlayer.PausedState):
            self.playerCore.play()
            if self.player.state() == QMediaPlayer.PlayingState:
                self.buttons['play'].setIcon(QIcon('icons/pause.png'))
                self.buttons['play'].setToolTip('pause')
        else:   # QMediaPlayer.PlayingState
            self.playerCore.pause()
            self.buttons['play'].setIcon(QIcon('icons/play.png'))
            self.buttons['play'].setToolTip('play')

        self.songLabel.setText('{} - {}'.format(
            self.playlistTable.item(self.currentPlaying, 0).text(),
            self.playlistTable.item(self.currentPlaying, 1).text()))

    def nextClicked(self):
        """Play next song."""
        self.playerCore.next()
        self.stateChanged()

    def muteClicked(self):
        """Mute / Unmute the player. Set volume slider position."""
        if self.playerCore.isMuted():
            self.playerCore.unmute()
            self.volumeChanged(self.currentVolume)
        else:
            self.playerCore.mute()
            self.volumeChanged(0)

    def addFiles(self):
        """Choose files (*.mp3) to add to the playlist."""
        fileNames, _ = QFileDialog.getOpenFileNames(
            self, 'Add songs', filter='Music (*.mp3 *.ogg *.flac *wav)')
        self.playerCore.add(fileNames)
        self.addClicked(fileNames)

    def addFolder(self):
        """Choose folder to add to the playlist."""
        directory = QFileDialog.getExistingDirectory(self, 'Add a folder')
        self.getFromDir(directory)

    def getFromDir(self, directory):
        """Extract files from directory and add them to the playlist."""
        if not directory:
            return

        dirContent = os.listdir(directory)
        fileNames = []
        for file in dirContent:
            path = '{}/{}'.format(directory, file)
            if os.path.isfile(path) and \
                    path[len(path) - 4:] in ['.mp3', '.ogg', 'flac', '.wav']:
                fileNames.append(path)
            elif os.path.isdir(path):
                self.getFromDir(path)
        self.playerCore.add(fileNames)
        self.addClicked(fileNames)

    def addClicked(self, fileNames):
        """Fill the playlist with fileNames' info."""
        if fileNames is None:
            return
        self.playlistTable.setSortingEnabled(False)
        songsToAdd = len(fileNames)
        for name, row in zip(fileNames, range(songsToAdd)):
            currentRow = row + self.playlist.mediaCount() - songsToAdd
            self.playlistTable.insertRow(currentRow)

            artist = self.playerCore.getArtist(name)[0]
            title = self.playerCore.getTitle(name)[0]
            album = self.playerCore.getAlbum(name)[0]
            seconds = self.playerCore.getDuration(name)
            duration = QTime(0, seconds // 60, seconds % 60)
            duration = duration.toString('mm:ss')

            rowInfo = [artist, title, album, duration]
            for info, index in zip(rowInfo, range(4)):
                cell = QTableWidgetItem(info)
                self.playlistTable.setItem(currentRow, index, cell)
                font = QFont(info, weight=QFont.Normal)
                cell.setFont(font)
                cell.setTextAlignment(Qt.AlignCenter)
        self.playlistTable.setSortingEnabled(True)

        for index in range(4):
            self.playlistTable.resizeColumnToContents(index)

    def initVolumeSlider(self):
        """Initialize volume slider."""
        self.volumeSlider = QSlider(Qt.Vertical, self)
        self.volumeSlider.setRange(0, 100)
        self.currentVolume = 70
        self.volumeSlider.setValue(self.currentVolume)
        self.volumeSlider.setToolTip('volume: {}'.format(self.currentVolume))
        self.volumeSlider.valueChanged[int].connect(self.volumeChanged)
        self.grid.addWidget(self.volumeSlider, 0, 4, Qt.AlignHCenter)
        self.playerCore.setVolume(self.currentVolume)

    def volumeChanged(self, value):
        """Set player's volume to value. Set icon for sound."""
        self.playerCore.setVolume(value)

        if value == 0:
            self.buttons['mute'].setIcon(QIcon('icons/mute.png'))
        elif value <= 35:
            self.buttons['mute'].setIcon(QIcon('icons/volumeMin.png'))
        elif value <= 70:
            self.buttons['mute'].setIcon(QIcon('icons/volumeMiddle.png'))
        else:   # value <= 100
            self.buttons['mute'].setIcon(QIcon('icons/volumeMax.png'))

        self.volumeSlider.setValue(value)
        self.volumeSlider.setToolTip('volume: {}'.format(value))

        if self.playerCore.isMuted():
            self.buttons['mute'].setToolTip('unmute')
        else:
            self.currentVolume = value
            self.buttons['mute'].setToolTip('mute')

    def initPositionSlider(self):
        """Initialize position slider."""
        self.positionSlider = QSlider(Qt.Horizontal, self)
        self.positionSlider.setValue(0)
        self.positionSlider.valueChanged[int].connect(self.position)
        self.positionSliderClicked = False
        self.grid.addWidget(self.positionSlider, 0, 0, 1, 3, Qt.AlignBottom)

    def initDurationLabel(self):
        """Initialize duration label."""
        self.durationLabel = QLabel('00:00 / 00:00')
        self.grid.addWidget(self.durationLabel, 0, 3, Qt.AlignBottom)

    def durationChanged(self, value):
        """Set the maximum of position slider to value when song is changed."""
        self.positionSlider.setMaximum(value)

    def songChanged(self, _):
        """Handle UI when song changes."""
        if self.doubleClicked or self.playlist.mediaCount() == 0:
            self.doubleClicked = False
            return

        self.lastPlayed = self.currentPlaying
        self.currentPlaying = self.playlist.currentIndex()

        if self.currentPlaying >= 0:
            self.setStyle(self.currentPlaying, QFont.Bold)
            self.songLabel.setText('{} - {}'.format(
                self.playlistTable.item(self.currentPlaying, 0).text(),
                self.playlistTable.item(self.currentPlaying, 1).text()))

        self.playlistTable.scrollToItem(
            self.playlistTable.item(self.currentPlaying, 0))

        if self.lastPlayed >= 0 and self.lastPlayed != self.currentPlaying:
            self.setStyle(self.lastPlayed, QFont.Normal)

        for index in range(4):
            self.playlistTable.resizeColumnToContents(index)

        self.previousButtonClicked = False

    def setStyle(self, row, style):
        """Set row's font to style."""
        for idx in range(4):
                text = self.playlistTable.item(row, idx).text()
                font = QFont(text, weight=style)
                self.playlistTable.item(row, idx).setFont(font)

    def position(self, value):
        """Set the position of player at value."""
        if not self.positionSliderClicked:
            self.positionSliderClicked = True
            self.player.setPosition(value)

    def positionChanged(self, value):
        """Update duration label according to value."""
        if not self.positionSliderClicked:
            self.positionSliderClicked = True
            self.positionSlider.setValue(value)
        self.positionSliderClicked = False

        songIndex = self.playlist.currentIndex()
        if songIndex >= 0:
            duration = self.playlistTable.item(
                self.playlist.currentIndex(), 3).text()
            currentSeconds = value // 1000
            currentTime = QTime(0, currentSeconds // 60, currentSeconds % 60)

            time = '{} / {}'.format(
                currentTime.toString('mm:ss'), duration)
        else:
            time = '00:00 / 00:00'

        self.durationLabel.setText(time)

    def stateChanged(self):
        """Check if stopped to update UI."""
        if self.player.state() == QMediaPlayer.StoppedState:
            self.stopClicked()

    def initSongLabel(self):
        """Initialize song label."""
        self.songLabel = QLabel()
        self.songLabel.setAlignment(Qt.AlignCenter)
        self.font = QFont()
        self.font.setBold(True)
        self.font.setItalic(True)
        self.font.setCapitalization(QFont.AllUppercase)
        self.font.setPixelSize(20)
        self.songLabel.setFont(self.font)
        self.grid.addWidget(self.songLabel, 0, 0, 1, 4, Qt.AlignVCenter)

    def initPlaylist(self):
        """Initialize song playlist."""
        self.playlistTable = QTableWidget()

        self.playlistTable.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.playlistTable.setSelectionMode(
            QAbstractItemView.ExtendedSelection)
        self.playlistTable.setSortingEnabled(True)

        self.playlistTable.setTabKeyNavigation(False)
        self.playlistTable.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.playlistTable.setAlternatingRowColors(True)

        self.playlistTable.setVerticalScrollMode(
            QAbstractItemView.ScrollPerPixel)
        self.playlistTable.setHorizontalScrollMode(
            QAbstractItemView.ScrollPerPixel)

        self.playlistTable.itemDoubleClicked.connect(self.doubleClicked)
        self.doubleClicked = False
        self.lastPlayed = -1
        self.currentPlaying = -1
        delete = QShortcut(
            QKeySequence.Delete, self.playlistTable, self.deleteSongs)
        delete.setContext(Qt.WidgetShortcut)

        self.playlistTable.setColumnCount(4)
        self.playlistTable.setHorizontalHeaderLabels(
            ['Artist', 'Title', 'Album', 'Duration'])

        # False - ascending order, True - descending
        self.descendingOrder = [False] * 4
        self.playlistTable.horizontalHeader().sectionClicked.connect(
            self.toSort)

        self.windows = []

        names = []
        for index in range(self.playlist.mediaCount()):
            names.append(self.playlist.media(index).canonicalUrl().path())
        self.addClicked(names)

        self.grid.addWidget(self.playlistTable, 2, 0, 1, 4)
        self.grid.setRowStretch(2, 1)

    def doubleClicked(self, item):
        """Play song at item's row."""
        self.doubleClicked = True
        self.lastPlayed = self.playlist.currentIndex()
        if self.lastPlayed >= 0:
            self.setStyle(self.lastPlayed, QFont.Normal)

        self.currentPlaying = item.row()
        self.playerCore.songChanged = True

        self.playlist.setCurrentIndex(self.currentPlaying)
        self.setStyle(self.currentPlaying, QFont.Bold)
        self.stopClicked()
        self.playClicked()
        self.songLabel.setText('{} - {}'.format(
            self.playlistTable.item(self.currentPlaying, 0).text(),
            self.playlistTable.item(self.currentPlaying, 1).text()))

        for index in range(4):
            self.playlistTable.resizeColumnToContents(index)

    def toSort(self, column):
        """Sort music by column."""
        if self.lastPlayed >= 0:
            self.setStyle(self.lastPlayed, QFont.Normal)
        self.playerCore.sort(column, self.descendingOrder[column])
        self.descendingOrder[column] = bool(1 - self.descendingOrder[column])
        for index in range(4):
            if index != column:
                self.descendingOrder[index] = False

    def deleteSongs(self):
        """Delete selected songs."""
        selectedSongs = self.playlistTable.selectedIndexes()
        indexes = [index.row() for index in selectedSongs]
        toBeRemoved = sorted(indexes[::4], reverse=True)

        currentIndex = self.playlist.currentIndex()
        if currentIndex >= 0:
            self.setStyle(currentIndex, QFont.Normal)

        self.playerCore.remove(toBeRemoved)

        for index in toBeRemoved:
            self.playlistTable.removeRow(index)

        if self.playlistTable.rowCount() == 0:
            return

        currentIndex = self.playlist.currentIndex()
        if currentIndex >= 0:
            self.setStyle(self.playlist.currentIndex(), QFont.Bold)
            self.songLabel.setText('{} - {}'.format(
                self.playlistTable.item(self.currentPlaying, 0).text(),
                self.playlistTable.item(self.currentPlaying, 1).text()))

        for index in range(4):
            self.playlistTable.resizeColumnToContents(index)

    def savePlaylist(self):
        """Save playlist."""
        url, _ = QFileDialog.getSaveFileUrl(self, 'Save playlist')
        self.playerCore.savePlaylist(url)

    def loadPlaylist(self):
        """Load playlist."""
        url, _ = QFileDialog.getOpenFileUrl(
            self, 'Load playlist', filter='Playlists (*.m3u)')

        count = self.playlist.mediaCount()
        self.playerCore.loadPlaylist(url)

        names = []
        for index in range(count, self.playlist.mediaCount()):
            names.append(self.playlist.media(index).canonicalUrl().path())
        self.addClicked(names)

    def clearPlaylist(self):
        """Remove all music from playlist."""
        self.playlistTable.setRowCount(0)
        self.playerCore.clearPlaylist()

    def closeEvent(self, event):
        """Saves current playlist and quits."""
        self.playerCore.savePlaylist(QUrl(
            'file://{}/lastListened.m3u'.format(os.getcwd())))
        event.accept()

    def findLyrics(self):
        """Finds and shows lyrics for selected song(s)."""
        songs = self.playlistTable.selectedIndexes()[::4]
        if not songs:
            return

        for index in songs:
            name = '{} - {}'.format(self.playerCore.musicOrder[index.row()][1],
                                    self.playerCore.musicOrder[index.row()][2])
            lyrics = 'Lyrics:\n\n{}'.format(
                self.playerCore.findLyrics(index.row()))
            self.windows.append(Window(name, lyrics))

        for window in self.windows:
            if window.isClosed:
                self.windows.remove(window)

    def findInfo(self):
        """Opens window with info for selected album at the table."""
        albums = self.playlistTable.selectedIndexes()[::4]
        if not albums:
            return

        for index in albums:
            info = self.playerCore.findInfo(index.row())
            text = '\n'.join(info)
            self.windows.append(Window('Info', text))

    def login(self):
        """Opens window for user to log in lastFM."""
        self.loginWindow = LoginDialog(self.playerCore)

    def logout(self):
        """Logs out current user"""
        if self.playerCore.network is None:
            return
        self.logoutWindow = Window('Logout', 'GoodBye, {}!'.format(
            self.playerCore.username))
        self.playerCore.logout()

    def love(self):
        """Loves selected songs in lastFM."""
        if self.playerCore.network is None:
            self.errorWindow = Window('Error', 'You shoud login first.')
            return
        songs = self.playlistTable.selectedIndexes()[::4]
        if not songs:
            return
        loved = []
        for index in songs:
            loved.append(self.playerCore.loveTrack(index.row()))
        if all(loved):
            self.successWindow = Window('Success', 'Songs loved!')
        else:
            self.errorWindow = Window(
                'Error', 'Something went wrong! Try again later.')

    def unlove(self):
        """Unloves selected songs in lastFM."""
        if self.playerCore.network is None:
            self.errorWindow = Window('Error', 'You shoud login first.')
            return
        songs = self.playlistTable.selectedIndexes()[::4]
        if not songs:
            return

        for index in songs:
            self.playerCore.unloveTrack(index.row())

    def center(self):
        """Position player application at the center of the screen."""
        # rectangle specifying the geometry of the widget
        rectangle = self.frameGeometry()
        # screen resolution -> center point
        centerPoint = QDesktopWidget().availableGeometry().center()
        # set the center of the rectangle to the center of the screen
        rectangle.moveCenter(centerPoint)
        # move the top-left point of the application window to the top-left
        # point of the rectangle
        self.move(rectangle.topLeft())
Beispiel #20
0
class MainWindow(QDialog, SetupTabStopsMixin, CenterOnScreenMixin):
    WINDOW_TITLE_TEXT = 'BAON'
    OPTIONS_BOX_TEXT = 'Options'
    SCAN_RECURSIVE_CHECKBOX_TEXT = 'Recursively scan subfolders'
    USE_PATH_CHECKBOX_TEXT = 'Use path'
    USE_EXTENSION_CHECKBOX_TEXT = 'Use extension'
    RULES_BOX_TEXT = 'Rename Rules'
    FILES_BOX_TEXT = 'Renamed Files'

    RENAME_WARNINGS_DIALOG_CAPTION = 'Please Confirm'
    RENAME_WARNINGS_DIALOG_TEXT = 'There are warnings for some of the files. Proceed with the rename operation anyway?'

    RENAME_COMPLETE_DIALOG_CAPTION = 'Rename Complete'
    RENAME_COMPLETE_DIALOG_TEXT =\
        'The files have been renamed successfully. Do you wish to perform another rename operation?'

    DEFAULT_WINDOW_WIDTH = 800
    DEFAULT_WINDOW_HEIGHT = 600
    RULES_BOX_HEIGHT = 112

    base_path_edited = pyqtSignal(str)
    scan_recursive_changed = pyqtSignal(bool)
    rules_text_changed = pyqtSignal(str)
    use_path_changed = pyqtSignal(bool)
    use_extension_changed = pyqtSignal(bool)

    request_add_override = pyqtSignal(BAONPath, BAONPath)
    request_remove_override = pyqtSignal(BAONPath)

    request_do_rename = pyqtSignal()

    request_rescan = pyqtSignal()

    _base_path_panel = None
    _scan_recursive_checkbox = None
    _use_path_checkbox = None
    _use_extension_checkbox = None
    _rules_editor = None
    _files_display = None
    _files_display_summary_panel = None
    _status_box = None
    _dialog_button_box = None

    def __init__(self, args):
        super().__init__()

        self._init_ui()
        self._fill_in_controls(args)
        self._center_on_screen()

    def _init_ui(self):
        self.setWindowTitle(self.WINDOW_TITLE_TEXT)
        self.resize(self.DEFAULT_WINDOW_WIDTH, self.DEFAULT_WINDOW_HEIGHT)

        main_layout = QVBoxLayout(self)
        main_layout.addWidget(self._create_base_path_panel())
        main_layout.addWidget(self._create_options_box())
        main_layout.addWidget(self._create_rules_box())
        main_layout.addWidget(self._create_files_box())
        main_layout.addWidget(self._create_status_box())
        main_layout.addWidget(self._create_dialog_buttons())

        self._setup_tab_stops(
            self._base_path_panel,
            self._scan_recursive_checkbox,
            self._use_path_checkbox,
            self._use_extension_checkbox,
            self._rules_editor,
            self._files_display,
            self._files_display_summary,
            self._dialog_button_box,
        )

    def _create_base_path_panel(self):
        self._base_path_panel = BasePathPanel(self)
        self._base_path_panel.path_edited.connect(self.base_path_edited)

        return self._base_path_panel

    def _create_options_box(self):
        box = QGroupBox(self.OPTIONS_BOX_TEXT, self)

        self._scan_recursive_checkbox = QCheckBox(self.SCAN_RECURSIVE_CHECKBOX_TEXT, box)
        self._scan_recursive_checkbox.toggled.connect(self.scan_recursive_changed)

        self._use_path_checkbox = QCheckBox(self.USE_PATH_CHECKBOX_TEXT, box)
        self._use_path_checkbox.toggled.connect(self.use_path_changed)

        self._use_extension_checkbox = QCheckBox(self.USE_EXTENSION_CHECKBOX_TEXT, box)
        self._use_extension_checkbox.toggled.connect(self.use_extension_changed)

        layout = QHBoxLayout(box)
        layout.addWidget(self._scan_recursive_checkbox)
        layout.addWidget(self._use_path_checkbox)
        layout.addWidget(self._use_extension_checkbox)
        layout.addStretch()

        return box

    def _create_rules_box(self):
        box = QGroupBox(self.RULES_BOX_TEXT, self)
        box.setMaximumHeight(self.RULES_BOX_HEIGHT)

        self._rules_editor = RulesEditor(box)
        self._rules_editor.rules_edited.connect(self.rules_text_changed)

        layout = QHBoxLayout(box)
        layout.addWidget(self._rules_editor)

        return box

    def _create_files_box(self):
        box = QGroupBox(self.FILES_BOX_TEXT, self)
        box.setSizePolicy(QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding))

        self._files_display = FilesDisplay(box)
        self._files_display_summary = FilesDisplaySummaryPanel(box)

        self._files_display.request_add_override.connect(self.request_add_override)
        self._files_display.request_remove_override.connect(self.request_remove_override)

        self._files_display.counts_changed.connect(self._files_display_summary.set_counts)
        self._files_display.is_browsing_category_changed.connect(self._files_display_summary.set_is_browsing_category)
        self._files_display.has_next_in_category_changed.connect(self._files_display_summary.set_has_next_in_category)
        self._files_display.has_prev_in_category_changed.connect(self._files_display_summary.set_has_prev_in_category)

        self._files_display_summary.start_browsing_category.connect(self._files_display.start_browsing_category)
        self._files_display_summary.next_in_category.connect(self._files_display.next_in_category)
        self._files_display_summary.prev_in_category.connect(self._files_display.prev_in_category)

        layout = QVBoxLayout(box)
        layout.addWidget(self._files_display)
        layout.addWidget(self._files_display_summary)

        return box

    def _create_status_box(self):
        self._status_box = StatusBox(self)

        return self._status_box

    def _create_dialog_buttons(self):
        self._dialog_button_box = QDialogButtonBox(self)
        self._dialog_button_box.setOrientation(Qt.Horizontal)
        self._dialog_button_box.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok)
        self._dialog_button_box.setCenterButtons(True)

        self._dialog_button_box.accepted.connect(self._confirm_rename)
        self._dialog_button_box.rejected.connect(self.reject)

        return self._dialog_button_box

    def _fill_in_controls(self, args):
        if args.base_path is not None:
            self._base_path_panel.set_base_path(args.base_path)
        if args.scan_recursive is not None:
            self._scan_recursive_checkbox.setChecked(args.scan_recursive)
        if args.use_extension is not None:
            self._use_extension_checkbox.setChecked(args.use_extension)
        if args.use_path is not None:
            self._use_path_checkbox.setChecked(args.use_path)
        if args.rules_text is not None:
            self._rules_editor.set_rules(args.rules_text)

    @pyqtSlot()
    def show_first_time(self):
        self.show()
        self.raise_()

        # We need to do this here as otherwise the operation may fail on some platforms
        self.setWindowIcon(QIcon(':/app_icon.png'))

    @pyqtSlot(str)
    def set_base_path(self, base_path):
        self._base_path_panel.set_base_path(base_path)

    @pyqtSlot(BAONStatus)
    def report_status(self, status):
        files_busy = \
            status.scan_status in [BAONStatus.IN_PROGRESS, BAONStatus.PENDING] or \
            status.rename_status in [BAONStatus.IN_PROGRESS, BAONStatus.PENDING]

        self._files_display.setEnabled(not files_busy)

        if status.rules_status == BAONStatus.ERROR:
            self._rules_editor.show_error(status.rules_status_extra.source_span)
        else:
            self._rules_editor.clear_error()

        self._status_box.show_status(status)

        self._dialog_button_box.button(QDialogButtonBox.Ok).setEnabled(
            status.execute_status in [BAONStatus.WAITING_FOR_USER, BAONStatus.ERROR]
        )

        if status.execute_status == BAONStatus.AVAILABLE:
            self._on_rename_completed()

    @pyqtSlot(list)
    def update_scanned_files(self, files):
        self._files_display.set_original_files(files)

    @pyqtSlot(list)
    def update_renamed_files(self, files):
        self._files_display.set_renamed_files(files)

    @pyqtSlot()
    def _confirm_rename(self):
        if self._files_display.has_rename_warnings():
            if not self._ask_user(self.RENAME_WARNINGS_DIALOG_CAPTION, self.RENAME_WARNINGS_DIALOG_TEXT):
                return

        self.request_do_rename.emit()

    def _on_rename_completed(self):
        self._rules_editor.clear()
        self.request_rescan.emit()

        if self._ask_user(self.RENAME_COMPLETE_DIALOG_CAPTION, self.RENAME_COMPLETE_DIALOG_TEXT):
            pass
        else:
            self.reject()

    def _ask_user(self, caption, text):
        on_mac = platform.system() == 'Darwin'

        dialog = QMessageBox(
            QMessageBox.Question,
            caption,
            text,
            QMessageBox.Yes | QMessageBox.No,
            self,
            Qt.Sheet if on_mac else Qt.Dialog | Qt.MSWindowsFixedSizeDialogHint,
        )
        dialog.setDefaultButton(QMessageBox.No)
        dialog.setWindowModality(Qt.WindowModal)

        return dialog.exec_() == QMessageBox.Yes
Beispiel #21
0
class CityTranslate(QDialog):
    city_signal = pyqtSignal([dict])

    def __init__(self, city, cities_list, parent=None):
        super(CityTranslate, self).__init__(parent)
        self.city = city
        self.settings = QSettings()
        self.trans_cities_dict = cities_list
        self.layout = QVBoxLayout()
        self.buttonLayout = QHBoxLayout()
        self.buttonBox = QDialogButtonBox()
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(
            QDialogButtonBox.Ok | QDialogButtonBox.Cancel
        )
        self.buttonBox.rejected.connect(self.reject)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonLayout.addWidget(self.buttonBox)
        self.untranslate_city_label = QLabel(self.find_city_key(self.city))
        self.translate_line = QLineEdit(self.city)
        self.translate_line.selectAll()
        self.translate_line.setMinimumWidth(300)
        self.status_layout = QHBoxLayout()
        self.status_label = QLabel()
        self.status_layout.addWidget(self.status_label)
        self.panel = QGridLayout()
        self.panel.addWidget(self.untranslate_city_label, 0, 0)
        self.panel.addWidget(self.translate_line, 1, 0)
        self.layout.addLayout(self.panel)
        self.layout.addLayout(self.status_layout)
        self.layout.addLayout(self.buttonLayout)
        self.setLayout(self.layout)
        self.setWindowTitle(QCoreApplication.translate('Window title',
                            'City translation', 'City translation dialogue'))

    def find_city_key(self, city):
        for key, value in self.trans_cities_dict.items():
            if value == city:
                return key
        return city

    def accept(self):
        city_dict = {}
        current_city = self.translate_line.text()
        for city, trans in self.trans_cities_dict.items():
            if (
                current_city == trans
                and city != self.untranslate_city_label.text()
            ):
                self.status_label.setText(
                    QCoreApplication.translate(
                        'Warning message in dialog status bar',
                        'The city allready exist',
                        'City translation'
                    )
                )
                return

        city_dict[self.untranslate_city_label.text()] = (
            self.translate_line.text()
        )

        self.city_signal[dict].emit(city_dict)
        QDialog.accept(self)
Beispiel #22
0
class PlotDialog(QDialog):
    def __init__(self, df=None):
        super().__init__()
        self.df = df
        self.resize(721, 586)

        # set up ok and cancel buttin box
        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setGeometry(QRect(360, 520, 341, 32))
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel
                                          | QDialogButtonBox.Ok)
        self.buttonBox.setObjectName("buttonBox")

        # set up chart select type tree widget in the left
        self.select_chart_type = QTreeWidget(self)
        self.select_chart_type.setGeometry(QRect(30, 30, 191, 471))
        self.select_chart_type.setObjectName("select_chart_type")

        self.scatter_plot = QTreeWidgetItem(self.select_chart_type)
        self.scatter = QTreeWidgetItem(self.scatter_plot)
        self.scatter_3d = QTreeWidgetItem(self.scatter_plot)

        self.line_plot = QTreeWidgetItem(self.select_chart_type)
        self.line = QTreeWidgetItem(self.line_plot)

        self.bar_plot = QTreeWidgetItem(self.select_chart_type)
        self.bar = QTreeWidgetItem(self.bar_plot)

        self.density_plot = QTreeWidgetItem(self.select_chart_type)
        self.density_contour = QTreeWidgetItem(self.density_plot)
        self.density_heatmap = QTreeWidgetItem(self.density_plot)
        self.histogram = QTreeWidgetItem(self.select_chart_type)

        self.select_chart_type.setCurrentItem(self.scatter)
        self.select_chart_type.currentItemChanged.connect(self.updateSetting)

        # set tab widget in the right
        self.scatter_tw = PlotSetting_2d(self, self.df)
        self.scatter_3d_tw = PlotSetting_3d(self, self.df)
        self.line_tw = PlotSetting_line_bar(self, self.df)
        self.bar_tw = PlotSetting_bar(self, self.df)
        self.density_contour_tw = PlotSetting_density_contour(self, self.df)
        self.density_heatmap_tw = PlotSetting_density_heatmap(self, self.df)
        self.histogram_tw = PlotSetting_histogram(self, self.df)

        self.scatter_tw.show()
        self.scatter_3d_tw.hide()
        self.line_tw.hide()
        self.bar_tw.hide()
        self.density_contour_tw.hide()
        self.density_heatmap_tw.hide()
        self.histogram_tw.hide()

        self.buttonBox.accepted.connect(self.ok)
        self.buttonBox.rejected.connect(self.cancel)
        QMetaObject.connectSlotsByName(self)
        self.setText()

        self.setWindowTitle("Plot Setting")
        self.setWindowIcon(QIcon('resource/icon.ico'))
        self.setWindowIconText('viuplot')
        self.show()

    # set up tab with in each element
    def setText(self):

        # select_chart_type
        self.select_chart_type.headerItem().setText(0, "Chart type")
        __sortingEnabled = self.select_chart_type.isSortingEnabled()
        self.select_chart_type.setSortingEnabled(False)
        self.scatter_plot.setText(0, "scatter plot")
        self.scatter.setText(0, "scatter")
        self.scatter_3d.setText(0, "scatter 3d")
        self.line_plot.setText(0, "line plot")
        self.line.setText(0, "line")
        self.bar_plot.setText(0, "bar plot")
        self.bar.setText(0, "bar")
        self.density_plot.setText(0, "density plot")
        self.density_contour.setText(0, "density contour")
        self.density_heatmap.setText(0, "density heatmap")
        self.histogram.setText(0, "histogram")
        self.select_chart_type.setSortingEnabled(__sortingEnabled)

    # update func for tab widget view when current tree widget changes
    def updateSetting(self):
        if self.select_chart_type.currentItem() == self.scatter:
            self.scatter_tw.show()
            self.scatter_3d_tw.hide()
            self.line_tw.hide()
            self.bar_tw.hide()
            self.density_contour_tw.hide()
            self.density_heatmap_tw.hide()
            self.histogram_tw.hide()
            print("scatter")
        elif self.select_chart_type.currentItem() == self.scatter_3d:
            self.scatter_tw.hide()
            self.scatter_3d_tw.show()
            self.line_tw.hide()
            self.bar_tw.hide()
            self.density_contour_tw.hide()
            self.density_heatmap_tw.hide()
            self.histogram_tw.hide()
            print("scatter 3d")
        elif self.select_chart_type.currentItem() == self.line:
            self.scatter_tw.hide()
            self.scatter_3d_tw.hide()
            self.line_tw.show()
            self.bar_tw.hide()
            self.density_contour_tw.hide()
            self.density_heatmap_tw.hide()
            self.histogram_tw.hide()
            print("line")
        elif self.select_chart_type.currentItem() == self.bar:
            self.scatter_tw.hide()
            self.scatter_3d_tw.hide()
            self.line_tw.hide()
            self.bar_tw.show()
            self.density_contour_tw.hide()
            self.density_heatmap_tw.hide()
            self.histogram_tw.hide()
            print("bar")
        elif self.select_chart_type.currentItem() == self.density_contour:
            self.scatter_tw.hide()
            self.scatter_3d_tw.hide()
            self.line_tw.hide()
            self.bar_tw.hide()
            self.density_contour_tw.show()
            self.density_heatmap_tw.hide()
            self.histogram_tw.hide()
            print("density contour")
        elif self.select_chart_type.currentItem() == self.density_heatmap:
            self.scatter_tw.hide()
            self.scatter_3d_tw.hide()
            self.line_tw.hide()
            self.bar_tw.hide()
            self.density_contour_tw.hide()
            self.density_heatmap_tw.show()
            self.histogram_tw.hide()
            print("density heatmap")
        elif self.select_chart_type.currentItem() == self.histogram:
            self.scatter_tw.hide()
            self.scatter_3d_tw.hide()
            self.line_tw.hide()
            self.bar_tw.hide()
            self.density_contour_tw.hide()
            self.density_heatmap_tw.hide()
            self.histogram_tw.show()
            print("histogram")

    # func for creating chart when clicking ok
    def ok(self):
        currentItem = self.select_chart_type.currentItem()

        if currentItem == self.scatter:
            info = self.scatter_tw.getCurrentInfo()
            info['chart_type'] = 'scatter'

        elif currentItem == self.scatter_3d:
            info = self.scatter_3d_tw.getCurrentInfo()
            info['chart_type'] = 'scatter_3d'

        elif currentItem == self.line:
            info = self.line_tw.getCurrentInfo()
            info['chart_type'] = 'line'

        elif currentItem == self.bar:
            info = self.bar_tw.getCurrentInfo()
            info['chart_type'] = 'bar'

        elif currentItem == self.density_contour:
            info = self.density_contour_tw.getCurrentInfo()
            info['chart_type'] = 'density_contour'

        elif currentItem == self.density_heatmap:
            info = self.density_heatmap_tw.getCurrentInfo()
            info['chart_type'] = 'density_heatmap'

        elif currentItem == self.histogram:
            info = self.histogram_tw.getCurrentInfo()
            info['chart_type'] = 'histogram'

        print(info)
        try:
            self.chart = Chart(self.df, info)
            self.close()
        except (AttributeError, ValueError, TypeError) as e:
            self.err_msg = QMessageBox()
            self.err_msg.setIcon(QMessageBox.Critical)
            self.err_msg.setText("Error")
            self.err_msg.setInformativeText(
                'Unable to plot with current setting.')
            self.err_msg.setWindowTitle("Error")
            self.err_msg.exec_()

    def cancel(self):
        self.close()
Beispiel #23
0
class IndputChapterDialog(QDialog):

    chapterInput = pyqtSignal(str, str)

    def init_ui(self):
        # Dialog
        self.Dialog = QDialog()
        self.Dialog.setWindowModality(Qt.NonModal)
        self.Dialog.resize(410, 190)
        self.Dialog.setWindowFlags(Qt.MSWindowsFixedSizeDialogHint)
        self.Dialog.setWindowIcon(QIcon((resource_path('icon.ico'))))
        font = QFont()
        font.setFamily('Verdana')
        self.Dialog.setFont(font)
        self.Dialog.setModal(True)
        self.Dialog.setWindowTitle('Please Input Chapter ...')

        # Button Box
        self.buttonBox = QDialogButtonBox(self.Dialog)
        self.buttonBox.setGeometry(QRect(190, 140, 201, 32))
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel
                                          | QDialogButtonBox.Ok)

        # From Chapter
        self.labelFromChapter = QLabel(self.Dialog)
        self.labelFromChapter.setGeometry(QRect(20, 30, 121, 31))
        font = QFont()
        font.setFamily('Verdana')
        font.setPointSize(9)
        self.labelFromChapter.setFont(font)
        self.labelFromChapter.setText('From Chapter:')

        self.inputFromChapter = QLineEdit(self.Dialog)
        self.inputFromChapter.setGeometry(QRect(140, 30, 251, 31))

        # To Chapter
        self.labelToChapter = QLabel(self.Dialog)
        self.labelToChapter.setGeometry(QRect(20, 80, 91, 31))
        font = QFont()
        font.setFamily('Verdana')
        font.setPointSize(9)
        self.labelToChapter.setFont(font)
        self.labelToChapter.setText('To Chapter:')

        self.inputToChapter = QLineEdit(self.Dialog)
        self.inputToChapter.setGeometry(QRect(140, 80, 251, 31))

        # Signal
        self.buttonBox.accepted.connect(self.get_chapter_input)
        self.buttonBox.rejected.connect(self.Dialog.reject)
        QMetaObject.connectSlotsByName(self.Dialog)

    def start(self):
        self.init_ui()
        self.Dialog.exec_()

    def get_chapter_input(self):
        self.chapterInput.emit(self.inputFromChapter.text(),
                               self.inputToChapter.text())
        self.Dialog.close()
Beispiel #24
0
class Ui_WineASIOSettings(object):
    OBJECT_NAME = "WineASIOSettings"

    def setupUi(self, WineASIOSettings):
        WineASIOSettings.setObjectName(self.OBJECT_NAME)
        WineASIOSettings.resize(400, 310)
        self.verticalLayout = QVBoxLayout(WineASIOSettings)
        self.verticalLayout.setObjectName("verticalLayout")
        self.group_ports = QGroupBox(WineASIOSettings)
        self.group_ports.setObjectName("group_ports")
        self.verticalLayout_22 = QVBoxLayout(self.group_ports)
        self.verticalLayout_22.setObjectName("verticalLayout_22")
        self.layout_ports_in = QHBoxLayout()
        self.layout_ports_in.setObjectName("layout_ports_in")
        self.label_ports_in = QLabel(self.group_ports)
        self.label_ports_in.setAlignment(Qt.AlignRight | Qt.AlignTrailing
                                         | Qt.AlignVCenter)
        self.label_ports_in.setObjectName("label_ports_in")
        self.layout_ports_in.addWidget(self.label_ports_in)
        self.sb_ports_in = QSpinBox(self.group_ports)
        self.sb_ports_in.setMaximum(128)
        self.sb_ports_in.setSingleStep(2)
        self.sb_ports_in.setObjectName("sb_ports_in")
        self.layout_ports_in.addWidget(self.sb_ports_in)
        self.verticalLayout_22.addLayout(self.layout_ports_in)
        self.layout_ports_out = QHBoxLayout()
        self.layout_ports_out.setObjectName("layout_ports_out")
        self.label_ports_out = QLabel(self.group_ports)
        self.label_ports_out.setAlignment(Qt.AlignRight | Qt.AlignTrailing
                                          | Qt.AlignVCenter)
        self.label_ports_out.setObjectName("label_ports_out")
        self.layout_ports_out.addWidget(self.label_ports_out)
        self.sb_ports_out = QSpinBox(self.group_ports)
        self.sb_ports_out.setMinimum(2)
        self.sb_ports_out.setMaximum(128)
        self.sb_ports_out.setSingleStep(2)
        self.sb_ports_out.setObjectName("sb_ports_out")
        self.layout_ports_out.addWidget(self.sb_ports_out)
        self.verticalLayout_22.addLayout(self.layout_ports_out)
        self.layout_ports_connect_hw = QHBoxLayout()
        self.layout_ports_connect_hw.setObjectName("layout_ports_connect_hw")
        spacerItem = QSpacerItem(150, 20, QSizePolicy.Fixed,
                                 QSizePolicy.Minimum)
        self.layout_ports_connect_hw.addItem(spacerItem)
        self.cb_ports_connect_hw = QCheckBox(self.group_ports)
        self.cb_ports_connect_hw.setObjectName("cb_ports_connect_hw")
        self.layout_ports_connect_hw.addWidget(self.cb_ports_connect_hw)
        self.verticalLayout_22.addLayout(self.layout_ports_connect_hw)
        self.verticalLayout.addWidget(self.group_ports)
        self.group_jack = QGroupBox(WineASIOSettings)
        self.group_jack.setObjectName("group_jack")
        self.verticalLayout_23 = QVBoxLayout(self.group_jack)
        self.verticalLayout_23.setObjectName("verticalLayout_23")
        self.layout_jack_autostart = QHBoxLayout()
        self.layout_jack_autostart.setObjectName("layout_jack_autostart")
        spacerItem1 = QSpacerItem(150, 20, QSizePolicy.Fixed,
                                  QSizePolicy.Minimum)
        self.layout_jack_autostart.addItem(spacerItem1)
        self.cb_jack_autostart = QCheckBox(self.group_jack)
        self.cb_jack_autostart.setObjectName("cb_jack_autostart")
        self.layout_jack_autostart.addWidget(self.cb_jack_autostart)
        self.verticalLayout_23.addLayout(self.layout_jack_autostart)
        self.layout_jack_fixed_bsize = QHBoxLayout()
        self.layout_jack_fixed_bsize.setObjectName("layout_jack_fixed_bsize")
        spacerItem2 = QSpacerItem(150, 20, QSizePolicy.Fixed,
                                  QSizePolicy.Minimum)
        self.layout_jack_fixed_bsize.addItem(spacerItem2)
        self.cb_jack_fixed_bsize = QCheckBox(self.group_jack)
        self.cb_jack_fixed_bsize.setObjectName("cb_jack_fixed_bsize")
        self.layout_jack_fixed_bsize.addWidget(self.cb_jack_fixed_bsize)
        self.verticalLayout_23.addLayout(self.layout_jack_fixed_bsize)
        self.layout_jack_buffer_size = QHBoxLayout()
        self.layout_jack_buffer_size.setObjectName("layout_jack_buffer_size")
        self.label_jack_buffer_size = QLabel(self.group_jack)
        self.label_jack_buffer_size.setAlignment(Qt.AlignRight
                                                 | Qt.AlignTrailing
                                                 | Qt.AlignVCenter)
        self.label_jack_buffer_size.setObjectName("label_jack_buffer_size")
        self.layout_jack_buffer_size.addWidget(self.label_jack_buffer_size)
        self.cb_jack_buffer_size = QComboBox(self.group_jack)
        self.cb_jack_buffer_size.setObjectName("cb_jack_buffer_size")
        self.layout_jack_buffer_size.addWidget(self.cb_jack_buffer_size)
        self.verticalLayout_23.addLayout(self.layout_jack_buffer_size)
        self.verticalLayout.addWidget(self.group_jack)
        self.buttonBox = QDialogButtonBox(WineASIOSettings)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel
                                          | QDialogButtonBox.Ok
                                          | QDialogButtonBox.RestoreDefaults)
        self.buttonBox.setObjectName("buttonBox")
        self.verticalLayout.addWidget(self.buttonBox)

        self.retranslateUi(WineASIOSettings)
        self.buttonBox.accepted.connect(WineASIOSettings.accept)
        self.buttonBox.rejected.connect(WineASIOSettings.reject)
        QMetaObject.connectSlotsByName(WineASIOSettings)

# ---------------------------------------------------------------------------------------------------------------------

    def retranslateUi(self, WineASIOSettings):
        _tr = QCoreApplication.translate
        WineASIOSettings.setWindowTitle(
            _tr(self.OBJECT_NAME, "WineASIO Settings"))

        # Audio Ports
        self.group_ports.setTitle(_tr(self.OBJECT_NAME, "Audio Ports"))

        self.label_ports_in.setText(_tr(self.OBJECT_NAME, "Number of inputs:"))
        self.label_ports_in.setToolTip(
            _tr(
                self.OBJECT_NAME,
                "Number of jack ports that wineasio will try to open.\n"
                "Default is 16"))

        self.sb_ports_in.setToolTip(
            _tr(
                self.OBJECT_NAME,
                "Number of jack ports that wineasio will try to open.\n"
                "Default is 16"))

        self.label_ports_out.setText(
            _tr(self.OBJECT_NAME, "Number of outputs:"))
        self.label_ports_out.setToolTip(
            _tr(
                self.OBJECT_NAME,
                "Number of jack ports that wineasio will try to open.\n"
                "Default is 16"))

        self.sb_ports_out.setToolTip(
            _tr(
                self.OBJECT_NAME,
                "Number of jack ports that wineasio will try to open.\n"
                "Default is 16"))

        self.cb_ports_connect_hw.setText(
            _tr(self.OBJECT_NAME, "Connect to hardware"))
        self.cb_ports_connect_hw.setToolTip(
            _tr(
                self.OBJECT_NAME, "Try to connect the asio channels to the\n"
                "physical I/O ports on your hardware.\n"
                "Default is on"))

        # JACK Options
        self.group_jack.setTitle(_tr(self.OBJECT_NAME, "JACK Options"))

        self.cb_jack_autostart.setText(
            _tr(self.OBJECT_NAME, "Autostart server"))
        self.cb_jack_autostart.setToolTip(
            _tr(
                self.OBJECT_NAME,
                "Enable wineasio to launch the jack server.\n"
                "Default is off"))

        self.cb_jack_fixed_bsize.setText(
            _tr(self.OBJECT_NAME, "Fixed buffersize"))
        self.cb_jack_fixed_bsize.setToolTip(
            _tr(
                self.OBJECT_NAME,
                "When on, an asio app will be able to change the jack buffer size.\n"
                "Default is off"))

        self.label_jack_buffer_size.setText(
            _tr(self.OBJECT_NAME, "Preferred buffersize:"))
Beispiel #25
0
class PlainTextImportDialog(QDialog):
    class TableModel(QAbstractTableModel):
        ROW_BATCH_COUNT: Final[int] = 10

        def __init__(self, parent=None):
            super().__init__(parent)
            self._data: List[Tuple[Union[str, int, float], ...]] = []
            self._header: Dict[int, Union[str, int, float]] = dict()
            self._rows_loaded: int = self.ROW_BATCH_COUNT

        def rowCount(self, parent=None):
            if self._data is None:
                return 0
            return len(self._data)

        def columnCount(self, parent=None):
            if self._data is None:
                return 0
            return len(self._header)

        def data(self, index, role=Qt.DisplayRole):
            if index.isValid():
                if role == Qt.DisplayRole:
                    return QVariant(
                        str(self._data[index.row()][index.column()]))
            return QVariant()

        def set_data(self, new_data: List[Tuple[Union[str, int, float], ...]]):
            self._data = new_data

        def headerData(self, col, orientation, role=None):
            if orientation == Qt.Horizontal and role == Qt.DisplayRole:
                return self._header[col]
            return None

        def setHeaderData(self,
                          section: int,
                          orientation: Qt.Orientation,
                          value,
                          role: int = ...) -> bool:
            if orientation == Qt.Horizontal and role == Qt.DisplayRole and 0 <= section < len(
                    self._header):
                self._header[section] = value
                return True
            return False

        def sort(self,
                 column: int,
                 order: Qt.SortOrder = Qt.AscendingOrder) -> None:
            self.beginResetModel()
            data_column: Final[int] = {0: 1, 1: 3, 2: 5, 3: 7}[column]
            self._data.sort(key=lambda l: l[data_column],
                            reverse=bool(order != Qt.AscendingOrder))
            self.endResetModel()

        def canFetchMore(self, index=QModelIndex()):
            return len(self._data) > self._rows_loaded

        def fetchMore(self, index=QModelIndex()):
            # https://sateeshkumarb.wordpress.com/2012/04/01/paginated-display-of-table-data-in-pyqt/
            reminder: int = len(self._data) - self._rows_loaded
            items_to_fetch: int = min(reminder, self.ROW_BATCH_COUNT)
            self.beginInsertRows(QModelIndex(), self._rows_loaded,
                                 self._rows_loaded + items_to_fetch - 1)
            self._rows_loaded += items_to_fetch
            self.endInsertRows()

    def __init__(self, file_name: str):
        super(PlainTextImportDialog, self).__init__()

        self._translate = QCoreApplication.translate

        self.setWindowModality(Qt.ApplicationModal)
        self.resize(594, 546)

        self.main_layout = QGridLayout(self)

        self.table_preview = QTableView(self)
        self.table_preview.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.table_preview.setAlternatingRowColors(True)
        self.table_preview_model = self.TableModel()
        self.table_preview.setModel(self.table_preview_model)

        self.main_layout.addWidget(self.table_preview, 0, 0, 1, 1)

        self.frame_settings = QFrame(self)
        self.frame_settings.setFrameShape(QFrame.StyledPanel)
        self.frame_settings.setFrameShadow(QFrame.Raised)
        self.layout_settings = QGridLayout(self.frame_settings)

        self.frame_column_naming = QFrame(self.frame_settings)
        self.layout_column_naming = QFormLayout(self.frame_column_naming)

        self.text_column_prefix = QLineEdit(self.frame_column_naming)
        self.layout_column_naming.addRow(
            self._translate('PlainTextImportDialog', 'Column prefix:'),
            self.text_column_prefix)

        self.text_column_suffix = QLineEdit(self.frame_column_naming)
        self.layout_column_naming.addRow(
            self._translate('PlainTextImportDialog', 'Column suffix:'),
            self.text_column_suffix)

        self.layout_settings.addWidget(self.frame_column_naming, 3, 1, 1, 1)

        self.frame_skip = QFrame(self.frame_settings)
        self.layout_skip = QFormLayout(self.frame_skip)

        self.spin_skip_rows_before_header = QSpinBox(self.frame_skip)
        self.spin_skip_rows_before_header.setMaximum(999)
        self.layout_skip.addRow(
            self._translate('PlainTextImportDialog',
                            'Skip rows before header:'),
            self.spin_skip_rows_before_header)

        self.check_has_header = QCheckBox(self.frame_skip)
        self.layout_skip.setWidget(1, QFormLayout.SpanningRole,
                                   self.check_has_header)
        self.check_has_units = QCheckBox(self.frame_skip)
        self.layout_skip.setWidget(2, QFormLayout.SpanningRole,
                                   self.check_has_units)

        self.spin_skip_rows_after_header = QSpinBox(self.frame_skip)
        self.spin_skip_rows_after_header.setMaximum(999)
        self.layout_skip.addRow(
            self._translate('PlainTextImportDialog',
                            'Skip rows after header:'),
            self.spin_skip_rows_after_header)

        self.spin_skip_rows_at_bottom = QSpinBox(self.frame_skip)
        self.spin_skip_rows_at_bottom.setMaximum(999)
        self.layout_skip.addRow(
            self._translate('PlainTextImportDialog', 'Skip rows at bottom:'),
            self.spin_skip_rows_at_bottom)

        self.text_skip_columns = QLineEdit(self.frame_skip)
        self.layout_skip.addRow(
            self._translate('PlainTextImportDialog', 'Skip columns:'),
            self.text_skip_columns)

        self.layout_settings.addWidget(self.frame_skip, 2, 0, 2, 1)

        self.layout_preview_rows = QFormLayout()
        self.spin_preview_rows = QSpinBox(self.frame_settings)
        self.spin_preview_rows.setMinimum(1)
        self.spin_preview_rows.setProperty('value', 10)
        self.layout_preview_rows.addRow(
            self._translate('PlainTextImportDialog', 'Rows in the preview:'),
            self.spin_preview_rows)

        self.layout_settings.addLayout(self.layout_preview_rows, 1, 0, 1, 1)
        self.frame_separators = QFrame(self.frame_settings)

        self.layout_separators = QFormLayout(self.frame_separators)
        self.combo_separator = QComboBox(self.frame_separators)
        self.combo_separator.setEditable(True)
        self.combo_separator.setSizeAdjustPolicy(QComboBox.AdjustToContents)
        self.combo_separator.addItem(
            self._translate('PlainTextImportDialog', 'comma (,)'))
        self.combo_separator.addItem(
            self._translate('PlainTextImportDialog', 'semicolon (;)'))
        self.combo_separator.addItem(
            self._translate('PlainTextImportDialog', 'space'))
        self.combo_separator.addItem(
            self._translate('PlainTextImportDialog', 'tab'))
        self.combo_separator.addItem(
            self._translate('PlainTextImportDialog', 'space or tab'))
        self.layout_separators.addRow(
            self._translate('PlainTextImportDialog', 'Separator:'),
            self.combo_separator)

        self.check_combine_separators = QCheckBox(self.frame_separators)
        self.layout_separators.setWidget(1, QFormLayout.SpanningRole,
                                         self.check_combine_separators)

        self.combo_comment = QComboBox(self.frame_separators)
        self.combo_comment.setEditable(True)
        self.combo_comment.setCurrentText('#')
        self.combo_comment.addItems(('#', ';', '%', '!'))
        self.layout_separators.addRow(
            self._translate('PlainTextImportDialog', 'Comment:'),
            self.combo_comment)

        self.combo_text_start = QComboBox(self.frame_separators)
        self.combo_text_start.setEditable(True)
        self.combo_text_start.setCurrentText("'")
        self.combo_text_start.addItems(('"', "'", '«', '„', '“', '‘', '`'))
        self.layout_separators.addRow(
            self._translate('PlainTextImportDialog', 'Text start:'),
            self.combo_text_start)

        self.combo_text_end = QComboBox(self.frame_separators)
        self.combo_text_end.setEditable(True)
        self.combo_text_end.setCurrentText("'")
        self.combo_text_end.addItems(('"', "'", '»', '”', '’', '`'))
        self.layout_separators.addRow(
            self._translate('PlainTextImportDialog', 'Text end:'),
            self.combo_text_end)

        self.layout_settings.addWidget(self.frame_separators, 1, 1, 2, 1)
        self.main_layout.addWidget(self.frame_settings, 2, 0, 1, 1)
        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel
                                          | QDialogButtonBox.Open)

        self.main_layout.addWidget(self.buttonBox, 5, 0, 1, 1)

        self.setWindowTitle(
            self._translate('PlainTextImportDialog', 'Plain Text Import'))
        self.text_skip_columns.setPlaceholderText(
            self._translate('PlainTextImportDialog', 'e.g., 1, 2, 4-6'))
        self.check_has_units.setText(
            self._translate('PlainTextImportDialog',
                            'The units are placed just after the header'))
        self.check_has_header.setText(
            self._translate('PlainTextImportDialog', 'The file has a header'))
        self.check_combine_separators.setText(
            self._translate('PlainTextImportDialog', 'Combine separators'))
        self.combo_comment.setToolTip(
            self._translate(
                'PlainTextImportDialog',
                'This marks comment lines. Separate multiple marks with spaces.'
            ))

        self.adjustSize()

        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)
        # QMetaObject.connectSlotsByName(self)

        self._file_name: Path = Path(file_name)
class PreferencesPanel(QDialog):
    def __init__(self, parent, app):
        # The flags we pass are that so we don't get the "What's this" button in the title bar
        QDialog.__init__(self, parent, Qt.WindowTitleHint | Qt.WindowSystemMenuHint)
        self.app = app
        self._setupUi()

        self.dateFormatEdit.editingFinished.connect(self.dateFormatEdited)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)

    def _setupUi(self):
        self.setWindowTitle(tr("Preferences"))
        self.resize(332, 170)
        self.verticalLayout = QVBoxLayout(self)
        self.formLayout = QFormLayout()

        self.autoSaveIntervalSpinBox = QSpinBox(self)
        self.autoSaveIntervalSpinBox.setMaximumSize(QSize(70, 0xffffff))
        self.label_5 = QLabel(tr("minute(s) (0 for none)"), self)
        self.formLayout.addRow(
            tr("Auto-save interval:"),
            horizontalWrap([self.autoSaveIntervalSpinBox, self.label_5])
        )

        self.dateFormatEdit = QLineEdit(self)
        self.dateFormatEdit.setMaximumSize(QSize(140, 0xffffff))
        self.formLayout.addRow(tr("Date format:"), self.dateFormatEdit)

        self.fontSizeSpinBox = QSpinBox()
        self.fontSizeSpinBox.setMinimum(5)
        self.fontSizeSpinBox.setMaximumSize(QSize(70, 0xffffff))
        self.formLayout.addRow(tr("Font size:"), self.fontSizeSpinBox)

        self.languageComboBox = QComboBox(self)
        LANGNAMES = get_langnames()
        for lang in SUPPORTED_LANGUAGES:
            self.languageComboBox.addItem(LANGNAMES[lang])
        self.languageComboBox.setMaximumSize(QSize(140, 0xffffff))
        self.formLayout.addRow(tr("Language:"), self.languageComboBox)
        self.verticalLayout.addLayout(self.formLayout)

        self.scopeDialogCheckBox = QCheckBox(tr("Show scope dialog when modifying a scheduled transaction"), self)
        self.verticalLayout.addWidget(self.scopeDialogCheckBox)
        self.autoDecimalPlaceCheckBox = QCheckBox(tr("Automatically place decimals when typing"), self)
        self.verticalLayout.addWidget(self.autoDecimalPlaceCheckBox)
        self.debugModeCheckBox = QCheckBox(tr("Debug mode (restart required)"), self)
        self.verticalLayout.addWidget(self.debugModeCheckBox)
        self.verticalLayout.addItem(verticalSpacer())
        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Ok)
        self.verticalLayout.addWidget(self.buttonBox)

    def load(self):
        appm = self.app.model
        self.autoSaveIntervalSpinBox.setValue(appm.autosave_interval)
        self.dateFormatEdit.setText(self.app.prefs.dateFormat)
        self.fontSizeSpinBox.setValue(self.app.prefs.tableFontSize)
        self.scopeDialogCheckBox.setChecked(appm.show_schedule_scope_dialog)
        self.autoDecimalPlaceCheckBox.setChecked(appm.auto_decimal_place)
        self.debugModeCheckBox.setChecked(self.app.prefs.debugMode)
        try:
            langindex = SUPPORTED_LANGUAGES.index(self.app.prefs.language)
        except ValueError:
            langindex = 0
        self.languageComboBox.setCurrentIndex(langindex)

    def save(self):
        restartRequired = False
        appm = self.app.model
        appm.autosave_interval = self.autoSaveIntervalSpinBox.value()
        if self.dateFormatEdit.text() != self.app.prefs.dateFormat:
            restartRequired = True
        self.app.prefs.dateFormat = self.dateFormatEdit.text()
        self.app.prefs.tableFontSize = self.fontSizeSpinBox.value()
        appm.show_schedule_scope_dialog = self.scopeDialogCheckBox.isChecked()
        appm.auto_decimal_place = self.autoDecimalPlaceCheckBox.isChecked()
        self.app.prefs.debugMode = self.debugModeCheckBox.isChecked()
        lang = SUPPORTED_LANGUAGES[self.languageComboBox.currentIndex()]
        oldlang = self.app.prefs.language
        if oldlang not in SUPPORTED_LANGUAGES:
            oldlang = 'en'
        if lang != oldlang:
            restartRequired = True
        self.app.prefs.language = lang
        if restartRequired:
            QMessageBox.information(self, "", tr("moneyGuru has to restart for these changes to take effect"))

    #--- Signals
    def dateFormatEdited(self):
        self.dateFormatEdit.setText(clean_format(self.dateFormatEdit.text()))
Beispiel #27
0
class NewProjectDialog(QDialog):

    #此处定义常量

    #此处定义信号

    def __init__(self):
        QDialog.__init__(self)
        self.project_dir = None
        self.project_name = None

    def setup(self):
        self.resize(450, 120)
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth())
        self.setSizePolicy(sizePolicy)
        self.verticalLayout = QVBoxLayout(self)
        self.verticalLayout.setObjectName("verticalLayout")
        self.horizontalLayout = QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.label_project_name = QLabel(self)
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.label_project_name.sizePolicy().hasHeightForWidth())
        self.label_project_name.setSizePolicy(sizePolicy)
        self.label_project_name.setMinimumSize(QSize(80, 24))
        self.label_project_name.setMaximumSize(QSize(80, 24))
        self.label_project_name.setObjectName("label_project_name")
        self.horizontalLayout.addWidget(self.label_project_name)
        self.lineEdit_project_name = QLineEdit(self)
        self.lineEdit_project_name.setObjectName("lineEdit_project_name")
        self.horizontalLayout.addWidget(self.lineEdit_project_name)
        self.verticalLayout.addLayout(self.horizontalLayout)
        self.horizontalLayout_2 = QHBoxLayout()
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.label_location = QLabel(self)
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.label_location.sizePolicy().hasHeightForWidth())
        self.label_location.setSizePolicy(sizePolicy)
        self.label_location.setMinimumSize(QSize(80, 24))
        self.label_location.setMaximumSize(QSize(80, 24))
        self.label_location.setObjectName("label_location")
        self.horizontalLayout_2.addWidget(self.label_location)
        self.lineEdit_location = QLineEdit(self)
        self.lineEdit_location.setObjectName("lineEdit_location")
        self.lineEdit_location.setReadOnly(True)
        self.lineEdit_location.setText(os.getcwd())
        self.horizontalLayout_2.addWidget(self.lineEdit_location)
        self.toolbutton_open = QToolButton(self)
        self.toolbutton_open.setMinimumSize(QSize(24, 24))
        self.toolbutton_open.setMaximumSize(QSize(24, 24))
        self.toolbutton_open.setObjectName("toolbutton_open")
        self.horizontalLayout_2.addWidget(self.toolbutton_open)
        self.verticalLayout.addLayout(self.horizontalLayout_2)
        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel
                                          | QDialogButtonBox.Ok)
        self.buttonBox.setObjectName("buttonBox")
        self.verticalLayout.addWidget(self.buttonBox)

        self.retranslateUi()

        #        给项目路径和项目赋初值
        self.project_dir = self.lineEdit_location.text()
        self.project_name = self.lineEdit_project_name.text()
        #        信号与槽进行连接
        self.buttonBox.accepted.connect(self.slot_accept)
        self.buttonBox.rejected.connect(self.reject)
        self.toolbutton_open.clicked.connect(self.slot_open)
        self.lineEdit_project_name.textChanged.connect(self.slot_set_dir)
        QMetaObject.connectSlotsByName(self)

    def get_project_info(self):
        self.setup()
        flag = self.exec_()
        if (flag == QDialog.Accepted):
            #            返回一个元组,包含路径和项目名
            return (self.project_dir, self.project_name)
        else:
            return (None, None)

# =============================================================================
# Slots
# =============================================================================
#    让用户选择项目的路径

    def slot_open(self):

        sel_dir = QFileDialog.getExistingDirectory(self, 'Select Folder')
        if sel_dir:
            sel_dir = sel_dir.replace('/', '\\')
            self.project_dir = sel_dir
            if self.project_name:
                self.lineEdit_location.setText(self.project_dir + '\\' +
                                               self.project_name)
            else:
                self.lineEdit_location.setText(self.project_dir)

#    自定义一个接受的事件,需要判断用户是否已完成项目的创建

    def slot_accept(self):

        if (self.project_dir and self.project_name):
            self.accept()
        else:
            tipDialog = QMessageBox(self)
            tipDialog.resize(300, 100)
            tipDialog.setWindowTitle("Caution")
            tipDialog.setText("You have not created a project yet!")
            tipDialog.exec_()

    def slot_set_dir(self):

        #        这里还应该判断用户输入正确的项目名字符串
        self.project_name = self.lineEdit_project_name.text()
        if self.project_name:
            self.lineEdit_location.setText(self.project_dir + '\\' +
                                           self.project_name)
        else:
            self.lineEdit_location.setText(self.project_dir)

    def retranslateUi(self):
        _translate = QCoreApplication.translate
        self.setWindowTitle(_translate("NewProjectDialog", "创建新项目"))
        self.label_project_name.setText(_translate("NewProjectDialog", "项目名"))
        self.label_location.setText(_translate("NewProjectDialog", "路径"))
        self.toolbutton_open.setText(_translate("NewProjectDialog", "..."))


#    def retranslateUi(self):
#        _translate = QCoreApplication.translate
#        self.setWindowTitle(_translate("NewProjectDialog", "Create new project"))
#        self.label_project_name.setText(_translate("NewProjectDialog", "Project name"))
#        self.label_location.setText(_translate("NewProjectDialog", "Location"))
#        self.toolbutton_open.setText(_translate("NewProjectDialog", "..."))
Beispiel #28
0
class CalibrateDialog(QDialog):
	def __init__(self, parent=None):
		super(CalibrateDialog, self).__init__(parent)
		self.parent = parent


		self.verticalLayout = QVBoxLayout(self)
		self.verticalLayout.addWidget(self.createCallStepButtons())
		self.verticalLayout.addWidget(self.createCallSaveLoadButtons())
		self.verticalLayout.addStretch(1)
		self.verticalLayout.addWidget(self.createCloseButttonContainer())



		self.plot_paths = ['S21']


	def createCloseButttonContainer(self):

		self.buttonBox = QDialogButtonBox(self)
		self.buttonBox.setOrientation(Qt.Horizontal)
		self.buttonBox.setStandardButtons(QDialogButtonBox.Ok)

		# Cheat a bit here, and just call the close method directly.
		self.buttonBox.clicked.connect(self.close)

		return self.buttonBox


	def createCallSaveLoadButtons(self):
		steps = [
			("CAL_LOAD", QPushButton('Load')),
			("CAL_SAVE", QPushButton('Save')),
		]

		layout = QHBoxLayout()
		for key, wid in steps:
			layout.addWidget(wid)
			wid.setProperty("btn_name", key)
			wid.clicked.connect(self.callDataButtonClicked)


		calstep_container = QGroupBox("Save/Load Cal");
		calstep_container.setLayout(layout)

		return calstep_container

	def createCallStepButtons(self):
		steps = [
			("STEP_THRU",     QPushButton('Through')),
			("STEP_P1_OPEN",  QPushButton('Port 1 Open')),
			("STEP_P1_SHORT", QPushButton('Port 1 Short')),
			("STEP_P1_LOAD",  QPushButton('Port 1 Load')),
			("STEP_P2_OPEN",  QPushButton('Port 2 Open')),
			("STEP_P2_SHORT", QPushButton('Port 2 Short')),
			("STEP_P2_LOAD",  QPushButton('Port 2 Load')),
		]

		layout = QVBoxLayout()
		for key, wid in steps:
			layout.addWidget(wid)
			wid.setProperty("btn_name", key)
			wid.clicked.connect(self.callButtonClicked)


		calstep_container = QGroupBox("Calibration Steps");
		calstep_container.setLayout(layout)

		return calstep_container

	def callDataButtonClicked(self):
		stepname = self.sender().property('btn_name')
		self.parent.doCalDataManip(stepname)

	def callButtonClicked(self):
		stepname = self.sender().property('btn_name')
		self.parent.doCalStep(stepname)
Beispiel #29
0
class AboutVM(QDialog):
    def __init__(self, parent=None):
        """Class initializer."""
        super(AboutVM, self).__init__(parent)
        self.setWindowTitle(self.tr('About VideoMorph'))
        self.resize(374, 404)
        self.horizontalLayout_3 = QHBoxLayout(self)
        self.verticalLayout_4 = QVBoxLayout()
        self.horizontalLayout_2 = QHBoxLayout()
        self.label = QLabel(self)
        self.label.setMinimumSize(QSize(64, 64))
        self.label.setMaximumSize(QSize(64, 64))
        self.label.setText("")
        self.label.setPixmap(QPixmap(':/logo/images/videomorph.png'))
        self.label.setScaledContents(True)
        self.horizontalLayout_2.addWidget(self.label)
        self.label_2 = QLabel(
            "<p align=\"center\"><span style=\" font-size:20pt; font-weight:600;\">VideoMorph</span></p><p align=\"center\"><span style=\" font-size:9pt; font-weight:600;\">version {v}</span></p>".format(
                v=VERSION))
        self.label_2.setMinimumSize(QSize(0, 64))
        self.label_2.setMaximumSize(QSize(16777215, 64))
        self.horizontalLayout_2.addWidget(self.label_2)
        self.verticalLayout_4.addLayout(self.horizontalLayout_2)
        self.tabWidget = QTabWidget(self)
        self.tab = QWidget()
        self.verticalLayout_2 = QVBoxLayout(self.tab)
        self.textEdit_3 = QTextEdit(self.tab)
        self.textEdit_3.setReadOnly(True)
        self.verticalLayout_2.addWidget(self.textEdit_3)
        self.tabWidget.addTab(self.tab, "")
        self.tab_2 = QWidget()
        self.verticalLayout_3 = QVBoxLayout(self.tab_2)
        self.textEdit_2 = QTextEdit(self.tab_2)
        self.textEdit_2.setReadOnly(True)
        self.verticalLayout_3.addWidget(self.textEdit_2)
        self.tabWidget.addTab(self.tab_2, "")
        self.tab_3 = QWidget()
        self.verticalLayout = QVBoxLayout(self.tab_3)
        self.plainTextEdit = QPlainTextEdit(self.tab_3)
        self.plainTextEdit.setReadOnly(True)
        self.verticalLayout.addWidget(self.plainTextEdit)
        self.tabWidget.addTab(self.tab_3, "")
        self.verticalLayout_4.addWidget(self.tabWidget)
        self.horizontalLayout = QHBoxLayout()
        spacerItem = QSpacerItem(40,
                                 20,
                                 QSizePolicy.Expanding,
                                 QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem)
        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Ok)
        self.buttonBox.accepted.connect(self.accept)
        self.horizontalLayout.addWidget(self.buttonBox)
        self.verticalLayout_4.addLayout(self.horizontalLayout)
        self.horizontalLayout_3.addLayout(self.verticalLayout_4)

        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab),
                                  self.tr("Info"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2),
                                  self.tr("Credits"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3),
                                  self.tr("License"))

        self.textEdit_2.setHtml(self.tr(
            "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
            "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
            "p, li { white-space: pre-wrap; }\n"
            "</style></head><body style=\" font-family:\'Sans Serif\'; font-size:10pt; font-weight:400; font-style:normal;\">\n"
            "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:11pt; font-weight:600;\">Developers:</span></p>\n"
            "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Ozkar L. Garcell - project leader</p>\n"
            "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">&lt;[email protected]&gt;</p>\n"
            "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><br /></p>\n"
            "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Leodanis Pozo Ramos - main developer</p>\n"
            "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">&lt;[email protected]&gt;</p>\n"
            "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt; font-weight:600;\"><br /></p>\n"
            "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:11pt; font-weight:600;\">Translators:</span></p>\n"
            "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Ozkar L. Garcell - en_US, es_ES</p>\n"
            "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt; font-weight:600;\"><br /></p>\n"
            "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:11pt; font-weight:600;\">Contributors:</span></p>\n"
            "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Carlos Parra Zaldivar - Artwork.</p>\n"
            "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt; font-weight:600;\"><br /></p></body></html>"
        ))

        self.textEdit_3.setHtml(self.tr(
            "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
            "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
            "p, li { white-space: pre-wrap; }\n"
            "</style></head><body style=\" font-family:\'Sans Serif\'; font-size:10pt; font-weight:400; font-style:normal;\">\n"
            "<p align=\"center\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:12pt; font-weight:600;\">A simple and lightweight video transcoder.</span></p>\n"
            "<p align=\"center\" style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:12pt; font-weight:600;\"><br /></p>\n"
            "<p align=\"justify\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:11pt; font-weight:600;\">VideoMorph</span><span style=\" font-size:11pt;\"> is a small GUI front-end for </span><a href=\"http://ffmpeg.org/\"><span style=\" font-size:11pt; text-decoration: underline; color:#2980b9;\">ffmpeg</span></a><span style=\" font-size:11pt;\"> and avconv, based on code from </span><a href=\"https://github.com/senko/python-video-converter\"><span style=\" font-size:11pt; text-decoration: underline; color:#2980b9;\">python-video-converter</span></a><span style=\" font-size:11pt;\"> and presets idea from </span><a href=\"http://qwinff.github.io/\"><span style=\" font-size:11pt; text-decoration: underline; color:#2980b9;\">QWinFF</span></a><span style=\" font-size:11pt;\">.</span></p>\n"
            "<p align=\"justify\" style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;\"><br /></p>\n"
            "<p align=\"center\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><a href=\"https://github.com/codeshard/videomorph\"><span style=\" text-decoration: underline; color:#2980b9;\">https://github.com/codeshard/videomorph</span></a></p></body></html>"
        ))

        self.plainTextEdit.setPlainText(self.tr(
            "                                 Apache License\n"
            "                           Version 2.0, January 2004\n"
            "                        http://www.apache.org/licenses/\n"
            "\n"
            "   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n"
            "\n"
            "   1. Definitions.\n"
            "\n"
            "      \"License\" shall mean the terms and conditions for use, reproduction,\n"
            "      and distribution as defined by Sections 1 through 9 of this document.\n"
            "\n"
            "      \"Licensor\" shall mean the copyright owner or entity authorized by\n"
            "      the copyright owner that is granting the License.\n"
            "\n"
            "      \"Legal Entity\" shall mean the union of the acting entity and all\n"
            "      other entities that control, are controlled by, or are under common\n"
            "      control with that entity. For the purposes of this definition,\n"
            "      \"control\" means (i) the power, direct or indirect, to cause the\n"
            "      direction or management of such entity, whether by contract or\n"
            "      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n"
            "      outstanding shares, or (iii) beneficial ownership of such entity.\n"
            "\n"
            "      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n"
            "      exercising permissions granted by this License.\n"
            "\n"
            "      \"Source\" form shall mean the preferred form for making modifications,\n"
            "      including but not limited to software source code, documentation\n"
            "      source, and configuration files.\n"
            "\n"
            "      \"Object\" form shall mean any form resulting from mechanical\n"
            "      transformation or translation of a Source form, including but\n"
            "      not limited to compiled object code, generated documentation,\n"
            "      and conversions to other media types.\n"
            "\n"
            "      \"Work\" shall mean the work of authorship, whether in Source or\n"
            "      Object form, made available under the License, as indicated by a\n"
            "      copyright notice that is included in or attached to the work\n"
            "      (an example is provided in the Appendix below).\n"
            "\n"
            "      \"Derivative Works\" shall mean any work, whether in Source or Object\n"
            "      form, that is based on (or derived from) the Work and for which the\n"
            "      editorial revisions, annotations, elaborations, or other modifications\n"
            "      represent, as a whole, an original work of authorship. For the purposes\n"
            "      of this License, Derivative Works shall not include works that remain\n"
            "      separable from, or merely link (or bind by name) to the interfaces of,\n"
            "      the Work and Derivative Works thereof.\n"
            "\n"
            "      \"Contribution\" shall mean any work of authorship, including\n"
            "      the original version of the Work and any modifications or additions\n"
            "      to that Work or Derivative Works thereof, that is intentionally\n"
            "      submitted to Licensor for inclusion in the Work by the copyright owner\n"
            "      or by an individual or Legal Entity authorized to submit on behalf of\n"
            "      the copyright owner. For the purposes of this definition, \"submitted\"\n"
            "      means any form of electronic, verbal, or written communication sent\n"
            "      to the Licensor or its representatives, including but not limited to\n"
            "      communication on electronic mailing lists, source code control systems,\n"
            "      and issue tracking systems that are managed by, or on behalf of, the\n"
            "      Licensor for the purpose of discussing and improving the Work, but\n"
            "      excluding communication that is conspicuously marked or otherwise\n"
            "      designated in writing by the copyright owner as \"Not a Contribution.\"\n"
            "\n"
            "      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n"
            "      on behalf of whom a Contribution has been received by Licensor and\n"
            "      subsequently incorporated within the Work.\n"
            "\n"
            "   2. Grant of Copyright License. Subject to the terms and conditions of\n"
            "      this License, each Contributor hereby grants to You a perpetual,\n"
            "      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n"
            "      copyright license to reproduce, prepare Derivative Works of,\n"
            "      publicly display, publicly perform, sublicense, and distribute the\n"
            "      Work and such Derivative Works in Source or Object form.\n"
            "\n"
            "   3. Grant of Patent License. Subject to the terms and conditions of\n"
            "      this License, each Contributor hereby grants to You a perpetual,\n"
            "      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n"
            "      (except as stated in this section) patent license to make, have made,\n"
            "      use, offer to sell, sell, import, and otherwise transfer the Work,\n"
            "      where such license applies only to those patent claims licensable\n"
            "      by such Contributor that are necessarily infringed by their\n"
            "      Contribution(s) alone or by combination of their Contribution(s)\n"
            "      with the Work to which such Contribution(s) was submitted. If You\n"
            "      institute patent litigation against any entity (including a\n"
            "      cross-claim or counterclaim in a lawsuit) alleging that the Work\n"
            "      or a Contribution incorporated within the Work constitutes direct\n"
            "      or contributory patent infringement, then any patent licenses\n"
            "      granted to You under this License for that Work shall terminate\n"
            "      as of the date such litigation is filed.\n"
            "\n"
            "   4. Redistribution. You may reproduce and distribute copies of the\n"
            "      Work or Derivative Works thereof in any medium, with or without\n"
            "      modifications, and in Source or Object form, provided that You\n"
            "      meet the following conditions:\n"
            "\n"
            "      (a) You must give any other recipients of the Work or\n"
            "          Derivative Works a copy of this License; and\n"
            "\n"
            "      (b) You must cause any modified files to carry prominent notices\n"
            "          stating that You changed the files; and\n"
            "\n"
            "      (c) You must retain, in the Source form of any Derivative Works\n"
            "          that You distribute, all copyright, patent, trademark, and\n"
            "          attribution notices from the Source form of the Work,\n"
            "          excluding those notices that do not pertain to any part of\n"
            "          the Derivative Works; and\n"
            "\n"
            "      (d) If the Work includes a \"NOTICE\" text file as part of its\n"
            "          distribution, then any Derivative Works that You distribute must\n"
            "          include a readable copy of the attribution notices contained\n"
            "          within such NOTICE file, excluding those notices that do not\n"
            "          pertain to any part of the Derivative Works, in at least one\n"
            "          of the following places: within a NOTICE text file distributed\n"
            "          as part of the Derivative Works; within the Source form or\n"
            "          documentation, if provided along with the Derivative Works; or,\n"
            "          within a display generated by the Derivative Works, if and\n"
            "          wherever such third-party notices normally appear. The contents\n"
            "          of the NOTICE file are for informational purposes only and\n"
            "          do not modify the License. You may add_file Your own attribution\n"
            "          notices within Derivative Works that You distribute, alongside\n"
            "          or as an addendum to the NOTICE text from the Work, provided\n"
            "          that such additional attribution notices cannot be construed\n"
            "          as modifying the License.\n"
            "\n"
            "      You may add_file Your own copyright statement to Your modifications and\n"
            "      may provide additional or different license terms and conditions\n"
            "      for use, reproduction, or distribution of Your modifications, or\n"
            "      for any such Derivative Works as a whole, provided Your use,\n"
            "      reproduction, and distribution of the Work otherwise complies with\n"
            "      the conditions stated in this License.\n"
            "\n"
            "   5. Submission of Contributions. Unless You explicitly state otherwise,\n"
            "      any Contribution intentionally submitted for inclusion in the Work\n"
            "      by You to the Licensor shall be under the terms and conditions of\n"
            "      this License, without any additional terms or conditions.\n"
            "      Notwithstanding the above, nothing herein shall supersede or modify\n"
            "      the terms of any separate license agreement you may have executed\n"
            "      with Licensor regarding such Contributions.\n"
            "\n"
            "   6. Trademarks. This License does not grant permission to use the trade\n"
            "      names, trademarks, service marks, or product names of the Licensor,\n"
            "      except as required for reasonable and customary use in describing the\n"
            "      origin of the Work and reproducing the content of the NOTICE file.\n"
            "\n"
            "   7. Disclaimer of Warranty. Unless required by applicable law or\n"
            "      agreed to in writing, Licensor provides the Work (and each\n"
            "      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n"
            "      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n"
            "      implied, including, without limitation, any warranties or conditions\n"
            "      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n"
            "      PARTICULAR PURPOSE. You are solely responsible for determining the\n"
            "      appropriateness of using or redistributing the Work and assume any\n"
            "      risks associated with Your exercise of permissions under this License.\n"
            "\n"
            "   8. Limitation of Liability. In no event and under no legal theory,\n"
            "      whether in tort (including negligence), contract, or otherwise,\n"
            "      unless required by applicable law (such as deliberate and grossly\n"
            "      negligent acts) or agreed to in writing, shall any Contributor be\n"
            "      liable to You for damages, including any direct, indirect, special,\n"
            "      incidental, or consequential damages of any character arising as a\n"
            "      result of this License or out of the use or inability to use the\n"
            "      Work (including but not limited to damages for loss of goodwill,\n"
            "      work stoppage, computer failure or malfunction, or any and all\n"
            "      other commercial damages or losses), even if such Contributor\n"
            "      has been advised of the possibility of such damages.\n"
            "\n"
            "   9. Accepting Warranty or Additional Liability. While redistributing\n"
            "      the Work or Derivative Works thereof, You may choose to offer,\n"
            "      and charge a fee for, acceptance of support, warranty, indemnity,\n"
            "      or other liability obligations and/or rights consistent with this\n"
            "      License. However, in accepting such obligations, You may act only\n"
            "      on Your own behalf and on Your sole responsibility, not on behalf\n"
            "      of any other Contributor, and only if You agree to indemnify,\n"
            "      defend, and hold each Contributor harmless for any liability\n"
            "      incurred by, or claims asserted against, such Contributor by reason\n"
            "      of your accepting any such warranty or additional liability.\n"
            "\n"
            "   END OF TERMS AND CONDITIONS"
        ))
class CustomDateRangePanel(Panel):
    FIELDS = [
        ('startDateEdit', 'start_date'),
        ('endDateEdit', 'end_date'),
        ('slotIndexComboBox', 'slot_index'),
        ('slotNameEdit', 'slot_name'),
    ]
    PERSISTENT_NAME = 'customDateRangePanel'

    def __init__(self, model, mainwindow):
        Panel.__init__(self, mainwindow)
        self.setAttribute(Qt.WA_DeleteOnClose)
        self._setupUi()
        self.model = model

        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)

    def _setupUi(self):
        self.setWindowTitle(tr("Custom Date Range"))
        self.resize(292, 86)
        self.setModal(True)
        self.verticalLayout = QVBoxLayout(self)
        self.label = QLabel(tr("Select start and end dates from your custom range:"))
        self.verticalLayout.addWidget(self.label)
        self.horizontalLayout = QHBoxLayout()
        self.label_2 = QLabel(tr("Start:"))
        self.horizontalLayout.addWidget(self.label_2)
        self.startDateEdit = DateEdit(self)
        self.horizontalLayout.addWidget(self.startDateEdit)
        self.label_3 = QLabel(tr("End:"))
        self.horizontalLayout.addWidget(self.label_3)
        self.endDateEdit = DateEdit(self)
        self.horizontalLayout.addWidget(self.endDateEdit)
        self.verticalLayout.addLayout(self.horizontalLayout)
        self.horizontalLayout_2 = QHBoxLayout()
        self.label_4 = QLabel(tr("Save this range under slot:"))
        self.horizontalLayout_2.addWidget(self.label_4)
        self.slotIndexComboBox = QComboBox(self)
        sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.slotIndexComboBox.sizePolicy().hasHeightForWidth())
        self.slotIndexComboBox.setSizePolicy(sizePolicy)
        for s in [tr("None"), tr("#1"), tr("#2"), tr("#3")]:
            self.slotIndexComboBox.addItem(s)
        self.horizontalLayout_2.addWidget(self.slotIndexComboBox)
        spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.horizontalLayout_2.addItem(spacerItem)
        self.verticalLayout.addLayout(self.horizontalLayout_2)
        self.horizontalLayout_3 = QHBoxLayout()
        self.label_5 = QLabel(tr("Under the name:"))
        self.horizontalLayout_3.addWidget(self.label_5)
        self.slotNameEdit = QLineEdit(self)
        sizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.slotNameEdit.sizePolicy().hasHeightForWidth())
        self.slotNameEdit.setSizePolicy(sizePolicy)
        self.horizontalLayout_3.addWidget(self.slotNameEdit)
        self.verticalLayout.addLayout(self.horizontalLayout_3)
        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Ok)
        self.verticalLayout.addWidget(self.buttonBox)
Beispiel #31
0
class FiltersDialog(QDialog):
    def __init__(
        self, application: "Application", engine: Engine, parent: QObject = None
    ) -> None:
        super().__init__(parent)
        self.setAttribute(Qt.WA_DeleteOnClose)

        # The window doesn't raise on Windows when the app is not in focus,
        # so after the login in the browser, we open the filters window with
        # the "stay on top" hint to make sure it comes back to the front
        # instead of just having a blinking icon in the taskbar.
        self.setWindowFlags(Qt.WindowStaysOnTopHint)
        self.setWindowTitle(Translator.get("FILTERS_WINDOW_TITLE"))

        self.vertical_layout = QVBoxLayout(self)
        self.vertical_layout.setContentsMargins(0, 0, 0, 0)

        self._engine = engine
        self.syncing = self._engine.is_syncing()  # NXDRIVE-959
        self.application = application
        self.setWindowIcon(self.application.icon)

        self.no_root_label = self.get_no_roots_label()
        self.tree_view = self.get_tree_view()
        self.vertical_layout.addWidget(self.tree_view)
        self.vertical_layout.addWidget(self.no_root_label)

        # Select/Unselect roots
        self.select_all_state = True
        self.select_all_text = (
            Translator.get("UNSELECT_ALL"),
            Translator.get("SELECT_ALL"),
        )

        self.button_box = QDialogButtonBox(self)
        self.button_box.setOrientation(Qt.Horizontal)
        buttons = QDialogButtonBox.Ok
        if not self.syncing:
            buttons |= QDialogButtonBox.Cancel
            self.select_all_button = self.button_box.addButton(
                self.select_all_text[self.select_all_state], QDialogButtonBox.ActionRole
            )
            self.select_all_button.clicked.connect(self._select_unselect_all_roots)

        self.button_box.setStandardButtons(buttons)
        self.vertical_layout.addWidget(self.button_box)
        self.button_box.accepted.connect(self.accept)
        self.button_box.rejected.connect(self.reject)

    def get_tree_view(self) -> Union[QLabel, FolderTreeview]:
        if self.syncing:
            # Prevent filter modifications while syncing
            label = QLabel(Translator.get("FILTERS_DISABLED"))
            label.setMargin(15)
            label.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
            return label

        self.resize(491, 443)
        filters = self._engine.get_dao().get_filters()
        remote = self._engine.remote
        client = FsClient(remote, filters)
        tree_view = FolderTreeview(self, client)
        tree_view.noRoots.connect(self._handle_no_roots)
        return tree_view

    def get_no_roots_label(self) -> QLabel:
        label = QLabel(parent=self)
        text = Translator.get(
            "NO_ROOTS",
            [
                self._engine.server_url,
                "https://doc.nuxeo.com/nxdoc/nuxeo-drive/#synchronizing-a-folder",
            ],
        )
        label.setText(text)
        label.setMargin(15)
        label.resize(400, 200)
        label.setWordWrap(True)
        label.setVisible(False)
        label.setOpenExternalLinks(True)
        label.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
        return label

    def _handle_no_roots(self) -> None:
        self.no_root_label.setVisible(True)
        self.select_all_button.setVisible(False)
        self.tree_view.setVisible(False)
        self.tree_view.resize(0, 0)
        self.setGeometry(self.x() + 50, self.y() + 150, 400, 200)

    def accept(self) -> None:
        """ When you click on the OK button. """

        if not self.syncing:
            # Prevent filter modifications while syncing
            self.apply_filters()

        super().accept()

    def apply_filters(self) -> None:
        items = sorted(self.tree_view.dirty_items, key=lambda x: x.get_path())
        for item in items:
            path = item.get_path()
            if item.state == Qt.Unchecked:
                self._engine.add_filter(path)
            elif item.state == Qt.Checked:
                self._engine.remove_filter(path)
            elif item.old_state == Qt.Unchecked:
                # Now partially checked and was before a filter

                # Remove current parent filter and need to commit to enable the
                # add
                self._engine.remove_filter(path)

                # We need to browse every child and create a filter for
                # unchecked as they are not dirty but has become root filter
                for child in item.get_children():
                    if child.state == Qt.Unchecked:
                        self._engine.add_filter(child.get_path())

        if not self._engine.is_started():
            self._engine.start()

    def _select_unselect_all_roots(self, _: Qt.CheckState) -> None:
        """Select/Unselect all roots."""
        state = Qt.Checked if self.select_all_state else Qt.Unchecked

        roots = sorted(self.tree_view.client.roots, key=lambda x: x.get_path())
        for num, root in enumerate(roots):
            index = self.tree_view.model().index(num, 0)
            item = self.tree_view.model().itemFromIndex(index)
            if item.checkState() != state:
                item.setCheckState(state)
                self.tree_view.update_item_changed(item)

        self.select_all_state = not self.select_all_state
        self.select_all_button.setText(self.select_all_text[self.select_all_state])
Beispiel #32
0
class SinogramDialog(QDialog):
    def __init__(self, image, alpha, detectors, width, parent=None):
        super(SinogramDialog, self).__init__(parent)
        self.image = image
        self.alpha = float(alpha)
        self.detectors = int(detectors)
        self.width = int(width)
        self.scene = QGraphicsScene()
        self.sscene = QGraphicsScene()
        self.sinogram = np.zeros((1, self.detectors))
        self.setWindowTitle("Sinogram")
        self.slider = QtWidgets.QSlider(Qt.Horizontal)
        self.slider.setFixedWidth(360)
        self.slider.setRange(0, 100)
        self.slider.valueChanged.connect(self.valuechange)
        self.slabel = QLabel("")
        self.testButton = QPushButton("Click")
        self.testButton.clicked.connect(lambda: self.computeSinogram(self.slider.value()))
        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok)
        # self.buttonBox.accepted.connect() <- what will happen on Ok
        self.buttonBox.rejected.connect(self.close) # <- what will happen on Cancel
        self.gv = QGraphicsView(self.scene, self)
        self.gv.setGeometry(QRect(0, 0, 300, 300))
        self.gvresult = QGraphicsView(self.sscene, self)
        self.gvresult.setGeometry(QRect(0, 0, 300, 300))
        self.verticalLayout = QtWidgets.QVBoxLayout(self)
        self.horizontalLayout = QtWidgets.QHBoxLayout(self)
        self.verticalform = QtWidgets.QVBoxLayout(self)
        self.patient_sex = QTextEdit()
        self.patient_sex.setFixedWidth(200)
        self.patient_sex.setFixedHeight(25)
        self.patient_sex_label = QLabel("Type patient's sex (M F)")
        self.patient_sex_label.setFixedHeight(25)
        self.patient_name = QTextEdit()
        self.patient_name.setFixedWidth(200)
        self.patient_name.setFixedHeight(25)
        self.patient_name_label = QLabel("Type patient's name (Name^Surname)")
        self.patient_name_label.setFixedHeight(25)
        self.patients_ID = QTextEdit()
        self.patients_ID.setFixedWidth(200)
        self.patients_ID.setFixedHeight(25)
        self.patients_ID_label = QLabel("Type patient's ID")
        self.patients_ID_label.setFixedHeight(25)
        self.comment = QTextEdit()
        self.comment.setFixedWidth(200)
        self.comment.setFixedHeight(25)
        self.comment_label = QLabel("Type your comment")
        self.comment_label.setFixedHeight(25)
        self.date = QTextEdit()
        self.date.setFixedWidth(200)
        self.date.setFixedHeight(25)
        self.date_label = QLabel("Type date of photo (YYYYMMDD)")
        self.date_label.setFixedHeight(25)
        self.time = QTextEdit()
        self.time.setFixedWidth(200)
        self.time.setFixedHeight(25)
        self.time_label = QLabel("Type time of photo (HHMMSS.MMMMM")
        self.time_label.setFixedHeight(25)
        self.dicom_button = QPushButton("Save result to DICOM")
        self.dicom_button.setFixedHeight(25)
        self.dicom_button.clicked.connect(self.save_to_dicom)
        self.verticalform.addWidget(self.patient_name_label)
        self.verticalform.addWidget(self.patient_name)
        self.verticalform.addWidget(self.patients_ID_label)
        self.verticalform.addWidget(self.patients_ID)
        self.verticalform.addWidget(self.patient_sex_label)
        self.verticalform.addWidget(self.patient_sex)
        self.verticalform.addWidget(self.comment_label)
        self.verticalform.addWidget(self.comment)
        self.verticalform.addWidget(self.date_label)
        self.verticalform.addWidget(self.date)
        self.verticalform.addWidget(self.time_label)
        self.verticalform.addWidget(self.time)
        self.verticalform.addWidget(self.dicom_button)
        self.verticalform.addStretch(1)
        self.horizontalLayout.addLayout(self.verticalform)
        self.horizontalLayout.addWidget(self.gv)
        self.horizontalLayout.addWidget(self.gvresult)
        self.verticalLayout.addWidget(self.slider)
        self.verticalLayout.addWidget(self.slabel)
        self.verticalLayout.addWidget(self.testButton)
        self.verticalLayout.addLayout(self.horizontalLayout)
        self.verticalLayout.addWidget(self.buttonBox)
        self.sinogramLogic = SinogramLogic(self.image, self.alpha, self.detectors, self.width)

    def save_to_dicom(self):
        save_to_dicom_file(self.invsg, "dicom_output.dcm", self.patient_name.toPlainText(), self.patients_ID.toPlainText(), self.patient_sex.toPlainText(),
                           self.comment.toPlainText(), self.date.toPlainText(), self.time.toPlainText())
        self.info = QMessageBox.information(self, "File saved", "File saved to .dcm", QMessageBox.Ok)


    def valuechange(self):
        self.slabel.setText(str(self.slider.value())+"%")
        # sg = self.sinograms[self.slider.value()]
        # invsg = self.invsinograms[self.slider.value()]
        # self.img = QImage(sg.astype(np.uint8), sg.shape[1], sg.shape[0], sg.shape[1], QImage.Format_Grayscale8)
        # self.pict = QPixmap(self.img)
        # print(type(self.pict))
        # self.scene.clear()
        # self.scene.addPixmap(self.pict)
        # self.gv.fitInView(QGraphicsPixmapItem(self.pict).boundingRect(), Qt.KeepAspectRatio)
        # self.gv.setScene(self.scene)
        # self.img2 = QImage(invsg.astype(np.uint8), invsg.shape[1], invsg.shape[0], invsg.shape[1], QImage.Format_Grayscale8)
        # self.pict2 = QPixmap(self.img2)
        # self.sscene.clear()
        # self.sscene.addPixmap(self.pict2)
        # self.gvresult.fitInView(QGraphicsPixmapItem(self.pict2).boundingRect(), Qt.KeepAspectRatio)
        # self.gvresult.setScene(self.sscene)

    def plotEmitersAndDecoders(self, x, y, iks, igrek, detectors_x_list, detectors_y_list):
        plt.scatter(iks, igrek, color="red")
        plt.scatter(detectors_x_list, detectors_y_list, color="blue")
        circle = plt.Circle([x / 2, y / 2], radius=x / 2, fill=False, color='green')
        for (x2, y2) in zip(detectors_x_list, detectors_y_list):
            plt.plot([iks, x2], [igrek, y2], color='gray', linestyle='dashed', linewidth=2)
        ax = plt.gca()
        ax.set_xlim(-1, x + 1)
        ax.set_ylim(-1, y + 1)
        ax.imshow(self.image, cmap='gray')
        ax.add_artist(circle)
        # plt.show()
        plt.savefig('wiz.png')

    def computeSinogram(self, progress):
        progress = progress*1.0/100
        sinogram = SinogramLogic(self.image, self.alpha, self.detectors, self.width)
        print("ok")
        sg, invsg = sinogram.image_processing(self.image, self.alpha, progress, self.detectors, self.width)
        print(sg.shape, type(sg), invsg.shape, type(invsg))
        sg = sg*1.0/np.max(sg)*255  # normalize
        self.invsg = invsg*1.0/np.max(invsg)*255  # normalize
        plt.imshow(sg, cmap="gray")
        plt.savefig('foo.png')
        self.img = QImage(sg.astype(np.uint8), sg.shape[1], sg.shape[0], sg.shape[1], QImage.Format_Grayscale8)
        self.pict = QPixmap(self.img)
        print(type(self.pict))
        self.scene.clear()
        self.scene.addPixmap(self.pict)
        self.gv.fitInView(QGraphicsPixmapItem(self.pict).boundingRect(), Qt.KeepAspectRatio)
        self.gv.setScene(self.scene)
        self.img2 = QImage(self.invsg.astype(np.uint8), self.invsg.shape[1], self.invsg.shape[0], self.invsg.shape[1], QImage.Format_Grayscale8)
        self.pict2 = QPixmap(self.img2)
        self.sscene.clear()
        self.sscene.addPixmap(self.pict2)
        self.gvresult.fitInView(QGraphicsPixmapItem(self.pict2).boundingRect(), Qt.KeepAspectRatio)
        self.gvresult.setScene(self.sscene)
        plt.imshow(sg, cmap="gray")
        plt.savefig('result.png')
Beispiel #33
0
class AccountPanel(Panel):
    FIELDS = [
        ('nameEdit', 'name'),
        ('accountNumberEdit', 'account_number'),
        ('inactiveBox', 'inactive'),
        ('notesEdit', 'notes'),
    ]
    PERSISTENT_NAME = 'accountPanel'

    def __init__(self, model, mainwindow):
        Panel.__init__(self, mainwindow)
        self.setAttribute(Qt.WA_DeleteOnClose)
        self._setupUi()
        self.model = model
        self.typeComboBox = ComboboxModel(model=self.model.type_list, view=self.typeComboBoxView)
        self.currencyComboBox = ComboboxModel(model=self.model.currency_list, view=self.currencyComboBoxView)

        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)

    def _setupUi(self):
        self.setWindowTitle(tr("Account Info"))
        self.resize(274, 121)
        self.setModal(True)
        self.verticalLayout = QVBoxLayout(self)
        self.formLayout = QFormLayout()
        self.formLayout.setFieldGrowthPolicy(QFormLayout.ExpandingFieldsGrow)
        self.label = QLabel(tr("Name"))
        self.formLayout.setWidget(0, QFormLayout.LabelRole, self.label)
        self.nameEdit = QLineEdit()
        self.formLayout.setWidget(0, QFormLayout.FieldRole, self.nameEdit)
        self.label_2 = QLabel(tr("Type"))
        self.formLayout.setWidget(1, QFormLayout.LabelRole, self.label_2)
        self.typeComboBoxView = QComboBox()
        self.formLayout.setWidget(1, QFormLayout.FieldRole, self.typeComboBoxView)
        self.label_3 = QLabel(tr("Currency"))
        self.formLayout.setWidget(2, QFormLayout.LabelRole, self.label_3)
        self.currencyComboBoxView = QComboBox()
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.currencyComboBoxView.sizePolicy().hasHeightForWidth())
        self.currencyComboBoxView.setSizePolicy(sizePolicy)
        self.currencyComboBoxView.setEditable(True)
        self.currencyComboBoxView.setInsertPolicy(QComboBox.NoInsert)
        self.formLayout.setWidget(2, QFormLayout.FieldRole, self.currencyComboBoxView)
        self.accountNumberLabel = QLabel(tr("Account #"))
        self.formLayout.setWidget(3, QFormLayout.LabelRole, self.accountNumberLabel)
        self.accountNumberEdit = QLineEdit()
        self.accountNumberEdit.setMaximumSize(QSize(80, 16777215))
        self.formLayout.setWidget(3, QFormLayout.FieldRole, self.accountNumberEdit)
        self.inactiveBox = QCheckBox()
        self.formLayout.addRow(tr("Inactive:"), self.inactiveBox)
        self.notesEdit = QPlainTextEdit()
        self.formLayout.addRow(tr("Notes:"), self.notesEdit)
        self.verticalLayout.addLayout(self.formLayout)
        self.buttonBox = QDialogButtonBox()
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Save)
        self.verticalLayout.addWidget(self.buttonBox)
        self.label.setBuddy(self.nameEdit)
        self.label_2.setBuddy(self.typeComboBoxView)
        self.label_3.setBuddy(self.currencyComboBoxView)

    def _loadFields(self):
        Panel._loadFields(self)
        self.currencyComboBoxView.setEnabled(self.model.can_change_currency)
class Bookmarks_Dialog(object):
    def setupUi(self, Dialog, bookmark_data, favourites):
        Dialog.resize(740, 450)
        Dialog.setWindowTitle('Bookmarks Manager')
        self.layout = QGridLayout(Dialog)
        self.urlLabel = QLabel('URL :', Dialog)
        self.layout.addWidget(self.urlLabel, 0, 0, 1, 1)
        self.urlBox = UrlBox(Dialog)
        self.layout.addWidget(self.urlBox, 0, 1, 1, 5)
        # Create Tab Widget
        self.tabWidget = QTabWidget(Dialog)
        self.tabWidget.setDocumentMode(True)
        self.tabWidget.tabBar().setExpanding(True)
        # Add Bookmarks Table
        self.bookmarks_table = BookmarksTable(Dialog, bookmark_data, True)
        self.tabWidget.addTab(self.bookmarks_table, 'Bookmarks')
        # Add Favourites table

        self.layout.addWidget(self.tabWidget, 1, 0, 1, 6)

        # Add Buttons
        self.moveUpBtn = QPushButton(QIcon(":/go-up.png"), '', Dialog)
        self.moveUpBtn.clicked.connect(self.moveItemUp)
        self.layout.addWidget(self.moveUpBtn, 2, 0, 1, 1)
        self.moveDownBtn = QPushButton(QIcon(":/go-down.png"), '', Dialog)
        self.moveDownBtn.clicked.connect(self.moveItemDown)
        self.layout.addWidget(self.moveDownBtn, 2, 1, 1, 1)
        self.copyLinkBtn = QPushButton(QIcon(":/edit-copy.png"), '', Dialog)
        self.copyLinkBtn.clicked.connect(self.copyItemLink)
        self.layout.addWidget(self.copyLinkBtn, 2, 2, 1, 1)
        self.editBtn = QPushButton(QIcon(":/edit.png"), '', Dialog)
        self.editBtn.clicked.connect(self.editItem)
        self.layout.addWidget(self.editBtn, 2, 3, 1, 1)
        self.deleteBtn = QPushButton(QIcon(":/edit-delete.png"), '', Dialog)
        self.deleteBtn.clicked.connect(self.deleteItem)
        self.layout.addWidget(self.deleteBtn, 2, 4, 1, 1)
        # Add ButtonBox
        self.buttonBox = QDialogButtonBox(Dialog)
        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Close)
        self.layout.addWidget(self.buttonBox, 2, 5, 1, 1)

        self.bookmarks_table.urlSelected.connect(self.urlBox.setText)
        self.bookmarks_table.doubleclicked.connect(Dialog.accept)
        self.bookmarks_table.itemSelectionChanged.connect(
            self.toggleButtonAccess)

        self.tabWidget.currentChanged.connect(self.toggleButtonAccess)
        self.buttonBox.accepted.connect(Dialog.accept)
        self.buttonBox.rejected.connect(Dialog.reject)
        self.bookmarks_table.selectRow(0)
        self.bookmarks_table.setFocus()

    def toggleButtonAccess(self):
        selection_count = len(self.tabWidget.currentWidget().selectedIndexes())
        if selection_count == 1:
            self.setButtonEnabled(True, True, True, True, True)
        elif selection_count > 1:
            self.setButtonEnabled(False, False, False, False, True)
        else:
            self.setButtonEnabled(False, False, False, False, False)

    def setButtonEnabled(self, state1, state2, state3, state4, state5):
        self.moveUpBtn.setEnabled(state1)
        self.moveDownBtn.setEnabled(state2)
        self.copyLinkBtn.setEnabled(state3)
        self.editBtn.setEnabled(state4)
        self.deleteBtn.setEnabled(state5)

    def moveItemUp(self):
        self.tabWidget.currentWidget().moveItemUp()
        self.tabWidget.currentWidget().setFocus()

    def moveItemDown(self):
        self.tabWidget.currentWidget().moveItemDown()
        self.tabWidget.currentWidget().setFocus()

    def copyItemLink(self):
        self.tabWidget.currentWidget().copyItemLink()
        self.tabWidget.currentWidget().setFocus()

    def editItem(self):
        self.tabWidget.currentWidget().editItem()
        self.tabWidget.currentWidget().setFocus()

    def deleteItem(self):
        self.tabWidget.currentWidget().deleteItem()
Beispiel #35
0
class VentanaCajero(QDialog):

    def __init__(self, parent=None, username=""):
        super(VentanaCajero, self).__init__(parent)

        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
        self.buttonBox.setStandardButtons(
            QDialogButtonBox.Cancel | QDialogButtonBox.Ok)

        self.clienteLabel = QLabel("Nombre cliente", self)
        self.clienteText = QLineEdit(self)
        self.idLabel = QLabel("RUT", self)
        self.idText = QLineEdit(self)
        self.gastadoLabel = QLabel("Gastado", self)
        self.gastadoText = QLineEdit(self)

        self.verticalLayout = QVBoxLayout(self)
        self.verticalLayout.addWidget(self.clienteLabel)
        self.verticalLayout.addWidget(self.clienteText)
        self.verticalLayout.addWidget(self.idLabel)
        self.verticalLayout.addWidget(self.idText)
        self.verticalLayout.addWidget(self.gastadoLabel)
        self.verticalLayout.addWidget(self.gastadoText)
        self.verticalLayout.addWidget(self.buttonBox)

        self.buttonBox.accepted.connect(self.serializarCliente)
        self.buttonBox.rejected.connect(self.close)

    def serializarCliente(self):
        #####

        ID_cliente = self.idText.text()
        Archivo_cliente = str(ID_cliente) + ".walkcart"

        # Verificamos si cliente existe en DB
        if Archivo_cliente in os.listdir("ClientesDB"):

            # Existe -> Abrimos, cambiamos y cerramos

            with open("ClientesDB/" + Archivo_cliente, "rb") as file:
                cliente_existente = pickle.load(file)

            cliente_existente.actualizarGasto(int(self.gastadoText.text()))

            with open("ClientesDB/" + Archivo_cliente, "wb") as file:
                pickle.dump(cliente_existente, file)

        else:
            # No existe -> Creamos y cerramos
            nuevo_cliente = Cliente(
                self.clienteText.text(),
                int(self.idText.text()),
                int(self.gastadoText.text())
            )

            nuevo_archivo = "ClientesDB/" + str(nuevo_cliente.ID) + ".walkcart"

            with open(nuevo_archivo, "wb") as file:
                pickle.dump(nuevo_cliente)
        #####

        self.clienteText.setText("")
        self.idText.setText("")
        self.gastadoText.setText("")
Beispiel #36
0
class MeteoSettings(QDialog):
    applied_signal = pyqtSignal()

    def __init__(self, accurate_url, appid, parent=None):
        super(MeteoSettings, self).__init__(parent)
        self.settings = QSettings()
        trans_cities_dict = self.settings.value('CitiesTranslation') or '{}'
        self.trans_cities_dict = eval(trans_cities_dict)
        self.layout = QVBoxLayout()
        self.accurate_url = accurate_url
        self.appid = appid
        self.set_city = self.settings.value('City') or '?'
        locale = QLocale.system().name()
        locale_long = ['pt_BR', 'zh_CN', 'zh_TW']
        if locale not in locale_long:
            locale = locale[:2]
        self.interval_set = self.settings.value('Interval') or '30'
        self.temp_tray_color = self.settings.value('TrayColor') or ''
        # -----Cities comboBox------------------------
        self.first = True
        self.clear_combo = False
        self.city_list_before = []
        self.citylist = []
        self.city_combo = QComboBox()
        if self.set_city != '?':
            self.add_cities_incombo()
        self.city_combo.currentIndexChanged.connect(self.city_default)
        self.city_title = QLabel(self.tr('City'))
        self.city_button = QPushButton()
        self.city_button.setIcon(QIcon(':/configure'))
        self.city_button.setToolTip(self.tr('Click to edit the cities list'))
        self.city_button.clicked.connect(self.edit_cities_list)
        # ------Language------------------------------
        self.language_label = QLabel(self.tr('Language'))
        self.language_combo = QComboBox()
        self.language_combo.setToolTip(
            QCoreApplication.translate('Tooltip',
                'The application has to be restared to apply the language setting',
                'Settings dialogue'))
        self.language_dico = {'bg': self.tr('Bulgarian'),
                              'ca': self.tr('Catalan'),
                              'cs': self.tr('Czech'),
                              'da': self.tr('Danish'),
                              'de': self.tr('German'),
                              'el': self.tr('Greek'),
                              'en': self.tr('English'),
                              'es': self.tr('Spanish'),
                              'fi': self.tr('Finnish'),
                              'fr': self.tr('French'),
                              'he': self.tr('Hebrew'),
                              'hr': self.tr('Croatian'),
                              'hu': self.tr('Hungarian'),
                              'it': self.tr('Italian'),
                              'ja': self.tr('Japanese'),
                              'lt': self.tr('Lithuanian'),
                              'nb': self.tr('Norwegian (Bokmaal)'),
                              'nl': self.tr('Dutch'),
                              'pl': self.tr('Polish'),
                              'pt': self.tr('Portuguese'),
                              'pt_BR': self.tr('Brazil Portuguese'),
                              'ro': self.tr('Romanian'),
                              'ru': self.tr('Russian'),
                              'sk': self.tr('Slovak'),
                              'sv': self.tr('Swedish'),
                              'tr': self.tr('Turkish'),
                              'uk': self.tr('Ukrainian'),
                              'zh_TW': self.tr('Chinese Traditional'),
                              'zh_CN': self.tr('Chinese Simplified')}
        lang_list = sorted(self.language_dico.values())
        # English as fallback language
        if locale not in self.language_dico:
            locale = 'en'
        self.setLanguage = self.settings.value('Language') or locale
        self.language_combo.addItems(lang_list)
        self.language_combo.setCurrentIndex(self.language_combo.findText
                                            (self.language_dico[self.setLanguage]))
        self.language_combo.currentIndexChanged.connect(self.language)
        self.lang_changed = False
        # Unit system
        self.units_changed = False
        self.temp_unit = self.settings.value('Unit')
        if self.temp_unit is None or self.temp_unit == '':
            self.temp_unit = 'metric'
            self.units_changed = True
        self.units_label = QLabel(self.tr('Temperature unit'))
        self.units_combo = QComboBox()
        self.units_dico = {'metric': '°C', 'imperial': '°F', ' ': '°K'}
        units_list = sorted(self.units_dico.values())
        self.units_combo.addItems(units_list)
        self.units_combo.setCurrentIndex(self.units_combo.findText(
            self.units_dico[self.temp_unit]))
        self.units_combo.currentIndexChanged.connect(self.units)
        # Beaufort
        self.bft_checkbox = QCheckBox(QCoreApplication.translate('Wind unit - Checkbox label',
                                        'Wind unit in Beaufort', 'Settings dialogue'))
        bft_bool = self.settings.value('Beaufort') or 'False'
        self.bft_bool = eval(bft_bool)
        self.bft_checkbox.setChecked(self.bft_bool)
        self.bft_checkbox.stateChanged.connect(self.beaufort)
        self.bft_changed = False
        # Decimal in trayicon
        self.temp_decimal_label = QLabel(QCoreApplication.translate(
                    'If the temperature will be shown with a decimal or rounded in tray icon',
                    'Temperature accuracy in system tray', 'Settings dialogue'))
        self.temp_decimal_combo = QComboBox()
        temp_decimal_combo_dico = {'False': '0°', 'True': '0.1°'}
        temp_decimal_combo_list = [temp_decimal_combo_dico['False'], temp_decimal_combo_dico['True']]
        self.temp_decimal_combo.addItems(temp_decimal_combo_list)
        temp_decimal_bool_str = self.settings.value('Decimal') or 'False'
        self.temp_decimal_combo.setCurrentIndex(self.temp_decimal_combo.findText(
                                temp_decimal_combo_dico[temp_decimal_bool_str]))
        self.temp_decimal_combo.currentIndexChanged.connect(self.temp_decimal)
        self.temp_decimal_changed = False
        # Interval of updates
        self.interval_label = QLabel(self.tr('Update interval'))
        self.interval_min = QLabel(self.tr('minutes'))
        self.interval_combo = QComboBox()
        self.interval_list = ['15', '30', '45', '60', '90', '120']
        self.interval_combo.addItems(self.interval_list)
        self.interval_combo.setCurrentIndex(self.interval_combo.findText(
            self.interval_list[self.interval_list.index(self.interval_set)]))
        self.interval_combo.currentIndexChanged.connect(self.interval)
        self.interval_changed = False
        # OK Cancel Apply Buttons
        self.buttonLayout = QHBoxLayout()
        self.buttonLayout.addStretch()
        self.buttonBox = QDialogButtonBox()
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(
            QDialogButtonBox.Ok | QDialogButtonBox.Apply | QDialogButtonBox.Cancel)
        self.buttonBox.setContentsMargins(0, 30, 0, 0)
        self.buttonLayout.addWidget(self.buttonBox)
        self.buttonBox.button(QDialogButtonBox.Apply).clicked.connect(self.apply_settings)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(False)
        # Autostart
        self.autostart_label = QLabel(self.tr('Launch at startup'))
        self.autostart_checkbox = QCheckBox()
        autostart_bool = self.settings.value('Autostart') or 'False'
        autostart_bool = eval(autostart_bool)
        self.autostart_checkbox.setChecked(autostart_bool)
        self.autostart_checkbox.stateChanged.connect(self.autostart)
        self.autostart_changed = False
        # Tray temp° color
        self.temp_colorLabel = QLabel(self.tr('Font colour in the tray'))
        self.temp_colorButton = QPushButton()
        self.temp_colorButton.setStyleSheet(
            'QWidget {{ background-color: {0} }}'.format(self.temp_tray_color))
        self.temp_colorButton.setMaximumSize(QSize(44, 24))
        self.temp_colorButton.clicked.connect(self.color_chooser)
        self.temp_color_resetButton = QPushButton(self.tr('Reset'))
        self.temp_color_resetButton.setToolTip(
            self.tr('Reset font colour to system default'))
        self.temp_color_resetButton.clicked.connect(self.color_reset)
        # Display notifications
        self.notifier_label = QLabel(self.tr('Notification on weather update'))
        self.notifier_checkbox = QCheckBox()
        notifier_bool = self.settings.value('Notifications') or 'True'
        notifier_bool = eval(notifier_bool)
        self.notifier_checkbox.setChecked(notifier_bool)
        self.notifier_checkbox.stateChanged.connect(self.notifier)
        self.notifier_changed = False
        # Icon & Temp
        self.tray_icon_temp_label = QLabel(QCoreApplication.translate(
            "Settings dialogue", "System tray icon",
            '''Setting to choose the type of the icon on the tray (only icon,
            only text, icon&text'''))
        self.tray_icon_combo = QComboBox()
        tray_icon_temp = QCoreApplication.translate(
            "Settings dialogue", "Icon & temperature",
            'Setting to choose the type of the icon on the tray')
        tray_icon = QCoreApplication.translate(
            "Settings dialogue", "Icon",
            'Setting to choose the type of the icon on the tray')
        tray_temp = QCoreApplication.translate(
            "Settings dialogue", "Temperature",
            'Setting to choose the type of the icon on the tray')
        self.tray_dico = {'icon&temp': tray_icon_temp, 'icon': tray_icon,
                          'temp': tray_temp}
        set_tray_icon = self.settings.value('TrayType') or 'icon&temp'
        tray_icon_list = sorted(self.tray_dico.values())
        self.tray_icon_combo.addItems(tray_icon_list)
        self.tray_icon_combo.setCurrentIndex(self.tray_icon_combo.findText
                                             (self.tray_dico[set_tray_icon]))
        self.tray_icon_combo.currentIndexChanged.connect(self.tray)
        self.tray_changed = False
        # Font size
        fontsize = self.settings.value('FontSize') or '18'
        self.fontsize_label = QLabel(QCoreApplication.translate(
            "Settings dialog", "Font size in tray",
            "Setting for the font size of the temperature in the tray icon"))
        self.fontsize_spinbox = QSpinBox()
        self.fontsize_spinbox.setRange(12, 32)
        self.fontsize_spinbox.setValue(int(fontsize))
        if fontsize is None or fontsize == '':
            self.settings.setValue('FontSize', '18')
        self.fontsize_changed = False
        self.fontsize_spinbox.valueChanged.connect(self.fontsize_change)
        # Font weight
        self.bold_checkbox = QCheckBox(QCoreApplication.translate('Font setting - Checkbox label',
                                        'Bold', 'Settings dialogue'))
        bold_bool = self.settings.value('Bold') or 'False'
        self.bold_bool = eval(bold_bool)
        self.bold_checkbox.setChecked(self.bold_bool)
        self.bold_checkbox.stateChanged.connect(self.bold)
        self.bold_changed = False
        # Proxy
        self.proxy_label = QLabel(QCoreApplication.translate(
                            'Checkbox', 'Connection by proxy', 'Settings dialogue'))
        self.proxy_chbox = QCheckBox()
        proxy_bool = self.settings.value('Proxy') or 'False'
        self.proxy_bool = eval(proxy_bool)
        self.proxy_chbox.setChecked(self.proxy_bool)
        self.proxy_chbox.stateChanged.connect(self.proxy)
        self.proxy_changed = False
        self.proxy_button = QPushButton(QCoreApplication.translate(
            'Label of button to open the proxy dialogue', 'Settings', 'Settings dialogue'))
        self.proxy_button.clicked.connect(self.proxy_settings)
        self.proxy_button.setEnabled(self.proxy_bool)
        # Openweathermap key
        self.owmkey_label = QLabel(QCoreApplication.translate(
            'The key that user can generate in his OpenWeatherMap profile',
            'OpenWeatherMap key', 'Settings dialogue'))
        self.owmkey_create = QLabel(QCoreApplication.translate(
            'Link to create a profile in OpenWeatherMap',
            "<a href=\"http://home.openweathermap.org/users/sign_up\">Create key</a>",
            'Settings dialogue'))
        self.owmkey_create.setOpenExternalLinks(True)
        apikey = self.settings.value('APPID') or ''
        self.owmkey_text = QLineEdit()
        self.owmkey_text.setText(apikey)
        self.owmkey_text.textChanged.connect(self.apikey_changed)
        # ----------
        self.panel = QGridLayout()
        self.panel.addWidget(self.city_title, 0, 0)
        self.panel.addWidget(self.city_combo, 0, 1)
        self.panel.addWidget(self.city_button, 0, 2)
        self.panel.addWidget(self.language_label, 1, 0)
        self.panel.addWidget(self.language_combo, 1, 1)
        self.panel.addWidget(self.units_label, 2, 0)
        self.panel.addWidget(self.units_combo, 2, 1)
        self.panel.addWidget(self.bft_checkbox, 2, 2)
        self.panel.addWidget(self.temp_decimal_label, 3, 0)
        self.panel.addWidget(self.temp_decimal_combo, 3, 1)
        self.panel.addWidget(self.interval_label, 4, 0)
        self.panel.addWidget(self.interval_combo, 4, 1)
        self.panel.addWidget(self.interval_min, 4, 2)
        self.panel.addWidget(self.autostart_label, 5, 0)
        self.panel.addWidget(self.autostart_checkbox, 5, 1)
        self.panel.addWidget(self.temp_colorLabel, 6, 0)
        self.panel.addWidget(self.temp_colorButton, 6, 1)
        self.panel.addWidget(self.temp_color_resetButton, 6, 2)
        self.panel.addWidget(self.notifier_label, 7, 0)
        self.panel.addWidget(self.notifier_checkbox, 7, 1)
        self.panel.addWidget(self.tray_icon_temp_label, 8, 0)
        self.panel.addWidget(self.tray_icon_combo, 8, 1)
        self.panel.addWidget(self.fontsize_label, 9, 0)
        self.panel.addWidget(self.fontsize_spinbox, 9, 1)
        self.panel.addWidget(self.bold_checkbox, 9, 2)
        self.panel.addWidget(self.proxy_label, 10, 0)
        self.panel.addWidget(self.proxy_chbox, 10, 1)
        self.panel.addWidget(self.proxy_button, 10, 2)
        self.panel.addWidget(self.owmkey_label, 11, 0)
        self.panel.addWidget(self.owmkey_text, 11, 1)
        self.panel.addWidget(self.owmkey_create, 11, 2)

        self.layout.addLayout(self.panel)
        self.layout.addLayout(self.buttonLayout)
        self.statusbar = QLabel()
        self.layout.addWidget(self.statusbar)
        self.nokey_message = QCoreApplication.translate(
                'Warning message after pressing Ok', 'Please enter your OpenWeatherMap key',
                'Settings dialogue')
        self.nocity_message = QCoreApplication.translate(
                'Warning message after pressing OK', 'Please add a city',
                'Settings dialogue')
        self.setLayout(self.layout)
        self.setWindowTitle(self.tr('Meteo-qt Configuration'))

    def units(self):
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)
        self.units_changed = True

    def language(self):
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)
        self.lang_changed = True

    def city_default(self):
        allitems = [self.city_combo.itemText(i) for i in range(self.city_combo.count())]
        allitems_not_translated = []
        for i in allitems:
            allitems_not_translated.append(self.find_city_key(i))
        city_name = self.city_combo.currentText()
        city_name = self.find_city_key(city_name)
        citytosave = city_name.split('_')
        # This self variable will serve to check if a translation
        # exist for the current city when quitting
        self.citytosave = '_'.join(citytosave)
        if len(citytosave) < 3:
            return
        self.id_before = citytosave[2]
        self.city_before = citytosave[0]
        self.country_before = citytosave[1]
        self.city_list_before = allitems_not_translated[:]
        self.city_list_before.pop(self.city_list_before.index(city_name))
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)

    def interval(self):
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)
        self.interval_changed = True

    def edit_cities_list(self):
        apikey = self.owmkey_text.text()
        apiid = '&APPID=' + apikey
        if apikey == '':
            self.statusbar.setText(self.nokey_message)
            return
        dialog = citylistdlg.CityListDlg(self.citylist, self.accurate_url,
                                         apiid, self.trans_cities_dict, self)
        dialog.citieslist_signal.connect(self.cities_list)
        dialog.citiesdict_signal.connect(self.cities_dict)
        dialog.exec_()

    def cities_dict(self, cit_dict):
        self.trans_cities_dict = cit_dict

    def cities_list(self, cit_list):
        if len(cit_list) > 0:
            citytosave = cit_list[0].split('_')
            self.id_before = citytosave[2]
            self.city_before = citytosave[0]
            self.country_before = citytosave[1]
            if len(cit_list) > 1:
                self.city_list_before = cit_list[1:]
            else:
                self.city_list_before = str('')
        else:
            self.id_before = ''
            self.city_before = ''
            self.country_before = ''
            self.city_list_before = []
            self.clear_combo = True
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)
        self.first = False
        self.add_cities_incombo()

    def autostart(self, state):
        self.autostart_state = state
        self.autostart_changed = True
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)

    def autostart_apply(self):
        dir_auto = '/.config/autostart/'
        d_file = 'meteo-qt.desktop'
        home = os.getenv('HOME')
        total_path = home + dir_auto + d_file
        if self.autostart_state == 2:
            desktop_file = ['[Desktop Entry]\n',
                            'Exec=meteo-qt\n',
                            'Name=meteo-qt\n',
                            'Type=Application\n',
                            'Version=1.0\n',
                            'X-LXQt-Need-Tray=true\n']
            if not os.path.exists(home + dir_auto):
                os.system('mkdir -p {}'.format(os.path.dirname(total_path)))
            with open(total_path, 'w') as out_file:
                out_file.writelines(desktop_file)
            self.settings.setValue('Autostart', 'True')
            logging.debug('Write desktop file in ~/.config/autostart')
        elif self.autostart_state == 0:
            if os.path.exists(total_path):
                os.remove(total_path)
            self.settings.setValue('Autostart', 'False')
            logging.debug('Remove desktop file from ~/.config/autostart')
        else:
            return

    def color_chooser(self):
        col = QColorDialog.getColor()
        if col.isValid():
            self.temp_colorButton.setStyleSheet(
                'QWidget {{ background-color: {0} }}'.format(col.name()))
            # focus to next elem to show immediatley the colour
            # in the button (in some DEs)
            self.temp_color_resetButton.setFocus()
            self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)
            self.color_before = col.name()
        else:
            logging.debug('Invalid color:' + str(col))

    def color_reset(self):
        self.temp_colorButton.setStyleSheet('QWidget { background-color:  }')
        self.color_before = ''
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)

    def notifier(self, state):
        self.notifier_state = state
        self.notifier_changed = True
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)

    def notifier_apply(self):
        if self.notifier_state == 2:
            self.settings.setValue('Notifications', 'True')
            logging.debug('Write: Notifications = True')
        elif self.notifier_state == 0:
            self.settings.setValue('Notifications', 'False')
            logging.debug('Write: Notifications = False')

    def temp_decimal(self, state):
        self.temp_decimal_state = state
        self.temp_decimal_changed = True
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)

    def tray(self):
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)
        self.tray_changed = True

    def tray_apply(self):
        tray = self.tray_icon_combo.currentText()
        self.settings.setValue('Tray', tray)
        logging.debug('Write >' + 'Tray >' + str(tray))
        settray = [key for key, value in self.tray_dico.items() if value == tray]
        self.settings.setValue('TrayType', settray[0])

    def fontsize_change(self, size):
        self.fontsize_changed = True
        self.fontsize_value = size
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)

    def fontsize_apply(self):
        logging.debug('Apply fontsize: ' + str(self.fontsize_value))
        self.settings.setValue('FontSize', str(self.fontsize_value))

    def bold(self, state):
        self.bold_state = state
        self.bold_changed = True
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)

    def bold_apply(self):
        if self.bold_state == 2:
            bold = 'True'
        else:
            bold = 'False'
        self.settings.setValue('Bold', str(bold))

    def beaufort(self, state):
        self.bft_state = state
        self.bft_changed = True
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)

    def beaufort_apply(self):
        if self.bft_state == 2:
            bft = 'True'
        else:
            bft = 'False'
        self.settings.setValue('Beaufort', str(bft))

    def proxy(self, state):
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)
        if state == 2:
            self.proxy_bool = True
            self.proxy_button.setEnabled(True)
        else:
            self.proxy_bool = False
            self.proxy_button.setEnabled(False)

    def proxy_settings(self):
        dialog = proxydlg.Proxy(self)
        dialog.exec_()

    def apikey_changed(self):
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)

    def apply_settings(self):
        self.accepted()

    def clear_translations(self):
        ''' Save the list of the current cities list
            and remove the odd or blank translations'''
        cities = self.citylist
        if hasattr(self, 'city_list_before'):
            self.settings.setValue('CityList', str(self.city_list_before))
            logging.debug('write ' + 'CityList ' + str(self.city_list_before))
            try:
                cities = self.city_list_before
                cities.append(self.citytosave)
            except:
                logging.debug('Empty cities list, default city: ' + str(cities))
                pass
        translations_to_delete = []
        for key, value in self.trans_cities_dict.items():
            if key == value or value == '' or key not in cities:
                translations_to_delete.append(key)
        for i in translations_to_delete:
            del self.trans_cities_dict[i]
        self.settings.setValue('CitiesTranslation', str(self.trans_cities_dict))
        logging.debug('write ' + 'CitiesTranslation ' + str(self.trans_cities_dict))

    def accepted(self):
        self.clear_translations()
        apikey = self.owmkey_text.text()
        city_name = self.city_combo.currentText()
        if apikey == '':
            self.statusbar.setText(self.nokey_message)
            return
        else:
            self.statusbar.setText('')
            self.settings.setValue('APPID', str(self.owmkey_text.text()))
        if city_name == '':
            self.statusbar.setText(self.nocity_message)
            return
        else:
            self.statusbar.setText('')
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(False)
        if hasattr(self, 'id_before'):
            self.settings.setValue('ID', self.id_before)
            logging.debug('write ' + 'ID' + str(self.id_before))
        if hasattr(self, 'city_before'):
            self.settings.setValue('City', self.city_before)
            logging.debug('write ' + 'City' + str(self.city_before))
        if hasattr(self, 'country_before'):
            self.settings.setValue('Country', self.country_before)
            logging.debug('write ' + 'Country' + str(self.country_before))
        if hasattr(self, 'color_before'):
            self.settings.setValue('TrayColor', self.color_before)
            if self.color_before == '':
                self.color_before = 'None'
            logging.debug('Write font color for temp in tray: {0}'.format(self.color_before))
        if self.autostart_changed:
            self.autostart_apply()
        if self.interval_changed:
            time = self.interval_combo.currentText()
            self.settings.setValue('Interval', time)
            logging.debug('Write ' + 'Interval ' + str(time))
        if self.lang_changed:
            lang = self.language_combo.currentText()
            setlang = [key for key, value in self.language_dico.items() if value == lang]
            self.settings.setValue('Language', setlang[0])
            logging.debug('Write ' + 'Language ' + str(setlang[0]))
        if self.units_changed:
            unit = self.units_combo.currentText()
            setUnit = [key for key, value in self.units_dico.items() if value == unit]
            self.settings.setValue('Unit', setUnit[0])
            logging.debug('Write ' + 'Unit ' + str(setUnit[0]))
        if self.temp_decimal_changed:
            decimal = self.temp_decimal_combo.currentText()
            decimal_bool_str = 'False'
            if decimal == '0.1°':
                decimal_bool_str = 'True'
            self.settings.setValue('Decimal', decimal_bool_str)
            logging.debug('Write: Decimal in tray icon = ' + decimal_bool_str)
        if self.notifier_changed:
            self.notifier_apply()
        if self.tray_changed:
            self.tray_apply()
        if self.fontsize_changed:
            self.fontsize_apply()
        if self.bold_changed:
            self.bold_apply()
        if self.bft_changed:
            self.beaufort_apply()
        proxy_url = self.settings.value('Proxy_url') or ''
        if proxy_url == '':
            self.proxy_bool = False
        self.settings.setValue('Proxy', str(self.proxy_bool))
        self.applied_signal.emit()

    def accept(self):
        self.accepted()
        apikey = self.owmkey_text.text()
        city_name = self.city_combo.currentText()
        if apikey == '':
            self.statusbar.setText(self.nokey_message)
            return
        if city_name == '':
            self.statusbar.setText(self.nocity_message)
            return
        QDialog.accept(self)

    def add_cities_incombo(self):
        list_cities = ''
        self.city_combo.clear()
        if self.clear_combo:
            return
        if self.first:
            list_cities = self.settings.value('CityList')
            if list_cities is not None:
                self.city_list_before = list_cities[:]
            self.citylist = [self.set_city + '_' +
                             self.settings.value('Country') + '_' +
                             self.settings.value('ID')]
        else:
            self.citylist = [self.city_before + '_' + self.country_before +
                             '_' + self.id_before]
            list_cities = self.city_list_before[:]
        if list_cities is None:
            list_cities = []
        if list_cities != '' and list_cities is not None:
            if type(list_cities) is str:
                list_cities = eval(list_cities)
            self.citylist = self.citylist + list_cities
        duplicate = []
        for i in self.citylist:
            if i not in duplicate:
                duplicate.append(i)
        self.citylist = duplicate[:]
        self.translated = []
        for city in self.citylist:
            self.translated.append(self.trans_cities_dict.get(city, city))
        self.city_combo.addItems(self.translated)
        if len(list_cities) > 0:
            maxi = len(max(list_cities, key=len))
            self.city_combo.setMinimumSize(maxi*8, 23)

    def find_city_key(self, city):
        for key, value in self.trans_cities_dict.items():
            if value == city:
                return key
        return city
Beispiel #37
0
class SchedulePanel(Panel):
    FIELDS = [
        ('startDateEdit', 'start_date'),
        ('repeatEverySpinBox', 'repeat_every'),
        ('stopDateEdit', 'stop_date'),
        ('descriptionEdit', 'description'),
        ('payeeEdit', 'payee'),
        ('checkNoEdit', 'checkno'),
        ('notesEdit', 'notes'),
    ]
    PERSISTENT_NAME = 'schedulePanel'

    def __init__(self, model, mainwindow):
        Panel.__init__(self, mainwindow)
        self.setAttribute(Qt.WA_DeleteOnClose)
        self.model = model
        self._setupUi()
        self.splitTable = SplitTable(model=self.model.split_table, view=self.splitTableView)
        self.repeatTypeComboBox = ComboboxModel(model=self.model.repeat_type_list, view=self.repeatTypeComboBoxView)

        self.addSplitButton.clicked.connect(self.splitTable.model.add)
        self.removeSplitButton.clicked.connect(self.splitTable.model.delete)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)

    def _setupUi(self):
        self.setWindowTitle(tr("Schedule Info"))
        self.resize(469, 416)
        self.setModal(True)
        self.verticalLayout_2 = QVBoxLayout(self)
        self.tabWidget = QTabWidget(self)
        self.tab = QWidget()
        self.formLayout = QFormLayout(self.tab)
        self.formLayout.setFieldGrowthPolicy(QFormLayout.ExpandingFieldsGrow)
        self.label_2 = QLabel(tr("Start Date:"))
        self.formLayout.setWidget(0, QFormLayout.LabelRole, self.label_2)
        self.startDateEdit = DateEdit(self.tab)
        self.startDateEdit.setMaximumSize(QSize(120, 16777215))
        self.formLayout.setWidget(0, QFormLayout.FieldRole, self.startDateEdit)
        self.label_7 = QLabel(tr("Repeat Type:"))
        self.formLayout.setWidget(1, QFormLayout.LabelRole, self.label_7)
        self.repeatTypeComboBoxView = QComboBox(self.tab)
        self.formLayout.setWidget(1, QFormLayout.FieldRole, self.repeatTypeComboBoxView)
        self.label_8 = QLabel(tr("Every:"))
        self.formLayout.setWidget(2, QFormLayout.LabelRole, self.label_8)
        self.horizontalLayout_2 = QHBoxLayout()
        self.repeatEverySpinBox = QSpinBox(self.tab)
        self.repeatEverySpinBox.setMinimum(1)
        self.horizontalLayout_2.addWidget(self.repeatEverySpinBox)
        self.repeatEveryDescLabel = QLabel(self.tab)
        self.horizontalLayout_2.addWidget(self.repeatEveryDescLabel)
        self.formLayout.setLayout(2, QFormLayout.FieldRole, self.horizontalLayout_2)
        self.label_9 = QLabel(tr("Stop Date:"))
        self.formLayout.setWidget(3, QFormLayout.LabelRole, self.label_9)
        self.stopDateEdit = DateEdit(self.tab, is_clearable=True)
        self.stopDateEdit.setMaximumSize(QSize(120, 16777215))
        self.formLayout.setWidget(3, QFormLayout.FieldRole, self.stopDateEdit)
        self.label_3 = QLabel(tr("Description:"))
        self.formLayout.setWidget(4, QFormLayout.LabelRole, self.label_3)
        self.descriptionEdit = DescriptionEdit(self.model.completable_edit, self.tab)
        self.formLayout.setWidget(4, QFormLayout.FieldRole, self.descriptionEdit)
        self.label_4 = QLabel(tr("Payee:"))
        self.formLayout.setWidget(5, QFormLayout.LabelRole, self.label_4)
        self.payeeEdit = PayeeEdit(self.model.completable_edit, self.tab)
        self.formLayout.setWidget(5, QFormLayout.FieldRole, self.payeeEdit)
        self.label_5 = QLabel(tr("Check #:"))
        self.formLayout.setWidget(6, QFormLayout.LabelRole, self.label_5)
        self.checkNoEdit = QLineEdit(self.tab)
        self.checkNoEdit.setMaximumSize(QSize(120, 16777215))
        self.formLayout.setWidget(6, QFormLayout.FieldRole, self.checkNoEdit)
        self.amountLabel = QLabel(tr("Transfers:"))
        self.formLayout.setWidget(7, QFormLayout.LabelRole, self.amountLabel)
        self.splitTableView = TableView(self.tab)
        self.splitTableView.setMinimumSize(QSize(355, 0))
        self.splitTableView.setAcceptDrops(True)
        self.splitTableView.setDragEnabled(True)
        self.splitTableView.setDragDropOverwriteMode(False)
        self.splitTableView.setDragDropMode(QAbstractItemView.InternalMove)
        self.splitTableView.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.splitTableView.horizontalHeader().setDefaultSectionSize(40)
        self.splitTableView.verticalHeader().setVisible(False)
        self.splitTableView.verticalHeader().setDefaultSectionSize(18)
        self.formLayout.setWidget(7, QFormLayout.FieldRole, self.splitTableView)
        self.widget = QWidget(self.tab)
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.widget.sizePolicy().hasHeightForWidth())
        self.widget.setSizePolicy(sizePolicy)
        self.horizontalLayout_6 = QHBoxLayout(self.widget)
        self.horizontalLayout_6.setContentsMargins(0, 0, 0, 0)
        spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.horizontalLayout_6.addItem(spacerItem)
        self.addSplitButton = QPushButton(self.widget)
        icon = QIcon()
        icon.addPixmap(QPixmap(':/plus_8'), QIcon.Normal, QIcon.Off)
        self.addSplitButton.setIcon(icon)
        self.horizontalLayout_6.addWidget(self.addSplitButton)
        self.removeSplitButton = QPushButton(self.widget)
        icon1 = QIcon()
        icon1.addPixmap(QPixmap(':/minus_8'), QIcon.Normal, QIcon.Off)
        self.removeSplitButton.setIcon(icon1)
        self.horizontalLayout_6.addWidget(self.removeSplitButton)
        self.formLayout.setWidget(8, QFormLayout.FieldRole, self.widget)
        self.tabWidget.addTab(self.tab, tr("Info"))
        self.tab_3 = QWidget()
        self.horizontalLayout_5 = QHBoxLayout(self.tab_3)
        self.notesEdit = QPlainTextEdit(self.tab_3)
        self.horizontalLayout_5.addWidget(self.notesEdit)
        self.tabWidget.addTab(self.tab_3, tr("Notes"))
        self.verticalLayout_2.addWidget(self.tabWidget)
        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Save)
        self.verticalLayout_2.addWidget(self.buttonBox)
        self.label_2.setBuddy(self.startDateEdit)
        self.label_7.setBuddy(self.repeatTypeComboBoxView)
        self.label_3.setBuddy(self.descriptionEdit)
        self.label_4.setBuddy(self.payeeEdit)
        self.label_5.setBuddy(self.checkNoEdit)

        self.tabWidget.setCurrentIndex(0)

    def _loadFields(self):
        Panel._loadFields(self)
        self.tabWidget.setCurrentIndex(0)

    # --- model --> view
    def refresh_for_multi_currency(self):
        pass

    def refresh_repeat_every(self):
        self.repeatEveryDescLabel.setText(self.model.repeat_every_desc)
Beispiel #38
0
class LoadKineticsDialog(PersistentDialog):

    def __init__(self, accept_func: Callable, parent=None):
        super(LoadKineticsDialog, self).__init__(parent)

        self.setWindowTitle("Batch Load Kinetics")
        self.sett = Settings()

        self.description = QLabel("""
Loads UV-Vis kinetics. The spectra can be in various formats (dx, csv, txt, etc.). If blank spectrum is provided, it will be subtracted from each of the spectra. Time corresponding to each spectrum will be set as the name for that spectrum. Times can be provided by time difference (in case kinetics was measured reguraly) or from filename. Postprocessing (baseline correction and/or cut of spectra) can be performed on loaded dataset.
Required folder structure for one kinetics:
[kinetics folder]
    [spectra folder]
         01.dx
         02.dx
         ...
    times.txt (optional)
    blank.dx (optional)
        
""")
        self.description.setWordWrap(True)
        self.accept_func = accept_func

        self.btnChooseDirs = QToolButton()
        self.btnChooseDirs.setText('...')

        self.layout_button = QHBoxLayout()
        self.layout_button.addWidget(QLabel('Folders to load:'))
        self.layout_button.addWidget(self.btnChooseDirs)

        self.lwFolders = MyQListWidget(self)

        self.grid_layout = QGridLayout()
        self.lbl1 = QLabel('Spectra folder name:')
        self.lbl2 = QLabel('Blank spectrum name (optional):')
        self.cbKineticsMeasuredByEach = QCheckBox('Kinetics measured by each (time unit):')
        self.cbKineticsMeasuredByEach.setChecked(True)
        self.lbl4 = QLabel('Use times from filename (optional):')
        self.cbBCorr = QCheckBox('Apply baseline correction in range:')
        self.cbCut = QCheckBox('Cut spectra to range:')

        self.leSpectra = QLineEdit('spectra')
        self.leBlank = QLineEdit('blank.dx')
        self.leTimeUnit = QLineEdit('1')
        self.leTimes = QLineEdit('times.txt')
        self.leBCorr0 = QLineEdit('700')
        self.leBCorr1 = QLineEdit('800')
        self.leCut0 = QLineEdit('230')
        self.leCut1 = QLineEdit('650')

        self.Hlayout1 = QHBoxLayout()
        self.Hlayout1.addWidget(self.leBCorr0)
        self.Hlayout1.addWidget(QLabel('to'))
        self.Hlayout1.addWidget(self.leBCorr1)

        self.Hlayout2 = QHBoxLayout()
        self.Hlayout2.addWidget(self.leCut0)
        self.Hlayout2.addWidget(QLabel('to'))
        self.Hlayout2.addWidget(self.leCut1)

        self.grid_layout.addWidget(self.lbl1, 0, 0, 1, 1)
        self.grid_layout.addWidget(self.lbl2, 1, 0, 1, 1)
        self.grid_layout.addWidget(self.cbKineticsMeasuredByEach, 2, 0, 1, 1)
        self.grid_layout.addWidget(self.lbl4, 3, 0, 1, 1)
        self.grid_layout.addWidget(self.cbBCorr, 4, 0, 1, 1)
        self.grid_layout.addWidget(self.cbCut, 5, 0, 1, 1)
        self.grid_layout.addWidget(self.leSpectra, 0, 1, 1, 1)
        self.grid_layout.addWidget(self.leBlank, 1, 1, 1, 1)
        self.grid_layout.addWidget(self.leTimeUnit, 2, 1, 1, 1)
        self.grid_layout.addWidget(self.leTimes, 3, 1, 1, 1)
        self.grid_layout.addLayout(self.Hlayout1, 4, 1, 1, 1)
        self.grid_layout.addLayout(self.Hlayout2, 5, 1, 1, 1)

        self.button_box = QDialogButtonBox()
        self.button_box.setOrientation(Qt.Horizontal)
        self.button_box.setStandardButtons(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        self.button_box.accepted.connect(self.accept)  # OK button
        self.button_box.rejected.connect(self.reject)  # Cancel button

        self.main_layout = QVBoxLayout(self)
        self.main_layout.addWidget(self.description)
        self.main_layout.addLayout(self.layout_button)
        self.main_layout.addWidget(self.lwFolders)
        self.main_layout.addLayout(self.grid_layout)
        self.main_layout.addWidget(self.button_box)

        self.setLayout(self.main_layout)

        self.cbKineticsMeasuredByEach.toggled.connect(self.cbKineticsMeasuredByEach_toggled)
        self.cbBCorr.toggled.connect(self.cbBCorr_toggled)
        self.cbCut.toggled.connect(self.cbCut_toggled)
        self.btnChooseDirs.clicked.connect(self.btnChooseDirs_clicked)

        self.cbKineticsMeasuredByEach_toggled()
        self.cbBCorr_toggled()
        self.cbCut_toggled()

    def btnChooseDirs_clicked(self):
        # https://stackoverflow.com/questions/38252419/how-to-get-qfiledialog-to-select-and-return-multiple-folders
        # just copied :)
        file_dialog = QFileDialog()
        file_dialog.setFileMode(QFileDialog.DirectoryOnly)
        file_dialog.setOption(QFileDialog.DontUseNativeDialog, True)
        file_dialog.setDirectory(self.sett['/Private settings/Load kinetics last path'])
        file_view = file_dialog.findChild(QListView, 'listView')

        # to make it possible to select multiple directories:
        if file_view:
            file_view.setSelectionMode(QAbstractItemView.MultiSelection)
        f_tree_view = file_dialog.findChild(QTreeView)
        if f_tree_view:
            f_tree_view.setSelectionMode(QAbstractItemView.MultiSelection)

        if file_dialog.exec():
            for path in file_dialog.selectedFiles():
                head, tail = os.path.split(path)
                head2, tail2 = os.path.split(head)
                name = os.path.join(tail2, tail)
                self.sett['/Private settings/Load kinetics last path'] = head
                if name not in self.lwFolders.item_names:
                    self.lwFolders.addItem(name, path)

    def cbBCorr_toggled(self):
        checked = self.cbBCorr.isChecked()
        self.leBCorr0.setEnabled(checked)
        self.leBCorr1.setEnabled(checked)

    def cbCut_toggled(self):
        checked = self.cbCut.isChecked()
        self.leCut0.setEnabled(checked)
        self.leCut1.setEnabled(checked)

    def cbKineticsMeasuredByEach_toggled(self):
        checked = self.cbKineticsMeasuredByEach.isChecked()
        self.leTimeUnit.setEnabled(checked)
        self.leTimes.setEnabled(not checked)

    def accept(self):
        try:
            float(self.leTimeUnit.text())
            float(self.leCut0.text())
            float(self.leCut1.text())
            float(self.leBCorr0.text())
            float(self.leBCorr1.text())
        except ValueError:
            QMessageBox.critical(self, 'Error', "Invalid input, please check the fields.")
            return

        self.sett.save()
        self.accept_func()
        super(LoadKineticsDialog, self).accept()
Beispiel #39
0
    def showDialog(self, currentCard=None):
        if currentCard:
            self.did = currentCard.did
        elif mw._selectedDeck():
            self.did = mw._selectedDeck()['id']
        else:
            return

        if not self._getCardInfo(self.did):
            showInfo('Please select an Incremental Reading deck.')
            return

        dialog = QDialog(mw)
        layout = QVBoxLayout()
        self.cardListWidget = QListWidget()
        self.cardListWidget.setAlternatingRowColors(True)
        self.cardListWidget.setSelectionMode(
            QAbstractItemView.ExtendedSelection)
        self.cardListWidget.setWordWrap(True)
        self.cardListWidget.itemDoubleClicked.connect(lambda: showBrowser(
            self.cardListWidget.currentItem().data(Qt.UserRole)['nid']))

        self._updateListItems()

        upButton = QPushButton('Up')
        upButton.clicked.connect(self._moveUp)
        downButton = QPushButton('Down')
        downButton.clicked.connect(self._moveDown)
        topButton = QPushButton('Top')
        topButton.clicked.connect(self._moveToTop)
        bottomButton = QPushButton('Bottom')
        bottomButton.clicked.connect(self._moveToBottom)
        randomizeButton = QPushButton('Randomize')
        randomizeButton.clicked.connect(self._randomize)

        controlsLayout = QHBoxLayout()
        controlsLayout.addWidget(topButton)
        controlsLayout.addWidget(upButton)
        controlsLayout.addWidget(downButton)
        controlsLayout.addWidget(bottomButton)
        controlsLayout.addStretch()
        controlsLayout.addWidget(randomizeButton)

        buttonBox = QDialogButtonBox(QDialogButtonBox.Close
                                     | QDialogButtonBox.Save)
        buttonBox.accepted.connect(dialog.accept)
        buttonBox.rejected.connect(dialog.reject)
        buttonBox.setOrientation(Qt.Horizontal)

        layout.addLayout(controlsLayout)
        layout.addWidget(self.cardListWidget)
        layout.addWidget(buttonBox)

        dialog.setLayout(layout)
        dialog.setWindowModality(Qt.WindowModal)
        dialog.resize(500, 500)
        choice = dialog.exec_()

        if choice == 1:
            cids = []
            for i in range(self.cardListWidget.count()):
                card = self.cardListWidget.item(i).data(Qt.UserRole)
                cids.append(card['id'])

            self.reorder(cids)
Beispiel #40
0
class Proxy(QDialog):
    id_signal = pyqtSignal([tuple])
    city_signal = pyqtSignal([tuple])
    country_signal = pyqtSignal([tuple])

    def __init__(self, parent=None):
        super(Proxy, self).__init__(parent)
        self.settings = QSettings()

        self.layout = QVBoxLayout()

        self.buttonLayout = QHBoxLayout()
        self.buttonBox = QDialogButtonBox()
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(
            QDialogButtonBox.Ok | QDialogButtonBox.Cancel
        )
        self.buttonBox.rejected.connect(self.reject)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonLayout.addWidget(self.buttonBox)

        self.proxy_url_label = QLabel(
            QCoreApplication.translate(
                'Entry label for the proxy url',
                'Proxy URL:',
                'Proxy settings dialogue'
            )
        )
        self.proxy_url_line = QLineEdit()
        url = self.settings.value('Proxy_url') or ''
        self.proxy_url_line = QLineEdit(url)
        self.proxy_url_line.setMinimumWidth(300)

        self.proxy_port_label = QLabel(
            QCoreApplication.translate(
                'Entry label for the proxy port',
                'Port:',
                'Proxy settings dialogue'
            )
        )
        port = self.settings.value('Proxy_port') or ''
        self.proxy_port_line = QLineEdit(port)

        self.proxy_auth_label = QLabel(
            QCoreApplication.translate(
                'Checkbox',
                'Use proxy authentification',
                'Proxy settings dialogue'
            )
        )
        self.proxy_auth_checkbox = QCheckBox()
        self.proxy_auth_bool = eval(
            self.settings.value('Use_proxy_authentification')
            or 'False'
        )
        self.proxy_auth_checkbox.setChecked(self.proxy_auth_bool)
        self.proxy_auth_checkbox.stateChanged.connect(self.proxy_auth)

        self.proxy_user_label = QLabel(QCoreApplication.translate(
            'Proxy username authentification',
            'User ID:', 'Proxy configuration dialogue'))
        self.proxy_user_label.setEnabled(self.proxy_auth_bool)
        self.proxy_pass_label = QLabel(QCoreApplication.translate(
            'Proxy password authentification',
            'Password:'******'Proxy configuration dialogue'))
        self.proxy_pass_label.setEnabled(self.proxy_auth_bool)

        user = self.settings.value('Proxy_user') or ''
        self.proxy_user_line = QLineEdit(user)
        self.proxy_user_line.setEnabled(self.proxy_auth_bool)
        password = self.settings.value('Proxy_password') or ''
        self.proxy_pass_line = QLineEdit(password)
        self.proxy_pass_line.setEnabled(self.proxy_auth_bool)
        self.proxy_pass_line.setEchoMode(QLineEdit.Password)

        self.status_layout = QHBoxLayout()
        self.status_label = QLabel()
        self.status_layout.addWidget(self.status_label)

        self.panel = QGridLayout()
        self.panel.addWidget(self.proxy_url_label, 0, 0)
        self.panel.addWidget(self.proxy_url_line, 0, 1)
        self.panel.addWidget(self.proxy_port_label, 0, 2)
        self.panel.addWidget(self.proxy_port_line, 0, 3)
        self.panel.addWidget(self.proxy_auth_label, 1, 0)
        self.panel.addWidget(self.proxy_auth_checkbox, 1, 1)
        self.panel.addWidget(self.proxy_user_label, 2, 0)
        self.panel.addWidget(self.proxy_user_line, 2, 1)
        self.panel.addWidget(self.proxy_pass_label, 3, 0)
        self.panel.addWidget(self.proxy_pass_line, 3, 1)

        self.layout.addLayout(self.panel)
        self.layout.addLayout(self.status_layout)
        self.layout.addLayout(self.buttonLayout)

        self.setLayout(self.layout)

    def proxy_auth(self, state):
        if state == 2:
            self.proxy_auth_bool = True
            self.proxy_user_label.setEnabled(True)
            self.proxy_pass_label.setEnabled(True)
            self.proxy_user_line.setEnabled(True)
            self.proxy_pass_line.setEnabled(True)
        else:
            self.proxy_auth_bool = False
            self.proxy_user_label.setEnabled(False)
            self.proxy_pass_label.setEnabled(False)
            self.proxy_user_line.setEnabled(False)
            self.proxy_pass_line.setEnabled(False)

    def accept(self):
        port = self.proxy_port_line.text()
        if port.isdigit() or port == '':
            self.settings.setValue('Proxy_url', self.proxy_url_line.text())
            self.settings.setValue('Proxy_port', port)
            self.settings.setValue('Use_proxy_authentification',
                                   str(self.proxy_auth_bool))
            if self.proxy_auth_bool:
                self.settings.setValue('Proxy_user',
                                       self.proxy_user_line.text())
                self.settings.setValue('Proxy_password',
                                       self.proxy_pass_line.text())
        else:
            self.status_label.setText('Port number must contain only digits')
            return
        QDialog.accept(self)
class ExportPanel(Panel):
    FIELDS = []
    PERSISTENT_NAME = 'exportPanel'

    def __init__(self, model, mainwindow):
        Panel.__init__(self, mainwindow)
        self.setAttribute(Qt.WA_DeleteOnClose)
        self.mainwindow = mainwindow
        self._setupUi()
        self.model = model
        self.accountTable = ExportAccountTable(model=self.model.account_table, view=self.tableView)

        self.exportTypeButtons.buttonClicked[int].connect(self.exportTypeSelected)
        self.exportFormatButtons.buttonClicked[int].connect(self.exportFormatSelected)
        self.buttonBox.rejected.connect(self.reject)
        self.exportButton.clicked.connect(self.exportButtonClicked)

    def _setupUi(self):
        self.setWindowTitle(tr("Export Options"))
        self.mainLayout = QVBoxLayout(self)

        self.label1 = QLabel(tr("Which accounts do you want to export?"), self)
        self.mainLayout.addWidget(self.label1)
        self.exportTypeButtons = QButtonGroup(self)
        self.exportAllButton = QRadioButton(tr("All"), self)
        self.mainLayout.addWidget(self.exportAllButton)
        self.exportTypeButtons.addButton(self.exportAllButton, ExportType.All)
        self.exportAllButton.setChecked(True)
        self.exportSelectedButton = QRadioButton(tr("Selected"), self)
        self.mainLayout.addWidget(self.exportSelectedButton)
        self.exportTypeButtons.addButton(self.exportSelectedButton, ExportType.Selected)

        self.tableView = QTableView(self)
        self.tableView.setSelectionMode(QAbstractItemView.SingleSelection)
        self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.tableView.verticalHeader().setVisible(False)
        self.tableView.verticalHeader().setDefaultSectionSize(18)
        self.mainLayout.addWidget(self.tableView)

        self.label2 = QLabel(tr("Export format:"), self)
        self.mainLayout.addWidget(self.label2)
        self.exportFormatButtons = QButtonGroup(self)
        self.exportAsQIFButton = QRadioButton("QIF", self)
        self.mainLayout.addWidget(self.exportAsQIFButton)
        self.exportFormatButtons.addButton(self.exportAsQIFButton, ExportFormat.QIF)
        self.exportAsQIFButton.setChecked(True)
        self.exportAsCSVButton = QRadioButton("CSV", self)
        self.mainLayout.addWidget(self.exportAsCSVButton)
        self.exportFormatButtons.addButton(self.exportAsCSVButton, ExportFormat.CSV)

        self.label3 = QLabel(tr("Export scope:"))
        self.mainLayout.addWidget(self.label3)
        self.dateRangeOnlyCheckbox = QCheckBox(tr("Current date range only"))
        self.mainLayout.addWidget(self.dateRangeOnlyCheckbox)

        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel)
        self.exportButton = self.buttonBox.addButton(tr("Export"), QDialogButtonBox.ActionRole)
        self.mainLayout.addWidget(self.buttonBox)

    #--- Overrides
    def _loadFields(self):
        self.exportAllButton.setChecked(self.model.export_all)
        self.exportAsQIFButton.setChecked(self.model.export_format == ExportFormat.QIF)
        self.dateRangeOnlyCheckbox.setChecked(self.model.current_daterange_only)

    def _saveFields(self):
        self.model.current_daterange_only = self.dateRangeOnlyCheckbox.isChecked()

    #--- Event Handlers
    def exportButtonClicked(self):
        title = tr("Export")
        fileext = 'qif' if self.model.export_format == ExportFormat.QIF else 'csv'
        filters = tr("{0} Files (*.{1})").format(fileext.upper(), fileext)
        filename = 'export.{0}'.format(fileext)
        docpath = str(QFileDialog.getSaveFileName(self.mainwindow, title, filename, filters))
        if docpath:
            self.model.export_path = docpath
            self.accept()

    def exportTypeSelected(self, typeId):
        self.model.export_all = typeId == ExportType.All

    def exportFormatSelected(self, typeId):
        self.model.export_format = typeId

    #--- model --> view
    def set_table_enabled(self, enabled):
        self.tableView.setEnabled(enabled)

    def set_export_button_enabled(self, enabled):
        self.exportButton.setEnabled(enabled)
Beispiel #42
0
class AddConnectedPointsDialogWidget(QDialog):
    def __init__(self, parent=None, command=None):
        """Constructor

        Args:
            parent: Qt parent Widget
            iface: QGiS interface
            command: Command instance with a run_it method which will be called
                     on acceptance of the dialog
        """
        super().__init__(parent)
        self.setupUi()

        self.command = command

        self.databases = get_databases()
        self.database_combo.addItems(list(self.databases.keys()))

        # Connect signals
        self.buttonBox.accepted.connect(self.on_accept)
        self.buttonBox.rejected.connect(self.on_reject)

        self.filename = None

    def on_accept(self):
        """Accept and run the Command.run_it method."""

        db_key = self.database_combo.currentText()
        db_entry = self.databases[db_key]
        db_type = db_entry["db_type"]

        _db_settings = db_entry["db_settings"]

        if db_type == "spatialite":
            # usage of db_type 'spatialite' instead of 'sqlite'
            # makes much more sense because it also used internally
            # by qgis, for example when by the ``QgsVectorLayer()``-object
            host = _db_settings["db_path"]
            db_settings = {
                "host": host,
                "port": "",
                "name": "",
                "username": "",
                "password": "",
                "schema": "",
                "database": "",
                "db_path": host,
            }
        else:
            db_settings = _db_settings
            db_settings["schema"] = "public"
        self.command.run_it(db_settings, db_type)

        self.accept()

    def on_reject(self):
        """Cancel"""
        self.reject()
        logger.debug("Reject")

    def closeEvent(self, event):
        """
        Close widget, called by Qt on close
        :param event: QEvent, close event
        """

        self.buttonBox.accepted.disconnect(self.on_accept)
        self.buttonBox.rejected.disconnect(self.on_reject)

        event.accept()

    def setupUi(self):

        self.resize(815, 250)
        self.verticalLayout = QVBoxLayout(self)

        self.groupBox_2 = QGroupBox(self)
        self.groupBox_2.setObjectName("groupBox_2")
        self.database_combo = QComboBox(self.groupBox_2)
        self.database_combo.setGeometry(QRect(10, 30, 481, 34))

        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.database_combo.sizePolicy().hasHeightForWidth()
        )
        self.database_combo.setSizePolicy(sizePolicy)
        self.database_combo.setObjectName("database_combo")
        self.verticalLayout.addWidget(self.groupBox_2)

        self.groupBox = QGroupBox(self)
        self.verticalLayoutBox = QVBoxLayout(self.groupBox)

        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok)
        self.buttonBox.setObjectName("buttonBox")
        self.verticalLayout.addWidget(self.buttonBox)

        self.retranslateUi()
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)
        QMetaObject.connectSlotsByName(self)

    def retranslateUi(self):
        self.setWindowTitle("Add connected points")
        self.groupBox_2.setTitle("Load from model database")
Beispiel #43
0
class LoginDialog(QDialog):
    """登录对话框"""

    clicked_ok = pyqtSignal()

    def __init__(self, config):
        super().__init__()
        self._config = config
        self._user = ""
        self._pwd = ""
        self._cookie = ""
        self.initUI()
        self.setStyleSheet(dialog_qss_style)
        self.setMinimumWidth(300)
        # 信号
        self.name_ed.textChanged.connect(self.set_user)
        self.pwd_ed.textChanged.connect(self.set_pwd)
        self.cookie_ed.textChanged.connect(self.set_cookie)

        self.buttonBox.accepted.connect(self._ok)
        self.buttonBox.rejected.connect(self._cancel)

    def default_var(self):
        try:
            with open(self._config, "rb") as _file:
                _info = load(_file)
            self._user = _info["user"]
            self._pwd = _info["pwd"]
            self._cookie = _info["cookie"]
        except Exception:
            pass
        self.name_ed.setText(self._user)
        self.pwd_ed.setText(self._pwd)
        self.cookie_ed.setPlainText(self._cookie)

    def initUI(self):
        self.setWindowTitle("登录蓝奏云")
        self.setWindowIcon(QIcon("./icon/login.ico"))
        self.logo = QLabel()
        self.logo.setPixmap(QPixmap("./icon/logo3.gif"))
        self.logo.setStyleSheet("background-color:rgb(0,153,255);")
        self.logo.setAlignment(Qt.AlignCenter)
        self.name_lb = QLabel("&User")
        self.name_lb.setAlignment(Qt.AlignCenter)
        self.name_ed = QLineEdit()
        self.name_lb.setBuddy(self.name_ed)

        self.pwd_lb = QLabel("&Password")
        self.pwd_lb.setAlignment(Qt.AlignCenter)
        self.pwd_ed = QLineEdit()
        self.pwd_ed.setEchoMode(QLineEdit.Password)
        self.pwd_lb.setBuddy(self.pwd_ed)

        self.cookie_lb = QLabel("&Cookie")
        self.cookie_ed = QTextEdit()
        notice = "如果由于滑动验证,无法使用用户名与密码登录,则需要输入cookie,自行使用浏览器获取," \
            "cookie会保持在本地,下次使用。其格式如下:\n\n key1=value1; key2=value2"
        self.cookie_ed.setPlaceholderText(notice)
        self.cookie_lb.setBuddy(self.cookie_ed)

        self.buttonBox = QDialogButtonBox()
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)

        main_layout = QGridLayout()
        main_layout.addWidget(self.logo, 0, 0, 2, 4)
        main_layout.addWidget(self.name_lb, 2, 0)
        main_layout.addWidget(self.name_ed, 2, 1, 1, 3)
        main_layout.addWidget(self.pwd_lb, 3, 0)
        main_layout.addWidget(self.pwd_ed, 3, 1, 1, 3)
        # main_layout.addWidget(self.cookie_lb, 4, 0)  # cookie输入框
        # main_layout.addWidget(self.cookie_ed, 4, 1, 2, 3)
        main_layout.addWidget(self.buttonBox, 4, 2)
        self.setLayout(main_layout)
        self.default_var()

    def set_user(self, user):
        self._user = user

    def set_pwd(self, pwd):
        self._pwd = pwd

    def set_cookie(self):
        self._cookie = self.cookie_ed.toPlainText()

    def _cancel(self):
        self.default_var()
        self.close()

    def _ok(self):
        up_info = {"user": self._user, "pwd": self._pwd, "cookie": self._cookie}
        update_settings(self._config, up_info)
        self.clicked_ok.emit()
        self.close()
    def initUI(self):
        # Dialog stuff

        self.setWindowTitle("Select features and label")
        self.setWindowFlags(Qt.WindowTitleHint | Qt.CustomizeWindowHint)
        self.setStyleSheet("""
            QDialog {
                background-color: rgb(255, 229, 204);
                color: #fffff8;
            }
        """)

        self.resize(1280, 720)

        # Outer layout to contain the tableview and the groupbox for selections
        layout = QVBoxLayout()

        # Datatable
        self.tableView = TableView(self.data, self.columns)

        # Groupbox to split into two groupboxes for selections
        groupbox = QGroupBox("Selections")
        groupboxLayout = QHBoxLayout()
        groupbox.setLayout(groupboxLayout)

        # Feature groupbox
        featureGroupbox = QGroupBox("Select your features")
        featureGroupboxLayout = QVBoxLayout()
        featureGroupbox.setLayout(featureGroupboxLayout)

        # Label groupbox
        labelGroupbox = QGroupBox("Select your label")
        labelGroupboxLayout = QVBoxLayout()
        labelGroupbox.setLayout(labelGroupboxLayout)

        groupboxLayout.addWidget(featureGroupbox)
        groupboxLayout.addWidget(labelGroupbox)

        # Save the buttons in arrays for each group box
        self.arrayOfFeatureCheckboxes = []
        self.arrayOfLabelRadioButtons = []
        for column in self.columns:
            checkbox = QCheckBox(column)
            radioButton = QRadioButton(column)

            checkbox.stateChanged.connect(partial(self.changeCheckboxState, checkbox))
            radioButton.toggled.connect(partial(self.changeRadioButtonState, radioButton))

            self.arrayOfFeatureCheckboxes.append(checkbox)
            self.arrayOfLabelRadioButtons.append(radioButton)

            featureGroupboxLayout.addWidget(checkbox)
            labelGroupboxLayout.addWidget(radioButton)

        # Ok and Cancel buttons
        confirmButtonBox = QDialogButtonBox(self)
        confirmButtonBox.setOrientation(Qt.Horizontal)
        confirmButtonBox.setStandardButtons(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        confirmButtonBox.accepted.connect(self.confirm)
        confirmButtonBox.rejected.connect(self.reject)

        layout.addWidget(self.tableView)
        layout.addWidget(groupbox)
        layout.addWidget(confirmButtonBox)

        self.setLayout(layout)
Beispiel #45
0
class AboutDialog(QDialog):
    check_update = pyqtSignal(str, bool)

    def __init__(self, parent=None):
        super(AboutDialog, self).__init__(parent)
        self._ver = ''
        self._github = 'https://github.com/rachpt/lanzou-gui'
        self._api_url = 'https://github.com/zaxtyson/LanZouCloud-API'
        self._gitee = 'https://gitee.com/rachpt/lanzou-gui'
        self._home_page = 'https://rachpt.cn/lanzou-gui/'
        self.initUI()
        self.setStyleSheet(others_style)

    def set_values(self, version):
        self._ver = version
        self.lb_name_text.setText(f"{version}  (点击检查更新)")  # 更新版本

    def show_update(self, ver, msg):
        self.lb_new_ver = QLabel("新版")  # 检测新版
        self.lb_new_ver_msg = QLabel()
        self.lb_new_ver_msg.setOpenExternalLinks(True)
        self.lb_new_ver_msg.setWordWrap(True)
        if ver != '0':
            self.lb_name_text.setText(f"{self._ver}  ➡  {ver}")
        self.lb_new_ver_msg.setText(msg)
        self.lb_new_ver_msg.setMinimumWidth(700)
        if self.form.rowCount() < 5:
            self.form.insertRow(1, self.lb_new_ver, self.lb_new_ver_msg)

    def initUI(self):
        self.setWindowTitle("关于 lanzou-gui")
        about = f'本项目使用PyQt5实现图形界面,可以完成蓝奏云的大部分功能<br/> \
    得益于 <a href="{self._api_url}">API</a> 的功能,可以间接突破单文件最大 100MB 的限制,同时增加了批量上传/下载的功能<br/> \
Python 依赖见<a href="{self._github }/blob/master/requirements.txt">requirements.txt</a>,\
<a href="{self._github}/releases">releases</a> 有打包好了的 Windows 可执行程序,但可能不是最新的'

        project_url = f'<a href="{self._home_page}">主页</a> | <a href="{self._github}">repo</a> | \
                        <a href="{self._gitee}">mirror repo</a>'

        self.logo = QLabel()  # logo
        self.logo.setPixmap(QPixmap("./src/logo2.gif"))
        self.logo.setStyleSheet("background-color:rgb(255,255,255);")
        self.logo.setAlignment(Qt.AlignCenter)
        self.lb_name = QLabel("版本")  # 版本
        self.lb_name_text = QPushButton("")  # 版本
        self.lb_name_text.setToolTip("点击检查更新")
        ver_style = "QPushButton {border:none; background:transparent;font-weight:bold;color:blue;}"
        self.lb_name_text.setStyleSheet(ver_style)
        self.lb_name_text.clicked.connect(
            lambda: self.check_update.emit(self._ver, True))
        self.lb_about = QLabel("关于")  # about
        self.lb_about_text = QLabel()
        self.lb_about_text.setText(about)
        self.lb_about_text.setOpenExternalLinks(True)
        self.lb_author = QLabel("作者")  # author
        self.lb_author_mail = QLabel(
            "<a href='mailto:[email protected]'>rachpt</a>")
        self.lb_author_mail.setOpenExternalLinks(True)
        self.lb_update = QLabel("项目")  # 更新
        self.lb_update_url = QLabel(project_url)
        self.lb_update_url.setOpenExternalLinks(True)
        self.buttonBox = QDialogButtonBox()
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Close)
        self.buttonBox.button(QDialogButtonBox.Close).setText("关闭")
        self.buttonBox.rejected.connect(self.reject)
        self.buttonBox.setStyleSheet(btn_style)

        self.line = QLine(QPoint(), QPoint(550, 0))
        self.lb_line = QLabel()
        self.lb_line.setText('<html><hr /></html>')

        vbox = QVBoxLayout()
        vbox.addWidget(self.logo)
        vbox.addStretch(1)
        self.form = QFormLayout()
        self.form.setLabelAlignment(Qt.AlignRight)
        self.form.setFormAlignment(Qt.AlignLeft)
        self.form.setHorizontalSpacing(40)
        self.form.setVerticalSpacing(15)
        self.form.addRow(self.lb_name, self.lb_name_text)
        self.form.addRow(self.lb_update, self.lb_update_url)
        self.form.addRow(self.lb_author, self.lb_author_mail)
        self.form.addRow(self.lb_about, self.lb_about_text)
        vbox.addLayout(self.form)
        vbox.addStretch(1)
        vbox.addWidget(self.lb_line)
        donate = QLabel()
        donate.setText("<b>捐助我</b>&nbsp;如果你愿意")
        donate.setAlignment(Qt.AlignCenter)
        hbox = QHBoxLayout()
        hbox.addStretch(2)
        for it in ["wechat", "alipay", "qqpay"]:
            lb = QLabel()
            lb.setPixmap(QPixmap(f"./src/{it}.jpg"))
            hbox.addWidget(lb)
        hbox.addStretch(1)
        hbox.addWidget(self.buttonBox)
        vbox.addWidget(donate)
        vbox.addLayout(hbox)
        self.setLayout(vbox)
        self.setMinimumWidth(720)

    def paintEvent(self, event):
        QDialog.paintEvent(self, event)
        if not self.line.isNull():
            painter = QPainter(self)
            pen = QPen(Qt.red, 3)
            painter.setPen(pen)
            painter.drawLine(self.line)
Beispiel #46
0
class UploadDialog(QDialog):
    """文件上传对话框"""
    new_infos = pyqtSignal(object)

    def __init__(self):
        super().__init__()
        self.cwd = os.getcwd()
        self._folder_id = -1
        self._folder_name = "LanZouCloud"
        self.set_pwd = False
        self.set_desc = False
        self.pwd = ''
        self.desc = ''
        self.allow_big_file = False
        self.max_size = 100
        self.selected = []
        self.initUI()
        self.set_size()
        self.setStyleSheet(dialog_qss_style)

    def set_pwd_desc_bigfile(self, set_pwd, pwd, set_desc, desc,
                             allow_big_file, max_size):
        self.set_pwd = set_pwd
        self.set_desc = set_desc
        self.pwd = pwd
        self.desc = desc
        self.allow_big_file = allow_big_file
        self.max_size = max_size
        if self.allow_big_file:
            self.btn_chooseMultiFile.setToolTip("")
        else:
            self.btn_chooseMultiFile.setToolTip(f"文件大小上线 {self.max_size}MB")

    def set_values(self, folder_name, folder_id, files):
        self.setWindowTitle("上传文件至 ➩ " + str(folder_name))
        self._folder_id = folder_id
        self._folder_name = folder_name
        if files:
            self.selected = files
            self.show_selected()
        self.exec()

    def initUI(self):
        self.setWindowTitle("上传文件")
        self.setWindowIcon(QIcon("./src/upload.ico"))
        self.logo = QLabel()
        self.logo.setPixmap(QPixmap("./src/logo3.gif"))
        self.logo.setStyleSheet("background-color:rgb(0,153,255);")
        self.logo.setAlignment(Qt.AlignCenter)

        # btn 1
        self.btn_chooseDir = QPushButton("选择文件夹", self)
        self.btn_chooseDir.setObjectName("btn_chooseDir")
        self.btn_chooseDir.setObjectName("btn_chooseDir")
        self.btn_chooseDir.setIcon(QIcon("./src/folder.gif"))

        # btn 2
        self.btn_chooseMultiFile = QPushButton("选择多文件", self)
        self.btn_chooseDir.setObjectName("btn_chooseMultiFile")
        self.btn_chooseMultiFile.setObjectName("btn_chooseMultiFile")
        self.btn_chooseMultiFile.setIcon(QIcon("./src/file.ico"))

        # btn 3
        self.btn_deleteSelect = QPushButton("移除", self)
        self.btn_deleteSelect.setObjectName("btn_deleteSelect")
        self.btn_deleteSelect.setIcon(QIcon("./src/delete.ico"))
        self.btn_deleteSelect.setToolTip("按 Delete 移除选中文件")

        # 列表
        self.list_view = MyListView()
        self.list_view.drop_files.connect(self.add_drop_files)
        self.list_view.setViewMode(QListView.ListMode)
        self.slm = QStandardItem()
        self.model = QStandardItemModel()
        self.list_view.setModel(self.model)
        self.model.removeRows(0, self.model.rowCount())  # 清除旧的选择
        self.list_view.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.list_view.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.list_view.setSelectionMode(QAbstractItemView.ExtendedSelection)

        self.buttonBox = QDialogButtonBox()
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Ok
                                          | QDialogButtonBox.Cancel)
        self.buttonBox.button(QDialogButtonBox.Ok).setText("确定")
        self.buttonBox.button(QDialogButtonBox.Cancel).setText("取消")

        vbox = QVBoxLayout()
        hbox_head = QHBoxLayout()
        hbox_button = QHBoxLayout()
        hbox_head.addWidget(self.btn_chooseDir)
        hbox_head.addStretch(1)
        hbox_head.addWidget(self.btn_chooseMultiFile)
        hbox_button.addWidget(self.btn_deleteSelect)
        hbox_button.addStretch(1)
        hbox_button.addWidget(self.buttonBox)
        vbox.addWidget(self.logo)
        vbox.addLayout(hbox_head)
        vbox.addWidget(self.list_view)
        vbox.addLayout(hbox_button)
        self.setLayout(vbox)
        self.setMinimumWidth(350)

        # 设置信号
        self.btn_chooseDir.clicked.connect(self.slot_btn_chooseDir)
        self.btn_chooseMultiFile.clicked.connect(self.slot_btn_chooseMultiFile)
        self.btn_deleteSelect.clicked.connect(self.slot_btn_deleteSelect)

        self.buttonBox.accepted.connect(self.slot_btn_ok)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.clear_old)
        self.buttonBox.rejected.connect(self.reject)

    def set_size(self):
        if self.selected:
            h = 18 if len(self.selected) > 18 else 10
            w = 40
            for i in self.selected:
                i_len = len(i)
                if i_len > 100:
                    w = 100
                    break
                if i_len > w:
                    w = i_len
            self.resize(120 + w * 7, h * 30)
        else:
            self.resize(400, 300)

    def clear_old(self):
        self.selected = []
        self.model.removeRows(0, self.model.rowCount())
        self.set_size()

    def show_selected(self):
        self.model.removeRows(0, self.model.rowCount())
        for item in self.selected:
            if os.path.isfile(item):
                self.model.appendRow(
                    QStandardItem(QIcon("./src/file.ico"), item))
            else:
                self.model.appendRow(
                    QStandardItem(QIcon("./src/folder.gif"), item))
            self.set_size()

    def backslash(self):
        """Windows backslash"""
        tasks = {}
        for item in self.selected:
            furl = os.path.normpath(item)
            tasks[furl] = UpJob(furl=furl,
                                id=self._folder_id,
                                folder=self._folder_name,
                                set_pwd=self.set_pwd,
                                pwd=self.pwd,
                                set_desc=self.set_desc,
                                desc=self.desc)
        return tasks

    def slot_btn_ok(self):
        tasks = self.backslash()
        if self.selected:
            self.new_infos.emit(tasks)
            self.clear_old()

    def slot_btn_deleteSelect(self):
        _indexes = self.list_view.selectionModel().selection().indexes()
        if not _indexes:
            return
        indexes = []
        for i in _indexes:  # 获取所选行号
            indexes.append(i.row())
        indexes = set(indexes)
        for i in sorted(indexes, reverse=True):
            self.selected.remove(self.model.item(i, 0).text())
            self.model.removeRow(i)
        self.set_size()

    def add_drop_files(self, files):
        for item in files:
            if item not in self.selected:
                self.selected.append(item)
            self.show_selected()

    def slot_btn_chooseDir(self):
        dir_choose = QFileDialog.getExistingDirectory(self, "选择文件夹",
                                                      self.cwd)  # 起始路径
        if dir_choose == "":
            return
        if dir_choose not in self.selected:
            self.selected.append(dir_choose)
        self.show_selected()

    def slot_btn_chooseMultiFile(self):
        files, _ = QFileDialog.getOpenFileNames(self, "选择多文件", self.cwd,
                                                "All Files (*)")
        if len(files) == 0:
            return
        for _file in files:
            if _file not in self.selected:
                if os.path.getsize(_file) <= self.max_size * 1048576:
                    self.selected.append(_file)
                elif self.allow_big_file:
                    self.selected.append(_file)
        self.show_selected()

    def keyPressEvent(self, e):
        if e.key() == Qt.Key_Delete:  # delete
            self.slot_btn_deleteSelect()
Beispiel #47
0
    def initUI(self):
        self.setWindowTitle("设置")
        logo = QLabel()  # logo
        logo.setPixmap(QPixmap("./src/logo2.gif"))
        logo.setStyleSheet("background-color:rgb(255,255,255);")
        logo.setAlignment(Qt.AlignCenter)
        self.download_threads_lb = QLabel("同时下载文件数")  # about
        self.download_threads_var = QLineEdit()
        self.download_threads_var.setPlaceholderText("范围:1-9")
        self.download_threads_var.setToolTip("范围:1-9")
        self.download_threads_var.setInputMask("D")
        self.max_size_lb = QLabel("分卷大小(MB)")
        self.max_size_var = QLineEdit()
        self.max_size_var.setPlaceholderText("普通用户最大100,vip用户根据具体情况设置")
        self.max_size_var.setToolTip("普通用户最大100,vip用户根据具体情况设置")
        self.max_size_var.setInputMask("D99")
        self.timeout_lb = QLabel("请求超时(秒)")
        self.timeout_var = QLineEdit()
        self.timeout_var.setPlaceholderText("范围:1-99")
        self.timeout_var.setToolTip("范围:1-99")
        self.timeout_var.setInputMask("D9")
        self.dl_path_lb = QLabel("下载保存路径")
        self.dl_path_var = MyLineEdit(self)
        self.dl_path_var.clicked.connect(self.set_download_path)
        self.time_fmt_box = QCheckBox("使用[年-月-日]时间格式")
        self.to_tray_box = QCheckBox("关闭到系统托盘")
        self.time_fmt_box.toggle()
        self.time_fmt_box.stateChanged.connect(self.change_time_fmt)
        self.to_tray_box.stateChanged.connect(self.change_to_tray)

        buttonBox = QDialogButtonBox()
        buttonBox.setOrientation(Qt.Horizontal)
        buttonBox.setStandardButtons(QDialogButtonBox.Reset
                                     | QDialogButtonBox.Save
                                     | QDialogButtonBox.Cancel)
        buttonBox.button(QDialogButtonBox.Reset).setText("重置")
        buttonBox.button(QDialogButtonBox.Save).setText("保存")
        buttonBox.button(QDialogButtonBox.Cancel).setText("取消")
        buttonBox.button(QDialogButtonBox.Reset).clicked.connect(
            lambda: self.set_values(reset=True))
        buttonBox.button(QDialogButtonBox.Save).clicked.connect(self.slot_save)
        buttonBox.rejected.connect(self.reject)

        form = QFormLayout()
        form.setLabelAlignment(Qt.AlignRight)
        form.setSpacing(10)
        form.addRow(self.download_threads_lb, self.download_threads_var)
        form.addRow(self.timeout_lb, self.timeout_var)
        form.addRow(self.max_size_lb, self.max_size_var)
        form.addRow(self.dl_path_lb, self.dl_path_var)

        vbox = QVBoxLayout()
        vbox.addWidget(logo)
        vbox.addStretch(1)
        vbox.addLayout(form)
        vbox.addStretch(1)
        hbox = QHBoxLayout()
        hbox.addWidget(self.time_fmt_box)
        hbox.addWidget(self.to_tray_box)
        vbox.addLayout(hbox)
        vbox.addStretch(1)
        vbox.addWidget(buttonBox)
        self.setLayout(vbox)
        self.setMinimumWidth(500)
Beispiel #48
0
class TorrentAddingDialog(QDialog):
    SELECTION_LABEL_FORMAT = 'Selected {} files ({})'

    def __init__(self, parent: QWidget, filename: str,
                 torrent_info: TorrentInfo,
                 control_thread: 'ControlManagerThread'):
        super().__init__(parent)

        self.app = QApplication.instance()

        self._torrent_filepath = Path(filename)

        self._torrent_info = torrent_info
        download_info = torrent_info.download_info
        self._control_thread = control_thread
        self._control = control_thread.control

        vbox = QVBoxLayout(self)

        self._download_dir = self.get_directory(
            self._control.last_download_dir)

        vbox.addWidget(QLabel('Download directory:'))
        vbox.addWidget(self._get_directory_browse_widget())

        vbox.addWidget(QLabel('Announce URLs:'))

        url_tree = QTreeWidget()
        url_tree.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel)
        url_tree.header().close()
        vbox.addWidget(url_tree)
        for i, tier in enumerate(torrent_info.announce_list):
            tier_item = QTreeWidgetItem(url_tree)
            tier_item.setText(0, 'Tier {}'.format(i + 1))
            for url in tier:
                url_item = QTreeWidgetItem(tier_item)
                url_item.setText(0, url)
        url_tree.expandAll()
        vbox.addWidget(url_tree, 1)

        file_tree = QTreeWidget()
        file_tree.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel)
        file_tree.setHeaderLabels(('Name', 'Size'))
        file_tree.header().setSectionResizeMode(0,
                                                QHeaderView.ResizeToContents)
        self._file_items = []
        self._traverse_file_tree(download_info.suggested_name,
                                 download_info.file_tree, file_tree)
        file_tree.sortItems(0, Qt.AscendingOrder)
        file_tree.expandAll()
        file_tree.itemClicked.connect(self._update_checkboxes)
        vbox.addWidget(file_tree, 3)

        self._selection_label = QLabel(
            TorrentAddingDialog.SELECTION_LABEL_FORMAT.format(
                len(download_info.files),
                humanize_size(download_info.total_size)))
        vbox.addWidget(self._selection_label)

        self._ipfsadd_checkbox = QCheckBox(
            'Import files to IPFS when download is complete')
        self._ipfsadd_checkbox.setCheckState(Qt.Unchecked)
        # vbox.addWidget(self._ipfsadd_checkbox)

        self._button_box = QDialogButtonBox(self)
        self._button_box.setOrientation(Qt.Horizontal)
        self._button_box.setStandardButtons(QDialogButtonBox.Cancel
                                            | QDialogButtonBox.Ok)
        self._button_box.button(QDialogButtonBox.Ok).clicked.connect(
            self.submit_torrent)
        self._button_box.button(QDialogButtonBox.Cancel).clicked.connect(
            self.close)
        vbox.addWidget(self._button_box)

        self.setWindowTitle('Add Torrent')

        self.setMinimumSize(
            QSize(self.app.desktopGeometry.width() / 3,
                  (2 * self.app.desktopGeometry.height()) / 3))

    def get_directory(self, directory: Optional[str]):
        dlPath = Path(self.app.settingsMgr.downloadsDir)
        downloadsDir = dlPath.joinpath('torrent')
        return directory if directory is not None else str(downloadsDir)

    def _traverse_file_tree(self, name: str, node: FileTreeNode,
                            parent: QWidget):
        item = QTreeWidgetItem(parent)
        item.setCheckState(0, Qt.Checked)
        item.setText(0, name)
        if isinstance(node, FileInfo):
            item.setText(1, humanize_size(node.length))
            item.setIcon(0, getMimeIcon('unknown'))
            self._file_items.append((node, item))
            return

        item.setIcon(0, getIcon('folder-open.png'))
        for name, child in node.items():
            self._traverse_file_tree(name, child, item)

    def _get_directory_browse_widget(self):
        widget = QWidget()
        hbox = QHBoxLayout(widget)
        hbox.setContentsMargins(0, 0, 0, 0)

        self._path_edit = QLineEdit(self._download_dir)
        self._path_edit.setReadOnly(True)
        hbox.addWidget(self._path_edit, 3)

        browse_button = QPushButton('Browse...')
        browse_button.clicked.connect(self._browse)
        hbox.addWidget(browse_button, 1)

        widget.setLayout(hbox)
        return widget

    def _browse(self):
        new_download_dir = QFileDialog.getExistingDirectory(
            self, 'Select download directory', self._download_dir)
        if not new_download_dir:
            return

        self._download_dir = new_download_dir
        self._path_edit.setText(new_download_dir)

    def _set_check_state_to_tree(self, item: QTreeWidgetItem,
                                 check_state: Qt.CheckState):
        for i in range(item.childCount()):
            child = item.child(i)
            child.setCheckState(0, check_state)
            self._set_check_state_to_tree(child, check_state)

    def _update_checkboxes(self, item: QTreeWidgetItem, column: int):
        if column != 0:
            return

        new_check_state = item.checkState(0)
        self._set_check_state_to_tree(item, new_check_state)

        while True:
            item = item.parent()
            if item is None:
                break

            has_checked_children = False
            has_partially_checked_children = False
            has_unchecked_children = False
            for i in range(item.childCount()):
                state = item.child(i).checkState(0)
                if state == Qt.Checked:
                    has_checked_children = True
                elif state == Qt.PartiallyChecked:
                    has_partially_checked_children = True
                else:
                    has_unchecked_children = True

            if not has_partially_checked_children and \
                    not has_unchecked_children:
                new_state = Qt.Checked
            elif has_checked_children or has_partially_checked_children:
                new_state = Qt.PartiallyChecked
            else:
                new_state = Qt.Unchecked
            item.setCheckState(0, new_state)

        self._update_selection_label()

    def _update_selection_label(self):
        selected_file_count = 0
        selected_size = 0
        for node, item in self._file_items:
            if item.checkState(0) == Qt.Checked:
                selected_file_count += 1
                selected_size += node.length

        ok_button = self._button_box.button(QDialogButtonBox.Ok)
        if not selected_file_count:
            ok_button.setEnabled(False)
            self._selection_label.setText('Nothing to download')
        else:
            ok_button.setEnabled(True)
            self._selection_label.setText(
                TorrentAddingDialog.SELECTION_LABEL_FORMAT.format(
                    selected_file_count, humanize_size(selected_size)))

    def submit_torrent(self):
        p = Path(self._download_dir)
        try:
            name = self._torrent_filepath.name.replace('.torrent', '')
            pFinal = p.joinpath(name)
            pFinal.mkdir(parents=True, exist_ok=True)
            self._torrent_info.download_dir = str(pFinal)
        except Exception:
            messageBox('Cannot create torrent destination directory')
            return

        self._control.last_download_dir = os.path.abspath(self._download_dir)

        file_paths = []
        for node, item in self._file_items:
            if item.checkState(0) == Qt.Checked:
                file_paths.append(node.path)

        if not self._torrent_info.download_info.single_file_mode:
            self._torrent_info.download_info.select_files(
                file_paths, 'whitelist')

        if self._ipfsadd_checkbox.checkState() == Qt.Checked:
            log.debug('Importing torrent to IPFS when complete')
            self._torrent_info.ipfsImportWhenComplete = True

        self._control_thread.loop.call_soon_threadsafe(self._control.add,
                                                       self._torrent_info)

        self.close()
Beispiel #49
0
class InfoDialog(QDialog):
    """文件信息对话框"""

    get_dl_link = pyqtSignal(str, str)

    def __init__(self, parent=None):
        super().__init__(parent)
        self.infos = None
        self.initUI()
        self.setStyleSheet(dialog_qss_style)

    def update_ui(self):
        self.tx_dl_link.setPlaceholderText("单击获取")
        self.tx_name.setText(self.infos[1])
        if self.infos[2]:
            self.setWindowTitle("文件信息")
            self.lb_name.setText("文件名:")
            self.lb_desc.setText("文件描述:")
            self.tx_dl_link.setText("")  # 清空旧的信息
            self.lb_dl_link.setVisible(True)
            self.tx_dl_link.setVisible(True)
        else:
            self.setWindowTitle("文件夹信息")
            self.lb_name.setText("文件夹名:")
            self.lb_desc.setText("文件夹描述:")
            self.lb_dl_link.setVisible(False)
            self.tx_dl_link.setVisible(False)

        if self.infos[2]:
            self.tx_size.setText(self.infos[2])
            self.lb_size.setVisible(True)
            self.tx_size.setVisible(True)
        else:
            self.tx_size.setVisible(False)
            self.lb_size.setVisible(False)

        if self.infos[3]:
            self.lb_time.setVisible(True)
            self.tx_time.setVisible(True)
            self.tx_time.setText(self.infos[3])
        else:
            self.lb_time.setVisible(False)
            self.tx_time.setVisible(False)

        if self.infos[4]:
            self.lb_dl_count.setVisible(True)
            self.tx_dl_count.setVisible(True)
            self.tx_dl_count.setText(str(self.infos[4]))
        else:
            self.tx_dl_count.setVisible(False)
            self.lb_dl_count.setVisible(False)

        if self.infos[5]:
            self.tx_pwd.setText(self.infos[5])
            self.tx_pwd.setPlaceholderText("")
        else:
            self.tx_pwd.setText("")
            self.tx_pwd.setPlaceholderText("无")

        if self.infos[6]:
            self.tx_desc.setText(self.infos[6])
            self.tx_desc.setPlaceholderText("")
        else:
            self.tx_desc.setText("")
            self.tx_desc.setPlaceholderText("无")

        self.tx_share_url.setText(self.infos[7])

    def set_values(self, infos):
        self.infos = infos
        self.update_ui()
        self.exec()

    def call_get_dl_link(self):
        url = self.tx_share_url.text()
        pwd = self.tx_pwd.text()
        self.get_dl_link.emit(url, pwd)
        self.tx_dl_link.setPlaceholderText("后台获取中,请稍后!")

    def initUI(self):
        self.setWindowIcon(QIcon("./src/share.ico"))
        self.setWindowTitle("文件信息")
        self.buttonBox = QDialogButtonBox()
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Close)
        self.buttonBox.button(QDialogButtonBox.Close).setText("关闭")
        self.buttonBox.rejected.connect(self.reject)

        self.logo = QLabel()
        self.logo.setPixmap(QPixmap("./src/q9.gif"))
        self.logo.setAlignment(Qt.AlignCenter)
        self.logo.setStyleSheet("background-color:rgb(255,204,51);")

        self.lb_name = QLabel()
        self.lb_name.setText("文件名:")
        self.tx_name = QLineEdit()
        self.tx_name.setReadOnly(True)

        self.lb_size = QLabel()
        self.lb_size.setText("文件大小:")
        self.tx_size = QLabel()

        self.lb_time = QLabel()
        self.lb_time.setText("上传时间:")
        self.tx_time = QLabel()

        self.lb_dl_count = QLabel()
        self.lb_dl_count.setText("下载次数:")
        self.tx_dl_count = QLabel()

        self.lb_share_url = QLabel()
        self.lb_share_url.setText("分享链接:")
        self.tx_share_url = QLineEdit()
        self.tx_share_url.setReadOnly(True)

        self.lb_pwd = QLabel()
        self.lb_pwd.setText("提取码:")
        self.tx_pwd = QLineEdit()
        self.tx_pwd.setReadOnly(True)

        self.lb_desc = QLabel()
        self.lb_desc.setText("文件描述:")
        self.tx_desc = AutoResizingTextEdit()
        self.tx_desc.setReadOnly(True)

        self.lb_dl_link = QLabel()
        self.lb_dl_link.setText("下载直链:")
        self.tx_dl_link = AutoResizingTextEdit(self)
        self.tx_dl_link.setPlaceholderText("单击获取")
        self.tx_dl_link.clicked.connect(self.call_get_dl_link)
        self.tx_dl_link.setReadOnly(True)

        vbox = QVBoxLayout()
        vbox.addWidget(self.logo)
        vbox.addStretch(1)
        form = QFormLayout()
        form.setLabelAlignment(Qt.AlignRight)
        form.addRow(self.lb_name, self.tx_name)
        form.addRow(self.lb_size, self.tx_size)
        form.addRow(self.lb_time, self.tx_time)
        form.addRow(self.lb_dl_count, self.tx_dl_count)
        form.addRow(self.lb_share_url, self.tx_share_url)
        form.addRow(self.lb_pwd, self.tx_pwd)
        form.addRow(self.lb_desc, self.tx_desc)
        form.addRow(self.lb_dl_link, self.tx_dl_link)
        vbox.addLayout(form)
        vbox.addStretch(1)
        vbox.addWidget(self.buttonBox)

        self.setLayout(vbox)
Beispiel #50
0
    def showDialog(self, currentCard=None):
        if currentCard:
            did = currentCard.did
        else:
            did = mw._selectedDeck()['id']

        cardInfo = self._getCardInfo(did)
        if not cardInfo:
            showInfo('Please select an Incremental Reading deck.')
            return

        dialog = QDialog(mw)
        layout = QVBoxLayout()
        self.cardListWidget = QListWidget()
        self.cardListWidget.setAlternatingRowColors(True)
        self.cardListWidget.setSelectionMode(
            QAbstractItemView.ExtendedSelection)
        self.cardListWidget.setWordWrap(True)

        posWidth = len(str(len(cardInfo) + 1))
        for i, card in enumerate(cardInfo, start=1):
            text = '❰ {} ❱\t{}'.format(
                str(i).zfill(posWidth), stripHTML(card['title']))
            item = QListWidgetItem(text)
            item.setData(Qt.UserRole, card)
            self.cardListWidget.addItem(item)

        upButton = QPushButton('Up')
        upButton.clicked.connect(self._moveUp)
        downButton = QPushButton('Down')
        downButton.clicked.connect(self._moveDown)
        topButton = QPushButton('Top')
        topButton.clicked.connect(self._moveToTop)
        bottomButton = QPushButton('Bottom')
        bottomButton.clicked.connect(self._moveToBottom)
        randomizeButton = QPushButton('Randomize')
        randomizeButton.clicked.connect(self._randomize)

        controlsLayout = QHBoxLayout()
        controlsLayout.addWidget(topButton)
        controlsLayout.addWidget(upButton)
        controlsLayout.addWidget(downButton)
        controlsLayout.addWidget(bottomButton)
        controlsLayout.addStretch()
        controlsLayout.addWidget(randomizeButton)

        buttonBox = QDialogButtonBox(QDialogButtonBox.Close
                                     | QDialogButtonBox.Save)
        buttonBox.accepted.connect(dialog.accept)
        buttonBox.rejected.connect(dialog.reject)
        buttonBox.setOrientation(Qt.Horizontal)

        layout.addLayout(controlsLayout)
        layout.addWidget(self.cardListWidget)
        layout.addWidget(buttonBox)

        dialog.setLayout(layout)
        dialog.setWindowModality(Qt.WindowModal)
        dialog.resize(500, 500)
        choice = dialog.exec_()

        if choice == 1:
            cids = []
            for i in range(self.cardListWidget.count()):
                card = self.cardListWidget.item(i).data(Qt.UserRole)
                cids.append(card['id'])

            self.reorder(cids)
Beispiel #51
0
class SetPwdDialog(QDialog):
    new_infos = pyqtSignal(object)

    def __init__(self, parent=None):
        super(SetPwdDialog, self).__init__(parent)
        self.infos = None
        self.initUI()
        self.update_text()
        self.setStyleSheet(dialog_qss_style)

    def set_values(self, infos):
        self.infos = infos
        self.update_text()  # 更新界面

    def set_tip(self):  # 用于提示状态
        self.setWindowTitle("请稍等……")

    def initUI(self):
        self.setWindowTitle("请稍等……")
        self.setWindowIcon(QIcon("./src/password.ico"))
        self.lb_oldpwd = QLabel()
        self.lb_oldpwd.setText("当前提取码:")
        self.lb_oldpwd.setAlignment(Qt.AlignRight | Qt.AlignTrailing
                                    | Qt.AlignVCenter)
        self.tx_oldpwd = QLineEdit()
        # 当前提取码 只读
        self.tx_oldpwd.setFocusPolicy(Qt.NoFocus)
        self.tx_oldpwd.setReadOnly(True)
        self.lb_newpwd = QLabel()
        self.lb_newpwd.setText("新的提取码:")
        self.lb_newpwd.setAlignment(Qt.AlignRight | Qt.AlignTrailing
                                    | Qt.AlignVCenter)
        self.tx_newpwd = QLineEdit()

        self.buttonBox = QDialogButtonBox()
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Ok
                                          | QDialogButtonBox.Cancel)
        self.buttonBox.button(QDialogButtonBox.Ok).setText("确定")
        self.buttonBox.button(QDialogButtonBox.Cancel).setText("取消")

        self.grid = QGridLayout()
        self.grid.setSpacing(10)
        self.grid.addWidget(self.lb_oldpwd, 1, 0)
        self.grid.addWidget(self.tx_oldpwd, 1, 1)
        self.grid.addWidget(self.lb_newpwd, 2, 0)
        self.grid.addWidget(self.tx_newpwd, 2, 1)
        self.grid.addWidget(self.buttonBox, 3, 0, 1, 2)
        self.setLayout(self.grid)
        self.buttonBox.accepted.connect(self.btn_ok)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.accepted.connect(self.set_tip)
        self.buttonBox.rejected.connect(self.reject)
        self.buttonBox.rejected.connect(self.set_tip)
        self.setMinimumWidth(280)

    def update_text(self):
        if self.infos:
            if self.infos[5]:
                self.tx_oldpwd.setText(str(self.infos[5]))
                self.tx_oldpwd.setPlaceholderText("")
            else:
                self.tx_oldpwd.setText("")
                self.tx_oldpwd.setPlaceholderText("无")

            if self.infos[2]:  # 文件  通过size列判断是否为文件
                self.setWindowTitle("修改文件提取码")
                self.tx_newpwd.setPlaceholderText("2-6位字符,关闭请留空")
                self.tx_newpwd.setMaxLength(6)  # 最长6个字符
            else:  # 文件夹
                self.setWindowTitle("修改文件夹名提取码")
                self.tx_newpwd.setPlaceholderText("2-12位字符,关闭请留空")
                self.tx_newpwd.setMaxLength(12)  # 最长12个字符

    def btn_ok(self):
        new_pwd = self.tx_newpwd.text()
        if new_pwd != self.infos[5]:
            self.new_infos.emit(
                (self.infos[0], new_pwd, self.infos[2]))  # 最后一位用于标示文件还是文件夹
Beispiel #52
0
class RenameDialog(QDialog):
    out = pyqtSignal(object)

    def __init__(self, parent=None):
        super(RenameDialog, self).__init__(parent)
        self.infos = None
        self.min_width = 400
        self.initUI()
        self.update_text()
        self.setStyleSheet(dialog_qss_style)

    def set_values(self, infos):
        self.infos = infos
        self.update_text()  # 更新界面

    def initUI(self):
        self.setWindowIcon(QIcon("./icon/desc.ico"))
        self.lb_name = QLabel()
        self.lb_name.setText("文件夹名:")
        self.lb_name.setAlignment(Qt.AlignRight | Qt.AlignTrailing
                                  | Qt.AlignVCenter)
        self.tx_name = QLineEdit()
        self.lb_desc = QLabel()
        self.tx_desc = QTextEdit()
        self.lb_desc.setText("描  述:")
        self.lb_desc.setAlignment(Qt.AlignRight | Qt.AlignTrailing
                                  | Qt.AlignVCenter)

        self.buttonBox = QDialogButtonBox()
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Ok
                                          | QDialogButtonBox.Cancel)

        self.grid = QGridLayout()
        self.grid.setSpacing(10)
        self.grid.addWidget(self.lb_name, 1, 0)
        self.grid.addWidget(self.tx_name, 1, 1)
        self.grid.addWidget(self.lb_desc, 2, 0)
        self.grid.addWidget(self.tx_desc, 2, 1, 5, 1)
        self.grid.addWidget(self.buttonBox, 7, 1, 1, 1)
        self.setLayout(self.grid)
        self.buttonBox.accepted.connect(self.btn_ok)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)

    def update_text(self):
        if self.infos:
            self.setWindowTitle("修改文件夹名与描述")
            self.tx_name.setText(str(self.infos[1]))
            if self.infos[6]:
                self.tx_desc.setText("")
                self.tx_desc.setPlaceholderText(str(self.infos[6]))
            else:
                self.tx_desc.setPlaceholderText("无")
            self.min_width = len(str(self.infos[1])) * 8
            if self.infos[2]:  # 文件无法重命名,由 infos[2] size表示文件
                self.setWindowTitle("修改文件描述")
                self.tx_name.setFocusPolicy(Qt.NoFocus)
                self.tx_name.setReadOnly(True)
            else:
                self.tx_name.setFocusPolicy(Qt.StrongFocus)
                self.tx_name.setReadOnly(False)

        else:
            self.setWindowTitle("新建文件夹")
            self.tx_name.setText("")
            self.tx_name.setFocusPolicy(Qt.StrongFocus)
            self.tx_name.setReadOnly(False)
            self.tx_desc.setPlaceholderText("可选项,建议160字数以内。")
        if self.min_width < 400:
            self.min_width = 400
        self.resize(self.min_width, 200)

    def btn_ok(self):
        new_name = self.tx_name.text()
        new_desc = self.tx_desc.toPlainText()
        if not self.infos and new_name:  # 在 work_id 新建文件夹
            self.out.emit(("new", "", new_name, new_desc))
            return
        if new_name != self.infos[1] or (new_desc
                                         and new_desc != self.infos[6]):
            if self.infos[2]:  # 文件
                self.out.emit(("file", self.infos[0], new_name, new_desc))
            else:
                self.out.emit(("folder", self.infos[0], new_name, new_desc))
Beispiel #53
0
class ExportPanel(Panel):
    FIELDS = []
    PERSISTENT_NAME = 'exportPanel'

    def __init__(self, model, mainwindow):
        Panel.__init__(self, mainwindow)
        self.setAttribute(Qt.WA_DeleteOnClose)
        self.mainwindow = mainwindow
        self._setupUi()
        self.model = model
        self.accountTable = ExportAccountTable(model=self.model.account_table,
                                               view=self.tableView)

        self.exportTypeButtons.buttonClicked[int].connect(
            self.exportTypeSelected)
        self.exportFormatButtons.buttonClicked[int].connect(
            self.exportFormatSelected)
        self.buttonBox.rejected.connect(self.reject)
        self.exportButton.clicked.connect(self.exportButtonClicked)

    def _setupUi(self):
        self.setWindowTitle(tr("Export Options"))
        self.mainLayout = QVBoxLayout(self)

        self.label1 = QLabel(tr("Which accounts do you want to export?"), self)
        self.mainLayout.addWidget(self.label1)
        self.exportTypeButtons = QButtonGroup(self)
        self.exportAllButton = QRadioButton(tr("All"), self)
        self.mainLayout.addWidget(self.exportAllButton)
        self.exportTypeButtons.addButton(self.exportAllButton, ExportType.All)
        self.exportAllButton.setChecked(True)
        self.exportSelectedButton = QRadioButton(tr("Selected"), self)
        self.mainLayout.addWidget(self.exportSelectedButton)
        self.exportTypeButtons.addButton(self.exportSelectedButton,
                                         ExportType.Selected)

        self.tableView = QTableView(self)
        self.tableView.setSelectionMode(QAbstractItemView.SingleSelection)
        self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.tableView.verticalHeader().setVisible(False)
        self.tableView.verticalHeader().setDefaultSectionSize(18)
        self.mainLayout.addWidget(self.tableView)

        self.label2 = QLabel(tr("Export format:"), self)
        self.mainLayout.addWidget(self.label2)
        self.exportFormatButtons = QButtonGroup(self)
        self.exportAsQIFButton = QRadioButton("QIF", self)
        self.mainLayout.addWidget(self.exportAsQIFButton)
        self.exportFormatButtons.addButton(self.exportAsQIFButton,
                                           ExportFormat.QIF)
        self.exportAsQIFButton.setChecked(True)
        self.exportAsCSVButton = QRadioButton("CSV", self)
        self.mainLayout.addWidget(self.exportAsCSVButton)
        self.exportFormatButtons.addButton(self.exportAsCSVButton,
                                           ExportFormat.CSV)

        self.label3 = QLabel(tr("Export scope:"))
        self.mainLayout.addWidget(self.label3)
        self.dateRangeOnlyCheckbox = QCheckBox(tr("Current date range only"))
        self.mainLayout.addWidget(self.dateRangeOnlyCheckbox)

        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel)
        self.exportButton = self.buttonBox.addButton(
            tr("Export"), QDialogButtonBox.ActionRole)
        self.mainLayout.addWidget(self.buttonBox)

    # --- Overrides
    def _loadFields(self):
        self.exportAllButton.setChecked(self.model.export_all)
        self.exportAsQIFButton.setChecked(
            self.model.export_format == ExportFormat.QIF)
        self.dateRangeOnlyCheckbox.setChecked(
            self.model.current_daterange_only)

    def _saveFields(self):
        self.model.current_daterange_only = self.dateRangeOnlyCheckbox.isChecked(
        )

    # --- Event Handlers
    def exportButtonClicked(self):
        title = tr("Export")
        fileext = 'qif' if self.model.export_format == ExportFormat.QIF else 'csv'
        filters = tr("{0} Files (*.{1})").format(fileext.upper(), fileext)
        filename = 'export.{0}'.format(fileext)
        docpath = QFileDialog.getSaveFileName(self.mainwindow, title, filename,
                                              filters)[0]
        if docpath:
            self.model.export_path = docpath
            self.accept()

    def exportTypeSelected(self, typeId):
        self.model.export_all = typeId == ExportType.All

    def exportFormatSelected(self, typeId):
        self.model.export_format = typeId

    # --- model --> view
    def set_table_enabled(self, enabled):
        self.tableView.setEnabled(enabled)

    def set_export_button_enabled(self, enabled):
        self.exportButton.setEnabled(enabled)
Beispiel #54
0
class CityListDlg(QDialog):
    citieslist_signal = pyqtSignal([list])

    def __init__(self, citylist, accurate_url, appid, parent=None):
        super(CityListDlg, self).__init__(parent)
        self.citylist = citylist
        self.accurate_url = accurate_url
        self.appid = appid
        self.listWidget = QListWidget()
        self.listWidget.addItems(self.citylist)
        buttonLayout = QVBoxLayout()
        self.buttonBox = QDialogButtonBox()
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        self.buttonBox.rejected.connect(self.reject)
        self.buttonBox.accepted.connect(self.accept)
        layoutT = QVBoxLayout()
        layout = QHBoxLayout()
        layout.addWidget(self.listWidget)
        layout.addLayout(buttonLayout)
        for text, slot in ((self.tr("&Add..."), self.add),
                           (self.tr("&Remove..."), self.remove),
                           (self.tr("&Up"), self.up),
                           (self.tr("&Down"), self.down),
                           (self.tr("De&fault"), self.default),
                           (self.tr("&Sort"), self.listWidget.sortItems)):
            button = QPushButton(text)
            buttonLayout.addWidget(button)
            button.clicked.connect(slot)
        buttonLayout.addWidget(self.buttonBox)
        self.status = QLabel()
        layoutT.addLayout(layout)
        layoutT.addWidget(self.status)
        self.setLayout(layoutT)
        self.checklength()

    def add(self):
        self.status.setText('')
        lista = []
        newitem = ''
        self.citytoadd = ''
        self.countrytoadd = ''
        self._idtoadd = ''
        dialog = searchcity.SearchCity(self.accurate_url, self.appid, self)
        dialog.id_signal.connect(self.addcity)
        dialog.city_signal.connect(self.addcity)
        dialog.country_signal.connect(self.addcity)
        if dialog.exec_() == 1:
            newitem = (self.citytoadd + '_' + self.countrytoadd + '_' +
                       self._idtoadd)
            for row in range(self.listWidget.count()):
                lista.append(self.listWidget.item(row).text())
            if newitem in lista:
                self.status.setText(QCoreApplication.translate('Status bar message',
                                    'The city already exists in the list', 'Cities list dialogue'))
                return
            else:
                self.listWidget.addItem(newitem)
                self.checklength()

    def addcity(self, what):
        self.status.setText('')
        if what[0] == 'ID':
            self._idtoadd = what[1]
        elif what[0] == 'City':
            self.citytoadd = what[1]
        elif what[0] == 'Country':
            self.countrytoadd = what[1]

    def remove(self):
        self.status.setText('')
        if self.listWidget.count() == 0:
            self.status.setText(self.tr('The list is empty'))
            return
        row = self.listWidget.currentRow()
        item = self.listWidget.item(row)
        if item is None:
            return
        message = self.tr('The city "{0}" has been removed').format(
            self.listWidget.item(row).text())
        item = self.listWidget.takeItem(row)
        del item
        self.status.setText(message)

    def up(self):
        self.status.setText('')
        row = self.listWidget.currentRow()
        if row >= 1:
            item = self.listWidget.takeItem(row)
            self.listWidget.insertItem(row - 1, item)
            self.listWidget.setCurrentItem(item)

    def down(self):
        self.status.setText('')
        row = self.listWidget.currentRow()
        if row < self.listWidget.count() - 1:
            item = self.listWidget.takeItem(row)
            self.listWidget.insertItem(row + 1, item)
            self.listWidget.setCurrentItem(item)

    def default(self):
        self.status.setText('')
        row = self.listWidget.currentRow()
        if row >= 1:
            item = self.listWidget.takeItem(row)
            self.listWidget.insertItem(0, item)
            self.listWidget.setCurrentItem(item)

    def checklength(self):
        listtosend = []
        for row in range(self.listWidget.count()):
            listtosend.append(self.listWidget.item(row).text())
        if len(listtosend) == 0:
            return
        self.listWidget.setMinimumWidth(self.listWidget.sizeHintForColumn(0))

    def accept(self):
        listtosend = []
        for row in range(self.listWidget.count()):
            listtosend.append(self.listWidget.item(row).text())
        self.citieslist_signal[list].emit(listtosend)
        QDialog.accept(self)
Beispiel #55
0
class OnkyoSettings(QDialog):
	applied_signal = pyqtSignal()

	def __init__(self, parent=None):
		super(OnkyoSettings, self).__init__(parent)
		self.layout = QVBoxLayout()

		# Host IP
		self.settings = QSettings('onkyoqt', 'settings')
		host = self.settings.value('host') or ''
		self.host_label = QLabel(QCoreApplication.translate('Get it from receiver settings','Receiver IP (Restart needed after change)', 'Settings dialogue'))
		self.host_text = QLineEdit()
		self.host_text.setText(host)
		self.host_text.textChanged.connect(self.host_changed)
		self.nohost_message = QCoreApplication.translate('Warning message after pressing Ok', 'Please enter your receiver IP address', 'Settings dialogue')

		# Hide main window on start to tray or not
		self.hide_label = QLabel(self.tr('Run in tray'))
		self.hide_checkbox = QCheckBox()
		self.hide_bool = self.settings.value('hide') or 'False'
		self.hide_bool = eval(self.hide_bool)
		self.hide_checkbox.setChecked(self.hide_bool)
		self.hide_checkbox.stateChanged.connect(self.hide)
		self.hide_changed = False

		# OK Cancel Apply Buttons
		self.buttonLayout = QHBoxLayout()
		self.buttonLayout.addStretch()
		self.buttonBox = QDialogButtonBox()
		self.buttonBox.setOrientation(Qt.Horizontal)
		self.buttonBox.setStandardButtons(QDialogButtonBox.Ok | QDialogButtonBox.Apply | QDialogButtonBox.Cancel)
		self.buttonBox.setContentsMargins(0, 30, 0, 0)
		self.buttonLayout.addWidget(self.buttonBox)
		self.buttonBox.button(QDialogButtonBox.Apply).clicked.connect(self.apply_settings)
		self.buttonBox.accepted.connect(self.accept)
		self.buttonBox.rejected.connect(self.reject)
		self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(False)
		self.statusbar = QLabel()
		self.layout.addWidget(self.statusbar)

		self.panel = QGridLayout()
		self.panel.addWidget(self.hide_label, 0, 0)
		self.panel.addWidget(self.hide_checkbox, 0, 1)
		self.panel.addWidget(self.host_label, 1, 0)
		self.panel.addWidget(self.host_text, 1, 1)
		self.layout.addLayout(self.panel)
		self.layout.addLayout(self.buttonLayout)
		self.setLayout(self.layout)
		self.setWindowTitle(self.tr('Onkyo QT Configuration'))

	def apply_settings(self):
		self.accepted()

	def host_changed(self):
		self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)

	def accepted(self):
		host = self.host_text.text()
		if host == '':
			self.statusbar.setText(self.nohost_message)
			return
		else:
			self.settings.setValue('host', str(self.host_text.text()))
		self.applied_signal.emit()

		if self.hide_changed:
			self.hide_apply()

	def hide(self, state):
		self.hide_state = state
		self.hide_changed = True
		self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)

	def hide_apply(self):
		if self.hide_state == 2:
			self.settings.setValue('hide', 'True')
		elif self.hide_state == 0:
			self.settings.setValue('hide', 'False')
		else:
			return
Beispiel #56
-1
class ConfigurationWidget(QWidget):
    """
    Class implementing a dialog for the configuration of eric6.
    
    @signal preferencesChanged() emitted after settings have been changed
    @signal masterPasswordChanged(str, str) emitted after the master
        password has been changed with the old and the new password
    @signal accepted() emitted to indicate acceptance of the changes
    @signal rejected() emitted to indicate rejection of the changes
    """
    preferencesChanged = pyqtSignal()
    masterPasswordChanged = pyqtSignal(str, str)
    accepted = pyqtSignal()
    rejected = pyqtSignal()
    
    DefaultMode = 0
    HelpBrowserMode = 1
    TrayStarterMode = 2
    HexEditorMode = 3
    
    def __init__(self, parent=None, fromEric=True, displayMode=DefaultMode,
                 expandedEntries=[]):
        """
        Constructor
        
        @param parent The parent widget of this dialog. (QWidget)
        @keyparam fromEric flag indicating a dialog generation from within the
            eric6 ide (boolean)
        @keyparam displayMode mode of the configuration dialog
            (DefaultMode, HelpBrowserMode, TrayStarterMode, HexEditorMode)
        @exception RuntimeError raised to indicate an invalid dialog mode
        @keyparam expandedEntries list of entries to be shown expanded
            (list of strings)
        """
        assert displayMode in (
            ConfigurationWidget.DefaultMode,
            ConfigurationWidget.HelpBrowserMode,
            ConfigurationWidget.TrayStarterMode,
            ConfigurationWidget.HexEditorMode,
        )
        
        super(ConfigurationWidget, self).__init__(parent)
        self.fromEric = fromEric
        self.displayMode = displayMode
        
        self.__setupUi()
        
        self.itmDict = {}
        
        if not fromEric:
            from PluginManager.PluginManager import PluginManager
            try:
                self.pluginManager = e5App().getObject("PluginManager")
            except KeyError:
                self.pluginManager = PluginManager(self)
                e5App().registerObject("PluginManager", self.pluginManager)
        
        if displayMode == ConfigurationWidget.DefaultMode:
            self.configItems = {
                # key : [display string, pixmap name, dialog module name or
                #        page creation function, parent key,
                #        reference to configuration page (must always be last)]
                # The dialog module must have the module function 'create' to
                # create the configuration page. This must have the method
                # 'save' to save the settings.
                "applicationPage":
                [self.tr("Application"), "preferences-application.png",
                 "ApplicationPage", None, None],
                "cooperationPage":
                [self.tr("Cooperation"), "preferences-cooperation.png",
                 "CooperationPage", None, None],
                "corbaPage":
                [self.tr("CORBA"), "preferences-orbit.png",
                 "CorbaPage", None, None],
                "emailPage":
                [self.tr("Email"), "preferences-mail_generic.png",
                 "EmailPage", None, None],
                "graphicsPage":
                [self.tr("Graphics"), "preferences-graphics.png",
                 "GraphicsPage", None, None],
                "hexEditorPage":
                [self.tr("Hex Editor"), "hexEditor.png",
                 "HexEditorPage", None, None],
                "iconsPage":
                [self.tr("Icons"), "preferences-icons.png",
                 "IconsPage", None, None],
                "ircPage":
                [self.tr("IRC"), "irc.png",
                 "IrcPage", None, None],
                "logViewerPage":
                [self.tr("Log-Viewer"), "preferences-logviewer.png",
                 "LogViewerPage", None, None],
                "mimeTypesPage":
                [self.tr("Mimetypes"), "preferences-mimetypes.png",
                 "MimeTypesPage", None, None],
                "networkPage":
                [self.tr("Network"), "preferences-network.png",
                 "NetworkPage", None, None],
                "notificationsPage":
                [self.tr("Notifications"),
                 "preferences-notifications.png",
                 "NotificationsPage", None, None],
                "pluginManagerPage":
                [self.tr("Plugin Manager"),
                 "preferences-pluginmanager.png",
                 "PluginManagerPage", None, None],
                "printerPage":
                [self.tr("Printer"), "preferences-printer.png",
                 "PrinterPage", None, None],
                "pythonPage":
                [self.tr("Python"), "preferences-python.png",
                 "PythonPage", None, None],
                "qtPage":
                [self.tr("Qt"), "preferences-qtlogo.png",
                 "QtPage", None, None],
                "securityPage":
                [self.tr("Security"), "preferences-security.png",
                 "SecurityPage", None, None],
                "shellPage":
                [self.tr("Shell"), "preferences-shell.png",
                 "ShellPage", None, None],
                "tasksPage":
                [self.tr("Tasks"), "task.png",
                 "TasksPage", None, None],
                "templatesPage":
                [self.tr("Templates"), "preferences-template.png",
                 "TemplatesPage", None, None],
                "trayStarterPage":
                [self.tr("Tray Starter"), "erict.png",
                 "TrayStarterPage", None, None],
                "vcsPage":
                [self.tr("Version Control Systems"),
                 "preferences-vcs.png",
                 "VcsPage", None, None],
                
                "0debuggerPage":
                [self.tr("Debugger"), "preferences-debugger.png",
                 None, None, None],
                "debuggerGeneralPage":
                [self.tr("General"), "preferences-debugger.png",
                 "DebuggerGeneralPage", "0debuggerPage", None],
                "debuggerPythonPage":
                [self.tr("Python"), "preferences-pyDebugger.png",
                 "DebuggerPythonPage", "0debuggerPage", None],
                "debuggerPython3Page":
                [self.tr("Python3"), "preferences-pyDebugger.png",
                 "DebuggerPython3Page", "0debuggerPage", None],
                
                "0editorPage":
                [self.tr("Editor"), "preferences-editor.png",
                 None, None, None],
                "editorAPIsPage":
                [self.tr("APIs"), "preferences-api.png",
                 "EditorAPIsPage", "0editorPage", None],
                "editorAutocompletionPage":
                [self.tr("Autocompletion"),
                 "preferences-autocompletion.png",
                 "EditorAutocompletionPage", "0editorPage", None],
                "editorAutocompletionQScintillaPage":
                [self.tr("QScintilla"), "qscintilla.png",
                 "EditorAutocompletionQScintillaPage",
                 "editorAutocompletionPage", None],
                "editorCalltipsPage":
                [self.tr("Calltips"), "preferences-calltips.png",
                 "EditorCalltipsPage", "0editorPage", None],
                "editorCalltipsQScintillaPage":
                [self.tr("QScintilla"), "qscintilla.png",
                 "EditorCalltipsQScintillaPage", "editorCalltipsPage", None],
                "editorGeneralPage":
                [self.tr("General"), "preferences-general.png",
                 "EditorGeneralPage", "0editorPage", None],
                "editorFilePage":
                [self.tr("Filehandling"),
                 "preferences-filehandling.png",
                 "EditorFilePage", "0editorPage", None],
                "editorSearchPage":
                [self.tr("Searching"), "preferences-search.png",
                 "EditorSearchPage", "0editorPage", None],
                "editorSpellCheckingPage":
                [self.tr("Spell checking"),
                 "preferences-spellchecking.png",
                 "EditorSpellCheckingPage", "0editorPage", None],
                "editorStylesPage":
                [self.tr("Style"), "preferences-styles.png",
                 "EditorStylesPage", "0editorPage", None],
                "editorSyntaxPage":
                [self.tr("Code Checkers"), "preferences-debugger.png",
                 "EditorSyntaxPage", "0editorPage", None],
                "editorTypingPage":
                [self.tr("Typing"), "preferences-typing.png",
                 "EditorTypingPage", "0editorPage", None],
                "editorExportersPage":
                [self.tr("Exporters"), "preferences-exporters.png",
                 "EditorExportersPage", "0editorPage", None],
                
                "1editorLexerPage":
                [self.tr("Highlighters"),
                 "preferences-highlighting-styles.png",
                 None, "0editorPage", None],
                "editorHighlightersPage":
                [self.tr("Filetype Associations"),
                 "preferences-highlighter-association.png",
                 "EditorHighlightersPage", "1editorLexerPage", None],
                "editorHighlightingStylesPage":
                [self.tr("Styles"),
                 "preferences-highlighting-styles.png",
                 "EditorHighlightingStylesPage", "1editorLexerPage", None],
                "editorKeywordsPage":
                [self.tr("Keywords"), "preferences-keywords.png",
                 "EditorKeywordsPage", "1editorLexerPage", None],
                "editorPropertiesPage":
                [self.tr("Properties"), "preferences-properties.png",
                 "EditorPropertiesPage", "1editorLexerPage", None],
                
                "1editorMouseClickHandlers":
                [self.tr("Mouse Click Handlers"),
                 "preferences-mouse-click-handler.png",
                 "EditorMouseClickHandlerPage", "0editorPage", None],
                
                "0helpPage":
                [self.tr("Help"), "preferences-help.png",
                 None, None, None],
                "helpDocumentationPage":
                [self.tr("Help Documentation"),
                 "preferences-helpdocumentation.png",
                 "HelpDocumentationPage", "0helpPage", None],
                "helpViewersPage":
                [self.tr("Help Viewers"),
                 "preferences-helpviewers.png",
                 "HelpViewersPage", "0helpPage", None],
                
                "0projectPage":
                [self.tr("Project"), "preferences-project.png",
                 None, None, None],
                "projectBrowserPage":
                [self.tr("Project Viewer"), "preferences-project.png",
                 "ProjectBrowserPage", "0projectPage", None],
                "projectPage":
                [self.tr("Project"), "preferences-project.png",
                 "ProjectPage", "0projectPage", None],
                "multiProjectPage":
                [self.tr("Multiproject"),
                 "preferences-multiproject.png",
                 "MultiProjectPage", "0projectPage", None],
                
                "0interfacePage":
                [self.tr("Interface"), "preferences-interface.png",
                 None, None, None],
                "interfacePage":
                [self.tr("Interface"), "preferences-interface.png",
                 "InterfacePage", "0interfacePage", None],
                "viewmanagerPage":
                [self.tr("Viewmanager"), "preferences-viewmanager.png",
                 "ViewmanagerPage", "0interfacePage", None],
            }
            try:
                from PyQt5 import QtWebKit      # __IGNORE_WARNING__
                self.configItems.update({
                    "helpAppearancePage":
                    [self.tr("Appearance"), "preferences-styles.png",
                     "HelpAppearancePage", "0helpPage", None],
                    "helpFlashCookieManagerPage":
                    [self.tr("Flash Cookie Manager"),
                     "flashCookie16.png",
                     "HelpFlashCookieManagerPage", "0helpPage", None],
                    "helpVirusTotalPage":
                    [self.tr("VirusTotal Interface"), "virustotal.png",
                     "HelpVirusTotalPage", "0helpPage", None],
                    "helpWebBrowserPage":
                    [self.tr("eric6 Web Browser"), "ericWeb.png",
                     "HelpWebBrowserPage", "0helpPage", None],
                })
            except ImportError:
                pass
            
            self.configItems.update(
                e5App().getObject("PluginManager").getPluginConfigData())
        
        elif displayMode == ConfigurationWidget.HelpBrowserMode:
            self.configItems = {
                # key : [display string, pixmap name, dialog module name or
                #        page creation function, parent key,
                #        reference to configuration page (must always be last)]
                # The dialog module must have the module function 'create' to
                # create the configuration page. This must have the method
                # 'save' to save the settings.
                "interfacePage":
                [self.tr("Interface"), "preferences-interface.png",
                 "HelpInterfacePage", None, None],
                "networkPage":
                [self.tr("Network"), "preferences-network.png",
                 "NetworkPage", None, None],
                "printerPage":
                [self.tr("Printer"), "preferences-printer.png",
                 "PrinterPage", None, None],
                "securityPage":
                [self.tr("Security"), "preferences-security.png",
                 "SecurityPage", None, None],
                
                "0helpPage":
                [self.tr("Help"), "preferences-help.png",
                 None, None, None],
                "helpDocumentationPage":
                [self.tr("Help Documentation"),
                 "preferences-helpdocumentation.png",
                 "HelpDocumentationPage", "0helpPage", None],
            }
            try:
                from PyQt5 import QtWebKit      # __IGNORE_WARNING__
                self.configItems.update({
                    "helpAppearancePage":
                    [self.tr("Appearance"), "preferences-styles.png",
                     "HelpAppearancePage", "0helpPage", None],
                    "helpFlashCookieManagerPage":
                    [self.tr("Flash Cookie Manager"),
                     "flashCookie16.png",
                     "HelpFlashCookieManagerPage", "0helpPage", None],
                    "helpVirusTotalPage":
                    [self.tr("VirusTotal Interface"), "virustotal.png",
                     "HelpVirusTotalPage", "0helpPage", None],
                    "helpWebBrowserPage":
                    [self.tr("eric6 Web Browser"), "ericWeb.png",
                     "HelpWebBrowserPage", "0helpPage", None],
                })
            except ImportError:
                pass
        
        elif displayMode == ConfigurationWidget.TrayStarterMode:
            self.configItems = {
                # key : [display string, pixmap name, dialog module name or
                #        page creation function, parent key,
                #        reference to configuration page (must always be last)]
                # The dialog module must have the module function 'create' to
                # create the configuration page. This must have the method
                # 'save' to save the settings.
                "trayStarterPage":
                [self.tr("Tray Starter"), "erict.png",
                 "TrayStarterPage", None, None],
            }
        
        elif displayMode == ConfigurationWidget.HexEditorMode:
            self.configItems = {
                # key : [display string, pixmap name, dialog module name or
                #        page creation function, parent key,
                #        reference to configuration page (must always be last)]
                # The dialog module must have the module function 'create' to
                # create the configuration page. This must have the method
                # 'save' to save the settings.
                "hexEditorPage":
                [self.tr("Hex Editor"), "hexEditor.png",
                 "HexEditorPage", None, None],
            }
        
        else:
            raise RuntimeError("Illegal mode value: {0}".format(displayMode))
        
        # generate the list entries
        self.__expandedEntries = []
        for key in sorted(self.configItems.keys()):
            pageData = self.configItems[key]
            if pageData[3]:
                if pageData[3] in self.itmDict:
                    pitm = self.itmDict[pageData[3]]  # get the parent item
                else:
                    continue
            else:
                pitm = self.configList
            self.itmDict[key] = ConfigurationPageItem(pitm, pageData[0], key,
                                                      pageData[1])
            self.itmDict[key].setData(0, Qt.UserRole, key)
            if (not self.fromEric or
                displayMode != ConfigurationWidget.DefaultMode or
                    key in expandedEntries):
                self.itmDict[key].setExpanded(True)
        self.configList.sortByColumn(0, Qt.AscendingOrder)
        
        # set the initial size of the splitter
        self.configSplitter.setSizes([200, 600])
        
        self.configList.itemActivated.connect(self.__showConfigurationPage)
        self.configList.itemClicked.connect(self.__showConfigurationPage)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.rejected)
        
        if displayMode in [ConfigurationWidget.HelpBrowserMode,
                           ConfigurationWidget.TrayStarterMode,
                           ConfigurationWidget.HexEditorMode]:
            self.configListSearch.hide()
        
        if displayMode not in [ConfigurationWidget.TrayStarterMode,
                               ConfigurationWidget.HexEditorMode]:
            self.__initLexers()
        
    def accept(self):
        """
        Public slot to accept the buttonBox accept signal.
        """
        if not isMacPlatform():
            wdg = self.focusWidget()
            if wdg == self.configList:
                return
        
        self.accepted.emit()
        
    def __setupUi(self):
        """
        Private method to perform the general setup of the configuration
        widget.
        """
        self.setObjectName("ConfigurationDialog")
        self.resize(900, 650)
        self.verticalLayout_2 = QVBoxLayout(self)
        self.verticalLayout_2.setSpacing(6)
        self.verticalLayout_2.setContentsMargins(6, 6, 6, 6)
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        
        self.configSplitter = QSplitter(self)
        self.configSplitter.setOrientation(Qt.Horizontal)
        self.configSplitter.setObjectName("configSplitter")
        
        self.configListWidget = QWidget(self.configSplitter)
        self.leftVBoxLayout = QVBoxLayout(self.configListWidget)
        self.leftVBoxLayout.setContentsMargins(0, 0, 0, 0)
        self.leftVBoxLayout.setSpacing(0)
        self.leftVBoxLayout.setObjectName("leftVBoxLayout")
        self.configListSearch = E5ClearableLineEdit(
            self, self.tr("Enter search text..."))
        self.configListSearch.setObjectName("configListSearch")
        self.leftVBoxLayout.addWidget(self.configListSearch)
        self.configList = QTreeWidget()
        self.configList.setObjectName("configList")
        self.leftVBoxLayout.addWidget(self.configList)
        self.configListSearch.textChanged.connect(self.__searchTextChanged)
        
        self.scrollArea = QScrollArea(self.configSplitter)
        self.scrollArea.setFrameShape(QFrame.NoFrame)
        self.scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.scrollArea.setWidgetResizable(False)
        self.scrollArea.setObjectName("scrollArea")
        
        self.configStack = QStackedWidget()
        self.configStack.setFrameShape(QFrame.Box)
        self.configStack.setFrameShadow(QFrame.Sunken)
        self.configStack.setObjectName("configStack")
        self.scrollArea.setWidget(self.configStack)
        
        self.emptyPage = QWidget()
        self.emptyPage.setGeometry(QRect(0, 0, 372, 591))
        self.emptyPage.setObjectName("emptyPage")
        self.vboxlayout = QVBoxLayout(self.emptyPage)
        self.vboxlayout.setSpacing(6)
        self.vboxlayout.setContentsMargins(6, 6, 6, 6)
        self.vboxlayout.setObjectName("vboxlayout")
        spacerItem = QSpacerItem(
            20, 20, QSizePolicy.Minimum, QSizePolicy.Expanding)
        self.vboxlayout.addItem(spacerItem)
        self.emptyPagePixmap = QLabel(self.emptyPage)
        self.emptyPagePixmap.setAlignment(Qt.AlignCenter)
        self.emptyPagePixmap.setObjectName("emptyPagePixmap")
        self.emptyPagePixmap.setPixmap(
            QPixmap(os.path.join(getConfig('ericPixDir'), 'eric.png')))
        self.vboxlayout.addWidget(self.emptyPagePixmap)
        self.textLabel1 = QLabel(self.emptyPage)
        self.textLabel1.setAlignment(Qt.AlignCenter)
        self.textLabel1.setObjectName("textLabel1")
        self.vboxlayout.addWidget(self.textLabel1)
        spacerItem1 = QSpacerItem(
            20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)
        self.vboxlayout.addItem(spacerItem1)
        self.configStack.addWidget(self.emptyPage)
        
        self.verticalLayout_2.addWidget(self.configSplitter)
        
        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(
            QDialogButtonBox.Apply | QDialogButtonBox.Cancel |
            QDialogButtonBox.Ok | QDialogButtonBox.Reset)
        self.buttonBox.setObjectName("buttonBox")
        if not self.fromEric and \
                self.displayMode == ConfigurationWidget.DefaultMode:
            self.buttonBox.button(QDialogButtonBox.Apply).hide()
        self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(False)
        self.buttonBox.button(QDialogButtonBox.Reset).setEnabled(False)
        self.verticalLayout_2.addWidget(self.buttonBox)

        self.setWindowTitle(self.tr("Preferences"))
        
        self.configList.header().hide()
        self.configList.header().setSortIndicator(0, Qt.AscendingOrder)
        self.configList.setSortingEnabled(True)
        self.textLabel1.setText(
            self.tr("Please select an entry of the list \n"
                    "to display the configuration page."))
        
        QMetaObject.connectSlotsByName(self)
        self.setTabOrder(self.configList, self.configStack)
        
        self.configStack.setCurrentWidget(self.emptyPage)
        
        self.configList.setFocus()
    
    def __searchTextChanged(self, text):
        """
        Private slot to handle a change of the search text.
        
        @param text text to search for (string)
        """
        self.__searchChildItems(self.configList.invisibleRootItem(), text)
    
    def __searchChildItems(self, parent, text):
        """
        Private method to enable child items based on a search string.
        
        @param parent reference to the parent item (QTreeWidgetItem)
        @param text text to search for (string)
        @return flag indicating an enabled child item (boolean)
        """
        childEnabled = False
        text = text.lower()
        for index in range(parent.childCount()):
            itm = parent.child(index)
            if itm.childCount() > 0:
                enable = self.__searchChildItems(itm, text) or \
                    text == "" or text in itm.text(0).lower()
            else:
                enable = text == "" or text in itm.text(0).lower()
            if enable:
                childEnabled = True
            itm.setDisabled(not enable)
        
        return childEnabled
    
    def __initLexers(self):
        """
        Private method to initialize the dictionary of preferences lexers.
        """
        import QScintilla.Lexers
        from .PreferencesLexer import PreferencesLexer, \
            PreferencesLexerLanguageError
        
        self.lexers = {}
        for language in QScintilla.Lexers.getSupportedLanguages():
            if language not in self.lexers:
                try:
                    self.lexers[language] = PreferencesLexer(language, self)
                except PreferencesLexerLanguageError:
                    pass
        
    def __importConfigurationPage(self, name):
        """
        Private method to import a configuration page module.
        
        @param name name of the configuration page module (string)
        @return reference to the configuration page module
        """
        modName = "Preferences.ConfigurationPages.{0}".format(name)
        try:
            mod = __import__(modName)
            components = modName.split('.')
            for comp in components[1:]:
                mod = getattr(mod, comp)
            return mod
        except ImportError:
            E5MessageBox.critical(
                self,
                self.tr("Configuration Page Error"),
                self.tr("""<p>The configuration page <b>{0}</b>"""
                        """ could not be loaded.</p>""").format(name))
            return None
        
    def __showConfigurationPage(self, itm, column):
        """
        Private slot to show a selected configuration page.
        
        @param itm reference to the selected item (QTreeWidgetItem)
        @param column column that was selected (integer) (ignored)
        """
        pageName = itm.getPageName()
        self.showConfigurationPageByName(pageName, setCurrent=False)
        
    def __initPage(self, pageData):
        """
        Private method to initialize a configuration page.
        
        @param pageData data structure for the page to initialize
        @return reference to the initialized page
        """
        page = None
        if isinstance(pageData[2], types.FunctionType):
            page = pageData[2](self)
        else:
            mod = self.__importConfigurationPage(pageData[2])
            if mod:
                page = mod.create(self)
        if page is not None:
            self.configStack.addWidget(page)
            pageData[-1] = page
            try:
                page.setMode(self.displayMode)
            except AttributeError:
                pass
        return page
        
    def showConfigurationPageByName(self, pageName, setCurrent=True):
        """
        Public slot to show a named configuration page.
        
        @param pageName name of the configuration page to show (string)
        @param setCurrent flag indicating to set the current item (boolean)
        """
        if pageName == "empty" or pageName not in self.configItems:
            page = self.emptyPage
        else:
            pageData = self.configItems[pageName]
            if pageData[-1] is None and pageData[2] is not None:
                # the page was not loaded yet, create it
                page = self.__initPage(pageData)
            else:
                page = pageData[-1]
            if page is None:
                page = self.emptyPage
            elif setCurrent:
                items = self.configList.findItems(
                    pageData[0],
                    Qt.MatchFixedString | Qt.MatchRecursive)
                for item in items:
                    if item.data(0, Qt.UserRole) == pageName:
                        self.configList.setCurrentItem(item)
        self.configStack.setCurrentWidget(page)
        ssize = self.scrollArea.size()
        if self.scrollArea.horizontalScrollBar():
            ssize.setHeight(
                ssize.height() -
                self.scrollArea.horizontalScrollBar().height() - 2)
        if self.scrollArea.verticalScrollBar():
            ssize.setWidth(
                ssize.width() -
                self.scrollArea.verticalScrollBar().width() - 2)
        psize = page.minimumSizeHint()
        self.configStack.resize(max(ssize.width(), psize.width()),
                                max(ssize.height(), psize.height()))
        
        if page != self.emptyPage:
            page.polishPage()
            self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True)
            self.buttonBox.button(QDialogButtonBox.Reset).setEnabled(True)
        else:
            self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(False)
            self.buttonBox.button(QDialogButtonBox.Reset).setEnabled(False)
        
        # reset scrollbars
        for sb in [self.scrollArea.horizontalScrollBar(),
                   self.scrollArea.verticalScrollBar()]:
            if sb:
                sb.setValue(0)
        
        self.__currentConfigurationPageName = pageName
        
    def getConfigurationPageName(self):
        """
        Public method to get the page name of the current page.
        
        @return page name of the current page (string)
        """
        return self.__currentConfigurationPageName
        
    def calledFromEric(self):
        """
        Public method to check, if invoked from within eric.
        
        @return flag indicating invocation from within eric (boolean)
        """
        return self.fromEric
        
    def getPage(self, pageName):
        """
        Public method to get a reference to the named page.
        
        @param pageName name of the configuration page (string)
        @return reference to the page or None, indicating page was
            not loaded yet
        """
        return self.configItems[pageName][-1]
        
    def getLexers(self):
        """
        Public method to get a reference to the lexers dictionary.
        
        @return reference to the lexers dictionary
        """
        return self.lexers
        
    def setPreferences(self):
        """
        Public method called to store the selected values into the preferences
        storage.
        """
        for key, pageData in list(self.configItems.items()):
            if pageData[-1]:
                pageData[-1].save()
                # page was loaded (and possibly modified)
                QApplication.processEvents()    # ensure HMI is responsive
        
    def on_buttonBox_clicked(self, button):
        """
        Private slot called by a button of the button box clicked.
        
        @param button button that was clicked (QAbstractButton)
        """
        if button == self.buttonBox.button(QDialogButtonBox.Apply):
            self.on_applyButton_clicked()
        elif button == self.buttonBox.button(QDialogButtonBox.Reset):
            self.on_resetButton_clicked()
        
    @pyqtSlot()
    def on_applyButton_clicked(self):
        """
        Private slot called to apply the settings of the current page.
        """
        if self.configStack.currentWidget() != self.emptyPage:
            page = self.configStack.currentWidget()
            savedState = page.saveState()
            page.save()
            self.preferencesChanged.emit()
            if savedState is not None:
                page.setState(savedState)
            page.polishPage()
        
    @pyqtSlot()
    def on_resetButton_clicked(self):
        """
        Private slot called to reset the settings of the current page.
        """
        if self.configStack.currentWidget() != self.emptyPage:
            currentPage = self.configStack.currentWidget()
            savedState = currentPage.saveState()
            pageName = self.configList.currentItem().getPageName()
            self.configStack.removeWidget(currentPage)
            if pageName == "editorHighlightingStylesPage":
                self.__initLexers()
            self.configItems[pageName][-1] = None
            
            self.showConfigurationPageByName(pageName)
            if savedState is not None:
                self.configStack.currentWidget().setState(savedState)
        
    def getExpandedEntries(self):
        """
        Public method to get a list of expanded entries.
        
        @return list of expanded entries (list of string)
        """
        return self.__expandedEntries
    
    @pyqtSlot(QTreeWidgetItem)
    def on_configList_itemCollapsed(self, item):
        """
        Private slot handling a list entry being collapsed.
        
        @param item reference to the collapsed item (QTreeWidgetItem)
        """
        pageName = item.data(0, Qt.UserRole)
        if pageName in self.__expandedEntries:
            self.__expandedEntries.remove(pageName)
    
    @pyqtSlot(QTreeWidgetItem)
    def on_configList_itemExpanded(self, item):
        """
        Private slot handling a list entry being expanded.
        
        @param item reference to the expanded item (QTreeWidgetItem)
        """
        pageName = item.data(0, Qt.UserRole)
        if pageName not in self.__expandedEntries:
            self.__expandedEntries.append(pageName)