Exemplo n.º 1
1
class ParamSpinBox(QAbstractSpinBox):
    # signals
    valueChanged = pyqtSignal(float)

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

        self.fName = ""

        self.fMinimum = 0.0
        self.fMaximum = 1.0
        self.fDefault = 0.0
        self.fValue   = None

        self.fStep      = 0.01
        self.fStepSmall = 0.0001
        self.fStepLarge = 0.1

        self.fIsReadOnly = False
        self.fScalePoints = None
        self.fUseScalePoints = False

        self.fBar = ParamProgressBar(self)
        self.fBar.setContextMenuPolicy(Qt.NoContextMenu)
        #self.fBar.show()

        self.fBox = None

        self.lineEdit().hide()

        self.customContextMenuRequested.connect(self.slot_showCustomMenu)
        self.fBar.valueChanged.connect(self.slot_progressBarValueChanged)

        QTimer.singleShot(0, self.slot_updateProgressBarGeometry)

    def setDefault(self, value):
        value = geFixedValue(self.fName, value, self.fMinimum, self.fMaximum)
        self.fDefault = value

    def setMinimum(self, value):
        self.fMinimum = value
        self.fBar.setMinimum(value)

    def setMaximum(self, value):
        self.fMaximum = value
        self.fBar.setMaximum(value)

    def setValue(self, value):
        value = geFixedValue(self.fName, value, self.fMinimum, self.fMaximum)

        if self.fValue == value:
            return False

        self.fValue = value
        self.fBar.setValue(value)

        if self.fUseScalePoints:
            self._setScalePointValue(value)

        self.valueChanged.emit(value)
        self.update()

        return True

    def setStep(self, value):
        if value == 0.0:
            self.fStep = 0.001
        else:
            self.fStep = value

        if self.fStepSmall > value:
            self.fStepSmall = value
        if self.fStepLarge < value:
            self.fStepLarge = value

        self.fBar.fIsInteger = bool(self.fStepSmall == 1.0)

    def setStepSmall(self, value):
        if value == 0.0:
            self.fStepSmall = 0.0001
        elif value > self.fStep:
            self.fStepSmall = self.fStep
        else:
            self.fStepSmall = value

        self.fBar.fIsInteger = bool(self.fStepSmall == 1.0)

    def setStepLarge(self, value):
        if value == 0.0:
            self.fStepLarge = 0.1
        elif value < self.fStep:
            self.fStepLarge = self.fStep
        else:
            self.fStepLarge = value

    def setLabel(self, label):
        self.fBar.setLabel(label)

    def setName(self, name):
        self.fName = name
        self.fBar.setName(name)

    def setTextCallback(self, textCall):
        self.fBar.setTextCall(textCall)

    def setReadOnly(self, yesNo):
        self.fIsReadOnly = yesNo
        self.setButtonSymbols(QAbstractSpinBox.UpDownArrows if yesNo else QAbstractSpinBox.NoButtons)
        QAbstractSpinBox.setReadOnly(self, yesNo)

    # FIXME use change event
    def setEnabled(self, yesNo):
        self.fBar.setEnabled(yesNo)
        QAbstractSpinBox.setEnabled(self, yesNo)

    def setScalePoints(self, scalePoints, useScalePoints):
        if len(scalePoints) == 0:
            self.fScalePoints     = None
            self.fUseScalePoints = False
            return

        self.fScalePoints     = scalePoints
        self.fUseScalePoints = useScalePoints

        if not useScalePoints:
            return

        # Hide ProgressBar and create a ComboBox
        self.fBar.close()
        self.fBox = QComboBox(self)
        self.fBox.setContextMenuPolicy(Qt.NoContextMenu)
        #self.fBox.show()
        self.slot_updateProgressBarGeometry()

        # Add items, sorted
        boxItemValues = []

        for scalePoint in scalePoints:
            value = scalePoint['value']

            if self.fStep == 1.0:
                label = "%i - %s" % (int(value), scalePoint['label'])
            else:
                label = "%f - %s" % (value, scalePoint['label'])

            if len(boxItemValues) == 0:
                self.fBox.addItem(label)
                boxItemValues.append(value)

            else:
                if value < boxItemValues[0]:
                    self.fBox.insertItem(0, label)
                    boxItemValues.insert(0, value)
                elif value > boxItemValues[-1]:
                    self.fBox.addItem(label)
                    boxItemValues.append(value)
                else:
                    for index in range(len(boxItemValues)):
                        if value >= boxItemValues[index]:
                            self.fBox.insertItem(index+1, label)
                            boxItemValues.insert(index+1, value)
                            break

        if self.fValue is not None:
            self._setScalePointValue(self.fValue)

        self.fBox.currentIndexChanged['QString'].connect(self.slot_comboBoxIndexChanged)

    def stepBy(self, steps):
        if steps == 0 or self.fValue is None:
            return

        value = self.fValue + (self.fStep * steps)

        if value < self.fMinimum:
            value = self.fMinimum
        elif value > self.fMaximum:
            value = self.fMaximum

        self.setValue(value)

    def stepEnabled(self):
        if self.fIsReadOnly or self.fValue is None:
            return QAbstractSpinBox.StepNone
        if self.fValue <= self.fMinimum:
            return QAbstractSpinBox.StepUpEnabled
        if self.fValue >= self.fMaximum:
            return QAbstractSpinBox.StepDownEnabled
        return (QAbstractSpinBox.StepUpEnabled | QAbstractSpinBox.StepDownEnabled)

    def updateAll(self):
        self.update()
        self.fBar.update()
        if self.fBox is not None:
            self.fBox.update()

    def resizeEvent(self, event):
        QAbstractSpinBox.resizeEvent(self, event)
        self.slot_updateProgressBarGeometry()

    @pyqtSlot(str)
    def slot_comboBoxIndexChanged(self, boxText):
        if self.fIsReadOnly:
            return

        value          = float(boxText.split(" - ", 1)[0])
        lastScaleValue = self.fScalePoints[-1]['value']

        if value == lastScaleValue:
            value = self.fMaximum

        self.setValue(value)

    @pyqtSlot(float)
    def slot_progressBarValueChanged(self, value):
        if self.fIsReadOnly:
            return

        if value <= self.fMinimum:
            realValue = self.fMinimum
        elif value >= self.fMaximum:
            realValue = self.fMaximum
        else:
            curStep   = int((value - self.fMinimum) / self.fStep + 0.5)
            realValue = self.fMinimum + (self.fStep * curStep)

            if realValue < self.fMinimum:
                realValue = self.fMinimum
            elif realValue > self.fMaximum:
                realValue = self.fMaximum

        self.setValue(realValue)

    @pyqtSlot()
    def slot_showCustomMenu(self):
        clipboard  = QApplication.instance().clipboard()
        pasteText  = clipboard.text()
        pasteValue = None

        if pasteText:
            try:
                pasteValue = float(pasteText)
            except:
                pass

        menu      = QMenu(self)
        actReset  = menu.addAction(self.tr("Reset (%f)" % self.fDefault))
        actRandom = menu.addAction(self.tr("Random"))
        menu.addSeparator()
        actCopy   = menu.addAction(self.tr("Copy (%f)" % self.fValue))

        if pasteValue is None:
            actPaste = menu.addAction(self.tr("Paste"))
            actPaste.setEnabled(False)
        else:
            actPaste = menu.addAction(self.tr("Paste (%f)" % pasteValue))

        menu.addSeparator()

        actSet = menu.addAction(self.tr("Set value..."))

        if self.fIsReadOnly:
            actReset.setEnabled(False)
            actRandom.setEnabled(False)
            actPaste.setEnabled(False)
            actSet.setEnabled(False)

        actSel = menu.exec_(QCursor.pos())

        if actSel == actReset:
            self.setValue(self.fDefault)

        elif actSel == actRandom:
            value = random() * (self.fMaximum - self.fMinimum) + self.fMinimum
            self.setValue(value)

        elif actSel == actCopy:
            clipboard.setText("%f" % self.fValue)

        elif actSel == actPaste:
            self.setValue(pasteValue)

        elif actSel == actSet:
            dialog = CustomInputDialog(self, self.fName, self.fValue, self.fMinimum, self.fMaximum, self.fStep, self.fScalePoints)
            if dialog.exec_():
                value = dialog.returnValue()
                self.setValue(value)

    @pyqtSlot()
    def slot_updateProgressBarGeometry(self):
        self.fBar.setGeometry(self.lineEdit().geometry())
        if self.fUseScalePoints:
            self.fBox.setGeometry(self.lineEdit().geometry())

    def _getNearestScalePoint(self, realValue):
        finalValue = 0.0

        for i in range(len(self.fScalePoints)):
            scaleValue = self.fScalePoints[i]["value"]
            if i == 0:
                finalValue = scaleValue
            else:
                srange1 = abs(realValue - scaleValue)
                srange2 = abs(realValue - finalValue)

                if srange2 > srange1:
                    finalValue = scaleValue

        return finalValue

    def _setScalePointValue(self, value):
        value = self._getNearestScalePoint(value)

        for i in range(self.fBox.count()):
            if float(self.fBox.itemText(i).split(" - ", 1)[0]) == value:
                self.fBox.setCurrentIndex(i)
                break
Exemplo n.º 2
0
def move_combo(direction: str, combo: QComboBox):
    current_index = combo.currentIndex()
    if direction == 'left':
        if current_index == 0:
            combo.setCurrentIndex(combo.count() - 1)
        else:
            combo.setCurrentIndex(current_index - 1)
    if direction == 'right':
        if current_index == combo.count() - 1:
            combo.setCurrentIndex(0)
        else:
            combo.setCurrentIndex(current_index + 1)
Exemplo n.º 3
0
def get_elements_from_combobox(combobox: QComboBox) -> List[str]:
    """
    Returns all elements from combobox provided in a list.
    :param combobox: Combobox to get list of elements from.
    :return: List of elements from combobox.
    """
    return [combobox.itemText(i) for i in range(combobox.count())]
Exemplo n.º 4
0
    def _create_control_select(self, device, zone, option):
        """
        Prepares and returns a dropdown for changing options.
        """
        params = option["parameters"]
        current_index = 0

        combo = QComboBox()
        combo.setIconSize(QSize(16, 16))
        for i, param in enumerate(params):
            icon_path = common.get_icon("params", param["id"])
            combo.addItem(param["label"])

            if icon_path:
                combo.setItemIcon(combo.count() - 1, QIcon(icon_path))

            if param["active"] is True:
                current_index = i
            i = i + 1

        combo.setCurrentIndex(current_index)

        def _current_index_changed(index):
            param = params[index]
            self._event_set_option(device, zone, option["id"], param["data"])

        combo.currentIndexChanged.connect(_current_index_changed)
        return [combo]
 def append_to_combobox(cbox: QComboBox):
     current = cbox.currentText()
     completions = set(cbox.itemText(i) for i in range(cbox.count()))
     completions.add(current)
     cbox.clear()
     cbox.addItems(completions)
     cbox.setCurrentIndex(cbox.findText(current))
Exemplo n.º 6
0
class NewContactDialog(QDialog):
    def __init__(self, users):
        super().__init__()

        self.setWindowTitle("New Contact")

        self.users = QComboBox()
        self.users.addItems(users)
        self.users.currentTextChanged.connect(self.userSelected)

        self.current = [self.users.itemText(i) for i in range(self.users.count())][0]

        self.addBtn = QPushButton()
        self.addBtn.setText('Add')
        self.addBtn.clicked.connect(self.addContact)

        self.layout = QVBoxLayout()
        self.layout.addWidget(self.users)
        self.layout.addWidget(self.addBtn)
        self.setLayout(self.layout)

    def addContact(self):
        self.close()

    def userSelected(self, value):
        self.current = value
Exemplo n.º 7
0
class QComboBoxDemo(QWidget):
    def __init__(self):
        super(QComboBoxDemo, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle('QComboBoxDemo')
        self.resize(300, 280)
        layout = QVBoxLayout()

        self.label = QLabel('请选择语言...')

        self.cb = QComboBox()
        self.cb.addItem('C')
        self.cb.addItem('C++')
        self.cb.addItems(['Java', 'Python'])

        self.cb.currentIndexChanged.connect(self.SelectionChanged)

        layout.addWidget(self.label)
        layout.addWidget(self.cb)
        self.setLayout(layout)

    def SelectionChanged(self, i):
        self.label.setText(self.cb.currentText())
        self.label.adjustSize()
        self.label.setFont(QFont('Arial', 20))

        for item in range(self.cb.count()):
            print('Item:' + str(item) + ',' + self.cb.itemText(item))

        print('CurrentIndex:' + str(i) + ',SelecctionChanged:' + self.cb.itemText(i))
Exemplo n.º 8
0
class FileChooser(QWidget):
    fileOpened = pyqtSignal(str)

    def __init__(self, parent=None):
        super().__init__(parent)
        self.folderBox = QComboBox(self)
        self.explorerTree = FileTreeView(self)
        self.explorerTree.doubleClickCallback = self._fileOpened
        self.explorerModel = QFileSystemModel(self)
        self.explorerModel.setFilter(
            QDir.AllDirs | QDir.Files | QDir.NoDotAndDotDot)
        self.explorerModel.setNameFilters(["*.py"])
        self.explorerModel.setNameFilterDisables(False)
        self.explorerTree.setModel(self.explorerModel)
        for index in range(1, self.explorerModel.columnCount()):
            self.explorerTree.hideColumn(index)
        self.setCurrentFolder()
        self.folderBox.currentIndexChanged[int].connect(
            self.updateCurrentFolder)

        layout = QVBoxLayout(self)
        layout.addWidget(self.folderBox)
        layout.addWidget(self.explorerTree)
        layout.setContentsMargins(5, 5, 0, 0)

    def _fileOpened(self, modelIndex):
        path = self.explorerModel.filePath(modelIndex)
        if os.path.isfile(path):
            self.fileOpened.emit(path)

    def currentFolder(self):
        return self.explorerModel.rootPath()

    def setCurrentFolder(self, path=None):
        if path is None:
            app = QApplication.instance()
            path = app.getScriptsDirectory()
        else:
            assert os.path.isdir(path)
        self.explorerModel.setRootPath(path)
        self.explorerTree.setRootIndex(self.explorerModel.index(path))
        self.folderBox.blockSignals(True)
        self.folderBox.clear()
        style = self.style()
        dirIcon = style.standardIcon(style.SP_DirIcon)
        self.folderBox.addItem(dirIcon, os.path.basename(path))
        self.folderBox.insertSeparator(1)
        self.folderBox.addItem(self.tr("Browse…"))
        self.folderBox.setCurrentIndex(0)
        self.folderBox.blockSignals(False)

    def updateCurrentFolder(self, index):
        if index < self.folderBox.count() - 1:
            return
        path = QFileDialog.getExistingDirectory(
            self, self.tr("Choose Directory"), self.currentFolder(),
            QFileDialog.ShowDirsOnly)
        if path:
            QSettings().setValue("scripting/path", path)
            self.setCurrentFolder(path)
Exemplo n.º 9
0
class comboBoxDemo(QWidget):
    def __init__(self):
        super(comboBoxDemo, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle('下拉列表框测试')

        self.label = QLabel('请选择您最喜欢的春节晚会节目')
        layout = QHBoxLayout()  # 使用水平布局
        self.cb = QComboBox()  # 实例化一个下拉列表框
        self.cb.addItems(['相声', '小品', '歌曲', '舞蹈'])  # 添加下拉列表中的选项
        self.cb.currentIndexChanged.connect(
            self.selectionChange)  # 信号绑定,并传递所选的索引Index
        # 控件使用水平布局
        layout.addWidget(self.label)
        layout.addWidget(self.cb)

        self.setLayout(layout)

    def selectionChange(self, i):
        "这是一个函数文档,下面的for循环及那个cb下拉列表框中的项都打印出来"
        for count in range(self.cb.count()):
            print('item' + str(count) + '=' + self.cb.itemText(count))
        # 打印目前选中的
        print('current index', i, 'selection changed', self.cb.currentText())
Exemplo n.º 10
0
 def needs_update(self, cb: QComboBox, new_data: list):
     if self.debug == True:
         print(new_data)
     if cb.count() <= 0:
         cb.addItems(new_data)
     else:
         self.update(cb, new_data)
Exemplo n.º 11
0
class SerialChooser(QWidget):
    def __init__(self, master):
        super().__init__(master)
        grid = QGridLayout()
        self.comboBox = QComboBox(self)
        self.comboBox.addItem(DEFAULT_ROBOT_SERIAL_PORT)
        self.comboBox.setEditable(True)
        grid.addWidget(self.comboBox, 0, 0)
        self.setLayout(grid)

    def setEntries(self, entries):
        for i in range(self.comboBox.count()):
            self.comboBox.removeItem(i)
        self.comboBox.addItems(entries)

    def getEntry(self):
        strList = self.comboBox.currentText().split()
        if len(strList) > 0:
            return strList[0]
        else:
            return ""

    def markBlank(self):
        self.comboBox.setStyleSheet("")

    def markWrong(self):
        self.comboBox.setStyleSheet("""QComboBox { background-color: rgb(249, 83, 83) }""")

    def markConnected(self):
        self.comboBox.setStyleSheet("""QComboBox { background-color: rgb(203, 230, 163) }""")
    def __init__(self, main_form, edit_these, new_item, title):
        QMainWindow.__init__(self, main_form)
        self.helper = HelpHandler(self)
        self.help_topic = "swmm/src/src/groundwaterfloweditordialog.htm"
        self._main_form = main_form
        self.project = main_form.project
        self.new_item = new_item
        self.refresh_column = -1
        self.setupUi(self)
        self.setWindowTitle(title)
        self.cmdOK.clicked.connect(self.cmdOK_Clicked)
        self.cmdCancel.clicked.connect(self.cmdCancel_Clicked)
        self.backend = PropertyEditorBackend(self.tblGeneric, self.lblNotes,
                                             main_form, edit_these, new_item)

        for column in range(0, self.tblGeneric.columnCount()):
            # for aquifers, show available aquifers
            aquifer_section = main_form.project.find_section("AQUIFERS")
            aquifer_list = aquifer_section.value[0:]
            combobox = QComboBox()
            combobox.addItem('')
            selected_index = 0
            for value in aquifer_list:
                combobox.addItem(value.name)
                if edit_these[column].aquifer == value.name:
                    selected_index = int(combobox.count()) - 1
            combobox.setCurrentIndex(selected_index)
            self.tblGeneric.setCellWidget(1, column, combobox)
            # also set special text plus button cells
            self.set_lateral_equation(column)
            self.set_deep_equation(column)

        self.installEventFilter(self)
Exemplo n.º 13
0
class MainWin(QWidget):
    def __init__(self, parent=None):
        super(MainWin, self).__init__(parent)

        layout = QVBoxLayout()
        self.cb = QComboBox()
        self.cb.addItem('C')
        self.cb.addItem('C++')
        self.cb.addItems(['Java', 'C#', 'Python'])
        self.cb.currentIndexChanged.connect(self.selectionchange)
        layout.addWidget(self.cb)

        self.lb = QLabel('')
        layout.addWidget(self.lb)

        self.setLayout(layout)
        self.resize(300, 90)
        self.setWindowTitle('ComboBox')

    def selectionchange(self, idx):
        self.lb.setText(self.cb.currentText())
        print('Items in the list are: ')
        for i in range(self.cb.count()):
            print('item {} = {}'.format(i, self.cb.itemText(i)))
        print('Current index', idx, 'selection changed', self.cb.currentText())
Exemplo n.º 14
0
class QComboBoxDemo(QWidget):
    def __init__(self):
        super(QComboBoxDemo, self).__init__()
        self.v_layout = QVBoxLayout()
        self.label = QLabel('请选择编程语言')
        self.comboBox = QComboBox()
        self.initUI()

    def initUI(self):
        self.setWindowTitle('下拉列表控件')
        self.comboBox.addItem('C++')
        self.comboBox.addItem('C')
        self.comboBox.addItem('Python')
        self.comboBox.addItems(['Java', 'C#', 'R'])
        self.comboBox.currentIndexChanged.connect(self.selection_change)

        self.v_layout.addWidget(self.label)
        self.v_layout.addWidget(self.comboBox)

        self.setLayout(self.v_layout)

    def selection_change(self, index):
        self.label.setText(self.comboBox.currentText())
        # self.label.adjustSize()

        for count in range(self.comboBox.count()):
            print('item {} = {}'.format(count, self.comboBox.itemText(count)))
        print('current index {}, selection changed {}'.format(
            index, self.comboBox.currentText()))
Exemplo n.º 15
0
class RosIPSetupWidget(QGroupBox):
    def __init__(self, parent=None):
        QGroupBox.__init__(self, "ros ip", parent)

        l = QVBoxLayout()
        self.setLayout(l)

        self.ip = QLineEdit("")

        self.comboip = QComboBox()
        for k, v in ip4_addresses().items():
            self.comboip.addItem(k+': '+v, v)
        self.comboip.addItem("other...", "")
        self.comboip.currentIndexChanged.connect(self.comboip_currentIndexChanged)

        l.addWidget(self.comboip)
        l.addWidget(self.ip)

    def comboipChangeIndex(self, index):
        self.comboip.setCurrentIndex(index)
        self.comboip_currentIndexChanged(index)

    def comboip_currentIndexChanged(self, index):
        if index == self.comboip.count() - 1:
            self.ip.setEnabled(True)
        else:
            self.ip.setEnabled(False)
            value = self.comboip.itemData(index)
            if not isinstance(value, basestring):
                value = value.toString() #then it should be a QVariant
            self.ip.setText(value)


    def setData(self, data):
        ip = data["ROS_IP"]
        self.ip.setText("{0}".format(ip))
        idx = self.comboip.findData(ip)
        if idx < 0:
            self.comboip.setItemData(self.comboip.count()-1, ip)
            self.comboipChangeIndex(self.comboip.count()-1)
        else:
            self.comboipChangeIndex(idx)



    def getData(self, data):
        data["ROS_IP"] = str(self.ip.text())
Exemplo n.º 16
0
 def get_style_combo_box(self):
     combo_box = QComboBox()
     combo_box.addItems(QStyleFactory.keys())
     combo_box.activated[str].connect(self.change_style)
     all_items = [combo_box.itemText(i) for i in range(combo_box.count())]
     idx = all_items.index('Fusion')
     combo_box.setCurrentIndex(idx)
     return combo_box
Exemplo n.º 17
0
 def addToCombo(self, combo: QComboBox, data):
     print(data, combo)
     if data:
         if 'id' in data.keys() and 'name' in data.keys():
             item = "{id} - {name}".format(**data)
             #QComboBox.itemText
             items = [combo.itemText(i) for i in range(combo.count())]
             if item not in items:
                 combo.addItem(item)
Exemplo n.º 18
0
    def __init__(self, main_form, edit_these, new_item):
        self.help_topic = "swmm/src/src/pumpproperties.htm"
        self._main_form = main_form
        self.project = main_form.project
        self.refresh_column = -1
        self.project_section = self.project.pumps
        if self.project_section and \
                isinstance(self.project_section.value, list) and \
                len(self.project_section.value) > 0 and \
                isinstance(self.project_section.value[0], self.SECTION_TYPE):

            if edit_these:  # Edit only specified item(s) in section
                if isinstance(edit_these[0], str):  # Translate list from names to objects
                    edit_names = edit_these
                    edit_objects = [item for item in self.project_section.value if item.name in edit_these]
                    edit_these = edit_objects

            else:  # Edit all items in section
                edit_these = []
                edit_these.extend(self.project_section.value)

        frmGenericPropertyEditor.__init__(self, main_form, self.project_section, edit_these, new_item,
                                          "SWMM " + self.SECTION_TYPE.__name__ + " Editor")

        for column in range(0, self.tblGeneric.columnCount()):
            # for curves, show available curves
            curves_section = self.project.find_section("CURVES")
            curves_list = curves_section.value[0:]
            combobox = QComboBox()
            combobox.addItem('*')
            selected_index = 0
            for curve in curves_list:
                if curve.curve_type in [CurveType.PUMP1, CurveType.PUMP2, CurveType.PUMP3, CurveType.PUMP4]:
                    combobox.addItem(curve.name)
                    if len(edit_these) > 0:
                        if edit_these[column].pump_curve == curve.name:
                            selected_index = int(combobox.count())-1
            combobox.setCurrentIndex(selected_index)
            self.tblGeneric.setCellWidget(5, column, combobox)
            # for initial status, show on/off
            combobox = QComboBox()
            combobox.addItem('OFF')
            combobox.addItem('ON')
            combobox.setCurrentIndex(1)
            if len(edit_these) > 0:
                if edit_these[column].initial_status == 'OFF':
                    combobox.setCurrentIndex(0)
            self.tblGeneric.setCellWidget(6, column, combobox)

        if (main_form.program_settings.value("Geometry/" + "frmPumps_geometry") and
                main_form.program_settings.value("Geometry/" + "frmPumps_state")):
            self.restoreGeometry(main_form.program_settings.value("Geometry/" + "frmPumps_geometry",
                                                                  self.geometry(), type=QtCore.QByteArray))
            self.restoreState(main_form.program_settings.value("Geometry/" + "frmPumps_state",
                                                               self.windowState(), type=QtCore.QByteArray))

        self.installEventFilter(self)
Exemplo n.º 19
0
        def setFieldNames(note_field_input: QComboBox, new_text):
            # clear out old options
            for index in range(note_field_input.count()):
                note_field_input.removeItem(0)

            for note_type in note_types:
                if note_type["name"] == new_text:
                    for field in note_type["flds"]:
                        note_field_input.addItem(field["name"])
Exemplo n.º 20
0
    def __init__(self, main_form, edit_these, new_item):
        self.help_topic = "swmm/src/src/outletproperties.htm"
        self._main_form = main_form
        self.project = main_form.project
        self.refresh_column = -1
        self.project_section = self.project.outlets
        if self.project_section and \
                isinstance(self.project_section.value, list) and \
                len(self.project_section.value) > 0 and \
                isinstance(self.project_section.value[0], self.SECTION_TYPE):

            if edit_these:  # Edit only specified item(s) in section
                if isinstance(edit_these[0],
                              str):  # Translate list from names to objects
                    edit_names = edit_these
                    edit_objects = [
                        item for item in self.project_section.value
                        if item.name in edit_these
                    ]
                    edit_these = edit_objects

            else:  # Edit all items in section
                edit_these = []
                edit_these.extend(self.project_section.value)

        frmGenericPropertyEditor.__init__(
            self, main_form, self.project_section, edit_these, new_item,
            "SWMM " + self.SECTION_TYPE.__name__ + " Editor")

        for column in range(0, self.tblGeneric.columnCount()):
            # for flapgate, show true/false
            combobox = QComboBox()
            combobox.addItem('True')
            combobox.addItem('False')
            combobox.setCurrentIndex(1)
            if len(edit_these) > 0:
                if edit_these[column].flap_gate == 'True' or edit_these[
                        column].flap_gate == True:
                    combobox.setCurrentIndex(0)
            self.tblGeneric.setCellWidget(6, column, combobox)
            # tabular curve name
            curves_section = self.project.find_section("CURVES")
            curves_list = curves_section.value[0:]
            combobox = QComboBox()
            combobox.addItem('*')
            selected_index = 0
            for value in curves_list:
                if value.curve_type == CurveType.RATING:
                    combobox.addItem(value.name)
                    if len(edit_these) > 0:
                        if edit_these[column].rating_curve == value.name:
                            selected_index = int(combobox.count()) - 1
            combobox.setCurrentIndex(selected_index)
            self.tblGeneric.setCellWidget(10, column, combobox)

        self.installEventFilter(self)
Exemplo n.º 21
0
    def __init__(self, main_form, edit_these, new_item):
        self.help_topic = "swmm/src/src/aquifereditordialog.htm"

        frmGenericPropertyEditor.__init__(
            self, main_form, main_form.project.aquifers, edit_these, new_item,
            "SWMM " + self.SECTION_TYPE.__name__ + " Editor")

        self.project_section = main_form.project.aquifers
        if self.project_section and \
                isinstance(self.project_section.value, list) and \
                len(self.project_section.value) > 0 and \
                isinstance(self.project_section.value[0], self.SECTION_TYPE):

            if edit_these:  # Edit only specified item(s) in section
                if isinstance(edit_these[0],
                              str):  # Translate list from names to objects
                    edit_names = edit_these
                    edit_objects = [
                        item for item in self.project_section.value
                        if item.name in edit_these
                    ]
                    edit_these = edit_objects

            else:  # Edit all items in section
                edit_these = []
                edit_these.extend(self.project_section.value)

        self.pattern_section = main_form.project.patterns
        pattern_list = self.pattern_section.value[0:]
        for column in range(0, self.tblGeneric.columnCount()):
            # for patterns, show available patterns
            combobox = QComboBox()
            combobox.addItem('')
            selected_index = 0
            for value in pattern_list:
                combobox.addItem(value.name)
                if edit_these[column].upper_evaporation_pattern == value.name:
                    selected_index = int(combobox.count()) - 1
            combobox.setCurrentIndex(selected_index)
            self.tblGeneric.setCellWidget(13, column, combobox)

        self._main_form = main_form
        if (main_form.program_settings.value("Geometry/" +
                                             "frmAquifers_geometry")
                and main_form.program_settings.value("Geometry/" +
                                                     "frmAquifers_state")):
            self.restoreGeometry(
                main_form.program_settings.value("Geometry/" +
                                                 "frmAquifers_geometry",
                                                 self.geometry(),
                                                 type=QtCore.QByteArray))
            self.restoreState(
                main_form.program_settings.value("Geometry/" +
                                                 "frmAquifers_state",
                                                 self.windowState(),
                                                 type=QtCore.QByteArray))
Exemplo n.º 22
0
    def IterComboBox(self, direction: int,
                     CMBX: QtWidgets.QComboBox):  # Tested
        """
        Iters and loads the corresponding for all the DB that have been declared for Apollo

        :Args:
        direction: int
            Direction for the list to iter in (Forward/Backward)
        CMBX: QtWidgets.QComboBox
            Combobox with all the DB names.
        """
        Index = CMBX.currentIndex() + (direction)
        if Index == CMBX.count():
            Index = 0
        elif Index < 0:
            Index = CMBX.count() - 1
        else:
            pass
        CMBX.setCurrentIndex(Index)
Exemplo n.º 23
0
    def PopulateCMBX(self, CMBX: QtWidgets.QComboBox, Data=None):  # Tested
        """
        Populates the CMBX with the data provided

        :Args:
        CMBX: QtWidgets.QComboBox
            Combobox with all the DB names.
        Data: list[str, str, str]
            data to fill in the combobox
        """
        if Data == None:
            DBnames = self.UI.DB_Monitored.keys()
        else:
            DBnames = Data

        [CMBX.removeItem(item) for item in range(CMBX.count())]
        CMBXitems = [CMBX.itemText(item) for item in range(CMBX.count())]
        for Name in DBnames:
            if Name not in CMBXitems:
                CMBX.addItem(Name)
Exemplo n.º 24
0
def addItem(combo: QComboBox, db_manager, data: dict, check=False) -> int:
    """добавление элемента"""
    display_key = combo.model().display
    if check:
        index = findItem(combo, data[display_key])
        if index >= 0:
            return index
    table_class = getattr(combo.model(), 'TableClass')
    new_id = db_manager.createRecord(table_class, data)
    data.update({'ID': new_id})
    combo.addItem(data[display_key], data)
    return combo.count() - 1
Exemplo n.º 25
0
    def __genSelectionEntry(self,  key,  setting):
        newItem = QTreeWidgetItem(self.__ui.settingsTree,  [key])
        selectionWidget = QComboBox(self.__ui.settingsTree)
        selectionWidget.setProperty("key",  key)
        for val in setting["values"]:
            selectionWidget.addItem(str(val),  val)
            if setting["value"] == val:
                selectionWidget.setCurrentIndex(selectionWidget.count() - 1)

        self.__ui.settingsTree.setItemWidget(newItem,  1,  selectionWidget)
        selectionWidget.currentIndexChanged[int].connect(self.__valueChangedIndex)
        return newItem
    def __init__(self, session, edit_these, new_item):
        self.help_topic = "epanet/src/src/Rese0029.htm"
        self.session = session
        self.project = session.project
        self.refresh_column = -1
        self.project_section = self.project.reservoirs
        if self.project_section and \
                isinstance(self.project_section.value, list) and \
                len(self.project_section.value) > 0 and \
                isinstance(self.project_section.value[0], self.SECTION_TYPE):

            if edit_these:  # Edit only specified item(s) in section
                if isinstance(edit_these[0],
                              str):  # Translate list from names to objects
                    edit_names = edit_these
                    edit_objects = [
                        item for item in self.project_section.value
                        if item.name in edit_these
                    ]
                    edit_these = edit_objects

            else:  # Edit all items in section
                edit_these = []
                edit_these.extend(self.project_section.value)

        frmGenericPropertyEditor.__init__(self, session,
                                          session.project.reservoirs,
                                          edit_these, new_item,
                                          "EPANET Reservoir Editor")

        for column in range(0, self.tblGeneric.columnCount()):
            # for pattern, show available patterns
            pattern_list = self.project.patterns.value
            combobox = QComboBox()
            combobox.addItem('')
            selected_index = 0
            for value in pattern_list:
                combobox.addItem(value.name)
                if edit_these[column].head_pattern_name == value.name:
                    selected_index = int(combobox.count()) - 1
            combobox.setCurrentIndex(selected_index)
            self.tblGeneric.setCellWidget(6, column, combobox)
            # set coordinates
            # coordinate_section = self.project.find_section("COORDINATES")
            # if coordinate_section.value[edit_these[column].name]:
            #     value = coordinate_section.value[edit_these[column].name].x
            #     self.tblGeneric.setItem(1, column, QTableWidgetItem(value))
            #     value = coordinate_section.value[edit_these[column].name].y
            #     self.tblGeneric.setItem(2, column, QTableWidgetItem(value))
            # also set special text plus button cells
            self.set_quality_cell(column)

        self.installEventFilter(self)
Exemplo n.º 27
0
    def set_combo_text(self, combo: QtWidgets.QComboBox, text: str) -> None:
        """Convenience function to update set the current text of a combobox.

        Parameters
        ----------
        combo: PyQt5.QtWidgets.QComboBox
            The combobox to modify
        text: str
            The item to use"""
        items = list(map(combo.itemText, range(combo.count())))
        if text in items:
            combo.setCurrentIndex(items.index(text))
Exemplo n.º 28
0
    def createEditor(self, parent, option, index):
        editor = QComboBox(parent)

        editor.addItem("Unknown (und)", None)
        editor.insertSeparator(editor.count())

        common_langs = ["eng", "deu", "ita", "spa", "fra", "por", "nld",
                        "swe", "nor", "fin", "pol", "ron", "rus", "tur",
                        "vie", "kor", "arz", "pes", "hin", "zho", "jpn"]

        for key in common_langs:
            lang = LANGUAGES[key]
            editor.addItem(f"{lang} ({key})", key)

        editor.insertSeparator(editor.count())

        for key, lang in sorted(LANGUAGES.items(), key=lambda item: item[1]):
            if key in common_langs:
                continue
            editor.addItem(f"{lang} ({key})", key)

        return editor
Exemplo n.º 29
0
    def display_ports(ports: typing.List[QtSerialPort.QSerialPortInfo],
                      combo: QComboBox) -> typing.Dict[str, str]:
        known_keys = set()
        remove_indices = []
        was_empty = combo.count() == 0

        def make_description(p: QtSerialPort.QSerialPortInfo) -> str:
            out = f'{p.portName()}: {p.manufacturer() or "Unknown vendor"} - {p.description() or "Unknown product"}'
            if p.serialNumber().strip():
                out += ' #' + str(p.serialNumber())

            return out

        description_location_mapping = {}
        description_icon_mapping = {}
        for x in ports:
            desc = make_description(x)
            icon = _get_port_icon(x)
            description_location_mapping[desc] = x.systemLocation()
            if icon:
                description_icon_mapping[desc] = icon

        # Marking known and scheduling for removal
        for idx in itertools.count():
            tx = combo.itemText(idx)
            if not tx:
                break

            known_keys.add(tx)
            if tx not in description_location_mapping:
                _logger.debug('Removing port %r', tx)
                remove_indices.append(idx)

        # Removing - starting from the last item in order to retain indexes
        for idx in remove_indices[::-1]:
            combo.removeItem(idx)

        # Adding new items - starting from the last item in order to retain the final order
        for key in list(description_location_mapping.keys())[::-1]:
            if key not in known_keys:
                _logger.debug('Adding port %r', key)
                try:
                    combo.insertItem(0, description_icon_mapping[key], key)
                except KeyError:
                    combo.insertItem(0, key)

        # Updating selection
        if was_empty:
            combo.setCurrentIndex(0)

        return description_location_mapping
Exemplo n.º 30
0
class LateralPanel(QWidget):

    def __init__(self, explorer):
        super(LateralPanel, self).__init__()
        vbox = QVBoxLayout(self)
        vbox.setContentsMargins(0, 0, 0, 0)
        vbox.addWidget(explorer)
        hbox = QHBoxLayout()
        hbox.setContentsMargins(0, 0, 0, 0)
        self.labelText = "Ln: %s, Col: %s"
        self.labelCursorPosition = QLabel(_translate("LateralPanel", self.labelText % (0, 0)))
        hbox.addWidget(self.labelCursorPosition)
        self.combo = QComboBox()
        ui_tools.ComboBoxButton(self.combo, self.combo.clear,
            self.style().standardPixmap(self.style().SP_TrashIcon))
        self.combo.setToolTip(_translate("LateralPanel", "Select the item from the Paste "
            "Historial list.\nYou can Copy items into this list with: "
            "%s\nor Paste them using: %s") %
                (resources.get_shortcut("History-Copy").toString(
                    QKeySequence.NativeText),
                resources.get_shortcut("History-Paste").toString(
                    QKeySequence.NativeText)))
        self.combo.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        hbox.addWidget(self.combo)
        vbox.addLayout(hbox)

    def update_line_col(self, line, col):
        self.labelCursorPosition.setText(_translate("LateralPanel", 
            self.labelText % (line, col)))

    def add_new_copy(self, copy):
        self.combo.insertItem(0, copy)
        self.combo.setCurrentIndex(0)
        if self.combo.count() > settings.COPY_HISTORY_BUFFER:
            self.combo.removeItem(self.combo.count() - 1)

    def get_paste(self):
        return self.combo.currentText()
Exemplo n.º 31
0
class SelectSpeciesDialog(QDialog):
    def __init__(self, species, parent=None):
        super(SelectSpeciesDialog, self).__init__(parent=parent)
        self.setWindowTitle('Select Species')
        layout = QGridLayout(self)
        label = QLabel('species shown in pictures:', self)

        self.species_combo = QComboBox(self)
        self.species_combo.setMinimumWidth(300)
        for s in species:
            self.species_combo.addItem(s)
        add_species_button = QPushButton('New', self)
        
        def add_species():
            name, ok = QInputDialog.getText(self, 'Add Species', 
                                            'name of species:')
            if name and ok:         
                # does species already exist?
                index = self.species_combo.findText(name, 
                                                    QtCore.Qt.MatchFixedString)
                if index >= 0:  
                    self.species_combo.setCurrentIndex(index)
                self.species_combo.addItem(name)
                self.species_combo.setCurrentIndex(
                    self.species_combo.count() - 1 )
                
        add_species_button.pressed.connect(add_species)
        spacer = QSpacerItem(20, 10, QSizePolicy.Fixed)
        buttons = QDialogButtonBox(
            QDialogButtonBox.Ok | QDialogButtonBox.Cancel, self)
        
        def check_selection():
            if len(self.species_combo.currentText()) > 0:
                self.accept()
        buttons.accepted.connect(check_selection)
        buttons.rejected.connect(self.reject)
        layout.addWidget(label, 0, 0)
        layout.addWidget(self.species_combo, 1, 0)
        layout.addWidget(add_species_button, 1, 1)
        layout.addItem(spacer, 2, 0)
        layout.addWidget(buttons, 3, 0)        
                    

    # static method to create the dialog and return (date, time, accepted)
    @staticmethod
    def get_species(species, parent = None):
        dialog = SelectSpeciesDialog(species, parent)
        result = dialog.exec_()
        selection = dialog.species_combo.currentText()   
        return selection, result == QDialog.Accepted
    def __init__(self, main_form, edit_these, new_item):
        self.help_topic = "swmm/src/src/storageunitproperties.htm"
        self._main_form = main_form
        self.project = main_form.project
        self.refresh_column = -1
        self.project_section = self.project.storage
        self.new_item = new_item

        if self.project_section and \
                isinstance(self.project_section.value, list) and \
                len(self.project_section.value) > 0 and \
                isinstance(self.project_section.value[0], self.SECTION_TYPE):

            if edit_these:  # Edit only specified item(s) in section
                if isinstance(edit_these[0],
                              str):  # Translate list from names to objects
                    edit_names = edit_these
                    edit_objects = [
                        item for item in self.project_section.value
                        if item.name in edit_these
                    ]
                    edit_these = edit_objects

            else:  # Edit all items in section
                edit_these = []
                edit_these.extend(self.project_section.value)

        frmGenericPropertyEditor.__init__(self, main_form,
                                          self.project.storage, edit_these,
                                          new_item,
                                          "SWMM Storage Units Editor")

        for column in range(0, self.tblGeneric.columnCount()):
            combobox = QComboBox()
            combobox.addItem('')
            selected_index = 0
            for value in self.project.curves.value:
                if value.curve_type == CurveType.STORAGE:
                    combobox.addItem(value.name)
                    if edit_these[column].storage_curve == value.name:
                        selected_index = int(combobox.count()) - 1
            combobox.setCurrentIndex(selected_index)
            self.tblGeneric.setCellWidget(17, column, combobox)
            # also set special text plus button cells
            self.set_seepage_loss_cell(column)
            self.set_inflow_cell(column)
            self.set_treatment_cell(column)

        self.installEventFilter(self)
    def __init__(self, main_form, edit_these, new_item):
        self.help_topic = "swmm/src/src/flowdividerproperties.htm"
        self._main_form = main_form
        self.project = main_form.project
        self.refresh_column = -1
        self.project_section = self.project.dividers
        if self.project_section and \
                isinstance(self.project_section.value, list) and \
                len(self.project_section.value) > 0 and \
                isinstance(self.project_section.value[0], self.SECTION_TYPE):

            if edit_these:  # Edit only specified item(s) in section
                if isinstance(edit_these[0], str):  # Translate list from names to objects
                    edit_names = edit_these
                    edit_objects = [item for item in self.project_section.value if item.name in edit_these]
                    edit_these = edit_objects

            else:  # Edit all items in section
                edit_these = []
                edit_these.extend(self.project_section.value)

        frmGenericPropertyEditor.__init__(self, main_form, self.project_section, edit_these, new_item, "SWMM Dividers Editor")

        for column in range(0, self.tblGeneric.columnCount()):
            # for curves, show available curves
            curves_section = self.project.find_section("CURVES")
            curves_list = curves_section.value[0:]
            combobox = QComboBox()
            combobox.addItem('')
            selected_index = 0
            for value in curves_list:
                if value.curve_type == CurveType.DIVERSION:
                    combobox.addItem(value.name)
                    if edit_these[column].divider_curve == value.name:
                        selected_index = int(combobox.count())-1
            combobox.setCurrentIndex(selected_index)
            self.tblGeneric.setCellWidget(15, column, combobox)
            # also set special text plus button cells
            self.set_inflow_cell(column)
            self.set_treatment_cell(column)

        if (main_form.program_settings.value("Geometry/" + "frmDividers_geometry") and
                main_form.program_settings.value("Geometry/" + "frmDividers_state")):
            self.restoreGeometry(main_form.program_settings.value("Geometry/" + "frmDividers_geometry",
                                                                  self.geometry(), type=QtCore.QByteArray))
            self.restoreState(main_form.program_settings.value("Geometry/" + "frmDividers_state",
                                                               self.windowState(), type=QtCore.QByteArray))

        self.installEventFilter(self)
Exemplo n.º 34
0
class LateralPanel(QWidget):
    splitEditor = pyqtSignal('QObject*', 'QObject*', bool)
    closeSplit = pyqtSignal(QWidget)
    def __init__(self, parent=None):
        super(LateralPanel, self).__init__(parent)
        self.has_component = False
        self.vbox = QVBoxLayout(self)
        self.vbox.setContentsMargins(0, 0, 0, 0)
        hbox = QHBoxLayout()
        hbox.setContentsMargins(0, 0, 5, 5)
        self.combo = QComboBox()
        ui_tools.ComboBoxButton(self.combo, self.combo.clear,
            self.style().standardPixmap(self.style().SP_TrashIcon))
        self.combo.setToolTip(self.tr("Select the item from the Paste "
            "History list.\nYou can Copy items into this list with: "
            "%s\nor Paste them using: %s") %
                (resources.get_shortcut("History-Copy").toString(
                    QKeySequence.NativeText),
                resources.get_shortcut("History-Paste").toString(
                    QKeySequence.NativeText)))
        self.combo.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        hbox.addWidget(self.combo)
        self.vbox.addLayout(hbox)

    def add_component(self, widget):
        self.vbox.insertWidget(0, widget)
        self.has_component = True

    def add_new_copy(self, copy):
        self.combo.insertItem(0, copy)
        self.combo.setCurrentIndex(0)
        if self.combo.count() > settings.COPY_HISTORY_BUFFER:
            self.combo.removeItem(self.combo.count() - 1)

    def get_paste(self):
        return self.combo.currentText()
Exemplo n.º 35
0
class tb_pulse_load_type(QWidget):

	changed = pyqtSignal()

	def __init__(self,index):
		self.index=index

		QWidget.__init__(self)


		layout=QHBoxLayout()
		label=QLabel()
		label.setText(_("Load type:"))
		layout.addWidget(label)

		self.sim_mode = QComboBox(self)
		self.sim_mode.setEditable(True)


		layout.addWidget(self.sim_mode)

		self.setLayout(layout)

		self.sim_mode.addItem("open_circuit")
		self.sim_mode.addItem("load")
		self.sim_mode.addItem("ideal_diode_ideal_load")


		lines=[]
		inp_load_file(lines,os.path.join(get_inp_file_path(),"pulse"+str(self.index)+".inp"))

		token=inp_get_token_value("pulse"+str(self.index)+".inp", "#pulse_sim_mode")

		all_items  = [self.sim_mode.itemText(i) for i in range(self.sim_mode.count())]
		for i in range(0,len(all_items)):
		    if all_items[i] == token:
		        self.sim_mode.setCurrentIndex(i)

		self.sim_mode.currentIndexChanged.connect(self.call_back_sim_mode_changed)


	def call_back_sim_mode_changed(self):
		mode=self.sim_mode.currentText()
		inp_update_token_value("pulse"+str(self.index)+".inp", "#pulse_sim_mode", mode,1)
		self.changed.emit()
Exemplo n.º 36
0
class LabelComboBox(QWidget):
    def __init__(self, label='', items = {'UJ object reference value': 'Name to show'}):
        super(LabelComboBox, self).__init__()
        self.label = QLabel()
        self.label.setText(label)
        self.items = items
        self.combo_box = QComboBox()
        self.combo_box.insertItems(0, self.items.values())
        self.layout = QHBoxLayout()
        self.layout.setContentsMargins(0,0,0,0)
        self.layout.addWidget(self.label)
        self.layout.addWidget(self.combo_box, stretch = 1)

    def reset_items(self, items = {'UJ object reference value': 'Name to show'}):
        while self.combo_box.count() != 0:
            self.combo_box.removeItem(0)
        self.items = items
        self.combo_box.addItems(self.items.values())

    def show(self):
        self.combo_box.show()
        self.label.show()

    def hide(self):
        self.combo_box.hide()
        self.label.hide()

    def set_text(self, text):
        if text in self.items.values():
            self.combo_box.setCurrentText(text)

        if text in self.items.keys():
            self.combo_box.setCurrentText(self.items[text])

    def text(self):
        return self.combo_box.currentText()
Exemplo n.º 37
0
class NetworkSettingsPanel(SettingsPanel):
    def __init__(self, parent=None):
        super(NetworkSettingsPanel, self).__init__(parent)

        # Checkbox to toggle DNS prefetching.
        self.dnsPrefetchingToggle = QCheckBox(tr("Enable DNS &prefetching"), self)
        self.layout().addWidget(self.dnsPrefetchingToggle)

        # Checkbox to toggle XSS auditing.
        self.xssAuditingToggle = QCheckBox(tr("Enable X&SS auditing"), self)
        self.layout().addWidget(self.xssAuditingToggle)

        # Proxy label.
        proxyLabel = QLabel(tr("<b>Proxy configuration</b>"))
        self.layout().addWidget(proxyLabel)

        # Type row.
        typeRow = custom_widgets.Row(self)
        self.layout().addWidget(typeRow)

        # Create a nice label.
        typeLabel = QLabel(tr("Type:"), self)
        typeRow.addWidget(typeLabel)

        # Combo box to select proxy type.
        self.proxySelect = QComboBox(self)
        self.proxySelect.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        self.proxySelect.addItem("None")
        self.proxySelect.addItem('Socks5')
        self.proxySelect.addItem('Http')
        typeRow.addWidget(self.proxySelect)

        # Hostname and port row.
        self.hostNamePortRow = custom_widgets.Row()
        self.layout().addWidget(self.hostNamePortRow)

        # Hostname row.
        self.hostNameRow = custom_widgets.LineEditRow(tr("Hostname:"), self)
        self.hostNameEntry = self.hostNameRow.lineEdit
        self.hostNamePortRow.addWidget(self.hostNameRow)

        # Port row.
        self.portRow = custom_widgets.SpinBoxRow(tr("Port:"), self)
        self.portRow.expander.hide()
        self.portEntry = self.portRow.spinBox
        self.portEntry.setMaximum(99999)
        self.hostNamePortRow.addWidget(self.portRow)

        # User row.
        self.userRow = custom_widgets.LineEditRow(tr("User:"******"Password:"******"proxy/Hostname")))
        self.userEntry.setText(str(settings.settings.value("proxy/User")))
        self.passwordEntry.setText(str(settings.settings.value("proxy/Password")))
        self.xssAuditingToggle.setChecked(settings.setting_to_bool("network/XSSAuditingEnabled"))
        self.dnsPrefetchingToggle.setChecked(settings.setting_to_bool("network/DnsPrefetchingEnabled"))
        port = settings.setting_to_int("proxy/Port")
        if port == "None":
            port = str(settings.default_port)
        self.portEntry.setValue(port)
        for index in range(0, self.proxySelect.count()):
            if self.proxySelect.itemText(index) == settings.settings.value("proxy/Type"):
                self.proxySelect.setCurrentIndex(index)
                break

    def saveSettings(self):
        settings.settings.setValue("proxy/Hostname", self.hostNameEntry.text())
        proxyType = self.proxySelect.currentText()
        if proxyType == "None":
            proxyType = "No"
        settings.settings.setValue("network/XSSAuditingEnabled", self.xssAuditingToggle.isChecked())
        settings.settings.setValue("network/DnsPrefetchingEnabled", self.dnsPrefetchingToggle.isChecked())
        settings.settings.setValue("proxy/Type", proxyType)
        settings.settings.setValue("proxy/Port", self.portEntry.value())
        settings.settings.setValue("proxy/User", self.userEntry.text())
        settings.settings.setValue("proxy/Password", self.passwordEntry.text())
        common.applyWebSettings()
        settings.settings.sync()
Exemplo n.º 38
0
class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.parts = []
        self.blocks = []
        self.centralBlock = [0, 0, 0, 1]
        self.resolution = 16
        self.createGUI()
        self.createMenu()
        self.connectSlots()
        self.project_file = ""
        self.current_block = 0
        self.block_count = 0

    def createGUI(self):
        self.widget = QWidget(self)
        self.gvMain = MainView(self, 0, self.blocks)
        self.views = {key: XYZview(self, self.blocks, key)
                for key in ('xy', 'yz', 'zx')}
        self.cbSelectBox = QComboBox(self)
        self.pbAddBox = QPushButton("Add Box", self)
        self.pbDeleteBox = QPushButton("Delete selected box", self)
        self.slScale = QSlider(self)
        self.slScale.setOrientation(Qt.Horizontal)
        self.slScale.setRange(2, 15)
        self.slScale.setValue(5)
        self.slResolution = QSlider(self)
        self.slResolution.setOrientation(Qt.Horizontal)
        self.slResolution.setRange(1, 6) # resolution is 2**this_value
        self.slResolution.setValue(4) # 2**4 is 16 -- initial resolution
        self.turn_buttons = {'x': QPushButton("Turn around X axis", self),
                             'y': QPushButton("Turn around Y axis", self),
                             'z': QPushButton("Turn around Z axis", self)}
        self.swap_buttons = {'xy': QPushButton("Swap X and Y", self),
                             'yz': QPushButton("Swap Y and Z", self),
                             'zx': QPushButton("Swap Z and X", self)}
        self.grLayout = QGridLayout()
        self.grLayout.addWidget(QLabel("Main view"), 0, 0)
        self.grLayout.addWidget(self.gvMain, 1, 0)
        self.grLayout.addWidget(QLabel("Y view"), 0, 1)
        self.grLayout.addWidget(self.views['zx'], 1, 1)

        self.vbRightLayout = QVBoxLayout()
        self.vbRightLayout.addWidget(QLabel("Select box"))
        self.vbRightLayout.addWidget(self.cbSelectBox)
        self.vbRightLayout.addWidget(self.pbAddBox)
        self.vbRightLayout.addWidget(self.pbDeleteBox)
        self.vbRightLayout.addWidget(QLabel("Scale"))
        self.vbRightLayout.addWidget(self.slScale)
        self.vbRightLayout.addWidget(QLabel("Resolution"))
        self.vbRightLayout.addWidget(self.slResolution)
        self.vbRightLayout.addItem(
            QSpacerItem(0, 0, QSizePolicy.Minimum, QSizePolicy.Expanding))
        for button in self.swap_buttons.values():
            self.vbRightLayout.addWidget(button)
        for button in self.turn_buttons.values():
            self.vbRightLayout.addWidget(button)

        self.hbMainLayout = QHBoxLayout()
        self.hbMainLayout.addLayout(self.grLayout, 10)
        self.hbMainLayout.addLayout(self.vbRightLayout, 1)

        self.grLayout.addWidget(QLabel("X view"), 2, 0)
        self.grLayout.addWidget(self.views['yz'], 3, 0)
        self.grLayout.addWidget(QLabel("Z view"), 2, 1)
        self.grLayout.addWidget(self.views['xy'], 3, 1)
        self.widget.setLayout(self.hbMainLayout)
        self.setCentralWidget(self.widget)
        self.setWindowTitle("Nodebox editor")
        self.resize(1000, 600)

    def createMenu(self):
        self.menuBar = QMenuBar()
        self.fileMenu = self.menuBar.addMenu("&File")
        self.helpMenu = self.menuBar.addMenu("&Help")
        self.aNewProject = self.fileMenu.addAction("Start new project")
        self.aOpen = self.fileMenu.addAction("Open")
        self.aSave = self.fileMenu.addAction("Save as...")
        self.aExport = self.fileMenu.addAction("Export as...")
        self.fileMenu.addSeparator()
        self.aExitApp = self.fileMenu.addAction("Exit")
        self.setMenuBar(self.menuBar)

    def addBox(self):
        self.blocks.append(Block([-8, -8, -8, 1],
                                 [8, 8, 8, 1]))
        self.block_count += 1 # BTW, we will not decrease this value
        self.cbSelectBox.addItems(["Block" + str(self.block_count)])
        self.cbSelectBox.setCurrentIndex(self.cbSelectBox.count()-1)
        self.update()
        self.current_block = self.blocks[self.cbSelectBox.currentIndex()]
        self.sendCurrentBlock(self.current_block)

    def deleteBox(self):
        if self.cbSelectBox.count() != 0:
            idx = self.cbSelectBox.currentIndex()
            del self.blocks[idx]
            self.cbSelectBox.removeItem(idx)
            if self.cbSelectBox.count() != 0:
                self.cbSelectBox.setCurrentIndex(0)
                self.current_block = self.blocks[0]
                self.sendCurrentBlock(self.current_block)
            else:
                self.current_block = 0;
                self.sendCurrentBlock(0)
        self.update()

    def connectSlots(self):
        self.aExitApp.triggered.connect(lambda: sys.exit(0))
        self.aExport.triggered.connect(self.actionExport)
        self.aSave.triggered.connect(self.actionSave)
        self.aNewProject.triggered.connect(self.actionNewProject)
        self.pbAddBox.clicked.connect(self.addBox)
        self.pbDeleteBox.clicked.connect(self.deleteBox)
        self.cbSelectBox.activated.connect(self.cbSwitch)
        self.slScale.valueChanged.connect(self.slScaleChange)
        self.slResolution.valueChanged.connect(self.slResolutionChange)
        self.aOpen.triggered.connect(self.actionOpen)
        for (key, button) in self.turn_buttons.items():
            button.clicked.connect(partial(self.turn, key))
        for (key, button) in self.swap_buttons.items():
            button.clicked.connect(partial(self.swap, key))

    def actionNewProject(self):
        self.blocks.clear()
        self.current_block = 0
        self.cbSelectBox.clear()
        self.sendCurrentBlock(0)
        self.block_count = 0
        self.update()

    def actionExport(self):
        if using_qt5:
            export_as = QFileDialog.getSaveFileName(self, "Export as...")[0]
        else:
            export_as = QFileDialog.getSaveFileName(self, "Export as...")
        create_code = codegen.codegen(self, "mynode", self.blocks, self.resolution)
        if export_as != "":
            create_code.writeToFile(export_as)

    def actionSave(self):
        if using_qt5:
            save_as = QFileDialog.getSaveFileName(self, "Save as...")[0]
        else:
            save_as = QFileDialog.getSaveFileName(self, "Save as...")
        if save_as != "":
            output_file = open(save_as, "w+")
            for b in self.blocks:
                output_file.write(" ".join([
                    str(b.p1()[0]), str(b.p1()[2]), str(b.p1()[1]),
                    str(b.p2()[0]), str(b.p2()[2]), str(b.p2()[1])]) + "\n")
            output_file.close()

    def sendCurrentBlock(self, block):
        for view in self.views.values():
            view.set_current_block(block)

    def sendScale(self, scale):
        for view in self.views.values():
            view.set_scale(scale)
        self.gvMain.scale = scale

    def sendResolution(self, resolution):
        for view in self.views.values():
            view.set_resolution(resolution)
        self.gvMain.resolution = resolution
        self.resolution        = resolution

    def actionOpen(self):
        if using_qt5:
            open_from = QFileDialog.getOpenFileName(self, "Open file")[0]
        else:
            open_from = QFileDialog.getOpenFileName(self, "Open file")
        input_file = open(open_from, "r")
        self.blocks.clear()
        self.sendCurrentBlock(0)
        self.cbSelectBox.clear()
        for line in input_file:
            t = [int(token) for token in line.split(" ")]
            self.blocks.append(Block([t[0], t[2], t[1], 1],
                [t[3], t[5], t[4], 1]))
            self.cbSelectBox.addItems(["Block" + str(len(self.blocks))])
        input_file.close()
        self.update()

    def cbSwitch(self):
        self.current_block = self.blocks[self.cbSelectBox.currentIndex()]
        self.sendCurrentBlock(self.current_block)
        self.update()

    def slScaleChange(self):
        self.sendScale(self.slScale.value())
        self.update()

    def slResolutionChange(self):
        self.sendResolution(2**self.slResolution.value())
        self.update()

    def swap(self, coords):
        for b in self.blocks:
            b.swap(coords)
        self.update()

    def turn(self, coord):
        for b in self.blocks:
            b.turn(coord)
        self.update()
Exemplo n.º 39
0
class MainWindow(QMainWindow):

    """Main window."""

    def __init__(self, parent=None):
        """Init class."""
        super(MainWindow, self).__init__()
        # self.statusBar().showMessage(__doc__.strip().capitalize())
        self.setWindowTitle(__doc__.strip().capitalize())
        self.setMinimumSize(600, 200)
        self.setMaximumSize(800, 400)
        self.resize(self.minimumSize())
        self.setWindowIcon(QIcon.fromTheme("preferences-system"))
        self.center()
        QShortcut("Ctrl+q", self, activated=lambda: self.close())
        self.menuBar().addMenu("&File").addAction("Exit", exit)
        windowMenu = self.menuBar().addMenu("&Window")
        windowMenu.addAction("Minimize", lambda: self.showMinimized())
        windowMenu.addAction("Maximize", lambda: self.showMaximized())
        windowMenu.addAction("FullScreen", lambda: self.showFullScreen())
        windowMenu.addAction("Restore", lambda: self.showNormal())
        windowMenu.addAction("Center", lambda: self.center())
        windowMenu.addAction("Top-Left", lambda: self.move(0, 0))
        windowMenu.addAction("To Mouse", lambda: self.move_to_mouse_position())
        windowMenu.addSeparator()
        windowMenu.addAction(
            "Increase size", lambda:
            self.resize(self.size().width() * 1.4, self.size().height() * 1.4))
        windowMenu.addAction("Decrease size", lambda: self.resize(
            self.size().width() // 1.4, self.size().height() // 1.4))
        windowMenu.addAction("Minimum size", lambda:
                             self.resize(self.minimumSize()))
        windowMenu.addAction("Maximum size", lambda:
                             self.resize(self.maximumSize()))
        windowMenu.addAction("Horizontal Wide", lambda: self.resize(
            self.maximumSize().width(), self.minimumSize().height()))
        windowMenu.addAction("Vertical Tall", lambda: self.resize(
            self.minimumSize().width(), self.maximumSize().height()))
        windowMenu.addSeparator()
        windowMenu.addAction("Disable Resize", lambda:
                             self.setFixedSize(self.size()))
        windowMenu.addAction("Set Interface Font...", lambda:
                             self.setFont(QFontDialog.getFont()[0]))
        helpMenu = self.menuBar().addMenu("&Help")
        helpMenu.addAction("About Qt 5", lambda: QMessageBox.aboutQt(self))
        helpMenu.addAction("About Python 3",
                           lambda: open_new_tab('https://www.python.org'))
        helpMenu.addAction("About" + __doc__,
                           lambda: QMessageBox.about(self, __doc__, HELP))
        helpMenu.addSeparator()
        helpMenu.addAction(
            "Keyboard Shortcut",
            lambda: QMessageBox.information(self, __doc__, "<b>Quit = CTRL+Q"))
        helpMenu.addAction("View Source Code",
                           lambda: call('xdg-open ' + __file__, shell=True))
        helpMenu.addAction("View GitHub Repo", lambda: open_new_tab(__url__))
        helpMenu.addAction("Check Updates", lambda: Downloader(self))
        container = QWidget()
        container_layout = QVBoxLayout(container)
        self.setCentralWidget(container)
        # widgets
        group0, group1 = QGroupBox("Message to QR Code"), QGroupBox("Options")
        container_layout.addWidget(group0)
        container_layout.addWidget(group1)
        # message
        self.message = QLineEdit()
        self.message.setPlaceholderText("{} type a message!".format(getuser()))
        self.message.setToolTip("Message Text to encode as QR Code Image")
        QHBoxLayout(group0).addWidget(self.message)
        # options
        self.background, self.foreground = QComboBox(), QComboBox()
        self.qrcodesize, self.qrerrorlvl = QSpinBox(), QSpinBox()
        self.background.setToolTip("Background Color")
        self.foreground.setToolTip("Foreground Color")
        self.qrcodesize.setToolTip("QR Code Size")
        self.qrerrorlvl.setToolTip("QR Code Error Tolerance Level")
        self.background.addItems(STANDARD_NAMED_COLORS)
        self.foreground.addItems(STANDARD_NAMED_COLORS)
        self.foreground.setCurrentIndex(randint(0, self.background.count()))
        self.qrcodesize.setRange(2, 20)
        self.qrcodesize.setValue(2)
        self.qrcodesize.setSingleStep(2)
        self.qrerrorlvl.setRange(0, 3)
        self.qrerrorlvl.setValue(1)
        self.qrerrorlvl.setSingleStep(1)
        opt_layout = QHBoxLayout(group1)
        opt_layout.addWidget(QLabel("<b>Background"))
        opt_layout.addWidget(self.background)
        opt_layout.addWidget(QLabel("<b>Foreground"))
        opt_layout.addWidget(self.foreground)
        opt_layout.addWidget(QLabel("<b>Size"))
        opt_layout.addWidget(self.qrcodesize)
        opt_layout.addWidget(QLabel("<b>Error Tolerance"))
        opt_layout.addWidget(self.qrerrorlvl)
        self.bt = QDialogButtonBox(self)
        self.bt.setStandardButtons(QDialogButtonBox.Ok |
                                   QDialogButtonBox.Close)
        self.bt.rejected.connect(exit)
        self.bt.accepted.connect(self.run)
        container_layout.addWidget(self.bt)

    def run(self):
        """Run the main method and create QR Code."""
        global BACKGROUND_COLOR, FOREGROUND_COLOR
        global QRCODE_SIZE, ERRORCORRECT_LVL
        if not len(self.message.text().strip()):
            return
        BACKGROUND_COLOR = str(self.background.currentText()).strip().lower()
        FOREGROUND_COLOR = str(self.foreground.currentText()).strip().lower()
        ERRORCORRECT_LVL = abs(self.qrerrorlvl.value())
        QRCODE_SIZE = abs(self.qrcodesize.value())
        qr = QRCode(QRCODE_SIZE, ERRORCORRECT_LVL)
        qr.addData(str(self.message.text()).strip().encode('ASCII', 'ignore'))
        qr.make()
        im = qr.makeImage()
        im.show()
        self.showMinimized()

    def center(self):
        """Center Window on the Current Screen,with Multi-Monitor support."""
        window_geometry = self.frameGeometry()
        mousepointer_position = QApplication.desktop().cursor().pos()
        screen = QApplication.desktop().screenNumber(mousepointer_position)
        centerPoint = QApplication.desktop().screenGeometry(screen).center()
        window_geometry.moveCenter(centerPoint)
        self.move(window_geometry.topLeft())

    def move_to_mouse_position(self):
        """Center the Window on the Current Mouse position."""
        window_geometry = self.frameGeometry()
        window_geometry.moveCenter(QApplication.desktop().cursor().pos())
        self.move(window_geometry.topLeft())

    def closeEvent(self, event):
        """Ask to Quit."""
        the_conditional_is_true = QMessageBox.question(
            self, __doc__.title(), 'Quit ?.', QMessageBox.Yes | QMessageBox.No,
            QMessageBox.No) == QMessageBox.Yes
        event.accept() if the_conditional_is_true else event.ignore()
Exemplo n.º 40
0
class Settings_Net(QWidget):
    def __init__(self, parent: QWidget):
        super(Settings_Net, self).__init__(parent)
        self._layout = QVBoxLayout()
        self.setLayout(self._layout)
        # construct layout
        min_width = 150
        self.user_agents = dict()
        self.user_agents["chrome_win7_x64"] = (
            "Chrome 41, Windows 7 x64",
            "Mozilla/5.0 (Windows NT 6.1; WOW64) "
            "AppleWebKit/537.36 (KHTML, like Gecko) "
            "Chrome/41.0.2227.0 Safari/537.36",
        )
        self.user_agents["chrome_linux_64"] = (
            "Chrome 41, Linux x86_64",
            "Mozilla/5.0 (X11; Linux x86_64) "
            "AppleWebKit/537.36 (KHTML, like Gecko) "
            "Chrome/41.0.2227.0 Safari/537.36",
        )
        self.user_agents["chrome_android"] = (
            "Chrome 47, Android 4.3 Galaxy-S3",
            "Mozilla/5.0 (Linux; Android 4.3; GT-I9300 Build/JSS15J) "
            "AppleWebKit/537.36 (KHTML, like Gecko) "
            "Chrome/47.0.2526.83 Mobile Safari/537.36",
        )
        self.user_agents["firefox_win32"] = (
            "Firefox 40, Windows 7 32-bit",
            "Mozilla/5.0 (Windows NT 6.1; rv:40.0) " "Gecko/20100101 Firefox/40.1",
        )
        self.user_agents["firefox_android"] = (
            "Firefox, Android 4.3 Galaxy-S3",
            "Mozilla/5.0 (Android 4.3; Mobile; rv:43.0) " "Gecko/43.0 Firefox/43.0",
        )
        self.user_agents["edge_win10"] = (
            "Microsoft Edge, Windows 10 x64",
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
            "AppleWebKit/537.36 (KHTML, like Gecko) "
            "Chrome/42.0.2311.135 Safari/537.36 Edge/12.246",
        )
        # server URL
        self._l_surl = QHBoxLayout()
        self._l_ua = QHBoxLayout()
        self._lbl_surl = QLabel(self.tr("Server URL:"), self)
        self._lbl_surl.setMinimumWidth(min_width)
        self._le_surl = QLineEdit(self)
        self._l_surl.addWidget(self._lbl_surl)
        self._l_surl.addWidget(self._le_surl)
        self._layout.addLayout(self._l_surl)
        # emulate browser combo box
        self._l_eb = QHBoxLayout()
        self._lbl_eb = QLabel(self.tr("Emulate browser:"), self)
        self._lbl_eb.setMinimumWidth(min_width)
        self._cb_eb = QComboBox(self)
        self._cb_eb.setEditable(False)
        self._cb_eb.setInsertPolicy(QComboBox.InsertAtBottom)
        ua_keylist = [i for i in self.user_agents.keys()]
        ua_keylist.sort()
        for key_id in ua_keylist:
            b_tuple = self.user_agents[key_id]
            display_string = b_tuple[0]
            self._cb_eb.addItem(display_string, QVariant(str(key_id)))
        self._cb_eb.addItem(self.tr("<Custom>"), QVariant("custom"))
        self._l_eb.addWidget(self._lbl_eb)
        self._l_eb.addWidget(self._cb_eb)
        self._layout.addLayout(self._l_eb)
        # custom user-agent string
        self._lbl_ua = QLabel(self.tr("User-agent string:"), self)
        self._lbl_ua.setMinimumWidth(min_width)
        self._le_ua = QLineEdit(self)
        self._l_ua.addWidget(self._lbl_ua)
        self._l_ua.addWidget(self._le_ua)
        self._layout.addLayout(self._l_ua)
        # proxy settings
        self._l_proxy = QHBoxLayout()
        self._lbl_proxy = QLabel(self.tr("Proxy type:"), self)
        self._lbl_proxy.setMinimumWidth(min_width)
        self._cb_proxy = QComboBox(self)
        self._cb_proxy.setEditable(False)
        self._cb_proxy.addItem(self.tr("No proxy"), QVariant("none"))
        self._cb_proxy.addItem(self.tr("HTTP proxy"), QVariant("http"))
        self._cb_proxy.addItem(self.tr("SOCKS5 proxy"), QVariant("socks5"))
        self._l_proxy.addWidget(self._lbl_proxy)
        self._l_proxy.addWidget(self._cb_proxy)
        self._layout.addLayout(self._l_proxy)
        self._l_proxy_s = QHBoxLayout()
        self._lbl_proxy_s = QLabel(self.tr("Proxy addr:port:"), self)
        self._lbl_proxy_s.setMinimumWidth(min_width)
        self._le_proxy_addr = QLineEdit(self)
        self._l_proxy_s.addWidget(self._lbl_proxy_s)
        self._l_proxy_s.addWidget(self._le_proxy_addr)
        self._layout.addLayout(self._l_proxy_s)
        # all connections
        self._cb_eb.currentIndexChanged.connect(self.on_cb_eb_current_index_changed)
        self._cb_proxy.currentIndexChanged.connect(self.on_cb_proxy_current_index_changed)
        # finalize
        self._layout.addStretch()

    @pyqtSlot(int)
    def on_cb_eb_current_index_changed(self, index: int):
        key_id = str(self._cb_eb.currentData(Qt.UserRole))
        if key_id == "custom":
            self._le_ua.setEnabled(True)
            return
        self._le_ua.setEnabled(False)
        if key_id in self.user_agents:
            b_tuple = self.user_agents[key_id]
            ua_str = b_tuple[1]
            self._le_ua.setText(ua_str)

    @pyqtSlot(int)
    def on_cb_proxy_current_index_changed(self, index: int):
        if index == 0:
            self._le_proxy_addr.setEnabled(False)
        else:
            self._le_proxy_addr.setEnabled(True)

    def ua_select(self, key_id: str):
        cnt = self._cb_eb.count()
        for i in range(cnt):
            item_key_id = str(self._cb_eb.itemData(i, Qt.UserRole))
            if item_key_id == key_id:
                self._cb_eb.setCurrentIndex(i)
                break

    def load_from_config(self, cfg: configparser.ConfigParser):
        # defaults
        xnova_url = "uni4.xnova.su"
        user_agent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0"
        user_agent_id = "custom"
        proxy = ""
        if "net" in cfg:
            xnova_url = cfg["net"]["xnova_url"]
            user_agent = cfg["net"]["user_agent"]
            user_agent_id = cfg["net"]["user_agent_id"]
            proxy = cfg["net"]["proxy"]
        self._le_surl.setText(xnova_url)
        self._le_surl.setEnabled(False)  # cannot be edited by user, for safety!
        # deal with user-agent
        self._le_ua.setText(user_agent)
        if user_agent_id == "custom":
            self._le_ua.setEnabled(True)
        else:
            self._le_ua.setEnabled(False)
        self.ua_select(user_agent_id)
        # deal with proxy
        if proxy == "":
            self._le_proxy_addr.setText("")
            self._cb_proxy.setCurrentIndex(0)
            self._le_proxy_addr.setEnabled(False)
        elif proxy.startswith("http://"):
            self._cb_proxy.setCurrentIndex(1)
            proxy_addr = proxy[7:]
            self._le_proxy_addr.setText(proxy_addr)
            self._le_proxy_addr.setEnabled(True)
        elif proxy.startswith("socks5://"):
            self._cb_proxy.setCurrentIndex(2)
            proxy_addr = proxy[9:]
            self._le_proxy_addr.setText(proxy_addr)
            self._le_proxy_addr.setEnabled(True)
        else:
            raise ValueError("Invalid proxy setting: " + proxy)

    def save_to_config(self, cfg: configparser.ConfigParser):
        # ensure there is a 'net' section
        if "net" not in cfg:
            cfg.add_section("net")
        # skip server url
        # deal with user-agent
        user_agent_id = ""
        user_agent = ""
        idx = self._cb_eb.currentIndex()
        if idx >= 0:
            user_agent_id = str(self._cb_eb.itemData(idx, Qt.UserRole))
            cfg["net"]["user_agent_id"] = user_agent_id
        user_agent = self._le_ua.text().strip()
        if user_agent != "":
            cfg["net"]["user_agent"] = user_agent
        # deal with proxy
        idx = self._cb_proxy.currentIndex()
        proxy_addr = self._le_proxy_addr.text().strip()
        if idx == 0:
            cfg["net"]["proxy"] = ""
        elif idx == 1:
            cfg["net"]["proxy"] = "http://" + proxy_addr
        elif idx == 2:
            cfg["net"]["proxy"] = "socks5://" + proxy_addr
        logger.debug("Saved network config")
Exemplo n.º 41
0
class LayoutSelect(QDialog):

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

        self.filepath = ''
        self.layouts = {}

        self.setWindowModality(Qt.ApplicationModal)
        self.setWindowTitle('Layout selection')
        self.setMaximumSize(675, 300)
        self.setMinimumSize(675, 300)
        self.resize(675, 300)

        self.setLayout(QGridLayout(self))
        self.layout().setContentsMargins(5, 5, 5, 5)

        self.layoutBox = QComboBox(self)
        self.layout().addWidget(self.layoutBox, 0, 0)

        self.layButton = QPushButton(self)
        self.layButton.setText('Select layout')
        self.layout().addWidget(self.layButton, 0, 1)

        self.fileButton = QPushButton(self)
        self.fileButton.setText('Open file')
        self.layout().addWidget(self.fileButton, 0, 2)

        self.layout().setColumnStretch(0, 3)
        self.layout().setColumnStretch(1, 2)
        self.layout().setColumnStretch(2, 1)

        line = QFrame(self)
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)
        self.layout().addWidget(line, 1, 0, 1, 3)

        self.description = QTextBrowser(self)
        self.layout().addWidget(self.description, 2, 0, 1, 3)

        for layout_class in layouts.get_layouts():
            self.layoutBox.addItem(layout_class.NAME)
            self.layouts[layout_class.NAME] = (layout_class,
                                               layout_class.DESCRIPTION)

        if self.layoutBox.count() == 0:
            raise Exception('No layout installed!')

        self.show_description(self.layoutBox.currentText())

        self.layoutBox.currentTextChanged.connect(self.show_description)
        self.layButton.clicked.connect(self.accept)
        self.fileButton.clicked.connect(self.open_file)

    def selected(self):
        return self.layouts[self.layoutBox.currentText()][0]

    def show_description(self, layout_name):
        self.description.setHtml('<center><h2>' + layout_name +
                                 '</h2></center><br>' +
                                 self.layouts[layout_name][1])

    def open_file(self):
        path, _ = QFileDialog.getOpenFileName(self, filter='*.lsp',
                                              directory=os.getenv('HOME'))
        self.filepath = path
        self.accept()

    def closeEvent(self, e):
        e.ignore()
Exemplo n.º 42
0
class PyMultiPageWidget(QWidget):

    currentIndexChanged = pyqtSignal(int)

    pageTitleChanged = pyqtSignal(str)

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

        self.comboBox = QComboBox()
        # MAGIC
        # It is important that the combo box has an object name beginning
        # with '__qt__passive_', otherwise, it is inactive in the form editor
        # of the designer and you can't change the current page via the
        # combo box.
        # MAGIC
        self.comboBox.setObjectName('__qt__passive_comboBox')        
        self.stackWidget = QStackedWidget()
        self.comboBox.activated.connect(self.setCurrentIndex)
        self.layout = QVBoxLayout()
        self.layout.addWidget(self.comboBox)
        self.layout.addWidget(self.stackWidget)
        self.setLayout(self.layout)

    def sizeHint(self):
        return QSize(200, 150)

    def count(self):
        return self.stackWidget.count()

    def widget(self, index):
        return self.stackWidget.widget(index)

    @pyqtSlot(QWidget)
    def addPage(self, page):
        self.insertPage(self.count(), page)

    @pyqtSlot(int, QWidget)
    def insertPage(self, index, page):
        page.setParent(self.stackWidget)
        self.stackWidget.insertWidget(index, page)
        title = page.windowTitle()
        if title == "":
            title = "Page %d" % (self.comboBox.count() + 1)
            page.setWindowTitle(title)
        self.comboBox.insertItem(index, title)

    @pyqtSlot(int)
    def removePage(self, index):
        widget = self.stackWidget.widget(index)
        self.stackWidget.removeWidget(widget)
        self.comboBox.removeItem(index)

    def getPageTitle(self):
        return self.stackWidget.currentWidget().windowTitle()
    
    @pyqtSlot(str)
    def setPageTitle(self, newTitle):
        self.comboBox.setItemText(self.getCurrentIndex(), newTitle)
        self.stackWidget.currentWidget().setWindowTitle(newTitle)
        self.pageTitleChanged.emit(newTitle)

    def getCurrentIndex(self):
        return self.stackWidget.currentIndex()

    @pyqtSlot(int)
    def setCurrentIndex(self, index):
        if index != self.getCurrentIndex():
            self.stackWidget.setCurrentIndex(index)
            self.comboBox.setCurrentIndex(index)
            self.currentIndexChanged.emit(index)

    pageTitle = pyqtProperty(str, fget=getPageTitle, fset=setPageTitle, stored=False)
    currentIndex = pyqtProperty(int, fget=getCurrentIndex, fset=setCurrentIndex)
Exemplo n.º 43
0
class ClearHistoryDialog(QDialog):
    def __init__(self, parent=None):
        super(ClearHistoryDialog, self).__init__(parent)

        self.setWindowFlags(Qt.Dialog)

        self.setWindowTitle(tr("Clear Data"))

        closeWindowAction = QAction(self)
        closeWindowAction.setShortcuts(["Esc", "Ctrl+W", "Ctrl+Shift+Del"])
        closeWindowAction.triggered.connect(self.close)
        self.addAction(closeWindowAction)

        self.layout = QVBoxLayout()
        self.setLayout(self.layout)
        label = QLabel(tr("What to clear:"), self)
        self.layout.addWidget(label)
        self.dataType = QComboBox(self)
        self.dataType.addItem(tr("History"))
        self.dataType.addItem(tr("Cookies"))
        self.dataType.addItem(tr("Memory Caches"))
        self.dataType.addItem(tr("Persistent Storage"))
        self.dataType.addItem(tr("Everything"))
        self.layout.addWidget(self.dataType)
        self.toolBar = QToolBar(self)
        self.toolBar.setStyleSheet(common.blank_toolbar)
        self.toolBar.setMovable(False)
        self.toolBar.setContextMenuPolicy(Qt.CustomContextMenu)
        self.layout.addWidget(self.toolBar)
        self.clearHistoryButton = QPushButton(tr("Clear"), self)
        self.clearHistoryButton.clicked.connect(self.clearHistory)
        self.toolBar.addWidget(self.clearHistoryButton)
        self.closeButton = QPushButton(tr("Close"), self)
        self.closeButton.clicked.connect(self.close)
        self.toolBar.addWidget(self.closeButton)

    def display(self):
        self.show()
        self.activateWindow()

    def clearHistory(self):
        clear_everything = (self.dataType.currentIndex() == self.dataType.count()-1)
        if self.dataType.currentIndex() == 0 or clear_everything:
            data.clearHistory()
        if self.dataType.currentIndex() == 1 or clear_everything:
            data.clearCookies()
        if self.dataType.currentIndex() == 2 or clear_everything:
            QWebSettings.globalSettings().clearMemoryCaches()
        if self.dataType.currentIndex() == 3 or clear_everything:
            QWebSettings.globalSettings().setIconDatabasePath("")
            QWebSettings.globalSettings().setLocalStoragePath("")
            QWebSettings.globalSettings().setOfflineStoragePath("")
            QWebSettings.globalSettings().setOfflineWebApplicationCachePath("")
            for subpath in ("WebpageIcons.db", "LocalStorage", "Databases",):
                path = os.path.abspath(os.path.join(settings.settings_folder, subpath))
                if os.path.isfile(path):
                    try: os.remove(path)
                    except: pass
                elif os.path.isdir(path):
                    if sys.platform.startswith("win"):
                        args = ["rmdir", "/s", "/q", "\"" + path + "\""]
                        try: os.system(" ".join(args))
                        except: pass
                    else:
                        try: subprocess.Popen(["rm", "-rf", path])
                        except: pass
            QWebSettings.globalSettings().enablePersistentStorage(settings.settings_folder)
Exemplo n.º 44
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)
Exemplo n.º 45
0
class CSVOptionsWindow(QWidget):
    def __init__(self, mainwindow):
        QWidget.__init__(self, mainwindow, Qt.Window)
        self._setupUi()
        self.doc = mainwindow.doc
        self.model = mainwindow.model.csv_options
        self.tableModel = CSVOptionsTableModel(self.model, self.tableView)
        self.model.view = self
        self.encodingComboBox.addItems(SUPPORTED_ENCODINGS)

        self.cancelButton.clicked.connect(self.hide)
        self.continueButton.clicked.connect(self.model.continue_import)
        self.targetComboBox.currentIndexChanged.connect(self.targetIndexChanged)
        self.layoutComboBox.currentIndexChanged.connect(self.layoutIndexChanged)
        self.rescanButton.clicked.connect(self.rescanClicked)

    def _setupUi(self):
        self.setWindowTitle(tr("CSV Options"))
        self.resize(526, 369)
        self.verticalLayout = QVBoxLayout(self)
        msg = tr(
            "Specify which CSV columns correspond to which transaction fields. You must also "
            "uncheck the \"Import\" column for lines that don\'t represent a transaction "
            "(header, footer, comments)."
        )
        self.label = QLabel(msg)
        self.label.setWordWrap(True)
        self.verticalLayout.addWidget(self.label)
        self.gridLayout = QGridLayout()
        self.label_2 = QLabel(tr("Layout:"))
        self.gridLayout.addWidget(self.label_2, 0, 0, 1, 1)
        self.layoutComboBox = QComboBox(self)
        self.layoutComboBox.setMinimumSize(QtCore.QSize(160, 0))
        self.gridLayout.addWidget(self.layoutComboBox, 0, 1, 1, 1)
        self.label_4 = QLabel(tr("Delimiter:"))
        self.gridLayout.addWidget(self.label_4, 0, 3, 1, 1)
        self.fieldSeparatorEdit = QLineEdit(self)
        self.fieldSeparatorEdit.setMaximumSize(QtCore.QSize(30, 16777215))
        self.gridLayout.addWidget(self.fieldSeparatorEdit, 0, 4, 1, 1)
        self.targetComboBox = QComboBox(self)
        self.gridLayout.addWidget(self.targetComboBox, 1, 1, 1, 1)
        self.label_3 = QLabel(tr("Target:"))
        self.gridLayout.addWidget(self.label_3, 1, 0, 1, 1)
        self.encodingComboBox = QComboBox(self)
        self.gridLayout.addWidget(self.encodingComboBox, 1, 4, 1, 1)
        spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.gridLayout.addItem(spacerItem, 2, 2, 1, 1)
        self.horizontalLayout_2 = QHBoxLayout()
        self.horizontalLayout_2.setSpacing(0)
        spacerItem1 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.horizontalLayout_2.addItem(spacerItem1)
        self.rescanButton = QPushButton(tr("Rescan"))
        sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.rescanButton.sizePolicy().hasHeightForWidth())
        self.rescanButton.setSizePolicy(sizePolicy)
        self.horizontalLayout_2.addWidget(self.rescanButton)
        self.gridLayout.addLayout(self.horizontalLayout_2, 2, 3, 1, 2)
        self.label_5 = QLabel(tr("Encoding:"))
        self.gridLayout.addWidget(self.label_5, 1, 3, 1, 1)
        self.verticalLayout.addLayout(self.gridLayout)
        self.tableView = QTableView(self)
        self.tableView.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.tableView.setShowGrid(False)
        self.tableView.horizontalHeader().setHighlightSections(False)
        self.tableView.verticalHeader().setVisible(False)
        self.tableView.verticalHeader().setDefaultSectionSize(18)
        self.verticalLayout.addWidget(self.tableView)
        self.horizontalLayout = QHBoxLayout()
        spacerItem2 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem2)
        self.cancelButton = QPushButton(tr("Cancel"))
        self.cancelButton.setShortcut("Esc")
        self.horizontalLayout.addWidget(self.cancelButton)
        self.continueButton = QPushButton(tr("Continue Import"))
        self.continueButton.setDefault(True)
        self.horizontalLayout.addWidget(self.continueButton)
        self.verticalLayout.addLayout(self.horizontalLayout)

    # --- Private
    def _newLayout(self):
        title = tr("New Layout")
        msg = tr("Choose a name for your new layout:")
        name, ok = QInputDialog.getText(self, title, msg)
        if ok and name:
            self.model.new_layout(name)

    def _renameLayout(self):
        title = tr("Rename Layout")
        msg = tr("Choose a name for your layout:")
        name, ok = QInputDialog.getText(self, title, msg)
        if ok and name:
            self.model.rename_selected_layout(name)

    # --- Event Handling
    def layoutIndexChanged(self, index):
        # This one is a little complicated. We want to only be able to select the layouts. If
        # anything else is clicked, we revert back to the old index. If the item has user data,
        # it means that an action has to be performed.
        if index < 0:
            return
        elif index < len(self.model.layout_names):
            layout_name = None if index == 0 else str(self.layoutComboBox.itemText(index))
            self.model.select_layout(layout_name)
        else:
            self.layoutComboBox.setCurrentIndex(self.layoutComboBox.findText(self.model.layout.name))
            data = str(self.layoutComboBox.itemData(index))
            if data == NEW_LAYOUT:
                self._newLayout()
            elif data == RENAME_LAYOUT:
                self._renameLayout()
            elif data == DELETE_LAYOUT:
                self.model.delete_selected_layout()

    def rescanClicked(self):
        self.model.encoding_index = self.encodingComboBox.currentIndex()
        self.model.field_separator = str(self.fieldSeparatorEdit.text())
        self.model.rescan()

    def targetIndexChanged(self, index):
        self.model.selected_target_index = index

    # --- model --> view
    # hide() is called from the model, but is already covered by QWidget
    def refresh_columns(self):
        self.tableModel.beginResetModel()
        self.tableModel.endResetModel()

    def refresh_columns_name(self):
        self.tableModel.refreshColumnsName()

    def refresh_layout_menu(self):
        self.layoutComboBox.currentIndexChanged.disconnect(self.layoutIndexChanged)
        self.layoutComboBox.clear()
        self.layoutComboBox.addItems(self.model.layout_names)
        self.layoutComboBox.insertSeparator(self.layoutComboBox.count())
        self.layoutComboBox.addItem(tr("New Layout..."), NEW_LAYOUT)
        self.layoutComboBox.addItem(tr("Rename Selected Layout..."), RENAME_LAYOUT)
        self.layoutComboBox.addItem(tr("Delete Selected Layout"), DELETE_LAYOUT)
        self.layoutComboBox.setCurrentIndex(self.layoutComboBox.findText(self.model.layout.name))
        self.layoutComboBox.currentIndexChanged.connect(self.layoutIndexChanged)

    def refresh_lines(self):
        self.tableModel.beginResetModel()
        self.tableModel.endResetModel()
        self.fieldSeparatorEdit.setText(self.model.field_separator)

    def refresh_targets(self):
        self.targetComboBox.currentIndexChanged.disconnect(self.targetIndexChanged)
        self.targetComboBox.clear()
        self.targetComboBox.addItems(self.model.target_account_names)
        self.targetComboBox.currentIndexChanged.connect(self.targetIndexChanged)

    def show(self):
        # For non-modal dialogs, show() is not enough to bring the window at the forefront, we have
        # to call raise() as well
        QWidget.show(self)
        self.raise_()

    def show_message(self, msg):
        title = "Warning"
        QMessageBox.warning(self, title, msg)
Exemplo n.º 46
0
class Example(QMainWindow):
    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):
        self.resize(800, 600)

        centralWidget = QWidget(self)
        grid = QGridLayout(centralWidget)
        grid.setSpacing(10)

        self.listOfDiscipline = QComboBox(centralWidget)
        grid.addWidget(self.listOfDiscipline, 0, 0, 1, 1)

        textIn = QLabel(centralWidget)
        textIn.setText('Входные компетенции')
        grid.addWidget(textIn, 1, 0, 1, 1)

        self.tableIn = QTableView(centralWidget)
        grid.addWidget(self.tableIn, 2, 0, 1, 1)

        textOut = QLabel(centralWidget)
        textOut.setText('Выходные компетенции')
        grid.addWidget(textOut, 3, 0, 1, 1)

        self.tableOut = QTableView(centralWidget)
        grid.addWidget(self.tableOut, 4, 0, 1, 1)

        self.setCentralWidget(centralWidget)

        openFile = QAction('Открыть базу данных', self)
        openFile.setShortcut('Ctrl+O')
        openFile.setStatusTip('Открыть базу данных комптенций')
        openFile.triggered.connect(self.MainFunc)

        exitWindow = QAction('Выход', self)
        exitWindow.setStatusTip('Завершение программы')
        exitWindow.triggered.connect(self.close)

        saveFile_one = QAction('Сохранить дисциплину', self)
        saveFile_one.setShortcut('Ctrl+S')
        saveFile_one.setStatusTip('Сохранить одну дисциплину в формате xlsx')
        saveFile_one.triggered.connect(self.save_one)

        saveFile_all = QAction('Сохранить все дисциплины', self)
        saveFile_all.setShortcut('Ctrl+A')
        saveFile_all.setStatusTip('Сохранить все дисциплины в формате xlsx')
        saveFile_all.triggered.connect(self.save_all)

        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&Файл')
        fileMenu.addAction(openFile)
        fileSaveMenu = fileMenu.addMenu('&Дисциплины')
        fileSaveMenu.addAction(saveFile_one)
        fileSaveMenu.addAction(saveFile_all)
        fileMenu.addAction(fileSaveMenu.menuAction())
        fileMenu.addSeparator()
        fileMenu.addAction(exitWindow)

        self.nameFileOpen = ''

        self.statusBar()
        self.setWindowTitle('Формирование компетенций')
        self.show()

    def MainFunc(self):
        """
        Основная функция
        :return:
        """
        self.nameFileOpen = self.showDialog()
        self.listOfDiscipline.activated[str].connect(self.comboPrint)

    def comboPrint(self, displ):
        self.formInComp(displ, self.nameFileOpen, 'table')

    def showDialog(self):
        """
        Открытие базы данных
        :return:
        """
        fname = QFileDialog.getOpenFileName(self, 'Открыть базу данных', '/', 'DataBase(*.sqlite)')[0]
        self.displ = self.listDB(fname)
        return fname

    def listDB(self, namebd):
        """
        Получение списка таблиц базы данных
        :param nameDB:
        :return:
        """
        cache = []
        db = sqlite3.connect(namebd)
        cur = db.cursor()

        k = cur.execute('SELECT * FROM sqlite_master WHERE type = "table"')
        for j in k:
            if j[1] != 'sqlite_stat1' and j[1] != 'ОК' and j[1] != 'ОПК':
                cache.append(j[1])

        cur.close()
        db.close()
        self.listOfDiscipline.addItems(cache)
        return cache

    def formInComp(self, displ, namebd, type):
        """
        Формирование входящих компетенций на основе выходящих
        :param list, namebd:
        :return:
        """
        self.cacheIn = []
        self.cacheOut = []
        self.cacheInDisp = []
        rowIn = 0
        rowOut = 0
        db = sqlite3.connect(namebd)
        cur = db.cursor()
        k = cur.execute('SELECT * FROM ' + displ)
        for line in k:
            inDisp = self.procInDisp(line[6])
            if str(line[0]).find('К') != -1:
                rowOut = rowOut + 1
                self.cacheOut.append(line)
            if inDisp != '':
                self.cacheInDisp.append(inDisp)

        for dis in self.cacheInDisp:
            if dis in self.displ:
                k = cur.execute('SELECT * FROM ' + dis)
                for line in k:
                    if (line[0] != '') and (line[0] != '\t'):
                        self.cacheIn.append(line)
                        rowIn = rowIn + 1

        self.cacheIn.sort()
        self.cacheOut.sort()
        if type == 'table':
            self.createTable('out', rowOut, self.cacheOut)
            self.createTable('in', rowIn, self.cacheIn)
        else:
            return self.cacheIn, self.cacheOut

        cur.close()
        db.close()

    def procInDisp(self, disp):
        """
        Обработка входящих дисциплин для применения в SQL запросах
        :param disp:
        :return:
        """
        m = disp
        m = m.strip()
        m = m.replace(' ', '_')
        m = m.replace('  ', '')
        m = m.replace('   ', '')
        m = m.replace('-', '_')
        m = m.replace('.', '')
        m = m.replace('«', '')
        m = m.replace('»', '')
        m = m.replace(',', '')
        m = m.capitalize()
        return m

    def createTable(self, type_table, rows, list_of_komp):
        """
        Создание и заполнение таблицы
        :param type_table:
        :param row:
        :param list_komp:
        :param list_desc:
        :return:
        """
        if type_table == 'out':
            model = QStandardItemModel(rows, 2)
            list_horizontal = ['Код компетенции', 'Описание компетенции']
            model.setHorizontalHeaderLabels(list_horizontal)
            self.tableOut.setModel(model)
            self.tableOut.setColumnWidth(0, 110)
            self.tableOut.setColumnWidth(1, self.tableOut.width() - 130)
            for row in range(rows):
                for column in range(2):
                    index = model.index(row, column, QModelIndex())
                    model.setData(index, str(list_of_komp[row][column]).strip())
        else:
            model = QStandardItemModel(rows, 2)
            list_horizontal = ['Код компетенции', 'Описание компетенции']
            model.setHorizontalHeaderLabels(list_horizontal)
            self.tableIn.setModel(model)
            self.tableIn.setColumnWidth(0, 110)
            self.tableIn.setColumnWidth(1, self.tableIn.width() - 130)
            for row in range(rows):
                for column in range(2):
                    index = model.index(row, column, QModelIndex())
                    model.setData(index, str(list_of_komp[row][column]).strip())

    def save_one(self):
        wb = openpyxl.Workbook()

        ws = wb.active
        ws.title = str(self.listOfDiscipline.currentText())[:20]
        ws.append(['Входящие компетенции'])
        for line in self.cacheIn:
            ws.append([line[0].strip(), line[1].strip()])
        ws.append(['Выходящие компетенции'])
        for line in self.cacheOut:
            ws.append([line[0].strip(), line[1].strip()])

        wb.save(self.listOfDiscipline.currentText() + '.xlsx')

    def save_all(self):
        count_displ = self.listOfDiscipline.count()
        wb = openpyxl.Workbook()

        ws = wb.active
        ws.title = 'Дисциплины'
        ws['A1'] = 'Сохранениые дисциплины'
        for count in range(count_displ):
            ws.append([str(self.listOfDiscipline.itemText(count))])
        for count in range(count_displ):
            inDis, outDis = self.formInComp(self.listOfDiscipline.itemText(count), self.nameFileOpen, ' ')
            ws = wb.create_sheet(self.listOfDiscipline.itemText(count)[:20])
            ws.append(['Входящие компетенции'])
            for line in inDis:
                ws.append([line[0].strip(), line[1].strip()])
            ws.append(['Выходящие компетенции'])
            for line in outDis:
                ws.append([line[0].strip(), line[1].strip()])
        wb.save('Все дисциплины.xlsx')
Exemplo n.º 47
0
class Interface(QWidget):
    """Interface widget class."""

    def __init__(self, parent):
        super(Interface, self).__init__()
        self._preferences, vbox = parent, QVBoxLayout(self)
        self.toolbar_settings = settings.TOOLBAR_ITEMS

        groupBoxExplorer = QGroupBox(
            translations.TR_PREFERENCES_INTERFACE_EXPLORER_PANEL)
        group_theme = QGroupBox(
            translations.TR_PREFERENCES_THEME)
        group_hdpi = QGroupBox(translations.TR_PREFERENCES_SCREEN_RESOLUTION)
        # groupBoxToolbar = QGroupBox(
        #    translations.TR_PREFERENCES_INTERFACE_TOOLBAR_CUSTOMIZATION)
        groupBoxLang = QGroupBox(
            translations.TR_PREFERENCES_INTERFACE_LANGUAGE)

       # Explorers
        vboxExplorer = QVBoxLayout(groupBoxExplorer)
        self._checkProjectExplorer = QCheckBox(
            translations.TR_PREFERENCES_SHOW_EXPLORER)
        self._checkSymbols = QCheckBox(
            translations.TR_PREFERENCES_SHOW_SYMBOLS)
        self._checkWebInspetor = QCheckBox(
            translations.TR_PREFERENCES_SHOW_WEB_INSPECTOR)
        self._checkFileErrors = QCheckBox(
            translations.TR_PREFERENCES_SHOW_FILE_ERRORS)
        self._checkMigrationTips = QCheckBox(
            translations.TR_PREFERENCES_SHOW_MIGRATION)
        vboxExplorer.addWidget(self._checkProjectExplorer)
        vboxExplorer.addWidget(self._checkSymbols)
        vboxExplorer.addWidget(self._checkWebInspetor)
        vboxExplorer.addWidget(self._checkFileErrors)
        vboxExplorer.addWidget(self._checkMigrationTips)
        # Theme
        vbox_theme = QVBoxLayout(group_theme)
        hbox = QHBoxLayout()
        hbox.addWidget(QLabel(translations.TR_PREFERENCES_NINJA_THEME))
        self._combobox_themes = QComboBox()
        # self._combobox_themes.addItems(theme.available_theme_names())
        self._combobox_themes.setCurrentText(settings.NINJA_SKIN)
        hbox.addWidget(self._combobox_themes)
        vbox_theme.addLayout(hbox)
        vbox_theme.addWidget(
            QLabel(translations.TR_PREFERENCES_REQUIRES_RESTART))
        # HDPI
        hbox = QHBoxLayout(group_hdpi)
        self._combo_resolution = QComboBox()
        self._combo_resolution.addItems([
            translations.TR_PREFERENCES_SCREEN_NORMAL,
            translations.TR_PREFERENCES_SCREEN_AUTO_HDPI,
            translations.TR_PREFERENCES_SCREEN_CUSTOM_HDPI
        ])
        self._combo_resolution.setSizePolicy(
            QSizePolicy.Expanding, QSizePolicy.Fixed)
        hbox.addWidget(self._combo_resolution)
        self._line_custom_hdpi = QLineEdit()
        self._line_custom_hdpi.setPlaceholderText("1.5")
        hbox.addWidget(self._line_custom_hdpi)
        #GUI - Toolbar
        #vbox_toolbar = QVBoxLayout(groupBoxToolbar)
        #hbox_select_items = QHBoxLayout()
        #label_toolbar = QLabel(translations.TR_PREFERENCES_TOOLBAR_ITEMS)
        #label_toolbar.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        #hbox_select_items.addWidget(label_toolbar)
        #self._comboToolbarItems = QComboBox()
        #self._load_combo_data(self._comboToolbarItems)
        #self._btnItemAdd = QPushButton(QIcon(":img/add"), '')
        #self._btnItemAdd.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        #self._btnItemAdd.setIconSize(QSize(16, 16))
        #self._btnItemRemove = QPushButton(QIcon(':img/delete'), '')
        #self._btnItemRemove.setIconSize(QSize(16, 16))
        #self._btnDefaultItems = QPushButton(
            #translations.TR_PREFERENCES_TOOLBAR_DEFAULT)
        #self._btnDefaultItems.setSizePolicy(QSizePolicy.Fixed,
                                            #QSizePolicy.Fixed)
        #self._btnItemRemove.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        #hbox_select_items.addWidget(self._comboToolbarItems)
        #hbox_select_items.addWidget(self._btnItemAdd)
        #hbox_select_items.addWidget(self._btnItemRemove)
        #hbox_select_items.addWidget(self._btnDefaultItems)
        #vbox_toolbar.addLayout(hbox_select_items)
        #self._toolbar_items = QToolBar()
        #self._toolbar_items.setObjectName("custom")
        #self._toolbar_items.setToolButtonStyle(Qt.ToolButtonIconOnly)
        #self._load_toolbar()
        #vbox_toolbar.addWidget(self._toolbar_items)
        #vbox_toolbar.addWidget(QLabel(
            #translations.TR_PREFERENCES_TOOLBAR_CONFIG_HELP))
        # Language
        vboxLanguage = QVBoxLayout(groupBoxLang)
        vboxLanguage.addWidget(QLabel(
            translations.TR_PREFERENCES_SELECT_LANGUAGE))
        self._comboLang = QComboBox()
        self._comboLang.setEnabled(False)
        vboxLanguage.addWidget(self._comboLang)
        vboxLanguage.addWidget(QLabel(
            translations.TR_PREFERENCES_REQUIRES_RESTART))

        # Load Languages
        self._load_langs()

        # Settings
        self._checkProjectExplorer.setChecked(
            settings.SHOW_PROJECT_EXPLORER)
        self._checkSymbols.setChecked(settings.SHOW_SYMBOLS_LIST)
        self._checkWebInspetor.setChecked(settings.SHOW_WEB_INSPECTOR)
        self._checkFileErrors.setChecked(settings.SHOW_ERRORS_LIST)
        self._checkMigrationTips.setChecked(settings.SHOW_MIGRATION_LIST)
        self._line_custom_hdpi.setText(settings.CUSTOM_SCREEN_RESOLUTION)
        index = 0
        if settings.HDPI:
            index = 1
        elif settings.CUSTOM_SCREEN_RESOLUTION:
            index = 2
        self._combo_resolution.setCurrentIndex(index)

        vbox.addWidget(groupBoxExplorer)
        vbox.addWidget(group_theme)
        vbox.addWidget(group_hdpi)
        # vbox.addWidget(groupBoxToolbar)
        vbox.addWidget(groupBoxLang)
        vbox.addStretch(1)

        # Signals
        # self.connect(self._btnItemAdd, SIGNAL("clicked()"),
        #             # self.toolbar_item_added)
        # self.connect(self._btnItemRemove, SIGNAL("clicked()"),
        #             # self.toolbar_item_removed)
        # self.connect(self._btnDefaultItems, SIGNAL("clicked()"),
        #             # self.toolbar_items_default)
        self._combo_resolution.currentIndexChanged.connect(
            self._on_resolution_changed)
        self._preferences.savePreferences.connect(self.save)

    def _on_resolution_changed(self, index):
        enabled = False
        if index == 2:
            enabled = True
        self._line_custom_hdpi.setEnabled(enabled)
    #def toolbar_item_added(self):
        #data = self._comboToolbarItems.itemData(
            #self._comboToolbarItems.currentIndex())
        #if data not in self.toolbar_settings or data == 'separator':
            #selected = self.actionGroup.checkedAction()
            #if selected is None:
                #self.toolbar_settings.append(data)
            #else:
                #dataAction = selected.data()
                #self.toolbar_settings.insert(
                    #self.toolbar_settings.index(dataAction) + 1, data)
            #self._load_toolbar()

##    def toolbar_item_removed(self):
        #data = self._comboToolbarItems.itemData(
            #self._comboToolbarItems.currentIndex())
        #if data in self.toolbar_settings and data != 'separator':
            #self.toolbar_settings.pop(self.toolbar_settings.index(data))
            #self._load_toolbar()
        #elif data == 'separator':
            #self.toolbar_settings.reverse()
            #self.toolbar_settings.pop(self.toolbar_settings.index(data))
            #self.toolbar_settings.reverse()
            #self._load_toolbar()

##    def toolbar_items_default(self):
        #self.toolbar_settings = settings.TOOLBAR_ITEMS_DEFAULT
        #self._load_toolbar()

##    def _load_combo_data(self, combo):
        #self.toolbar_items = {
            #'separator': [QIcon(':img/separator'), 'Add Separtor'],
            #'new-file': [QIcon(resources.IMAGES['new']), self.tr('New File')],
            #'new-project': [QIcon(resources.IMAGES['newProj']),
                #self.tr('New Project')],
            #'save-file': [QIcon(resources.IMAGES['save']),
                #self.tr('Save File')],
            #'save-as': [QIcon(resources.IMAGES['saveAs']), self.tr('Save As')],
            #'save-all': [QIcon(resources.IMAGES['saveAll']),
                #self.tr('Save All')],
            #'save-project': [QIcon(resources.IMAGES['saveAll']),
                #self.tr('Save Project')],
            #'reload-file': [QIcon(resources.IMAGES['reload-file']),
                #self.tr('Reload File')],
            #'open-file': [QIcon(resources.IMAGES['open']),
                #self.tr('Open File')],
            #'open-project': [QIcon(resources.IMAGES['openProj']),
                #self.tr('Open Project')],
            #'activate-profile': [QIcon(resources.IMAGES['activate-profile']),
                #self.tr('Activate Profile')],
            #'deactivate-profile':
                #[QIcon(resources.IMAGES['deactivate-profile']),
                #self.tr('Deactivate Profile')],
            #'print-file': [QIcon(resources.IMAGES['print']),
                #self.tr('Print File')],
            #'close-file':
                #[self.style().standardIcon(QStyle.SP_DialogCloseButton),
                #self.tr('Close File')],
            #'close-projects':
                #[self.style().standardIcon(QStyle.SP_DialogCloseButton),
                #self.tr('Close Projects')],
            #'undo': [QIcon(resources.IMAGES['undo']), self.tr('Undo')],
            #'redo': [QIcon(resources.IMAGES['redo']), self.tr('Redo')],
            #'cut': [QIcon(resources.IMAGES['cut']), self.tr('Cut')],
            #'copy': [QIcon(resources.IMAGES['copy']), self.tr('Copy')],
            #'paste': [QIcon(resources.IMAGES['paste']), self.tr('Paste')],
            #'find': [QIcon(resources.IMAGES['find']), self.tr('Find')],
            #'find-replace': [QIcon(resources.IMAGES['findReplace']),
                #self.tr('Find/Replace')],
            #'find-files': [QIcon(resources.IMAGES['find']),
                #self.tr('Find In files')],
            #'code-locator': [QIcon(resources.IMAGES['locator']),
                #self.tr('Code Locator')],
            #'splith': [QIcon(resources.IMAGES['splitH']),
                #self.tr('Split Horizontally')],
            #'splitv': [QIcon(resources.IMAGES['splitV']),
                #self.tr('Split Vertically')],
            #'follow-mode': [QIcon(resources.IMAGES['follow']),
                #self.tr('Follow Mode')],
            #'zoom-in': [QIcon(resources.IMAGES['zoom-in']), self.tr('Zoom In')],
            #'zoom-out': [QIcon(resources.IMAGES['zoom-out']),
                #self.tr('Zoom Out')],
            #'indent-more': [QIcon(resources.IMAGES['indent-more']),
                #self.tr('Indent More')],
            #'indent-less': [QIcon(resources.IMAGES['indent-less']),
                #self.tr('Indent Less')],
            #'comment': [QIcon(resources.IMAGES['comment-code']),
                #self.tr('Comment')],
            #'uncomment': [QIcon(resources.IMAGES['uncomment-code']),
                #self.tr('Uncomment')],
            #'go-to-definition': [QIcon(resources.IMAGES['go-to-definition']),
                #self.tr('Go To Definition')],
            #'insert-import': [QIcon(resources.IMAGES['insert-import']),
                #self.tr('Insert Import')],
            #'run-project': [QIcon(resources.IMAGES['play']), 'Run Project'],
            #'run-file': [QIcon(resources.IMAGES['file-run']), 'Run File'],
            #'stop': [QIcon(resources.IMAGES['stop']), 'Stop'],
            #'preview-web': [QIcon(resources.IMAGES['preview-web']),
                #self.tr('Preview Web')]}
        #for item in self.toolbar_items:
            #combo.addItem(self.toolbar_items[item][0],
                #self.toolbar_items[item][1], item)
        #combo.model().sort(0)

##    def _load_toolbar(self):
        #pass
        ##self._toolbar_items.clear()
        ##self.actionGroup = QActionGroup(self)
        ##self.actionGroup.setExclusive(True)
        ##for item in self.toolbar_settings:
            ##if item == 'separator':
                ##self._toolbar_items.addSeparator()
            ##else:
                ##action = self._toolbar_items.addAction(
                    ##self.toolbar_items[item][0], self.toolbar_items[item][1])
                ##action.setData(item)
                ##action.setCheckable(True)
                ##self.actionGroup.addAction(action)

    def _load_langs(self):
        langs = file_manager.get_files_from_folder(
            resources.LANGS, '.qm')
        self._languages = ['English'] + \
            [file_manager.get_module_name(lang) for lang in langs]
        self._comboLang.addItems(self._languages)
        if(self._comboLang.count() > 1):
            self._comboLang.setEnabled(True)
        if settings.LANGUAGE:
            index = self._comboLang.findText(settings.LANGUAGE)
        else:
            index = 0
        self._comboLang.setCurrentIndex(index)

    def save(self):
        qsettings = IDE.ninja_settings()

        qsettings.beginGroup("ide")
        qsettings.beginGroup("interface")

        ninja_theme = self._combobox_themes.currentText()
        settings.NINJA_SKIN = ninja_theme
        qsettings.setValue("skin", settings.NINJA_SKIN)
        settings.SHOW_PROJECT_EXPLORER = self._checkProjectExplorer.isChecked()
        qsettings.setValue("showProjectExplorer",
                           settings.SHOW_PROJECT_EXPLORER)
        settings.SHOW_SYMBOLS_LIST = self._checkSymbols.isChecked()
        qsettings.setValue("showSymbolsList", settings.SHOW_SYMBOLS_LIST)
        if self._line_custom_hdpi.isEnabled():
            screen_resolution = self._line_custom_hdpi.text().strip()
            settings.CUSTOM_SCREEN_RESOLUTION = screen_resolution
        else:
            settings.HDPI = bool(self._combo_resolution.currentIndex())
            qsettings.setValue("autoHdpi", settings.HDPI)
            settings.CUSTOM_SCREEN_RESOLUTION = ""
        qsettings.setValue("customScreenResolution",
                           settings.CUSTOM_SCREEN_RESOLUTION)

        qsettings.endGroup()
        qsettings.endGroup()
Exemplo n.º 48
0
class fullScreenEditor(QWidget):
    def __init__(self, index, parent=None):
        QWidget.__init__(self, parent)
        self._background = None
        self._index = index
        self._theme = findThemePath(settings.fullScreenTheme)
        self._themeDatas = loadThemeDatas(self._theme)
        self.setMouseTracking(True)
        self._geometries = {}

        # Text editor
        self.editor = MDEditView(self,
                                index=index,
                                spellcheck=settings.spellcheck,
                                highlighting=True,
                                dict=settings.dict)
        self.editor.setFrameStyle(QFrame.NoFrame)
        self.editor.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.editor.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.editor.installEventFilter(self)
        self.editor.setMouseTracking(True)
        self.editor.setVerticalScrollBar(myScrollBar())
        self.scrollBar = self.editor.verticalScrollBar()
        self.scrollBar.setParent(self)

        # Top Panel
        self.topPanel = myPanel(parent=self)
        # self.topPanel.layout().addStretch(1)

        # Spell checking
        if enchant:
            self.btnSpellCheck = QPushButton(self)
            self.btnSpellCheck.setFlat(True)
            self.btnSpellCheck.setIcon(QIcon.fromTheme("tools-check-spelling"))
            self.btnSpellCheck.setCheckable(True)
            self.btnSpellCheck.setChecked(self.editor.spellcheck)
            self.btnSpellCheck.toggled.connect(self.editor.toggleSpellcheck)
        else:
            self.btnSpellCheck = None

        # Navigation Buttons
        self.btnPrevious = QPushButton(self)
        self.btnPrevious.setFlat(True)
        self.btnPrevious.setIcon(QIcon.fromTheme("arrow-left"))
        self.btnPrevious.clicked.connect(self.switchPreviousItem)
        self.btnNext = QPushButton(self)
        self.btnNext.setFlat(True)
        self.btnNext.setIcon(QIcon.fromTheme("arrow-right"))
        self.btnNext.clicked.connect(self.switchNextItem)
        self.btnNew = QPushButton(self)
        self.btnNew.setFlat(True)
        self.btnNew.setIcon(QIcon.fromTheme("document-new"))
        self.btnNew.clicked.connect(self.createNewText)

        # Path and New Text Buttons
        self.wPath = myPath(self)

        # Close
        self.btnClose = QPushButton(self)
        self.btnClose.setIcon(qApp.style().standardIcon(QStyle.SP_DialogCloseButton))
        self.btnClose.clicked.connect(self.close)
        self.btnClose.setFlat(True)

        # Top panel Layout
        if self.btnSpellCheck:
            self.topPanel.layout().addWidget(self.btnSpellCheck)
        self.topPanel.layout().addSpacing(15)
        self.topPanel.layout().addWidget(self.btnPrevious)
        self.topPanel.layout().addWidget(self.btnNext)
        self.topPanel.layout().addWidget(self.btnNew)

        self.topPanel.layout().addStretch(1)
        self.topPanel.layout().addWidget(self.wPath)
        self.topPanel.layout().addStretch(1)

        self.topPanel.layout().addWidget(self.btnClose)
        self.updateTopBar()

        # Left Panel
        self._locked = False
        self.leftPanel = myPanel(vertical=True, parent=self)
        self.locker = locker(self)
        self.locker.lockChanged.connect(self.setLocked)
        self.leftPanel.layout().addWidget(self.locker)

        # Bottom Panel
        self.bottomPanel = myPanel(parent=self)

        self.bottomPanel.layout().addSpacing(24)
        self.lstThemes = QComboBox(self)
        self.lstThemes.setAttribute(Qt.WA_TranslucentBackground)
        paths = allPaths("resources/themes")
        for p in paths:
            lst = [i for i in os.listdir(p) if os.path.splitext(i)[1] == ".theme"]
            for t in lst:
                themeIni = os.path.join(p, t)
                name = loadThemeDatas(themeIni)["Name"]
                # self.lstThemes.addItem(os.path.splitext(t)[0])
                self.lstThemes.addItem(name)
                self.lstThemes.setItemData(self.lstThemes.count()-1, os.path.splitext(t)[0])

        self.lstThemes.setCurrentIndex(self.lstThemes.findData(settings.fullScreenTheme))
        # self.lstThemes.setCurrentText(settings.fullScreenTheme)
        self.lstThemes.currentTextChanged.connect(self.setTheme)
        self.lstThemes.setMaximumSize(QSize(300, QFontMetrics(qApp.font()).height()))
        themeLabel = QLabel(self.tr("Theme:"), self)
        self.bottomPanel.layout().addWidget(themeLabel)
        self.bottomPanel.layout().addWidget(self.lstThemes)
        self.bottomPanel.layout().addStretch(1)

        self.lblProgress = QLabel(self)
        self.lblProgress.setMaximumSize(QSize(200, 14))
        self.lblProgress.setMinimumSize(QSize(100, 14))
        self.lblWC = QLabel(self)
        self.lblClock = myClockLabel(self)
        self.bottomPanel.layout().addWidget(self.lblWC)
        self.bottomPanel.layout().addWidget(self.lblProgress)
        self.bottomPanel.layout().addSpacing(15)
        self.bottomPanel.layout().addWidget(self.lblClock)
        self.updateStatusBar()

        self.bottomPanel.layout().addSpacing(24)

        # Add Widget Settings
        if self.btnSpellCheck:
            self.topPanel.addWidgetSetting(self.tr("Spellcheck"), 'top-spellcheck', (self.btnSpellCheck, ))
        self.topPanel.addWidgetSetting(self.tr("Navigation"), 'top-navigation', (self.btnPrevious, self.btnNext))
        self.topPanel.addWidgetSetting(self.tr("New Text"), 'top-new-doc', (self.btnNew, ))
        self.topPanel.addWidgetSetting(self.tr("Title"), 'top-title', (self.wPath, ))
        self.topPanel.addSetting(self.tr("Title: Show Full Path"), 'title-show-full-path', True)
        self.topPanel.setSettingCallback('title-show-full-path', lambda var, val: self.updateTopBar())
        self.bottomPanel.addWidgetSetting(self.tr("Theme selector"), 'bottom-theme', (self.lstThemes, themeLabel))
        self.bottomPanel.addWidgetSetting(self.tr("Word count"), 'bottom-wc', (self.lblWC, ))
        self.bottomPanel.addWidgetSetting(self.tr("Progress"), 'bottom-progress', (self.lblProgress, ))
        self.bottomPanel.addSetting(self.tr("Progress: Auto Show/Hide"), 'progress-auto-show', True)
        self.bottomPanel.addWidgetSetting(self.tr("Clock"), 'bottom-clock', (self.lblClock, ))
        self.bottomPanel.addSetting(self.tr("Clock: Show Seconds"), 'clock-show-seconds', True)
        self.bottomPanel.setAutoHideVariable('autohide-bottom')
        self.topPanel.setAutoHideVariable('autohide-top')
        self.leftPanel.setAutoHideVariable('autohide-left')

        # Connection
        self._index.model().dataChanged.connect(self.dataChanged)

        # self.updateTheme()
        self.showFullScreen()
        # self.showMaximized()
        # self.show()

    def __del__(self):
        # print("Leaving fullScreenEditor via Destructor event", flush=True)
        self.showNormal()
        self.close()

    def setLocked(self, val):
        self._locked = val
        self.btnClose.setVisible(not val)

    def setTheme(self, themeName):
        themeName = self.lstThemes.currentData()
        settings.fullScreenTheme = themeName
        self._theme = findThemePath(themeName)
        self._themeDatas = loadThemeDatas(self._theme)
        self.updateTheme()

    def updateTheme(self):
        # Reinit stored geometries for hiding widgets
        self._geometries = {}
        rect = self.geometry()
        self._background = generateTheme(self._themeDatas, rect)

        setThemeEditorDatas(self.editor, self._themeDatas, self._background, rect)

        # Colors
        if self._themeDatas["Foreground/Color"] == self._themeDatas["Background/Color"] or \
                        self._themeDatas["Foreground/Opacity"] < 5:
            self._fgcolor = QColor(self._themeDatas["Text/Color"])
            self._bgcolor = QColor(self._themeDatas["Background/Color"])
        else:
            self._bgcolor = QColor(self._themeDatas["Foreground/Color"])
            self._bgcolor.setAlpha(self._themeDatas["Foreground/Opacity"] * 255 / 100)
            self._fgcolor = QColor(self._themeDatas["Text/Color"])
            if self._themeDatas["Text/Color"] == self._themeDatas["Foreground/Color"]:
                self._fgcolor = QColor(self._themeDatas["Background/Color"])

        # ScrollBar
        r = self.editor.geometry()
        w = qApp.style().pixelMetric(QStyle.PM_ScrollBarExtent)
        r.setWidth(w)
        r.moveRight(rect.right() - rect.left())
        self.scrollBar.setGeometry(r)
        # self.scrollBar.setVisible(False)
        self.hideWidget(self.scrollBar)
        p = self.scrollBar.palette()
        b = QBrush(self._background.copy(self.scrollBar.geometry()))
        p.setBrush(QPalette.Base, b)
        self.scrollBar.setPalette(p)

        self.scrollBar.setColor(self._bgcolor)

        # Left Panel
        r = self.locker.geometry()
        r.moveTopLeft(QPoint(
                0,
                self.geometry().height() / 2 - r.height() / 2
        ))
        self.leftPanel.setGeometry(r)
        self.hideWidget(self.leftPanel)
        self.leftPanel.setColor(self._bgcolor)

        # Top / Bottom Panels
        r = QRect(0, 0, 0, 24)
        r.setWidth(rect.width())
        # r.moveLeft(rect.center().x() - r.width() / 2)
        self.topPanel.setGeometry(r)
        # self.topPanel.setVisible(False)
        self.hideWidget(self.topPanel)
        r.moveBottom(rect.bottom() - rect.top())
        self.bottomPanel.setGeometry(r)
        # self.bottomPanel.setVisible(False)
        self.hideWidget(self.bottomPanel)
        self.topPanel.setColor(self._bgcolor)
        self.bottomPanel.setColor(self._bgcolor)

        # Lst theme
        # p = self.lstThemes.palette()
        p = self.palette()
        p.setBrush(QPalette.Button, self._bgcolor)
        p.setBrush(QPalette.ButtonText, self._fgcolor)
        p.setBrush(QPalette.WindowText, self._fgcolor)

        for panel in (self.bottomPanel, self.topPanel, self.leftPanel):
            for i in range(panel.layout().count()):
                item = panel.layout().itemAt(i)
                if item.widget():
                    item.widget().setPalette(p)
        # self.lstThemes.setPalette(p)
        # self.lblWC.setPalette(p)

        self.update()
        self.editor.centerCursor()

    def paintEvent(self, event):
        if self._background:
            painter = QPainter(self)
            painter.setClipRegion(event.region())
            painter.drawPixmap(event.rect(), self._background, event.rect())
            painter.end()

    def resizeEvent(self, event):
        self.updateTheme()

    def keyPressEvent(self, event):
        if event.key() in [Qt.Key_Escape, Qt.Key_F11] and \
                not self._locked:
            # print("Leaving fullScreenEditor via keyPressEvent", flush=True)
            self.showNormal()
            self.close()
        elif (event.modifiers() & Qt.AltModifier) and \
                event.key() in [Qt.Key_PageUp, Qt.Key_PageDown, Qt.Key_Left, Qt.Key_Right]:
            if event.key() in [Qt.Key_PageUp, Qt.Key_Left]:
                success = self.switchPreviousItem()
            if event.key() in [Qt.Key_PageDown, Qt.Key_Right]:
                success = self.switchNextItem()
            if not success:
                QWidget.keyPressEvent(self, event)
        else:
            QWidget.keyPressEvent(self, event)

    def mouseMoveEvent(self, event):
        r = self.geometry()

        for w in [self.scrollBar, self.topPanel,
                  self.bottomPanel, self.leftPanel]:
            # w.setVisible(w.geometry().contains(event.pos()))
            if self._geometries[w].contains(event.pos()):
                self.showWidget(w)
            else:
                self.hideWidget(w)

    def hideWidget(self, widget):
        if widget not in self._geometries:
            self._geometries[widget] = widget.geometry()

        if hasattr(widget, "_autoHide") and not widget._autoHide:
            return

        # Hides widget in the bottom right corner
        widget.move(self.geometry().bottomRight() + QPoint(1, 1))

    def showWidget(self, widget):
        if widget in self._geometries:
            widget.move(self._geometries[widget].topLeft())

    def eventFilter(self, obj, event):
        if obj == self.editor and event.type() == QEvent.Enter:
            for w in [self.scrollBar, self.topPanel,
                      self.bottomPanel, self.leftPanel]:
                # w.setVisible(False)
                self.hideWidget(w)
        return QWidget.eventFilter(self, obj, event)

    def dataChanged(self, topLeft, bottomRight):
        # This is called sometimes after self has been destroyed. Don't know why.
        if not self or not self._index:
            return
        if topLeft.row() <= self._index.row() <= bottomRight.row():
            self.updateStatusBar()

    def updateTopBar(self):
        item = self._index.internalPointer()
        previousItem = self.previousTextItem(item)
        nextItem = self.nextTextItem(item)
        self.btnPrevious.setEnabled(previousItem is not None)
        self.btnNext.setEnabled(nextItem is not None)
        self.wPath.setItem(item)

    def updateStatusBar(self):
        if self._index:
            item = self._index.internalPointer()

        wc = item.data(Outline.wordCount)
        goal = item.data(Outline.goal)
        pg = item.data(Outline.goalPercentage)

        if goal:
            if settings.fullscreenSettings.get("progress-auto-show", True):
                self.lblProgress.show()
            self.lblWC.setText(self.tr("{} words / {}").format(wc, goal))
        else:
            if settings.fullscreenSettings.get("progress-auto-show", True):
                self.lblProgress.hide()
            self.lblWC.setText(self.tr("{} words").format(wc))
            pg = 0
        rect = self.lblProgress.geometry()
        rect = QRect(QPoint(0, 0), rect.size())
        self.px = QPixmap(rect.size())
        self.px.fill(Qt.transparent)
        p = QPainter(self.px)
        drawProgress(p, rect, pg, 2)
        p.end()
        self.lblProgress.setPixmap(self.px)

        self.locker.setWordCount(wc)
        # If there's a goal, then we update the locker target's number of word accordingly
        # (also if there is a word count, we deduce it.
        if goal and not self.locker.isLocked():
            if wc and goal - wc > 0:
                self.locker.spnWordTarget.setValue(goal - wc)
            elif not wc:
                self.locker.spnWordTarget.setValue(goal)

    def setCurrentModelIndex(self, index):
        self._index = index
        self.editor.setCurrentModelIndex(index)
        self.updateTopBar()
        self.updateStatusBar()

    def switchPreviousItem(self):
        item = self._index.internalPointer()
        previousItem = self.previousTextItem(item)
        if previousItem:
            self.setCurrentModelIndex(previousItem.index())
            return True
        return False

    def switchNextItem(self):
        item = self._index.internalPointer()
        nextItem = self.nextTextItem(item)
        if nextItem:
            self.setCurrentModelIndex(nextItem.index())
            return True
        return False

    def switchToItem(self, item):
        item = self.firstTextItem(item)
        if item:
            self.setCurrentModelIndex(item.index())
        
    def createNewText(self):
        item = self._index.internalPointer()
        newItem = outlineItem(title=qApp.translate("outlineBasics", "New"), _type=settings.defaultTextType)
        self._index.model().insertItem(newItem, item.row() + 1, item.parent().index())
        self.setCurrentModelIndex(newItem.index())

    def previousModelItem(self, item):
        parent = item.parent()
        if not parent:
            # Root has no sibling
            return None

        row = parent.childItems.index(item)
        if row > 0:
            return parent.child(row - 1)
        return self.previousModelItem(parent)

    def nextModelItem(self, item):
        parent = item.parent()
        if not parent:
            # Root has no sibling
            return None

        row = parent.childItems.index(item)
        if row + 1 < parent.childCount():
            return parent.child(row + 1)
        return self.nextModelItem(parent)

    def previousTextItem(self, item):
        previous = self.previousModelItem(item)

        while previous:
            last = self.lastTextItem(previous)
            if last:
                return last
            previous = self.previousModelItem(previous)
        return None
        
    def nextTextItem(self, item):
        if item.isFolder() and item.childCount() > 0:
            next = item.child(0)
        else:
            next = self.nextModelItem(item)

        while next:
            first = self.firstTextItem(next)
            if first:
                return first
            next = self.nextModelItem(next)
        return None

    def firstTextItem(self, item):
        if item.isText():
            return item
        for child in item.children():
            first = self.firstTextItem(child)
            if first:
                return first
        return None

    def lastTextItem(self, item):
        if item.isText():
            return item
        for child in reversed(item.children()):
            last = self.lastTextItem(child)
            if last:
                return last
        return None
Exemplo n.º 49
0
class NBCopy(QWidget):

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

        # get all mounted drives
        self.drives = get_usb_drives()

        # set state variables
        self.debug = debug
        self.source = None
        self.destination = None

        self.initUI()

    def initUI(self):
        """Draw the UI."""

        QToolTip.setFont(QFont('SansSerif', 12))

        grid = QGridLayout()
        self.setLayout(grid)

        lbl_source = QLabel('Source:', self)
        lbl_source.setAlignment(Qt.AlignCenter)

        lbl_destination = QLabel('Destination:', self)
        lbl_destination.setAlignment(Qt.AlignCenter)

        self.cmb_source = QComboBox(self)
        self.populate_cmb_source()
        self.cmb_source.activated.connect(self.source_activated)
        self.cmb_source.setToolTip("Select either a source USB device "
                                   "or a source 'nb' backup directory")

        self.cmb_destination = QComboBox(self)
        self.populate_cmb_destination()
        self.cmb_destination.activated.connect(self.destination_activated)
        self.cmb_destination.setToolTip('Select a destination USB device')

        self.lbl_status = QLabel('', self)
        self.lbl_status.setAlignment(Qt.AlignLeft)
        self.btn_copy = QPushButton('Copy', self)
#        self.btn_copy.setFixedWidth(80)
        self.btn_copy.setFixedWidth(self.btn_copy.width())
        self.btn_copy.clicked.connect(self.start_copy)
        self.btn_copy.setEnabled(False)

        hbox = QHBoxLayout()
        hbox.addWidget(self.lbl_status, Qt.AlignLeft)
        hbox.addStretch(1)
        hbox.addWidget(self.btn_copy, Qt.AlignRight)
        hbox.maximumSize()

        grid.addWidget(lbl_source, 0, 0, Qt.AlignRight)
        grid.addWidget(self.cmb_source, 0, 1)

        grid.addWidget(lbl_destination, 1, 0, Qt.AlignRight)
        grid.addWidget(self.cmb_destination, 1, 1)

        grid.addLayout(hbox, 2, 1)

        grid.setColumnStretch(0, 0)
        grid.setColumnStretch(1, 1)

        self.setWindowTitle('%s %s' % (ProgName, ProgVersion))
        self.setMinimumWidth(MinimumWidth)
        self.show()
        self.setFixedHeight(self.height())

    def populate_cmb_source(self):
        """Fill the source combobox with choices."""

        # remove current items
        while self.cmb_source.count():
            self.cmb_source.removeItem(0)

        # fill combobox with new items
        self.cmb_source.addItem(SelectDirString)
        for path in self.drives:
            self.cmb_source.addItem(path)
        for path in SourcePaths:
            self.cmb_source.addItem(path)

    def populate_cmb_destination(self):
        """Fill the destination combobox with choices."""

        # remove current items
        while self.cmb_destination.count():
            self.cmb_destination.removeItem(0)

        self.cmb_destination.addItem(SelectDestDrive)
        for path in self.drives:
            self.cmb_destination.addItem(path)

    def source_activated(self):
        """User chooses source device/directory."""

        # get source path from combobox
        source = self.cmb_source.currentText()

        if source == SelectDirString:
            # user wants to source from a directory, choose with a file dialog
            dirname = QFileDialog.getExistingDirectory(self, 'Select a source directory:',
                                                       osp.expanduser('~'),
                                                       QFileDialog.ShowDirsOnly)
            self.source = dirname
            if dirname not in SourcePaths:
                SourcePaths.append(dirname)
            self.populate_cmb_source()
            index = self.cmb_source.findText(dirname, Qt.MatchFixedString)
            if index >= 0:
                self.cmb_source.setCurrentIndex(index)
        else:
            self.source = source

        # check that source is good
        if self.source:
            if not self.good_source(self.source):
                self.warn("Path '%s' is a bad source" % self.source)
                self.source = None

        self.check_copy_disabled()

    def destination_activated(self):
        self.destination = self.cmb_destination.currentText()

        # check with user if destination correct
        if not self.good_destination(self.destination):
            self.warn("Path '%s' is a bad destination" % self.destination)
            self.destination = None

        index = self.cmb_destination.findText(self.destination, Qt.MatchFixedString)
        if index >= 0:
            self.cmb_destination.setCurrentIndex(index)

        self.check_copy_disabled()

    def start_copy(self):
        """Start the actual copy.

        Two threads do the formatting/copying, a control thread and a worker
        thread.  This function starts the control thread which manages the 
        worker thread.  The control thread signals this (GUI) thread with two
        message types:
            Status
            Finished
        """

        # disable the 'Copy' button while doing this
        self.btn_copy.setEnabled(False)

        # start the thread to do the work
        self.threadCopy = CopyThread(log, self.source, self.destination)
        self.threadCopy.copy_done.connect(self.copy_thread_finished)
        self.threadCopy.status.connect(self.copy_thread_status)
        self.threadCopy.start()
        log('Copy thread started')

    def copy_thread_status(self, status):
        """Receive a status signal from the copy thread."""

        log('Thread.status=%s' % status)
        self.lbl_status.setText(status)

    def copy_thread_finished(self, new_destination):
        log("Writing '%s' into file '%s'" % (IdFileString, osp.join(new_destination, IdFile)))
        with open(osp.join(new_destination, IdFile), 'w') as fd:
            fd.write(IdFileString)

        self.warn("Finished copying to\n'%s'." % new_destination)

        # reset comboboxes for another possible copy
        self.cmb_source.setCurrentIndex(0)
        self.cmb_destination.setCurrentIndex(0)

        # reset source & destination ready for next try
        # this enables the 'Copy' button
        self.source = None
        self.destination = None
        self.check_copy_disabled()

        # clear the status display
        self.lbl_status.setText('')

    def check_copy_disabled(self):
        """Copy button only enabled if both src&dest defined."""

        state = bool(self.source and self.destination)
        self.btn_copy.setEnabled(state)

    def good_source(self, source):
        """Check that a given source path is a valid source.
       
        This mainly consists of checking that the '.diskid' file exists
        in the root directory and gas the right contents.
        """

        # we need the .diskid file with correct contents
        diskid_file = osp.join(source, IdFile)
        if not osp.isfile(diskid_file):
            log('%s is not a file!?' % diskid_file)
            return False
        with open(diskid_file, 'r') as fd:
            line = fd.read()
        if line != IdFileString:
            log("File %s doesn't contain '%s' but '%s'" % (diskid_file, IdFileString, line))
            return False

        return True

    def good_destination(self, destination):
        """Check that a given destination path is a valid destination."""

        return True

    def exec_cmd(self, cmd):
        """Execute command and return output and exit code."""

#        args = shlex.split(cmd)
#        process = Popen(args, stdout=PIPE)
        process = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT)
        (output, err) = process.communicate()
        exit_code = process.wait()
        output = output.decode("utf-8")
        return (output, exit_code)

    def warn(self, msg):
        log(msg)
        QMessageBox.information(self, '%s %s' % (ProgName, ProgVersion),
                                msg, QMessageBox.Ok, QMessageBox.Ok)
Exemplo n.º 50
0
class PlayerControls(QWidget):

    play = pyqtSignal()
    pause = pyqtSignal()
    stop = pyqtSignal()
    next = pyqtSignal()
    previous = pyqtSignal()
    changeVolume = pyqtSignal(int)
    changeMuting = pyqtSignal(bool)
    changeRate = pyqtSignal(float)

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

        self.playerState = QMediaPlayer.StoppedState
        self.playerMuted = False

        self.playButton = QToolButton(clicked=self.playClicked)
        self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))

        self.stopButton = QToolButton(clicked=self.stop)
        self.stopButton.setIcon(self.style().standardIcon(QStyle.SP_MediaStop))
        self.stopButton.setEnabled(False)

        self.nextButton = QToolButton(clicked=self.next)
        self.nextButton.setIcon(
                self.style().standardIcon(QStyle.SP_MediaSkipForward))

        self.previousButton = QToolButton(clicked=self.previous)
        self.previousButton.setIcon(
                self.style().standardIcon(QStyle.SP_MediaSkipBackward))

        self.muteButton = QToolButton(clicked=self.muteClicked)
        self.muteButton.setIcon(
                self.style().standardIcon(QStyle.SP_MediaVolume))

        self.volumeSlider = QSlider(Qt.Horizontal,
                sliderMoved=self.changeVolume)
        self.volumeSlider.setRange(0, 100)

        self.rateBox = QComboBox(activated=self.updateRate)
        self.rateBox.addItem("0.5x", 0.5)
        self.rateBox.addItem("1.0x", 1.0)
        self.rateBox.addItem("2.0x", 2.0)
        self.rateBox.setCurrentIndex(1)

        layout = QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self.stopButton)
        layout.addWidget(self.previousButton)
        layout.addWidget(self.playButton)
        layout.addWidget(self.nextButton)
        layout.addWidget(self.muteButton)
        layout.addWidget(self.volumeSlider)
        layout.addWidget(self.rateBox)
        self.setLayout(layout)

    def state(self):
        return self.playerState

    def setState(self,state):
        if state != self.playerState:
            self.playerState = state

            if state == QMediaPlayer.StoppedState:
                self.stopButton.setEnabled(False)
                self.playButton.setIcon(
                        self.style().standardIcon(QStyle.SP_MediaPlay))
            elif state == QMediaPlayer.PlayingState:
                self.stopButton.setEnabled(True)
                self.playButton.setIcon(
                        self.style().standardIcon(QStyle.SP_MediaPause))
            elif state == QMediaPlayer.PausedState:
                self.stopButton.setEnabled(True)
                self.playButton.setIcon(
                        self.style().standardIcon(QStyle.SP_MediaPlay))

    def volume(self):
        return self.volumeSlider.value()

    def setVolume(self, volume):
        self.volumeSlider.setValue(volume)

    def isMuted(self):
        return self.playerMuted

    def setMuted(self, muted):
        if muted != self.playerMuted:
            self.playerMuted = muted

            self.muteButton.setIcon(
                    self.style().standardIcon(
                            QStyle.SP_MediaVolumeMuted if muted else QStyle.SP_MediaVolume))

    def playClicked(self):
        if self.playerState in (QMediaPlayer.StoppedState, QMediaPlayer.PausedState):
            self.play.emit()
        elif self.playerState == QMediaPlayer.PlayingState:
            self.pause.emit()

    def muteClicked(self):
        self.changeMuting.emit(not self.playerMuted)

    def playbackRate(self):
        return self.rateBox.itemData(self.rateBox.currentIndex())

    def setPlaybackRate(self, rate):
        for i in range(self.rateBox.count()):
            if qFuzzyCompare(rate, self.rateBox.itemData(i)):
                self.rateBox.setCurrentIndex(i)
                return

        self.rateBox.addItem("%dx" % rate, rate)
        self.rateBox.setCurrentIndex(self.rateBox.count() - 1)

    def updateRate(self):
        self.changeRate.emit(self.playbackRate())
Exemplo n.º 51
0
class SqliteDbTableEditer(QWidget):
    #Db=sqlite3.connect("test.db")
    def __init__(self,dbPath,tblName='',parent=None):

        self.app=QApplication(sys.argv)
        self.SqliteDbTypes=['integer','real','text','blob']
        self.DbPath,self.CurrentTable=dbPath,tblName
        #连接数据库
        self.Db=sqlite3.connect(self.DbPath)
        #构建Gui组件
        super(SqliteDbTableEditer,self).__init__(parent)
        self.setWindowTitle('Sqlite数据库表修改器')
        screen=QDesktopWidget().availableGeometry(0)
        self.setGeometry(screen.width()/3/2-1,
                         screen.height()/5/2-1,
                         screen.width()*2/3,
                         screen.height()*4/5
                         )
        #lay
        lay=QVBoxLayout()
        self.setLayout(lay)
        #数据库表设置控件
        ##layDb
        layDb=QHBoxLayout()
        lay.addLayout(layDb)
        ###lblDb
        lblDb=QLabel('数据库:')
        layDb.addWidget(lblDb)
        ###self.leDb
        self.leDb=QLineEdit()
        self.leDb.setText(self.DbPath)
        layDb.addWidget(self.leDb)
        ###btnDb
        btnChangeDb=QPushButton('浏览')
        btnChangeDb.clicked.connect(self.btnChangeDb_Clicked)
        layDb.addWidget(btnChangeDb)
        ###lblTbl
        lblTbl=QLabel('数据表:')
        layDb.addWidget(lblTbl)
        ###self.cbbTbls
        self.cbbTbls=QComboBox()
        tbls=list(map(lambda x:x[1],
                      list(filter(lambda x:x[0]=='table',
                                  self.Db.execute(
                                      'Select * From sqlite_master'
                                      ).fetchall()
                                  )
                           )
                      )
                  )
        self.cbbTbls.addItems(tbls)
        if self.CurrentTable!='' :
            self.cbbTbls.setCurrentIndex(tbls.index(self.CurrentTable))
        else:
            self.CurrentTable=tbls[0]
            self.makeTableInfo()
            self.cbbTbls.setCurrentIndex(0)
        layDb.addWidget(self.cbbTbls)
        ###lblRename
        lblRename=QLabel('重命名为:')
        layDb.addWidget(lblRename)
        ###self.leRename
        self.leRename=QLineEdit()
        self.leRename.setFixedWidth(100)
        layDb.addWidget(self.leRename)
        ###btnRename
        btnRenameTable=QPushButton('重命名')
        btnRenameTable.clicked.connect(self.btnRenameTable_Clicked)
        layDb.addWidget(btnRenameTable)
        ###btnDeleteTable
        btnDeleteTable=QPushButton('删除表')
        btnDeleteTable.clicked.connect(self.btnDeleteTable_Clicked)
        layDb.addWidget(btnDeleteTable)
        ###btnShow
        self.btnShow=QPushButton('查看表结构')
        self.btnShow.clicked.connect(self.btnShow_Clicked)
        layDb.addWidget(self.btnShow)
        ###设置TableView控件self.tv,以呈现表数据
        self.tv=QTableView()
        lay.addWidget(self.tv)
        ###self.model基本初始化
        self.model=QSqlTableModel(self,QSqlDatabase.addDatabase('QSQLITE'))
        self.model.setEditStrategy(QSqlTableModel.OnFieldChange)
        ###self.tv链接到数据源
        self.tv.setModel(self.model)
        ###self.model数据初始化
        self.model.database().setDatabaseName(self.DbPath)
        self.model.database().open()
        self.model.setTable(self.CurrentTable)
        self.model.select()
        self.cbbTbls.currentIndexChanged.connect(self.changeTable)
        ##layBtns
        layBtns=QHBoxLayout()
        lay.addLayout(layBtns)
        ###btnAddColumn
        btnAddColumn=QPushButton('添加列')
        btnAddColumn.setToolTip('给当前表添加列')
        btnAddColumn.clicked.connect(self.btnAddColumn_Clicked)
        layBtns.addWidget(btnAddColumn)
        ###btnDeleteColumn
        btnDeleteColumn=QPushButton('删除列')
        btnDeleteColumn.setToolTip('删除当前表的列')
        btnDeleteColumn.clicked.connect(self.btnDeleteColumn_Clicked)
        layBtns.addWidget(btnDeleteColumn)
        ###btnRenameColumn
        btnRenameColumn=QPushButton('重命名列')
        btnRenameColumn.setToolTip('重命名当前表的列')
        btnRenameColumn.clicked.connect(self.btnRenameColumn_Clicked)
        layBtns.addWidget(btnRenameColumn)
        ###btnModifyColumnType
        btnModifyColumnType=QPushButton('修改列数据类型')
        btnModifyColumnType.setToolTip('修改当前表的列的数据类型')
        btnModifyColumnType.clicked.connect(self.btnModifyColumnType_Clicked)
        layBtns.addWidget(btnModifyColumnType)
        ###btnModifyColumnConstraint
        btnModifyColumnConstraint=QPushButton('修改列约束')
        btnModifyColumnConstraint.setToolTip('修改当前表的列的约束')
        btnModifyColumnConstraint.clicked.connect(
            self.btnModifyColumnConstraint_Clicked)
        layBtns.addWidget(btnModifyColumnConstraint)
        ###btnOrderColumns
        btnOrderColumns=QPushButton('调整列顺序')
        btnOrderColumns.setToolTip('调整当前表的列的顺序')
        btnOrderColumns.clicked.connect(self.btnOrderColumns_Clicked)
        layBtns.addWidget(btnOrderColumns)
        ###btnModifyTableStruct
        btnModifyTableStruct=QPushButton('修改表结构')
        btnModifyTableStruct.setToolTip('功能:1.增加列;2.删除列;'
                                        +'3.修改列名;4.修改列类型;'
                                        +'5.修改列约束;6.调整列顺序'
                                        )
        btnModifyTableStruct.clicked.connect(self.btnModifyTableStruct_Clicked)
        layBtns.addWidget(btnModifyTableStruct)
        ###btnInsertRow
        btnInsertRow=QPushButton('插入行')
        btnInsertRow.setToolTip('将在数据表最后增加一行新记录')
        btnInsertRow.clicked.connect(self.btnInsertRow_Clicked)
        layBtns.addWidget(btnInsertRow)
        ###btnDeleteRows
        btnDeleteRows=QPushButton('删除行')
        btnDeleteRows.setToolTip('删除所有选中项所在的行')
        btnDeleteRows.clicked.connect(self.btnDeleteRows_Clicked)
        layBtns.addWidget(btnDeleteRows)
        ###btnQuery
        btnQuery=QPushButton('查询数据')
        btnQuery.setToolTip('对当前表或数据库进行查询,查询语句将被直接链接到self.model上')
        btnQuery.clicked.connect(self.btnQuery_Clicked)
        layBtns.addWidget(btnQuery)

        self.show()
        self.app.exec_()

    def __del__(self):
        #销毁多余数据库连接
        #self.Db.commit()
        self.Db.close()
    #----------------------------------------------------------------
    def makeTableInfo(self):
        #table_info=self.Db.execute('pragma table_info(%s)'%self.CurrentTable).fetchall()
        paragmastr="pragma table_info( '" + self.CurrentTable + "' ) "
        table_info=self.Db.execute(paragmastr).fetchall()
        self.columnsCount=len(table_info)
        self.columnsName=list(map(lambda x:x[1],table_info))
        self.columnsType=list(map(lambda x:x[2],table_info))
        dbinfo=self.Db.execute('select * from sqlite_master').fetchall()
        for x in dbinfo:
            if x[0]=='table' and x[1]==self.CurrentTable:
                self.sqlStr=x[4]
                break
    def DeleteColumn(self,tableName,columnName,tempName=''):
        if tempName=='':
            #tempName==''表示直接删除对应的列并提交数据库更改
            tempName=tableName+'temp'
            sqlite_master_sql="select * from sqlite_master"
            sqlite_master=self.Db.execute(sqlite_master_sql).fetchall()
            createStr=filter(lambda x:x[0]=='table' and x[1]==tableName,
                             self.Db.execute('select * from sqlite_master').fetchall())[0][4]
            createStr=','.join(filter(lambda x:x.find(columnName)==-1,createStr.split(',')))
            newColumns=','.join(map(lambda x:x[1],self.Db.execute('Pragma table_info(%s)'%tableName).fetchall()))
            #将旧表重命名为临时表名
            self.Db.execute("Alter Table %s Rename To %s"%(tableName,tempName))
            #新建删除了指定列的数据表
            self.Db.execute(createStr)
            #将旧表的数据导入新表
            self.Db.execute('Insert Into %s Select %s From %s'%
                            (tableName,newColumns,tempName))
            #删除旧表
            self.Db.execute('Drop Table %s'%tempName)
    #----------------------------------------------------------------
    def btnChangeDb_Clicked(self,event):
        pt=QFileDialog.getOpenFileName(
            caption='请选择一个sqlite数据库文件:',
            filter='sqlite数据库文件 (*.db)',
            directory=os.path.dirname(self.DbPath)
            )
        p=pt[0]
        if platform.system()=='Windows':
            p=p.replace('/','\\')
        if os.path.exists(p):
            self.DbPath=p
            self.Db=sqlite3.connect(self.DbPath)
            tbls=map(lambda x:x[1],
                 filter(lambda x:x[0]=='table',
                        self.Db.execute(
                            'Select * From sqlite_master'
                            ).fetchall()
                        )
                 )
            self.cbbTbls.currentIndexChanged.disconnect(self.changeTable)
            self.cbbTbls.clear()
            self.cbbTbls.addItems(tbls)
            self.cbbTbls.currentIndexChanged.connect(self.changeTable)
            self.CurrentTable=tbls[0]
            self.cbbTbls.setCurrentIndex(0)
            self.leDb.setText(p)
            self.model.database().setDatabaseName(self.DbPath)
            self.model.database().open()
            self.model.setTable(self.CurrentTable)
            self.model.select()
    def changeTable(self,event):
        if self.CurrentTable!=self.cbbTbls.itemText(event):
            self.CurrentTable=self.cbbTbls.itemText(event)
            self.model.setTable(self.CurrentTable)
            self.model.select()
            self.makeTableInfo()
            self.btnShow.setText('查看表结构')
    def btnDeleteTable_Clicked(self,event):
        self.Db.execute('Drop Table %s'%self.CurrentTable)
        for i in range(self.cbbTbls.count()-1,-1,-1):
            if self.cbbTbls.itemText(i)==self.CurrentTable:
                self.cbbTbls.removeItem(i)
                break
        self.CurrentTable=self.cbbTbls.itemText(0)
        self.model.setTable(self.CurrentTable)
        self.model.select()
    def btnRenameTable_Clicked(self,event):
        if self.leRename.text()!='':
            if self.leRename.text()!=self.CurrentTable:
                try:
                    self.Db.execute('Alter Table %s Rename To %s'%
                                (self.CurrentTable,self.leRename.text())
                                )
                except sqlite3.OperationalError as e:
                    if e.message=='there is already another table or index with this name: %s'%self.leRename.text():
                        QMessageBox.information(self,'错误',
                            '抱歉,本数据库中以“'+self.leRename.text()+
                            '”为名称的表或索引已经存在,无法完'+
                            '成重命名,请重新输入一个名称',
                            '知道了')
                    else:
                        QMessageBox.information(self,'错误',
                            '抱歉,可能是因表名包含非法字符,故'+
                            '无法完成重命名,请重新输入表名',
                            '知道了')
                    self.leRename.setText('')
                    return
                self.CurrentTable=self.leRename.text()
                self.cbbTbls.setItemText(self.cbbTbls.currentIndex(),
                                         self.CurrentTable
                                         )
                self.model.clear()
                self.model.setQuery(QSqlQuery(
                    'Select * From %s'%self.CurrentTable))
                self.model.select()
                self.leRename.setText('')
        else:
            QMessageBox.information(self,'注意',
                '抱歉,你还没有输入当前表要修改成的表名\n\n'+
                '请先在文本框里输入当前表要重命名成的名字,再点击我',
                '知道了')
    def btnShow_Clicked(self,event):
        if self.btnShow.text()=='查看表结构':
            self.model.setTable('')
            self.model.setQuery(QSqlQuery(
                'pragma table_info(%s)'%self.CurrentTable))
            self.model.select()
            self.btnShow.setText('查看表数据')
        else:
            self.model.setTable(self.CurrentTable)
            self.model.select()
            self.btnShow.setText('查看表结构')
    #----------------------------------------------------------------
    def btnInsertRow_Clicked(self,event):
        self.dlg_InsertRow_Values=[]
        #self.dlg
        self.dlg=QDialog()
        self.dlg.setWindowTitle('插入数据行:')
        #lay
        lay=QVBoxLayout()
        self.dlg.setLayout(lay)
        #lblprompt
        lblprompt=QLabel(
            '请参照创建此表的Sql字符串:\n'+self.sqlStr+
            '\n设置各个字段的数据:')
        lay.addWidget(lblprompt)
        #layG
        layG=QGridLayout()
        lay.addLayout(layG)
        for i in range(len(self.columnsName)):
            #lbl
            lbl=QLabel(self.columnsName[i]+'('+self.columnsType[i]+'):')
            lbl.setAlignment(Qt.AlignRight)
            layG.addWidget(lbl,i,0)
            #le
            le=QLineEdit()
            layG.addWidget(le,i,1)
            if self.columnsType[i].lower() not in self.SqliteDbTypes:
                #cbb
                cbb=QComboBox()
                cbb.addItems(self.SqliteDbTypes)
                cbb.setCurrentIndex(2)
                cbb.setToolTip(
                    '此字段的数据类型不是sqlite标准数据'+
                    '类型,请设置其存储时的使用的sqlite数据类型')
                layG.addWidget(cbb,i,2)
                self.dlg_InsertRow_Values.append((le,cbb))
            else:
                self.dlg_InsertRow_Values.append((le,self.columnsType[i]))
        layG.setColumnStretch(1,1)
        #layH
        layH=QHBoxLayout()
        lay.addLayout(layH)
        #btnOk
        btnOk=QPushButton('确定')
        btnOk.clicked.connect(self.dlg_InsertRow_btnOk_Clicked)
        layH.addWidget(btnOk)
        #btnCancel
        btnCancel=QPushButton('取消')
        btnCancel.clicked.connect(self.dlg.close)
        layH.addWidget(btnCancel)
        self.dlg.show()
    def dlg_InsertRow_btnOk_Clicked(self,event):
        sqlStr="Insert Into %s Values("%self.CurrentTable
        for item in self.dlg_InsertRow_Values:
            if item[0].text()!='':
                if type(item[1])==QComboBox:
                    print (item[0].text(),item[1].currentText())
                else:
                    print (item[0].text(),item[1])
            else:
                pass
    def btnDeleteRows_Clicked(self,event):
        rs=list(map(lambda x:x.row(),self.tv.selectedIndexes()))
        if len(rs)==0:
            QMessageBox.information(self,'提醒','请先选中至少一行,再点击此按钮!')
            return
        for i in reversed(rs):
            self.model.removeRows(i,1)
        self.model.submitAll()
    def btnQuery_Clicked(self,event):
        sqltxt,ok=QInputDialog.getText(self,'查询语句设置',
           '参照创建此表的Sql字符串:\n'+self.sqlStr+
           '\n请输入要设置到self.model的查询语句:')
        if ok:
            self.model.setTable('')
            self.model.setQuery(QSqlQuery(sqltxt))
            self.model.select()
    #----------------------------------------------------------------
    def btnAddColumn_Clicked(self,event):
        self.dlgMake_AddColumn()
    def dlgMake_AddColumn(self,lay=None):
        if lay is None:
            self.dlg=QDialog(self)
            self.dlg.setWindowTitle('添加列:')
        else:
            ##self.grpAddColumn
            self.grpAddColumn=QGroupBox('添加列:')
            self.grpAddColumn.setCheckable(True)
            self.grpAddColumn.setChecked(True)
            lay.addWidget(self.grpAddColumn)
	###layAddColumn
        layAddColumn=QVBoxLayout()
        if lay is None:
            self.dlg.setLayout(layAddColumn)
        else:
            self.grpAddColumn.setLayout(layAddColumn)
        ####self.grpAddColumn_ByCmdArgs
        self.grpAddColumn_ByCmdArgs=QGroupBox('使用参数创建列:')
        self.grpAddColumn_ByCmdArgs.setCheckable(True)
        self.grpAddColumn_ByCmdArgs.setChecked(True)
        self.PreviousChecked=0
        self.grpAddColumn_ByCmdArgs.toggled.connect(
            self.grpAddColumn_ByCmd_toggled)
        layAddColumn.addWidget(self.grpAddColumn_ByCmdArgs)
        #####layAddColumn_ByCmdArgs
        layAddColumn_ByCmdArgs=QHBoxLayout()
        self.grpAddColumn_ByCmdArgs.setLayout(layAddColumn_ByCmdArgs)
        ####lblAddColumn_select
        lblAddColumn_name=QLabel('列名:')
        layAddColumn_ByCmdArgs.addWidget(lblAddColumn_name)
        ####self.leAddColumn_name
        self.leAddColumn_name=QLineEdit()
        self.leAddColumn_name.setFixedWidth(100)
        layAddColumn_ByCmdArgs.addWidget(self.leAddColumn_name)
        ######lblAddColumn_type
        lblAddColumn_type=QLabel('类型:')
        layAddColumn_ByCmdArgs.addWidget(lblAddColumn_type)
        ######self.cbbAddColumn_type
        self.cbbAddColumn_type=QComboBox()
        self.cbbAddColumn_type.addItems(self.SqliteDbTypes)
        self.cbbAddColumn_type.setCurrentIndex(0)
        self.cbbAddColumn_type.setEditable(True)
        layAddColumn_ByCmdArgs.addWidget(self.cbbAddColumn_type)
        ######lblAddColumn_constraint
        lblAddColumn_constraint=QLabel('约束字符串:')
        layAddColumn_ByCmdArgs.addWidget(lblAddColumn_constraint)
        ######self.leAddColumn_constraint
        self.leAddColumn_constraint=QLineEdit()
        layAddColumn_ByCmdArgs.addWidget(self.leAddColumn_constraint)
        ####self.grpAddColumn_ByCmdStr
        self.grpAddColumn_ByCmdStr=QGroupBox('使用sql字符串创建列:')
        self.grpAddColumn_ByCmdStr.setCheckable(True)
        self.grpAddColumn_ByCmdStr.setChecked(False)
        self.grpAddColumn_ByCmdStr.toggled.connect(
            self.grpAddColumn_ByCmd_toggled)
        layAddColumn.addWidget(self.grpAddColumn_ByCmdStr)
        #####layAddColumn_ByCmdStr
        layAddColumn_ByCmdStr=QHBoxLayout()
        self.grpAddColumn_ByCmdStr.setLayout(layAddColumn_ByCmdStr)
        ######lblAddColumn_cmdstr
        lblAddColumn_cmdstr=QLabel('用来增加列的部分或完整Sql字符串:')
        layAddColumn_ByCmdStr.addWidget(lblAddColumn_cmdstr)
        ######self.leAddColumn_cmdstr
        self.leAddColumn_cmdstr=QLineEdit()
        layAddColumn_ByCmdStr.addWidget(self.leAddColumn_cmdstr)
        if lay is None:
            self.dlg.show()
    def grpAddColumn_ByCmd_toggled(self,event):
        if self.PreviousChecked==0:
            self.grpAddColumn_ByCmdStr.setChecked(True)
            self.grpAddColumn_ByCmdArgs.setChecked(False)
            self.PreviousChecked=1
        else:
            self.grpAddColumn_ByCmdArgs.setChecked(True)
            self.grpAddColumn_ByCmdStr.setChecked(False)
            self.PreviousChecked=0
    #----------------------------------------------------------------
    def btnDeleteColumn_Clicked(self,event):
        self.dlgMake_DeleteColumn()
    def dlgMake_DeleteColumn(self,lay=None):
        if lay is None:
            self.dlg=QDialog(self)
            self.dlg.setWindowTitle('删除列:')
        else:
            ##self.grpDeleteColumn
            self.grpDeleteColumn=QGroupBox('删除列:')
            self.grpDeleteColumn.setCheckable(True)
            self.grpDeleteColumn.setChecked(False)
            lay.addWidget(self.grpDeleteColumn)
        ###layDeleteColumn
        layDeleteColumn=QHBoxLayout()
        if lay is None:
            self.dlg.setLayout(layDeleteColumn)
        else:
            self.grpDeleteColumn.setLayout(layDeleteColumn)
        ###layColumnList
        layColumnList=QVBoxLayout()
        layDeleteColumn.addLayout(layColumnList)
        ####lblDeleteColumn
        lblDeleteColumn=QLabel('原有的所有列:')
        layColumnList.addWidget(lblDeleteColumn)
        ####self.lstColumnList
        self.lstColumnList=QListWidget()
        self.lstColumnList.addItems(self.columnsName)
        self.lstColumnList.setFixedWidth(150)
        layColumnList.addWidget(self.lstColumnList)
        ###layDeleteBtns
        layDeleteBtns=QVBoxLayout()
        layDeleteColumn.addLayout(layDeleteBtns)
        ####btnDeleteColumn_Store
        btnDeleteColumn_Store=QPushButton('>>')
        btnDeleteColumn_Store.setFixedWidth(50)
        layDeleteBtns.addWidget(btnDeleteColumn_Store)
        ####btnDeleteColumn_Unstore
        btnDeleteColumn_Unstore=QPushButton('<<')
        btnDeleteColumn_Unstore.setFixedWidth(50)
        layDeleteBtns.addWidget(btnDeleteColumn_Unstore)
        ###layColumnsToDelete
        layColumnsToDelete=QVBoxLayout()
        layDeleteColumn.addLayout(layColumnsToDelete)
        ####lblColumnsToDelete
        lblColumnsToDelete=QLabel('要删除的列:')
        layColumnsToDelete.addWidget(lblColumnsToDelete)
        ####self.lstColumnsToDelete
        self.lstColumnsToDelete=QListWidget()
        self.lstColumnsToDelete.setFixedWidth(150)
        layColumnsToDelete.addWidget(self.lstColumnsToDelete)
        if lay is None:
            self.dlg.show()
    #----------------------------------------------------------------
    def btnRenameColumn_Clicked(self,event):
        self.dlgMake_RenameColumn()
    def dlgMake_RenameColumn(self,lay=None):
        if lay is None:
            self.dlg=QDialog(self)
            self.dlg.setWindowTitle('重命名列:')
        else:
            ##self.grpRenameColumn
            self.grpRenameColumn=QGroupBox('重命名列:')
            self.grpRenameColumn.setCheckable(True)
            self.grpRenameColumn.setChecked(False)
            lay.addWidget(self.grpRenameColumn)
        ###layRenameColumn
        layRenameColumn=QHBoxLayout()
        if lay is None:
            self.dlg.setLayout(layRenameColumn)
        else:
            self.grpRenameColumn.setLayout(layRenameColumn)
        ####lblRenameColumn_select
        lblRenameColumn_select=QLabel('选择列:')
        layRenameColumn.addWidget(lblRenameColumn_select)
        ####self.cbbRenameColumn_select
        self.cbbRenameColumn_select=QComboBox()
        self.cbbRenameColumn_select.addItems(self.columnsName)
        layRenameColumn.addWidget(self.cbbRenameColumn_select)
        ####lblRenameColumn_renameto
        lblRenameColumn_renameto=QLabel('重命名为:')
        layRenameColumn.addWidget(lblRenameColumn_renameto)
        ####self.leRenameColumn_renameto
        self.leRenameColumn_renameto=QLineEdit()
        self.leRenameColumn_renameto.setFixedWidth(80)
        layRenameColumn.addWidget(self.leRenameColumn_renameto)
        ####btnRenameColumn_Store
        btnRenameColumn_Store=QPushButton('标记 >>')
        layRenameColumn.addWidget(btnRenameColumn_Store)
        ####self.cbbRenameColumn_Store
        self.cbbRenameColumn_Store=QComboBox()
        layRenameColumn.addWidget(self.cbbRenameColumn_Store,1)
        if lay is None:
            self.dlg.show()
    #----------------------------------------------------------------
    def btnModifyColumnType_Clicked(self,event):
        self.dlgMake_ModifyColumnType()
    def dlgMake_ModifyColumnType(self,lay=None):
        if lay is None:
            self.dlg=QDialog(self)
            self.dlg.setWindowTitle('修改列数据类型:')
        else:
            ##self.grpModifyColumnType
            self.grpModifyColumnType=QGroupBox('修改列数据类型:')
            self.grpModifyColumnType.setCheckable(True)
            self.grpModifyColumnType.setChecked(False)
            lay.addWidget(self.grpModifyColumnType)
        ###layModifyColumnType
        layModifyColumnType=QHBoxLayout()
        if lay is None:
            self.dlg.setLayout(layModifyColumnType)
        else:
            self.grpModifyColumnType.setLayout(layModifyColumnType)
        ####lblModifyColumnType_select
        lblModifyColumnType_select=QLabel('选择列:')
        layModifyColumnType.addWidget(lblModifyColumnType_select)
        ####self.cbbModifyColumnType_select
        self.cbbModifyColumnType_select=QComboBox()
        self.cbbModifyColumnType_select.addItems(self.columnsName)
        layModifyColumnType.addWidget(self.cbbModifyColumnType_select)
        ####lblModifyColumnType_modifyto
        lblModifyColumnType_modifyto=QLabel('改类型为:')
        layModifyColumnType.addWidget(lblModifyColumnType_modifyto)
        ####self.cbbModifyColumnType_modifyto
        self.cbbModifyColumnType_modifyto=QComboBox()
        self.cbbModifyColumnType_modifyto.setEditable(True)
        self.cbbModifyColumnType_modifyto.addItems(self.SqliteDbTypes)
        self.cbbModifyColumnType_modifyto.setCurrentIndex(2)
        self.cbbModifyColumnType_modifyto.setFixedWidth(80)
        layModifyColumnType.addWidget(self.cbbModifyColumnType_modifyto)
        ####btnModifyColumnType_Store
        btnModifyColumnType_Store=QPushButton('标记 >>')
        layModifyColumnType.addWidget(btnModifyColumnType_Store)
        ####self.cbbModifyColumnType_Store
        self.cbbModifyColumnType_Store=QComboBox()
        layModifyColumnType.addWidget(self.cbbModifyColumnType_Store,1)
        if lay is None:
            self.dlg.show()
    #----------------------------------------------------------------
    def btnModifyColumnConstraint_Clicked(self,event):
        self.dlgMake_ModifyColumnConstraint()
    def dlgMake_ModifyColumnConstraint(self,lay=None):
        if lay is None:
            self.dlg=QDialog(self)
            self.dlg.setWindowTitle('修改列约束:')
        else:
            ##self.grpModifyColumnConstraint
            self.grpModifyColumnConstraint=QGroupBox('修改列约束:')
            self.grpModifyColumnConstraint.setCheckable(True)
            self.grpModifyColumnConstraint.setChecked(False)
            lay.addWidget(self.grpModifyColumnConstraint)
        ###layModifyColumnConstraint
        layModifyColumnConstraint=QHBoxLayout()
        if lay is None:
            self.dlg.setLayout(layModifyColumnConstraint)
        else:
            self.grpModifyColumnConstraint.setLayout(layModifyColumnConstraint)
        ####lblModifyColumnConstraint_select
        lblModifyColumnConstraint_select=QLabel('选择列:')
        layModifyColumnConstraint.addWidget(lblModifyColumnConstraint_select)
        ####self.cbbModifyColumnConstraint_select
        self.cbbModifyColumnConstraint_select=QComboBox()
        self.cbbModifyColumnConstraint_select.addItems(self.columnsName)
        layModifyColumnConstraint.addWidget(self.cbbModifyColumnConstraint_select)
        ####lblModifyColumnConstraint_modifyto
        lblModifyColumnConstraint_modifyto=QLabel('约束改为:')
        layModifyColumnConstraint.addWidget(lblModifyColumnConstraint_modifyto)
        ####self.leModifyColumnConstraint_modifyto
        self.leModifyColumnConstraint_modifyto=QLineEdit()
        self.leModifyColumnConstraint_modifyto.setFixedWidth(80)
        layModifyColumnConstraint.addWidget(self.leModifyColumnConstraint_modifyto)
        ####btnModifyColumnConstraint_Store
        btnModifyColumnConstraint_Store=QPushButton('标记 >>')
        layModifyColumnConstraint.addWidget(btnModifyColumnConstraint_Store)
        ####self.cbbModifyColumnConstraint_Store
        self.cbbModifyColumnConstraint_Store=QComboBox()
        layModifyColumnConstraint.addWidget(self.cbbModifyColumnConstraint_Store,1)
        if lay is None:
            self.dlg.show()
    #----------------------------------------------------------------
    def btnOrderColumns_Clicked(self,event):
        self.dlgMake_OrderColumns()
    def dlgMake_OrderColumns(self,lay=None):
        if lay is None:
            self.dlg=QDialog(self)
            self.dlg.setWindowTitle('调整列顺序:')
        else:
            ##self.grpAdjustColumnOrder
            self.grpAdjustColumnOrder=QGroupBox('调整列顺序:')
            self.grpAdjustColumnOrder.setCheckable(True)
            self.grpAdjustColumnOrder.setChecked(False)
            lay.addWidget(self.grpAdjustColumnOrder)
        ###layAdjustColumnOrder
        layAdjustColumnOrder=QVBoxLayout()
        if lay is None:
            self.dlg.setLayout(layAdjustColumnOrder)
        else:
            self.grpAdjustColumnOrder.setLayout(layAdjustColumnOrder)
        ####lblAdjustColumnOrder
        lblAdjustColumnOrder=QLabel('请调整列顺序:')
        layAdjustColumnOrder.addWidget(lblAdjustColumnOrder)
        ####self.lstAdjustColumnOrder
        self.lstAdjustColumnOrder=QListWidget()
        self.lstAdjustColumnOrder.addItems(self.columnsName)
        self.lstAdjustColumnOrder.setFixedWidth(150)
        layAdjustColumnOrder.addWidget(self.lstAdjustColumnOrder)
        if lay is None:
            self.dlg.setFixedWidth(175)
            self.dlg.show()
    #----------------------------------------------------------------
    def btnModifyTableStruct_Clicked(self,event):
        self.dlg=QDialog(self)
        self.dlg.setWindowTitle(self.CurrentTable+'表结构修改:')
        self.dlg.setWindowFlags(Qt.Window|
                           Qt.MSWindowsFixedSizeDialogHint
                           )
        #lay
        lay=QVBoxLayout()
        self.dlgMake_AddColumn(lay)
        self.dlgMake_RenameColumn(lay)
        self.dlgMake_ModifyColumnType(lay)
        self.dlgMake_ModifyColumnConstraint(lay)
        #layLists
        layLists=QHBoxLayout()
        lay.addLayout(layLists)
        self.dlgMake_DeleteColumn(layLists)
        self.dlgMake_OrderColumns(layLists)
        ##layBtns
        layBtns=QHBoxLayout()
        lay.addLayout(layBtns)
        ##btnOk
        btnOk=QPushButton('提交修改')
        btnOk.clicked.connect(self.btnOk_Clicked)
        layBtns.addWidget(btnOk)
        ##btnCancel
        btnCancel=QPushButton('放弃修改')
        btnCancel.clicked.connect(self.btnCancel_Clicked)
        layBtns.addWidget(btnCancel)

        self.dlg.setLayout(lay)
        self.dlg.open()
    def btnOk_Clicked(self,event):
        #do something here
        self.dlg.close()
    def btnCancel_Clicked(self,event):
        self.dlg.close()
Exemplo n.º 52
0
class Spectrum(QWidget):
    """Plot the power spectrum for a specified channel.

    Attributes
    ----------
    parent : instance of QMainWindow
        the main window.
    x_limit : tuple or list
        2 values specifying the limit on x-axis
    y_limit : tuple or list
        2 values specifying the limit on y-axis
    log : bool
        log-transform the data or not
    idx_chan : instance of QComboBox
        the element with the list of channel names.
    idx_x_min : instance of QLineEdit
        value with min x value
    idx_x_max : instance of QLineEdit
        value with max x value
    idx_y_min : instance of QLineEdit
        value with min y value
    idx_y_max : instance of QLineEdit
        value with max y value
    idx_log : instance of QCheckBox
        widget that defines if log should be used or not
    idx_fig : instance of QGraphicsView
        the view with the power spectrum
    scene : instance of QGraphicsScene
        the scene with GraphicsItems

    Notes
    -----
    If data contains NaN, it doesn't create any spectrum (feature or bug?).
    """
    def __init__(self, parent):
        super().__init__()
        self.parent = parent

        self.config = ConfigSpectrum(self.display_window)

        self.selected_chan = None
        self.idx_chan = None
        self.idx_fig = None
        self.scene = None

        self.create()

    def create(self):
        """Create empty scene for power spectrum."""
        self.idx_chan = QComboBox()
        self.idx_chan.activated.connect(self.display_window)

        self.idx_fig = QGraphicsView(self)
        self.idx_fig.scale(1, -1)

        layout = QVBoxLayout()
        layout.addWidget(self.idx_chan)
        layout.addWidget(self.idx_fig)
        self.setLayout(layout)

        self.resizeEvent(None)

    def show_channame(self, chan_name):
        self.selected_chan = self.idx_chan.currentIndex()

        self.idx_chan.clear()
        self.idx_chan.addItem(chan_name)
        self.idx_chan.setCurrentIndex(0)

    def update(self):
        """Add channel names to the combobox."""
        self.idx_chan.clear()
        for chan_name in self.parent.traces.chan:
            self.idx_chan.addItem(chan_name)

        if self.selected_chan is not None:
            self.idx_chan.setCurrentIndex(self.selected_chan)
            self.selected_chan = None

    def display_window(self):
        """Read the channel name from QComboBox and plot its spectrum.

        This function is necessary it reads the data and it sends it to
        self.display. When the user selects a smaller chunk of data from the
        visible traces, then we don't need to call this function.
        """
        if self.idx_chan.count() == 0:
            self.update()

        chan_name = self.idx_chan.currentText()
        lg.info('Power spectrum for channel ' + chan_name)

        if chan_name:
            trial = 0
            data = self.parent.traces.data(trial=trial, chan=chan_name)
            self.display(data)
        else:
            self.scene.clear()

    def display(self, data):
        """Make graphicsitem for spectrum figure.

        Parameters
        ----------
        data : ndarray
            1D vector containing the data only

        This function can be called by self.display_window (which reads the
        data for the selected channel) or by the mouse-events functions in
        traces (which read chunks of data from the user-made selection).
        """
        value = self.config.value
        self.scene = QGraphicsScene(value['x_min'], value['y_min'],
                                    value['x_max'] - value['x_min'],
                                    value['y_max'] - value['y_min'])
        self.idx_fig.setScene(self.scene)

        self.add_grid()
        self.resizeEvent(None)

        s_freq = self.parent.traces.data.s_freq
        f, Pxx = welch(data, fs=s_freq,
                       nperseg=int(min((s_freq, len(data)))))  # force int

        freq_limit = (value['x_min'] <= f) & (f <= value['x_max'])

        if self.config.value['log']:
            Pxx_to_plot = log(Pxx[freq_limit])
        else:
            Pxx_to_plot = Pxx[freq_limit]

        self.scene.addPath(Path(f[freq_limit], Pxx_to_plot),
                           QPen(QColor(LINE_COLOR), LINE_WIDTH))

    def add_grid(self):
        """Add axis and ticks to figure.

        Notes
        -----
        I know that visvis and pyqtgraphs can do this in much simpler way, but
        those packages create too large a padding around the figure and this is
        pretty fast.

        """
        value = self.config.value

        # X-AXIS
        # x-bottom
        self.scene.addLine(value['x_min'], value['y_min'],
                           value['x_min'], value['y_max'],
                           QPen(QColor(LINE_COLOR), LINE_WIDTH))
        # at y = 0, dashed
        self.scene.addLine(value['x_min'], 0,
                           value['x_max'], 0,
                           QPen(QColor(LINE_COLOR), LINE_WIDTH, Qt.DashLine))
        # ticks on y-axis
        y_high = int(floor(value['y_max']))
        y_low = int(ceil(value['y_min']))
        x_length = (value['x_max'] - value['x_min']) / value['x_tick']
        for y in range(y_low, y_high):
            self.scene.addLine(value['x_min'], y,
                               value['x_min'] + x_length, y,
                               QPen(QColor(LINE_COLOR), LINE_WIDTH))
        # Y-AXIS
        # left axis
        self.scene.addLine(value['x_min'], value['y_min'],
                           value['x_max'], value['y_min'],
                           QPen(QColor(LINE_COLOR), LINE_WIDTH))
        # larger ticks on x-axis every 10 Hz
        x_high = int(floor(value['x_max']))
        x_low = int(ceil(value['x_min']))
        y_length = (value['y_max'] - value['y_min']) / value['y_tick']
        for x in range(x_low, x_high, 10):
            self.scene.addLine(x, value['y_min'],
                               x, value['y_min'] + y_length,
                               QPen(QColor(LINE_COLOR), LINE_WIDTH))
        # smaller ticks on x-axis every 10 Hz
        y_length = (value['y_max'] - value['y_min']) / value['y_tick'] / 2
        for x in range(x_low, x_high, 5):
            self.scene.addLine(x, value['y_min'],
                               x, value['y_min'] + y_length,
                               QPen(QColor(LINE_COLOR), LINE_WIDTH))

    def resizeEvent(self, event):
        """Fit the whole scene in view.

        Parameters
        ----------
        event : instance of Qt.Event
            not important

        """
        value = self.config.value
        self.idx_fig.fitInView(value['x_min'],
                               value['y_min'],
                               value['x_max'] - value['x_min'],
                               value['y_max'] - value['y_min'])

    def reset(self):
        """Reset widget as new"""
        self.idx_chan.clear()
        if self.scene is not None:
            self.scene.clear()
        self.scene = None
Exemplo n.º 53
0
class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()

        centralWidget = QWidget()

        fontLabel = QLabel("Font:")
        self.fontCombo = QFontComboBox()
        sizeLabel = QLabel("Size:")
        self.sizeCombo = QComboBox()
        styleLabel = QLabel("Style:")
        self.styleCombo = QComboBox()
        fontMergingLabel = QLabel("Automatic Font Merging:")
        self.fontMerging = QCheckBox()
        self.fontMerging.setChecked(True)

        self.scrollArea = QScrollArea()
        self.characterWidget = CharacterWidget()
        self.scrollArea.setWidget(self.characterWidget)

        self.findStyles(self.fontCombo.currentFont())
        self.findSizes(self.fontCombo.currentFont())

        self.lineEdit = QLineEdit()
        clipboardButton = QPushButton("&To clipboard")

        self.clipboard = QApplication.clipboard()

        self.fontCombo.currentFontChanged.connect(self.findStyles)
        self.fontCombo.activated[str].connect(self.characterWidget.updateFont)
        self.styleCombo.activated[str].connect(self.characterWidget.updateStyle)
        self.sizeCombo.currentIndexChanged[str].connect(self.characterWidget.updateSize)
        self.characterWidget.characterSelected.connect(self.insertCharacter)
        clipboardButton.clicked.connect(self.updateClipboard)

        controlsLayout = QHBoxLayout()
        controlsLayout.addWidget(fontLabel)
        controlsLayout.addWidget(self.fontCombo, 1)
        controlsLayout.addWidget(sizeLabel)
        controlsLayout.addWidget(self.sizeCombo, 1)
        controlsLayout.addWidget(styleLabel)
        controlsLayout.addWidget(self.styleCombo, 1)
        controlsLayout.addWidget(fontMergingLabel)
        controlsLayout.addWidget(self.fontMerging, 1)
        controlsLayout.addStretch(1)

        lineLayout = QHBoxLayout()
        lineLayout.addWidget(self.lineEdit, 1)
        lineLayout.addSpacing(12)
        lineLayout.addWidget(clipboardButton)

        centralLayout = QVBoxLayout()
        centralLayout.addLayout(controlsLayout)
        centralLayout.addWidget(self.scrollArea, 1)
        centralLayout.addSpacing(4)
        centralLayout.addLayout(lineLayout)
        centralWidget.setLayout(centralLayout)

        self.setCentralWidget(centralWidget)
        self.setWindowTitle("Character Map")

    def findStyles(self, font):
        fontDatabase = QFontDatabase()
        currentItem = self.styleCombo.currentText()
        self.styleCombo.clear()

        for style in fontDatabase.styles(font.family()):
            self.styleCombo.addItem(style)

        styleIndex = self.styleCombo.findText(currentItem)
        if styleIndex == -1:
            self.styleCombo.setCurrentIndex(0)
        else:
            self.styleCombo.setCurrentIndex(styleIndex)

    def findSizes(self, font):
        fontDatabase = QFontDatabase()
        currentSize = self.sizeCombo.currentText()
        self.sizeCombo.blockSignals(True)
        self.sizeCombo.clear()

        if fontDatabase.isSmoothlyScalable(font.family(), fontDatabase.styleString(font)):
            for size in QFontDatabase.standardSizes():
                self.sizeCombo.addItem(str(size))
                self.sizeCombo.setEditable(True)
        else:
            for size in fontDatabase.smoothSizes(font.family(), fontDatabase.styleString(font)):
                self.sizeCombo.addItem(str(size))
                self.sizeCombo.setEditable(False)

        self.sizeCombo.blockSignals(False)

        sizeIndex = self.sizeCombo.findText(currentSize)
        if sizeIndex == -1:
            self.sizeCombo.setCurrentIndex(max(0, self.sizeCombo.count() / 3))
        else:
            self.sizeCombo.setCurrentIndex(sizeIndex)

    def insertCharacter(self, character):
        self.lineEdit.insert(character)

    def updateClipboard(self):
        self.clipboard.setText(self.lineEdit.text(), QClipboard.Clipboard)
        self.clipboard.setText(self.lineEdit.text(), QClipboard.Selection)
Exemplo n.º 54
0
class ProjectTreeColumn(QDialog):

    # Signalsnproject =
    dockWidget = pyqtSignal('PyQt_PyObject')
    undockWidget = pyqtSignal()
    changeTitle = pyqtSignal('PyQt_PyObject', 'QString')
    updateLocator = pyqtSignal()
    activeProjectChanged = pyqtSignal()

    def __init__(self, parent=None):
        super(ProjectTreeColumn, self).__init__(parent)
        vbox = QVBoxLayout(self)
        vbox.setSizeConstraint(QVBoxLayout.SetDefaultConstraint)
        vbox.setContentsMargins(0, 0, 0, 0)
        vbox.setSpacing(0)
        self._buttons = []
        frame = QFrame()
        frame.setObjectName("actionbar")
        box = QVBoxLayout(frame)
        box.setContentsMargins(1, 1, 1, 1)
        box.setSpacing(0)

        self._combo_project = QComboBox()
        self._combo_project.setSizePolicy(
            QSizePolicy.Expanding, QSizePolicy.Fixed)
        self._combo_project.setSizeAdjustPolicy(
            QComboBox.AdjustToMinimumContentsLengthWithIcon)
        self._combo_project.setObjectName("combo_projects")
        box.addWidget(self._combo_project)
        vbox.addWidget(frame)
        self._combo_project.setContextMenuPolicy(Qt.CustomContextMenu)
        self._projects_area = QStackedLayout()
        logger.debug("This is the projects area")
        vbox.addLayout(self._projects_area)

        # Empty widget
        self._empty_proj = QLabel(translations.TR_NO_PROJECTS)
        self._empty_proj.setAlignment(Qt.AlignCenter)
        self._empty_proj.setAutoFillBackground(True)
        self._empty_proj.setBackgroundRole(QPalette.Base)
        self._projects_area.addWidget(self._empty_proj)
        self._projects_area.setCurrentWidget(self._empty_proj)

        self.projects = []

        self._combo_project.activated.connect(
            self._change_current_project)
        self._combo_project.customContextMenuRequested[
            'const QPoint&'].connect(self.context_menu_for_root)

        connections = (
            {
                "target": "main_container",
                "signal_name": "addToProject",
                "slot": self._add_file_to_project
            },
            {
                "target": "main_container",
                "signal_name": "showFileInExplorer",
                "slot": self._show_file_in_explorer
            },
        )
        IDE.register_service('projects_explorer', self)
        IDE.register_signals('projects_explorer', connections)
        ExplorerContainer.register_tab(translations.TR_TAB_PROJECTS, self)

        # FIXME: Should have a ninja settings object that stores tree state
        # FIXME: Or bettter, application data object
        # TODO: check this:
        # self.connect(ide, SIGNAL("goingDown()"),
        #    self.tree_projects.shutdown)

        # def close_project_signal():
        #    self.emit(SIGNAL("updateLocator()"))

    def install_tab(self):
        ide = IDE.get_service('ide')
        ui_tools.install_shortcuts(self, actions.PROJECTS_TREE_ACTIONS, ide)
        ide.goingDown.connect(self._on_ide_going_down)

    def _on_ide_going_down(self):
        """Save some settings before close"""
        if self.current_tree is None:
            return
        ds = IDE.data_settings()
        show_filesize = not bool(self.current_tree.isColumnHidden(1))
        ds.setValue("projectsExplorer/showFileSize", show_filesize)

    def load_session_projects(self, projects):
        for project in projects:
            if os.path.exists(project):
                self._open_project_folder(project)

    def open_project_folder(self, folderName=None):
        if settings.WORKSPACE:
            directory = settings.WORKSPACE
        else:
            directory = os.path.expanduser("~")

        if folderName is None:
            folderName = QFileDialog.getExistingDirectory(
                self, translations.TR_OPEN_PROJECT_DIRECTORY, directory)
            logger.debug("Choosing Foldername")
        if folderName:
            if not file_manager.folder_exists(folderName):
                QMessageBox.information(
                    self,
                    translations.TR_PROJECT_NONEXIST_TITLE,
                    translations.TR_PROJECT_NONEXIST % folderName)
                return
            logger.debug("Opening %s" % folderName)
            for p in self.projects:
                if p.project.path == folderName:
                    QMessageBox.information(
                        self,
                        translations.TR_PROJECT_PATH_ALREADY_EXIST_TITLE,
                        translations.TR_PROJECT_PATH_ALREADY_EXIST
                        % folderName)
                    return
            self._open_project_folder(folderName)

    def _open_project_folder(self, folderName):
        ninjaide = IDE.get_service("ide")
        # TODO: handle exception when .nja file is empty
        project = NProject(folderName)
        qfsm = ninjaide.filesystem.open_project(project)
        if qfsm:
            self.add_project(project)
            self.save_recent_projects(folderName)
            # FIXME: show editor area?
            # main_container = IDE.get_service('main_container')
            # if main_container:
            #    main_container.show_editor_area()
            if len(self.projects) > 1:
                title = "%s (%s)" % (
                    translations.TR_TAB_PROJECTS, len(self.projects))
            else:
                title = translations.TR_TAB_PROJECTS
            self.changeTitle.emit(self, title)

    def _add_file_to_project(self, path):
        """Add the file for 'path' in the project the user choose here."""
        if self._projects_area.count() > 0:
            path_project = [self.current_project]
            _add_to_project = add_to_project.AddToProject(path_project, self)
            _add_to_project.exec_()
            if not _add_to_project.path_selected:
                return
            main_container = IDE.get_service('main_container')
            if not main_container:
                return
            editorWidget = main_container.get_current_editor()
            if not editorWidget.file_path:
                name = QInputDialog.getText(
                    None,
                    translations.TR_ADD_FILE_TO_PROJECT,
                    translations.TR_FILENAME + ": ")[0]
                if not name:
                    QMessageBox.information(
                        self,
                        translations.TR_INVALID_FILENAME,
                        translations.TR_INVALID_FILENAME_ENTER_A_FILENAME)
                    return
            else:
                name = file_manager.get_basename(editorWidget.file_path)
            new_path = file_manager.create_path(
                _add_to_project.path_selected, name)
            ide_srv = IDE.get_service("ide")
            old_file = ide_srv.get_or_create_nfile(path)
            new_file = old_file.save(editorWidget.text(), new_path)
            # FIXME: Make this file replace the original in the open tab
        else:
            pass
            # Message about no project

    def _show_file_in_explorer(self, path):
        '''Iterate through the list of available projects and show
        the current file in the explorer view for the first
        project that contains it (i.e. if the same file is
        included in multiple open projects, the path will be
        expanded for the first project only).
        Note: This slot is connected to the main container's
        "showFileInExplorer(QString)" signal.'''
        central = IDE.get_service('central_container')
        if central and not central.is_lateral_panel_visible():
            return
        for project in self.projects:
            index = project.model().index(path)
            if index.isValid():
                # This highlights the index in the tree for us
                project.scrollTo(index, QAbstractItemView.EnsureVisible)
                project.setCurrentIndex(index)
                break

    def add_project(self, project):
        if project not in self.projects:
            self._combo_project.addItem(project.name)
            tooltip = utils.path_with_tilde_homepath(project.path)
            self._combo_project.setToolTip(tooltip)
            index = self._combo_project.count() - 1
            self._combo_project.setItemData(index, project)
            ptree = TreeProjectsWidget(project)
            self._projects_area.addWidget(ptree)
            ptree.closeProject['PyQt_PyObject'].connect(self._close_project)
            pmodel = project.model
            ptree.setModel(pmodel)
            pindex = pmodel.index(pmodel.rootPath())
            ptree.setRootIndex(pindex)
            self.projects.append(ptree)
            self._projects_area.setCurrentWidget(ptree)  # Can be empty widget
            self._combo_project.setCurrentIndex(index)

        # FIXME: improve?
        # if len(self.projects) == 1:
        #     self._combo_project.currentIndexChanged[int].connect(
        #         self._change_current_project)

    def _close_project(self, widget):
        """Close the project related to the tree widget."""
        index = self._combo_project.currentIndex()
        self.projects.remove(widget)
        # index + 1 is necessary because the widget
        # with index 0 is the empty widget
        self._projects_area.takeAt(index + 1)
        self._combo_project.removeItem(index)
        index = self._combo_project.currentIndex()
        self._projects_area.setCurrentIndex(index + 1)
        ninjaide = IDE.get_service('ide')
        ninjaide.filesystem.close_project(widget.project.path)
        widget.deleteLater()
        if len(self.projects) > 1:
            title = "%s (%s)" % (
                translations.TR_TAB_PROJECTS, len(self.projects))
        else:
            title = translations.TR_TAB_PROJECTS
        self.changeTitle.emit(self, title)
        self.updateLocator.emit()

    def _change_current_project(self, index):
        nproject = self._combo_project.itemData(index)

        ninjaide = IDE.get_service("ide")
        projects = ninjaide.get_projects()
        for project in projects.values():
            if project == nproject:
                nproject.is_current = True
            else:
                project.is_current = False
        self._projects_area.setCurrentIndex(index + 1)
        self.activeProjectChanged.emit()

    def close_opened_projects(self):
        for project in reversed(self.projects):
            self._close_project(project)

    def save_project(self):
        """Save all the opened files that belongs to the actual project."""
        if self.current_project is not None:
            path = self.current_project.path
            main_container = IDE.get_service('main_container')
            if path and main_container:
                main_container.save_project(path)

    def create_new_project(self):
        wizard = new_project_manager.NewProjectManager(self)
        wizard.show()

    @property
    def current_project(self):
        project = None
        if self._projects_area.count() > 0 and self.current_tree is not None:
            project = self.current_tree.project
        return project

    @property
    def current_tree(self):
        tree = None
        widget = self._projects_area.currentWidget()
        if isinstance(widget, TreeProjectsWidget):
            tree = widget
        return tree

    def set_current_item(self, path):
        if self.current_project is not None:
            self.current_tree.set_current_item(path)

    def save_recent_projects(self, folder):
        settings = IDE.data_settings()
        recent_project_list = settings.value('recentProjects', {})
        # if already exist on the list update the date time
        projectProperties = json_manager.read_ninja_project(folder)
        name = projectProperties.get('name', '')
        description = projectProperties.get('description', '')

        if not name:
            name = file_manager.get_basename(folder)

        if not description:
            description = translations.TR_NO_DESCRIPTION

        if folder in recent_project_list:
            properties = recent_project_list[folder]
            properties["lastopen"] = QDateTime.currentDateTime()
            properties["name"] = name
            properties["description"] = description
            recent_project_list[folder] = properties
        else:
            recent_project_list[folder] = {
                "name": name,
                "description": description,
                "isFavorite": False, "lastopen": QDateTime.currentDateTime()}
            # if the length of the project list it's high that 10 then delete
            # the most old
            # TODO: add the length of available projects to setting
            if len(recent_project_list) > MAX_RECENT_PROJECTS:
                del recent_project_list[self.find_most_old_open(
                    recent_project_list)]
        settings.setValue('recentProjects', recent_project_list)

    def find_most_old_open(self, recent_project_list):
        listFounder = []
        for recent_project_path, content in list(recent_project_list.items()):
            listFounder.append((recent_project_path, int(
                content["lastopen"].toString("yyyyMMddHHmmzzz"))))
        listFounder = sorted(listFounder, key=lambda date: listFounder[1],
                             reverse=True)   # sort by date last used
        return listFounder[0][0]

    def reject(self):
        if self.parent() is None:
            self.dockWidget.emit(self)

    def closeEvent(self, event):
        self.dockWidget.emit(self)
        event.ignore()

    def context_menu_for_root(self):
        menu = QMenu(self)
        if self.current_tree is None:
            # No projects
            return
        path = self.current_tree.project.path
        # Reset index
        self.current_tree.setCurrentIndex(QModelIndex())

        action_add_file = menu.addAction(QIcon(":img/new"),
                                         translations.TR_ADD_NEW_FILE)
        action_add_folder = menu.addAction(QIcon(
            ":img/openProj"), translations.TR_ADD_NEW_FOLDER)
        action_create_init = menu.addAction(translations.TR_CREATE_INIT)
        menu.addSeparator()
        action_run_project = menu.addAction(translations.TR_RUN_PROJECT)
        action_properties = menu.addAction(translations.TR_PROJECT_PROPERTIES)
        action_show_file_size = menu.addAction(translations.TR_SHOW_FILESIZE)
        menu.addSeparator()
        action_close = menu.addAction(translations.TR_CLOSE_PROJECT)

        # Connections
        action_add_file.triggered.connect(
            lambda: self.current_tree._add_new_file(path))
        action_add_folder.triggered.connect(
            lambda: self.current_tree._add_new_folder(path))
        action_create_init.triggered.connect(self.current_tree._create_init)
        action_run_project.triggered.connect(
            self.current_tree._execute_project)
        action_properties.triggered.connect(
            self.current_tree.open_project_properties)
        action_close.triggered.connect(self.current_tree._close_project)
        action_show_file_size.triggered.connect(
            self.current_tree.show_filesize_info)

        # menu for the project
        for m in self.current_tree.extra_menus_by_scope['project']:
            if isinstance(m, QMenu):
                menu.addSeparator()
                menu.addMenu(m)

        # show the menu!
        menu.exec_(QCursor.pos())
Exemplo n.º 55
0
class fullScreenEditor(QWidget):
    def __init__(self, index, parent=None):
        QWidget.__init__(self, parent)
        self._background = None
        self._index = index
        self._theme = findThemePath(settings.fullScreenTheme)
        self._themeDatas = loadThemeDatas(self._theme)
        self.setMouseTracking(True)
        self._geometries = {}

        # Text editor
        self.editor = textEditView(self,
                                   index=index,
                                   spellcheck=settings.spellcheck,
                                   highlighting=True,
                                   dict=settings.dict)
        self.editor.setFrameStyle(QFrame.NoFrame)
        self.editor.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.editor.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.editor.installEventFilter(self)
        self.editor.setMouseTracking(True)
        self.editor.setVerticalScrollBar(myScrollBar())
        self.scrollBar = self.editor.verticalScrollBar()
        self.scrollBar.setParent(self)

        # Top Panel
        self.topPanel = myPanel(parent=self)
        # self.topPanel.layout().addStretch(1)

        # Spell checking
        if enchant:
            self.btnSpellCheck = QPushButton(self)
            self.btnSpellCheck.setFlat(True)
            self.btnSpellCheck.setIcon(QIcon.fromTheme("tools-check-spelling"))
            self.btnSpellCheck.setCheckable(True)
            self.btnSpellCheck.setChecked(self.editor.spellcheck)
            self.btnSpellCheck.toggled.connect(self.editor.toggleSpellcheck)
            self.topPanel.layout().addWidget(self.btnSpellCheck)

        self.topPanel.layout().addStretch(1)

        # Formatting
        self.textFormat = textFormat(self)
        self.topPanel.layout().addWidget(self.textFormat)
        self.topPanel.layout().addStretch(1)

        self.btnClose = QPushButton(self)
        self.btnClose.setIcon(qApp.style().standardIcon(QStyle.SP_DialogCloseButton))
        self.btnClose.clicked.connect(self.close)
        self.btnClose.setFlat(True)
        self.topPanel.layout().addWidget(self.btnClose)

        # Left Panel
        self._locked = False
        self.leftPanel = myPanel(vertical=True, parent=self)
        self.locker = locker(self)
        self.locker.lockChanged.connect(self.setLocked)
        self.leftPanel.layout().addWidget(self.locker)

        # Bottom Panel
        self.bottomPanel = myPanel(parent=self)

        self.bottomPanel.layout().addSpacing(24)
        self.lstThemes = QComboBox(self)
        self.lstThemes.setAttribute(Qt.WA_TranslucentBackground)
        paths = allPaths("resources/themes")
        for p in paths:
            lst = [i for i in os.listdir(p) if os.path.splitext(i)[1] == ".theme"]
            for t in lst:
                themeIni = os.path.join(p, t)
                name = loadThemeDatas(themeIni)["Name"]
                # self.lstThemes.addItem(os.path.splitext(t)[0])
                self.lstThemes.addItem(name)
                self.lstThemes.setItemData(self.lstThemes.count()-1, os.path.splitext(t)[0])

        self.lstThemes.setCurrentIndex(self.lstThemes.findData(settings.fullScreenTheme))
        # self.lstThemes.setCurrentText(settings.fullScreenTheme)
        self.lstThemes.currentTextChanged.connect(self.setTheme)
        self.lstThemes.setMaximumSize(QSize(300, QFontMetrics(qApp.font()).height()))
        self.bottomPanel.layout().addWidget(QLabel(self.tr("Theme:"), self))
        self.bottomPanel.layout().addWidget(self.lstThemes)
        self.bottomPanel.layout().addStretch(1)

        self.lblProgress = QLabel(self)
        self.lblProgress.setMaximumSize(QSize(200, 14))
        self.lblProgress.setMinimumSize(QSize(100, 14))
        self.lblWC = QLabel(self)
        self.bottomPanel.layout().addWidget(self.lblWC)
        self.bottomPanel.layout().addWidget(self.lblProgress)
        self.updateStatusBar()

        self.bottomPanel.layout().addSpacing(24)

        # Connection
        self._index.model().dataChanged.connect(self.dataChanged)

        # self.updateTheme()
        self.showFullScreen()
        # self.showMaximized()
        # self.show()

    def setLocked(self, val):
        self._locked = val
        self.btnClose.setVisible(not val)

    def setTheme(self, themeName):
        themeName = self.lstThemes.currentData()
        settings.fullScreenTheme = themeName
        self._theme = findThemePath(themeName)
        self._themeDatas = loadThemeDatas(self._theme)
        self.updateTheme()

    def updateTheme(self):
        # Reinit stored geometries for hiding widgets
        self._geometries = {}
        rect = self.geometry()
        self._background = generateTheme(self._themeDatas, rect)

        setThemeEditorDatas(self.editor, self._themeDatas, self._background, rect)

        # Colors
        if self._themeDatas["Foreground/Color"] == self._themeDatas["Background/Color"] or \
                        self._themeDatas["Foreground/Opacity"] < 5:
            self._bgcolor = QColor(self._themeDatas["Text/Color"])
            self._fgcolor = QColor(self._themeDatas["Background/Color"])
        else:
            self._bgcolor = QColor(self._themeDatas["Foreground/Color"])
            self._bgcolor.setAlpha(self._themeDatas["Foreground/Opacity"] * 255 / 100)
            self._fgcolor = QColor(self._themeDatas["Text/Color"])
            if self._themeDatas["Text/Color"] == self._themeDatas["Foreground/Color"]:
                self._fgcolor = QColor(self._themeDatas["Background/Color"])

        # ScrollBar
        r = self.editor.geometry()
        w = qApp.style().pixelMetric(QStyle.PM_ScrollBarExtent)
        r.setWidth(w)
        r.moveRight(rect.right() - rect.left())
        self.scrollBar.setGeometry(r)
        # self.scrollBar.setVisible(False)
        self.hideWidget(self.scrollBar)
        p = self.scrollBar.palette()
        b = QBrush(self._background.copy(self.scrollBar.geometry()))
        p.setBrush(QPalette.Base, b)
        self.scrollBar.setPalette(p)

        self.scrollBar.setColor(self._bgcolor)

        # Left Panel
        r = self.locker.geometry()
        r.moveTopLeft(QPoint(
                0,
                self.geometry().height() / 2 - r.height() / 2
        ))
        self.leftPanel.setGeometry(r)
        self.hideWidget(self.leftPanel)
        self.leftPanel.setColor(self._bgcolor)

        # Top / Bottom Panels
        r = QRect(0, 0, 0, 24)
        r.setWidth(rect.width())
        # r.moveLeft(rect.center().x() - r.width() / 2)
        self.topPanel.setGeometry(r)
        # self.topPanel.setVisible(False)
        self.hideWidget(self.topPanel)
        r.moveBottom(rect.bottom() - rect.top())
        self.bottomPanel.setGeometry(r)
        # self.bottomPanel.setVisible(False)
        self.hideWidget(self.bottomPanel)
        self.topPanel.setColor(self._bgcolor)
        self.bottomPanel.setColor(self._bgcolor)

        # Lst theme
        # p = self.lstThemes.palette()
        p = self.palette()
        p.setBrush(QPalette.Button, self._bgcolor)
        p.setBrush(QPalette.ButtonText, self._fgcolor)
        p.setBrush(QPalette.WindowText, self._fgcolor)

        for panel in (self.bottomPanel, self.topPanel):
            for i in range(panel.layout().count()):
                item = panel.layout().itemAt(i)
                if item.widget():
                    item.widget().setPalette(p)
        # self.lstThemes.setPalette(p)
        # self.lblWC.setPalette(p)

        self.update()

    def paintEvent(self, event):
        if self._background:
            painter = QPainter(self)
            painter.setClipRegion(event.region())
            painter.drawPixmap(event.rect(), self._background, event.rect())
            painter.end()

    def resizeEvent(self, event):
        self.updateTheme()

    def keyPressEvent(self, event):
        if event.key() in [Qt.Key_Escape, Qt.Key_F11] and \
                not self._locked:
            self.close()
        else:
            QWidget.keyPressEvent(self, event)

    def mouseMoveEvent(self, event):
        r = self.geometry()

        for w in [self.scrollBar, self.topPanel,
                  self.bottomPanel, self.leftPanel]:
            # w.setVisible(w.geometry().contains(event.pos()))
            if self._geometries[w].contains(event.pos()):
                self.showWidget(w)
            else:
                self.hideWidget(w)

    def hideWidget(self, widget):
        if widget not in self._geometries:
            self._geometries[widget] = widget.geometry()
        widget.move(self.geometry().bottomRight())

    def showWidget(self, widget):
        if widget in self._geometries:
            widget.move(self._geometries[widget].topLeft())

    def eventFilter(self, obj, event):
        if obj == self.editor and event.type() == QEvent.Enter:
            for w in [self.scrollBar, self.topPanel,
                      self.bottomPanel, self.leftPanel]:
                # w.setVisible(False)
                self.hideWidget(w)
        return QWidget.eventFilter(self, obj, event)

    def dataChanged(self, topLeft, bottomRight):
        if not self._index:
            return
        if topLeft.row() <= self._index.row() <= bottomRight.row():
            self.updateStatusBar()

    def updateStatusBar(self):
        if self._index:
            item = self._index.internalPointer()

        wc = item.data(Outline.wordCount.value)
        goal = item.data(Outline.goal.value)
        pg = item.data(Outline.goalPercentage.value)

        if goal:
            rect = self.lblProgress.geometry()
            rect = QRect(QPoint(0, 0), rect.size())
            self.px = QPixmap(rect.size())
            self.px.fill(Qt.transparent)
            p = QPainter(self.px)
            drawProgress(p, rect, pg, 2)
            p.end()
            self.lblProgress.setPixmap(self.px)
            self.lblWC.setText(self.tr("{} words / {}").format(wc, goal))
        else:
            self.lblProgress.hide()
            self.lblWC.setText(self.tr("{} words").format(wc))

        self.locker.setWordCount(wc)
        # If there's a goal, then we update the locker target's number of word accordingly
        # (also if there is a word count, we deduce it.
        if goal and not self.locker.isLocked():
            if wc and goal - wc > 0:
                self.locker.spnWordTarget.setValue(goal - wc)
            elif not wc:
                self.locker.spnWordTarget.setValue(goal)
Exemplo n.º 56
0
class MainWindow(QMainWindow):
	"""The main GUI application."""
	def __init__(self, config):
		"""Initializer for the GUI widgets. Pass in an instance of Config class, so that it may interact with the config."""
		super().__init__()

		self.config = config

		self.setWindowTitle("Livestreamer GUI v{}".format(APPVERSION))

		self.setup_systray()
		self.setup_menu()
		self.setup_geometry()

		self.livestreamer_thread = None
		self.thread_exit_grace_time = 10000 # How long a thread can take to exit in milliseconds
		self.timestamp_format = self.config.get_config_value("timestamp-format")

		self.setup_control_widgets()
		self.update_colors()

		# Load all streaming-related data
		self.selections = {"streamer": None, "channel": None}
		self.load_streamers()
		self.load_channels(self.streamer_input.currentText())
		
		# Do the first configuration, if the application was run for the first time
		self.do_init_config()

		# Finally show the window and the system tray icon, if it should be shown
		self.show()

		self.close_override = False
		self.show_hide_systray()

		self.check_and_do_database_migration()

	def do_init_config(self):
		do_config = self.config.get_config_value("is-configured")
		if do_config == 0:
			self.menu_cmd_configure()
			self.config.set_config_value("is-configured", 1)
		self.insertText("Using config database version '{}'".format(self.config.get_config_value("db-version")))

	def setup_systray(self):
		if not self.config.get_config_value("enable-systray-icon"):
			self.systray = None
			return

		self.systray = QSystemTrayIcon(self)
		self.systray.activated.connect(self.systray_activated)
		main_menu = QMenu(self)

		quit_action = QAction("&Quit", self)
		quit_action.triggered.connect(self.on_close_override)
		main_menu.addAction(quit_action)

		self.systray.setContextMenu(main_menu)

	def systray_activated(self, reason):
		if reason == QSystemTrayIcon.Trigger:
			if self.isVisible():
				self.hide()
			else:
				self.showNormal()

	def check_and_do_database_migration(self):
		current_version = self.config.get_config_value("db-version")
		if self.config.is_migration_needed():
			self.insertText("Detected pending config database upgrade to version '{}'. Awaiting user input...".format(DBVERSION))
			message = "You are using an older version of the application config database.\n\nWould you like to upgrade the database now? Your existing config database will be backed up."

			upgrade_is_mandatory = current_version < MANDATORY_DBVERSION

			if upgrade_is_mandatory:
				message = message + "\n\nWARNING: Your config database is not compatible with this version of Livestreamer GUI. UPDATE IS MANDATORY! If you cancel the update, the application will exit."

			reply = QMessageBox.question(self, "Pending config database upgrade", message, QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
			if reply == QMessageBox.Yes:
				self.insertText("Backing up config database...")
				backup = self.config.make_database_backup()
				self.insertText("Current config database backed up to '{}'".format(backup))
				self.insertText("Config database update initialized...")
				self.update()
				self.config.execute_migration()
				new_version = self.config.get_config_value("db-version")
				self.insertText("Config database update from version '{}' to '{}' finished.".format(current_version, new_version))
			elif reply == QMessageBox.No and upgrade_is_mandatory:
				QtCore.QTimer.singleShot(500, self.on_close_override)
				# self.on_close_override() # Calling this in an __init__()-called method doesn't seem to work...
			else:
				self.insertText("Config database update cancelled. No changes were made.")

	def setup_menu(self):
		config_action = QAction("&Configure...", self)
		config_action.triggered.connect(self.menu_cmd_configure)

		quit_action = QAction("&Quit", self)
		quit_action.setShortcut("Ctrl+Q")
		quit_action.triggered.connect(self.on_close_override)

		menu = self.menuBar()
		file_menu = menu.addMenu("&File")
		file_menu.addAction(config_action)
		file_menu.addSeparator()
		file_menu.addAction(quit_action)

	def setup_geometry(self):
		width = self.config.get_config_value("root-width")
		height = self.config.get_config_value("root-height")

		topleft = QApplication.desktop().availableGeometry().topLeft()
		if self.config.get_config_value("remember-window-position"):
			xoffset = self.config.get_config_value("root-xoffset")
			yoffset = self.config.get_config_value("root-yoffset")
			topleft.setX(self.config.get_config_value("root-xoffset"))
			topleft.setY(self.config.get_config_value("root-yoffset"))

		self.resize(width, height)
		self.setMinimumSize(500, 300)
		self.move(topleft)

		# Center the window
		# center_point = QApplication.desktop().availableGeometry().center()
		# frame_geometry = self.frameGeometry()
		# frame_geometry.moveCenter(center_point)
		# self.move(frame_geometry.topLeft())

	def setup_control_widgets(self):
		self.cwidget = QWidget(self)
		self.setCentralWidget(self.cwidget)

		layout = QGridLayout(self.cwidget)
		self.cwidget.setLayout(layout)

		fg_fav = self.config.get_config_value("button-foreground-favorite")
		fg_edit = self.config.get_config_value("button-foreground-edit")
		fg_add = self.config.get_config_value("button-foreground-add")
		fg_delete = self.config.get_config_value("button-foreground-delete")

		control_button_width = 30
		control_button_font_style = "QPushButton { font-family: Arial, sans-serif; font-size: 16px }"

		column = 0
		label_streamer_input = QLabel("Streamer", self.cwidget)
		layout.addWidget(label_streamer_input, 0, column)
		label_channel_input = QLabel("Channel", self.cwidget)
		layout.addWidget(label_channel_input, 1, column)
		label_quality_input = QLabel("Stream quality", self.cwidget)
		layout.addWidget(label_quality_input, 2, column)

		column += 1
		self.streamer_input = QComboBox(self.cwidget)
		self.streamer_input.setEnabled(False)
		self.streamer_input.currentIndexChanged.connect(self.on_streamer_select)
		layout.addWidget(self.streamer_input, 0, column)
		self.channel_input = QComboBox(self.cwidget)
		self.channel_input.setEnabled(False)
		self.channel_input.currentIndexChanged.connect(self.on_channel_select)
		layout.addWidget(self.channel_input, 1, column)
		self.quality_input = QComboBox(self.cwidget)
		self.quality_input.addItem("(auto-refresh is disabled; please refresh manually)")
		self.quality_input.setEnabled(False)
		layout.addWidget(self.quality_input, 2, column)
		layout.setColumnStretch(column, 5)

		column += 1
		self.fav_streamer_button = QPushButton("\u2764", self.cwidget)
		self.fav_streamer_button.setMaximumWidth(control_button_width)
		self.fav_streamer_button.setStyleSheet(":enabled {{ color: {0} }} {1}".format(fg_fav, control_button_font_style))
		self.fav_streamer_button.setEnabled(False)
		self.fav_streamer_button.setToolTip("Set the selected streamer as your most favorite streamer")
		self.fav_streamer_button.clicked.connect(self.cmd_set_favorite_streamer)
		layout.addWidget(self.fav_streamer_button, 0, column)
		self.fav_channel_button = QPushButton("\u2764", self.cwidget)
		self.fav_channel_button.setMaximumWidth(control_button_width)
		self.fav_channel_button.setStyleSheet(':enabled {{ color: {0} }} {1}'.format(fg_fav, control_button_font_style))
		self.fav_channel_button.setEnabled(False)
		self.fav_channel_button.setToolTip("Set the selected channel as your most favorite channel")
		self.fav_channel_button.clicked.connect(self.cmd_set_favorite_channel)
		layout.addWidget(self.fav_channel_button, 1, column)
		self.clear_quality_cache_button = QPushButton("Refresh streams", self.cwidget)
		self.clear_quality_cache_button.setEnabled(False)
		self.clear_quality_cache_button.clicked.connect(self.cmd_refresh_quality_cache)
		layout.addWidget(self.clear_quality_cache_button, 2, column, 1, 4)

		column += 1
		self.edit_streamer_button = QPushButton("\u270E", self.cwidget)
		self.edit_streamer_button.setMaximumWidth(control_button_width)
		self.edit_streamer_button.setStyleSheet(":enabled {{ color: {0} }} {1}".format(fg_edit, control_button_font_style))
		self.edit_streamer_button.setEnabled(False)
		self.edit_streamer_button.setToolTip("Edit data about the selected streamer")
		self.edit_streamer_button.clicked.connect(self.cmd_edit_streamer)
		layout.addWidget(self.edit_streamer_button, 0, column)
		self.edit_channel_button = QPushButton("\u270E", self.cwidget)
		self.edit_channel_button.setMaximumWidth(control_button_width)
		self.edit_channel_button.setStyleSheet(":enabled {{ color: {0} }} {1}".format(fg_edit, control_button_font_style))
		self.edit_channel_button.setToolTip("Edit data about the selected channel")
		self.edit_channel_button.clicked.connect(self.cmd_edit_channel)
		layout.addWidget(self.edit_channel_button, 1, column)

		column += 1
		self.add_streamer_button = QPushButton("\u271A", self.cwidget)
		self.add_streamer_button.setMaximumWidth(control_button_width)
		self.add_streamer_button.setStyleSheet(":enabled {{ color: {0} }} {1}".format(fg_add, control_button_font_style))
		self.add_streamer_button.setEnabled(False)
		self.add_streamer_button.setToolTip("Add a new streamer")
		self.add_streamer_button.clicked.connect(self.cmd_add_streamer)
		layout.addWidget(self.add_streamer_button, 0, column)
		self.add_channel_button = QPushButton("\u271A", self.cwidget)
		self.add_channel_button.setMaximumWidth(control_button_width)
		self.add_channel_button.setStyleSheet(":enabled {{ color: {0} }} {1}".format(fg_add, control_button_font_style))
		self.add_channel_button.setToolTip("Add a new channel")
		self.add_channel_button.clicked.connect(self.cmd_add_channel)
		layout.addWidget(self.add_channel_button, 1, column)

		column += 1
		self.delete_streamer_button = QPushButton("\u2716", self.cwidget)
		self.delete_streamer_button.setMaximumWidth(control_button_width)
		self.delete_streamer_button.setStyleSheet(":enabled {{ color: {0} }} {1}".format(fg_delete, control_button_font_style))
		self.delete_streamer_button.setEnabled(False)
		self.delete_streamer_button.setToolTip("Remove the selected streamer permanently")
		self.delete_streamer_button.clicked.connect(self.cmd_delete_streamer)
		layout.addWidget(self.delete_streamer_button, 0, column)
		self.delete_channel_button = QPushButton("\u2716", self.cwidget)
		self.delete_channel_button.setMaximumWidth(control_button_width)
		self.delete_channel_button.setStyleSheet(":enabled {{ color: {0} }} {1}".format(fg_delete, control_button_font_style))
		self.delete_channel_button.setToolTip("Remove the selected channel permanently")
		self.delete_channel_button.clicked.connect(self.cmd_delete_channel)
		layout.addWidget(self.delete_channel_button, 1, column)

		# Add button for running livestreamer at the fourth row
		self.run_livestreamer_button = QPushButton("Run Livestreamer", self.cwidget)
		self.run_livestreamer_button.setEnabled(False)
		self.run_livestreamer_button.clicked.connect(self.run_livestreamer)
		layout.addWidget(self.run_livestreamer_button, 3, 0)

		self.log_widget = QTextEdit(self.cwidget)
		layout.addWidget(self.log_widget, 4, 0, 1, column+1)
		self.log_widget.setAcceptRichText(False)
		self.log_widget.setReadOnly(True)
		self.log_widget.setTabChangesFocus(True)

	def set_window_icon(self):
		"""Sets the root window's icon, which is also shown in the taskbar."""
		streamer = self.config.get_streamer(self.streamer_input.currentText())
		icon = QIcon(os.path.join(IMAGESROOT, streamer["icon"]))
		self.setWindowIcon(icon)

		if self.systray is not None:
			self.systray.setIcon(icon)

	def closeEvent(self, event):
		"""When the QWidget is closed, QCloseEvent is triggered, and this method catches and handles it."""
		if not self.close_override and self.put_to_systray("close"):
			event.ignore()
			return

		if self.livestreamer_thread is not None and self.livestreamer_thread.keep_running:
			reply = QMessageBox.question(self, "Really quit Livestreamer GUI?", "Livestreamer is still running. Quitting will close it and the opened player.\n\nQuit?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
			if reply == QMessageBox.Yes:
				# Terminate the child process, else it'll keep running even after this application is closed
				if self.livestreamer_thread is not None:
					self.livestreamer_thread.term_process()
					self.livestreamer_thread.wait(self.thread_exit_grace_time)
					self.update()
				event.accept()
			else:
				event.ignore()

		# Explicitly hide the icon, if it remains visible after the application closes
		if self.systray is not None:
			self.systray.hide()

		# Remember the position of the window
		self.remember_window_position()

		event.accept()

	def changeEvent(self, event):
		if type(event) is not QWindowStateChangeEvent:
			return

		# It's one of the window state change events (normal, minimize, maximize, fullscreen, active)
		if self.isMinimized():
			self.put_to_systray("minimize")

	def remember_window_position(self):
		if self.config.get_config_value("remember-window-position"):
			point = self.frameGeometry().topLeft()
			self.config.set_config_value("root-xoffset", point.x())
			self.config.set_config_value("root-yoffset", point.y())
			self.insertText("Window position saved.")

	def show_hide_systray(self):
		if self.systray is None:
			self.setup_systray()
			if self.systray is None:
				return

		if self.config.get_config_value("enable-systray-icon"):
			self.systray.show()
		else:
			self.systray.hide()

	def put_to_systray(self, event):
		if event == "minimize":
			config_value = "minimize-to-systray"
		elif event == "close":
			config_value = "close-to-systray"
		else:
			return False

		if self.systray is not None and self.config.get_config_value(config_value) and self.isVisible():
			self.hide()
			return True
		return False

	def menu_cmd_configure(self):
		streamer = self.config.get_streamer(self.streamer_input.currentText())
		dialog = AppConfigDialog(self, self.config, streamer_icon=os.path.join(IMAGESROOT, streamer["icon"]))
		dialog.exec()
		if dialog.result() == QDialog.Accepted:
			self.show_hide_systray()
			self.update_colors()
		dialog.close()
		dialog = None

	def cmd_set_favorite_streamer(self):
		raise NotImplementedException()
		# self.fav_streamer_button.setEnabled(False)
		# self.config.set_favorite_streamer(self.streamer_input.setCurrentText())
		# self.insertText("Favorited streamer '{}'.".format(self.streamer_input.setCurrentText()))

	def cmd_edit_streamer(self):
		raise NotImplementedException()

	def cmd_add_streamer(self):
		raise NotImplementedException()

	def cmd_delete_streamer(self):
		raise NotImplementedException()

	def cmd_set_favorite_channel(self):
		self.fav_channel_button.setEnabled(False)
		self.config.set_favorite_channel(self.streamer_input.currentText(), self.channel_input.currentText())
		self.insertText("Favorited channel '{}'.".format(self.channel_input.currentText()))

	def cmd_edit_channel(self):
		streamer = self.config.get_streamer(self.streamer_input.currentText())
		streamer_icon = os.path.join(IMAGESROOT, streamer["icon"])
		channel_data = self.config.get_streamer_channel(streamer["name"], self.channel_input.currentText())
		dialog = AddEditChannelsDialog(self, self.config, title="Edit the channel", streamer_icon=streamer_icon, streamer=streamer, channel_data=channel_data)
		dialog.exec()
		result = dialog.result_data
		dialog.close()
		dialog = None
		if result is not None:
			self.insertText("Updated channel name '{old_name}' => '{new_name}, URL '{old_url}' => '{new_url}'".format(old_name=channel_data["name"], new_name=result["name"], old_url=channel_data["url"], new_url=result["url"]))
			self.load_channels(streamer["name"])
			
			# Set the active channel to the previously selected (due to possible name change and sorting)
			self.channel_input.setCurrentIndex(self.channel_input.findText(result["name"]))
			
	def cmd_add_channel(self):
		streamer = self.config.get_streamer(self.streamer_input.currentText())
		streamer_icon = os.path.join(IMAGESROOT, streamer["icon"])
		dialog = AddEditChannelsDialog(self, self.config, title="Add a channel", streamer_icon=streamer_icon, streamer=streamer)
		dialog.exec()
		result = dialog.result_data
		dialog.close()
		dialog = None
		if result is not None:
			self.insertText("Added channel '{}' with URL '{}'".format(result["name"], result["url"]))
			self.load_channels(streamer["name"])

	def cmd_delete_channel(self):
		channel = self.config.get_streamer_channel(self.streamer_input.currentText(), self.channel_input.currentText())
		reply = QMessageBox.question(self, "Delete channel", "Are you sure you want to remove the channel?\nName: {}\nURL: {}".format(channel["name"], channel["url"]), QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
		if reply == QMessageBox.Yes:
			self.config.delete_channel(self.streamer_input.currentText(), channel["name"])
			self.insertText("Removed channel '{}' with URL '{}'".format(channel["name"], channel["url"]))
			self.load_channels(self.streamer_input.currentText())

	def cmd_refresh_quality_cache(self):
		self.insertText("Refreshing cache for channel '{}'.".format(self.channel_input.currentText()))
		self.clear_quality_cache_button.setEnabled(False)
		self.clear_quality_cache_button.repaint() # Loading streams seems to block repainting of the GUI, so force a repaint here
		self.config.clean_quality_cache(self.streamer_input.currentText(), self.channel_input.currentText(), True)
		self.load_streams(True)
		self.clear_quality_cache_button.setEnabled(True)

	def on_close_override(self):
		self.close_override = True
		self.close()

	def on_streamer_select(self, event):
		# If the previously selected item is selected again, don't do anything
		if self.selections["streamer"] == self.streamer_input.currentText():
			return
		self.selections["streamer"] = self.streamer_input.currentText()
		streamer = self.config.get_streamer(self.streamer_input.currentText())
		self.set_window_icon()
		if streamer["favorite"]:
			self.fav_streamer_button.setEnabled(False)
		else:
			self.fav_streamer_button.setEnabled(True)

	def on_channel_select(self, event):
		# If the previously selected item is selected again, don't do anything
		if self.selections["channel"] == self.channel_input.currentText() or not self.channel_input.currentText():
			return
		self.selections["channel"] = self.channel_input.currentText()
		channel = self.config.get_streamer_channel(self.streamer_input.currentText(), self.channel_input.currentText())
		if channel and channel["favorite"]:
			self.fav_channel_button.setEnabled(False)
		else:
			self.fav_channel_button.setEnabled(True)

		self.load_streams()
		self.channel_input.setFocus(True)

	def load_streamers(self):
		streamers = self.config.get_streamers()
		favorite_streamer_index = 0
		streamer_list = []
		for index, streamer in enumerate(streamers):
			streamer_list.append(streamer["name"])
			if streamer["favorite"]:
				favorite_streamer_index = index
		self.streamer_input.clear()
		self.streamer_input.addItems(streamer_list)
		if len(streamer_list) != 0:
			self.streamer_input.setCurrentIndex(favorite_streamer_index)
		self.selections["streamer"] = self.streamer_input.currentText()
		self.fav_streamer_button.setEnabled(False)

	def load_channels(self, streamer_name):
		channels = self.config.get_streamer_channels(streamer_name)
		self.channel_input.clear()
		favorite_channel = None
		channel_list = []
		self.fav_channel_button.setEnabled(False)
		for index, channel in enumerate(channels):
			channel_list.append(channel["name"])
			if channel["favorite"]:
				favorite_channel = channel["name"]
		self.channel_input.addItems(sorted(channel_list))
		if len(channel_list) == 0:
			self.channel_input.addItem("(no channels exist for this streamer)")
			self.fav_channel_button.setEnabled(False)
			self.edit_channel_button.setEnabled(False)
			self.delete_channel_button.setEnabled(False)
			self.clear_quality_cache_button.setEnabled(False)
			self.channel_input.setEnabled(False)
		else:
			self.edit_channel_button.setEnabled(True)
			self.delete_channel_button.setEnabled(True)
			self.clear_quality_cache_button.setEnabled(True)
			self.channel_input.setEnabled(True)
			
			if favorite_channel is None:
				self.channel_input.setCurrentIndex(0)
				self.fav_channel_button.setEnabled(True)
			else:
				self.channel_input.setCurrentIndex(self.channel_input.findText(favorite_channel))

		self.selections["channel"] = self.channel_input.currentText()

	def display_loaded_streams(self, streams, skip_caching=False):
		self.quality_input.clear()
		if len(streams) == 0:
			self.quality_input.addItem("(channel is currently not streaming)")
		else:
			self.run_livestreamer_button.setEnabled(True)
			self.clear_quality_cache_button.setEnabled(True)
			self.quality_input.addItems(sorted(streams))
			self.quality_input.setCurrentIndex(0)
			self.quality_input.setEnabled(True)
			if not skip_caching:
				self.insertText("Cleaning any cached streams for channel '{}'...".format(self.channel_input.currentText()))
				self.config.clean_quality_cache(self.streamer_input.currentText(), self.channel_input.currentText())
				self.insertText("Adding probed streams for channel '{}' to cache...".format(self.channel_input.currentText()))
				self.config.add_quality_to_cache(self.streamer_input.currentText(), self.channel_input.currentText(), streams)
				self.insertText("Done.")

	def load_streams(self, force_refresh=False):
		self.quality_input.clear()
		self.run_livestreamer_button.setEnabled(False)
		self.channel_input.setEnabled(False)
		self.quality_input.setEnabled(False)

		if self.channel_input.count() == 0:
			return

		streams = self.config.get_quality_from_cache(self.streamer_input.currentText(), self.channel_input.currentText())
		if len(streams) > 0:
			self.display_loaded_streams(streams, True)
			self.insertText("Loaded streams for channel '{}' from cache.".format(self.channel_input.currentText()))
		else:
			self.insertText("No cached channel streams found for channel '{}'".format(self.channel_input.currentText()))
			if not force_refresh and self.config.get_config_value('auto-refresh-quality') == 0:
				self.quality_input.addItem("(auto-refresh is disabled; please refresh manually)")
				self.quality_input.setEnabled(False)
			else:
				stream_url = self.get_streamer_url()
				if stream_url is None:
					self.insertText("Failed to form a complete streamer URL (missing streamer/channel/stream)!")
					return
				self.probe_for_streams(stream_url)
		
		self.channel_input.setEnabled(True)

	def probe_for_streams(self, stream_url):
		self.insertText("Probing streamer's channel for live streams: {}".format(stream_url))
		livestreamer = self.config.get_config_value("livestreamer-path")
		if livestreamer is None or livestreamer.strip() == "" or not os.path.isfile(livestreamer):
			self.insertText("Livestreamer path is not configured or file doesn't exist!")
			return
		command_format = self.config.get_config_value("probe-command-format")
		command = command_format.format(livestreamer=livestreamer, url=stream_url)
		self.livestreamer_thread = LivestreamerWorker(shlex.split(command))
		self.livestreamer_thread.statusMessage.connect(self.parse_probed_streams, False)
		self.livestreamer_thread.start()
		self.livestreamer_thread.wait(self.thread_exit_grace_time)

	def parse_probed_streams(self, event):
		streams = []

		message = event.message.lower()
		if "no streams found on this url" in message:
			self.insertText("No streams found. The channel is probably not streaming.")
		else:
			pos = message.find("available streams:")
			if pos == -1:
				return

			if "(best, worst)" in message:
				message = message.replace("(best, worst)", "(best and worst)")
			elif "(worst, best)" in message:
				message = message.replace("(worst, best)", "(worst and best)")
			qualities = message[pos+18:].split(",")
			for item in qualities:
				streams.append(item.strip())
				left_parenthesis = item.find("(")
				if left_parenthesis == -1:
					continue
				if item.find("worst", left_parenthesis) >= left_parenthesis:
					streams.append("worst")
				if item.find("best", left_parenthesis) >= left_parenthesis:
					streams.append("best")
			streams.sort()
			self.insertText("Found {} stream(s): {}".format(len(streams), ", ".join(streams)))

		self.display_loaded_streams(streams)

	def get_streamer_url(self):
		streamer = self.config.get_streamer(self.streamer_input.currentText())
		if streamer is None:
			self.insertText("No streamer selected!")
			return
		if streamer["url"] is None or streamer["url"].strip() == "":
			self.insertText("Invalid streamer URL!")
			return
		if self.channel_input.count() == 0:
			self.insertText("No channels exist!")
			return
		channel = self.config.get_streamer_channel(streamer["name"], self.channel_input.currentText())
		return urljoin(streamer["url"], channel["url"])

	def run_livestreamer(self):
		if self.livestreamer_thread is not None:
			if self.livestreamer_thread.isRunning():
				self.insertText("Livestreamer should still be running!")
				return
			else:
				self.livestreamer_thread.wait(self.thread_exit_grace_time)
				self.livestreamer_thread = None
				self.update()

		if self.livestreamer_thread is None:
			livestreamer = self.config.get_config_value("livestreamer-path")
			if livestreamer is None or livestreamer.strip() == "" or not os.path.isfile(livestreamer):
				self.insertText("Livestreamer path is not configured or file doesn't exist!")
				return
			player = self.config.get_config_value("player-path")
			if player is None or player.strip() == "" or not os.path.isfile(player):
				self.insertText("Player path is not configured or file doesn't exist!")
				return
			stream_url = self.get_streamer_url()
			if stream_url is None:
				self.insertText("Failed to form a complete streamer URL (missing streamer/channel/stream)!")
				return
			command_format = self.config.get_config_value("command-format")
			quality = self.quality_input.currentText()
			if "(" in quality:
				quality = quality[:quality.find("(")].strip()
			command = command_format.format(livestreamer=livestreamer, player=player, url=stream_url, quality=quality)
			self.livestreamer_thread = LivestreamerWorker(shlex.split(command))
			self.insertText("Starting Livestreamer thread.")
			self.livestreamer_thread.finished.connect(self.handle_livestreamer_thread_finished_signal)
			self.livestreamer_thread.statusMessage.connect(self.handle_livestreamer_thread_message_signal)
			self.livestreamer_thread.start()

	@QtCore.pyqtSlot(object)
	def handle_livestreamer_thread_message_signal(self, event):
		self.insertText(event.message, event.add_newline, event.add_timestamp)

	def handle_livestreamer_thread_finished_signal(self):
		self.livestreamer_thread = None

	def update_colors(self):
		foreground_color = self.config.get_config_value("foreground-color")
		background_color = self.config.get_config_value("background-color")
		self.cwidget.setStyleSheet("QWidget QLabel {{ color: {0} }} .QWidget {{ background-color: {1} }}".format(foreground_color, background_color))
		self.cwidget.update()

	def insertText(self, msg, add_newline=True, timestamp=True):
		"""Helper method for outputting text to the text box."""
		text = ""
		if timestamp and self.timestamp_format is not None:
			timestamp = format(datetime.now().strftime(self.timestamp_format))
			text = "{} ".format(timestamp)
		text += msg
		self.log_widget.moveCursor(QTextCursor.End)
		self.log_widget.insertPlainText(text)
		if add_newline:
			self.log_widget.insertPlainText("\n")
		self.log_widget.update()
Exemplo n.º 57
0
class SchemeSelector(QWidget):

    currentChanged = pyqtSignal()
    changed = pyqtSignal()

    def __init__(self, parent=None):
        super(SchemeSelector, self).__init__(parent)
        layout = QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(layout)

        self.label = QLabel()
        self.scheme = QComboBox()
        self.menuButton = QPushButton(flat=True)
        menu = QMenu(self.menuButton)
        self.menuButton.setMenu(menu)
        layout.addWidget(self.label)
        layout.addWidget(self.scheme)
        layout.addWidget(self.menuButton)
        layout.addStretch(1)
        # action generator
        def act(slot, icon=None):
            a = QAction(self, triggered=slot)
            self.addAction(a)
            icon and a.setIcon(icons.get(icon))
            return a

        # add action
        a = self.addAction_ = act(self.slotAdd, 'list-add')
        menu.addAction(a)

        # remove action
        a = self.removeAction = act(self.slotRemove, 'list-remove')
        menu.addAction(a)


        # rename action
        a = self.renameAction = act(self.slotRename, 'document-edit')
        menu.addAction(a)

        menu.addSeparator()

        # import action
        a = self.importAction = act(self.slotImport, 'document-open')
        menu.addAction(a)

        # export action
        a = self.exportAction = act(self.slotExport, 'document-save-as')
        menu.addAction(a)


        self.scheme.currentIndexChanged.connect(self.slotSchemeChanged)
        app.translateUI(self)

    def translateUI(self):
        self.label.setText(_("Scheme:"))
        self.menuButton.setText(_("&Menu"))
        self.addAction_.setText(_("&Add..."))
        self.removeAction.setText(_("&Remove"))
        self.renameAction.setText(_("Re&name..."))
        self.importAction.setText(_("&Import..."))
        self.exportAction.setText(_("&Export..."))

    def slotSchemeChanged(self, index):
        """Called when the Scheme combobox is changed by the user."""
        self.disableDefault(self.scheme.itemData(index) == 'default')
        self.currentChanged.emit()
        self.changed.emit()

    def disableDefault(self, val):
        self.removeAction.setDisabled(val)
        self.renameAction.setDisabled(val)

    def schemes(self):
        """Returns the list with internal names of currently available schemes."""
        return [self.scheme.itemData(i) for i in range(self.scheme.count())]

    def currentScheme(self):
        """Returns the internal name of the currently selected scheme"""
        return self.scheme.itemData(self.scheme.currentIndex())

    def insertSchemeItem(self, name, scheme):
        for i in range(1, self.scheme.count()):
            n = self.scheme.itemText(i)
            if n.lower() > name.lower():
                self.scheme.insertItem(i, name, scheme)
                break
        else:
            self.scheme.addItem(name, scheme)

    def addScheme(self, name):
        num, key = 1, 'user1'
        while key in self.schemes() or key in self._schemesToRemove:
            num += 1
            key = 'user{0}'.format(num)
        self.insertSchemeItem(name, key)
        self.scheme.setCurrentIndex(self.scheme.findData(key))
        return key

    def slotAdd(self):
        name, ok = QInputDialog.getText(self,
            app.caption(_("Add Scheme")),
            _("Please enter a name for the new scheme:"))
        if ok:
            self.addScheme(name)


    def slotRemove(self):
        index = self.scheme.currentIndex()
        scheme = self.scheme.itemData(index)
        if scheme == 'default':
            return # default can not be removed

        self._schemesToRemove.add(scheme)
        self.scheme.removeItem(index)

    def slotRename(self):
        index = self.scheme.currentIndex()
        name = self.scheme.itemText(index)
        scheme = self.scheme.itemData(index)
        newName, ok = QInputDialog.getText(self, _("Rename"), _("New name:"), text=name)
        if ok:
            self.scheme.blockSignals(True)
            self.scheme.removeItem(index)
            self.insertSchemeItem(newName, scheme)
            self.scheme.setCurrentIndex(self.scheme.findData(scheme))
            self.scheme.blockSignals(False)
            self.changed.emit()

    def slotImport(self):
        filetypes = "{0} (*.xml);;{1} (*)".format(_("XML Files"), _("All Files"))
        caption = app.caption(_("dialog title", "Import color theme"))
        filename = QFileDialog.getOpenFileName(self, caption, QDir.homePath(), filetypes)[0]
        if filename:
            self.parent().import_(filename)

    def slotExport(self):
        name = self.scheme.currentText()
        filetypes = "{0} (*.xml);;{1} (*)".format(_("XML Files"), _("All Files"))
        caption = app.caption(_("dialog title",
            "Export {name}").format(name=name))
        path = os.path.join(QDir.homePath(), name+'.xml')
        filename = QFileDialog.getSaveFileName(self, caption, path, filetypes)[0]
        if filename:
            if os.path.splitext(filename)[1] != '.xml':
                filename += '.xml'
            self.parent().export(name, filename)


    def loadSettings(self, currentKey, namesGroup):
        # don't mark schemes for removal anymore
        self._schemesToRemove = set()

        s = QSettings()
        cur = s.value(currentKey, "default", str)

        # load the names for the shortcut schemes
        s.beginGroup(namesGroup)
        block = self.scheme.blockSignals(True)
        self.scheme.clear()
        self.scheme.addItem(_("Default"), "default")
        lst = [(s.value(key, key, str), key) for key in s.childKeys()]
        for name, key in sorted(lst, key=lambda f: f[0].lower()):
            self.scheme.addItem(name, key)

        # find out index
        index = self.scheme.findData(cur)
        self.disableDefault(cur == 'default')
        self.scheme.setCurrentIndex(index)
        self.scheme.blockSignals(block)
        self.currentChanged.emit()

    def saveSettings(self, currentKey, namesGroup, removePrefix=None):
        # first save new scheme names
        s = QSettings()
        s.beginGroup(namesGroup)
        for i in range(self.scheme.count()):
            if self.scheme.itemData(i) != 'default':
                s.setValue(self.scheme.itemData(i), self.scheme.itemText(i))

        for scheme in self._schemesToRemove:
            s.remove(scheme)
        s.endGroup()
        if removePrefix:
            for scheme in self._schemesToRemove:
                s.remove("{0}/{1}".format(removePrefix, scheme))
        # then save current
        scheme = self.currentScheme()
        s.setValue(currentKey, scheme)
        # clean up
        self._schemesToRemove = set()
Exemplo n.º 58
0
class LoginScreen(QWidget):
    """
    The login screen lets the user select a user profile or create a new one.
    """

    login_successful = pyqtSignal(str, UserProfile, name="login_successful")

    def __init__(self, *args, **kwargs):
        """
        Load the user profiles and create the login controls.
        """
        super().__init__(*args, **kwargs)

        # Load the user profile collection.
        try:
            self.user_profile_collection = UserProfileCollection.from_dict(global_settings["users"])
        except KeyError:
            self.user_profile_collection = UserProfileCollection()

        # Create and set the widget layout.
        layout = QVBoxLayout()
        layout.setAlignment(Qt.AlignCenter)
        self.setLayout(layout)

        # Fill the select-user combobox with the loaded profile names.
        self.select_user_combobox = QComboBox()
        layout.addWidget(self.select_user_combobox)
        self.select_user_combobox.addItem("")
        names = self.user_profile_collection.names()
        names = [(name.lower(), name) for name in names]  # convert to lower case for sorting
        for _, name in sorted(names):
            self.select_user_combobox.addItem(name)

        # Add the login button.
        self.login_btn = QPushButton(text="Login", enabled=False)
        layout.addWidget(self.login_btn)

        # Add the create-user link.
        txt = QLabel(text="<a href='#'>Create new user</a>")
        layout.addWidget(txt)
        txt.setContextMenuPolicy(Qt.PreventContextMenu)

        # Connect signals and slots. This must be done after initializing all class members.
        self.select_user_combobox.currentIndexChanged.connect(self.on_selection_changed)
        self.login_btn.clicked.connect(self.on_login)
        txt.linkActivated.connect(self.on_show_create_user_dialog)

    @pyqtSlot(int, name="on_selection_changed")
    @log_exceptions
    def on_selection_changed(self, i):
        """
        Disable the login button if no username is selected, enable it otherwise.
        :param i: The current selected index in the selection combobox.
        """
        self.login_btn.setEnabled(i != 0)

    @pyqtSlot(name="on_login")
    @log_exceptions
    def on_login(self):
        """
        If something is selected in the select-user combobox, the login_successful is emitted.
        """
        if self.select_user_combobox.currentIndex() != 0:
            name = self.select_user_combobox.currentText()
            profile = self.user_profile_collection[name]
            self.login_successful.emit(name, profile)
        else:
            logging.warning("LoginScreen.on_login(): Tried to login without selecting a user.")

    @pyqtSlot(name="on_show_create_user_dialog")
    @log_exceptions
    def on_show_create_user_dialog(self):
        """
        Show the dialog to create a new user.
        """
        names = self.user_profile_collection.names()
        db_locations = self.user_profile_collection.db_locations()
        w = CreateUserDialog(names, db_locations, parent=self)
        w.setAttribute(Qt.WA_DeleteOnClose, True)
        w.accepted.connect(self.on_create_user)
        w.show()

    @pyqtSlot(dict, name="on_create_user")
    @log_exceptions
    def on_create_user(self, data):
        """
        Add the user to the profile collection.
        """
        try:
            name = data.pop("display_name")

            profile = UserProfile()
            for key, value in data.items():
                profile[key] = value

            # Add the profile to the collection.
            self.user_profile_collection[name] = profile

            # Add the new name to the combobox while keeping the alphabetical order.
            for i in range(self.select_user_combobox.count()):
                if name.lower() < self.select_user_combobox.itemText(i).lower():
                    self.select_user_combobox.insertItem(i, name)
                    break
            else:
                self.select_user_combobox.addItem(name)
            self.select_user_combobox.setCurrentText(name)

            # Save the created user.
            global_settings["users"] = self.user_profile_collection

        except (KeyError, IndexError, OSError) as ex:
            logging.warning(str(ex))
Exemplo n.º 59
0
class LanguageSelectWidget(QWidget):
    language_changed = pyqtSignal(str)

    def __init__(self, lyrics_path, current_language, *args, **kwargs):

        super(LanguageSelectWidget, self).__init__(*args, **kwargs)

        self.lyrics_path = QStandardPaths.locate(QStandardPaths.AppDataLocation, lyrics_path,
                                                 QStandardPaths.LocateDirectory)
        self.current_language = current_language

        layout = QVBoxLayout()
        layout.setSpacing(5)
        layout.setContentsMargins(0, 0, 0, 0)

        languages = []
        try:
            for filename in os.listdir(self.lyrics_path):
                if filename != "timing" and os.path.isdir(os.path.join(self.lyrics_path, filename)):
                    languages.append(filename)
        except FileNotFoundError:
            pass

        self.languages_combo_box = QComboBox()
        self.languages_combo_box.addItems(sorted(languages) + [self.tr("New Language...")])
        self.languages_combo_box.currentTextChanged.connect(self._language_changed)

        self._select_current_language()
        layout.addWidget(self.languages_combo_box)

        self.edit_button = QPushButton(text=self.tr("Edit Language..."), clicked=self._edit_current_language)
        layout.addWidget(self.edit_button)

        self.setLayout(layout)

        self.import_lyrics_wizard = ImportLyricsWizard(lyrics_path,
                                                       accepted=self._wizard_done,
                                                       rejected=self._wizard_aborted,
                                                       )

        self._editing_language = False

        if not languages:
            self.import_lyrics_wizard.open()

    def _language_changed(self, name):

        if name == self.tr("New Language..."):
            self.import_lyrics_wizard.open()
        else:
            self.current_language = name
            self.language_changed.emit(name)

    def _wizard_done(self):

        languages = [self.languages_combo_box.itemText(i) for i in range(self.languages_combo_box.count() - 1)]

        if self._editing_language:
            self._editing_language = False
            old_index = languages.index(self.current_language)
            self.languages_combo_box.removeItem(old_index)
            languages.pop(old_index)

        new_language = self.import_lyrics_wizard.language
        print("new", new_language)

        languages.append(new_language)
        languages.sort()

        index = languages.index(new_language)
        self.languages_combo_box.insertItem(index, new_language)
        self.languages_combo_box.setCurrentIndex(index)

    def _wizard_aborted(self):
        self._select_current_language()

    def _select_current_language(self):
        languages = [self.languages_combo_box.itemText(i) for i in range(self.languages_combo_box.count() - 1)]
        if languages:
            self.languages_combo_box.setCurrentIndex(languages.index(self.current_language))

    def _edit_current_language(self):
        self._editing_language = True
        self.import_lyrics_wizard.open()
        self.import_lyrics_wizard.edit_language(self.current_language)
Exemplo n.º 60
0
class AvailableSizes(QDialog):
    def __init__(self):
        super(AvailableSizes, self).__init__()
        
        self.createCombos()
        self.createHeader()
        #self.createMenuBar()
        
        self.printOut = QTextEdit()
        self.printOut.setFont(QFont('Helvetica', 11, QFont.Bold))
        self.printOut.setReadOnly(True)
        
        mainLayout = QVBoxLayout()
        #mainLayout.setMenuBar(self.menuBar)
        mainLayout.addWidget(self.frmHeader)
        mainLayout.addWidget(self.grpBox)
        mainLayout.addWidget(self.printOut)
        #mainLayout.setAlignment(self.frmHeader, Qt.AlignRight)
        self.setLayout(mainLayout)
        
        #self.setWindowTitle("Available Sizes")
        self.setWindowFlags(Qt.FramelessWindowHint)
        bgColor = QPalette()
        bgColor.setColor(self.backgroundRole(), Qt.gray)
        self.setPalette(bgColor)
        self.setWindowIcon(QIcon('icon/PS_Icon.png'))
        self.cbSku.setFocus()
        
    def createHeader(self):
        blk = QPalette()
        blk.setColor(blk.Foreground, Qt.white)
        
        lblTitle = QLabel("Availability Checker")
        lblTitle.setFont(QFont("Times", 12, QFont.Bold ))
        lblTitle.setPalette(blk) 
         
        btnClose = QToolButton()
        btnClose.setIcon(QIcon("icon\size_exit.png"))
        btnClose.setAutoRaise(True)
        btnClose.setIconSize(QSize(25,25))
        btnClose.clicked.connect(lambda: self.close())
        
        hbHeader = QHBoxLayout()
        hbHeader.addWidget(lblTitle)
        hbHeader.addWidget(btnClose)
        hbHeader.setContentsMargins(0, 0, 0, 0)
        
        self.frmHeader = QFrame()
        self.frmHeader.setLayout(hbHeader)
        
    def createCombos(self):
        cbFont = QFont("Times", 8, QFont.Bold)
        designs = self.getDesigns()
        
        self.grpBox = QGroupBox()
        self.grpBox.setFont(QFont('Times', 10, QFont.Bold))
        layout = QFormLayout()
        
        self.cbSku = QComboBox()
        self.cbSku.addItem("Designs")
        self.cbSku.addItems(designs)
        self.cbSku.setFont(cbFont)
        self.cbSku.currentIndexChanged.connect(self.skuChanged)
        
        self.cbStyle = QComboBox()
        self.cbStyle.addItem("Styles")
        self.cbStyle.setFont(cbFont)
        self.cbStyle.currentIndexChanged.connect(self.styleChanged)
        
        layout.addRow(QLabel("Design:"), self.cbSku)
        layout.addRow(QLabel("Style:"), self.cbStyle)
        
        self.grpBox.setLayout(layout)
    
    def skuChanged(self):
        
        if self.cbStyle.count() > 0:
            self.cbStyle.clear()
            self.cbStyle.addItem("Style")
            self.cbStyle.setCurrentIndex(0)
            styles = self.getStyles(self.cbSku.currentText())
        else: 
            styles = self.getStyles(self.cbSku.currentText())
        self.cbStyle.addItems(styles)
        
    def styleChanged(self):
        self.printOut.clear()
        sizes = self.getSizes(self.cbSku.currentText(), self.cbStyle.currentText())
        if self.cbStyle.currentText() != "Styles":
            for i in sizes:
                self.printOut.insertPlainText(i + '\n')
                    
       
    def createMenuBar(self):
        self.menuBar = QMenuBar()

        self.fileMenu = QMenu("&File", self)
        self.exitAction = self.fileMenu.addAction("E&xit")
        self.menuBar.addMenu(self.fileMenu)

        self.exitAction.triggered.connect(self.accept)
        
    def getDesigns(self):
        sd = mysql_db.mysql_connect(self)
        sd.execute("""SELECT 
                            DISTINCT CONCAT(d.sku_code, " - ", d.name) design
                        FROM
                            designs d
                        JOIN packages p on p.design_id = d.id
                        ORDER BY RIGHT(d.sku_code, 3), LEFT(d.sku_code,1)""")
        ds = sd.fetchall()
        lsDesigns = []
        for i in ds:
            lsDesigns.append(i[0])
        return lsDesigns    
    
    def getStyles(self, sku):
        sd = mysql_db.mysql_connect(self)
        sd.execute("""SELECT
                            DISTINCT g.name
                        FROM 
                            garment_styles_ages g
                        JOIN packages p ON p.garment_styles_age_id = g.id
                        JOIN designs d ON d.id = p.design_id
                        WHERE d.sku_code = '""" + sku[:4] + """'
                        ORDER BY g.name""")
        ds = sd.fetchall()
        lsStyles = []
        for i in ds:
            lsStyles.append(i[0])
        return lsStyles
    
    def getSizes(self, sku, style):
        style = style.replace("'", "\\'")
        sd = mysql_db.mysql_connect(self)
        sd.execute("""
                        SELECT
                            DISTINCT CONCAT(s.name, ' - ', c.name) size
                        FROM 
                            sizes s
                        JOIN packages p ON p.size_id = s.id
                        JOIN designs d ON d.id = p.design_id
                        JOIN colors c ON c.id = p.color_id
                        JOIN garment_styles_ages g ON g.id = p.garment_styles_age_id
                        WHERE 
                            d.sku_code = '""" + sku[:4] + """'
                        AND
                            g.name = '""" + style + """'""")
        ds = sd.fetchall()
        lsSizes = []
        for i in ds:
            lsSizes.append(i[0])
        return lsSizes

    
    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.leftClick = True
            self.offset = event.pos()

    def mouseMoveEvent(self, event):
        if self.leftClick == True:
            x=event.globalX()
            y=event.globalY()
            x_w = self.offset.x()
            y_w = self.offset.y()
            self.move(x-x_w, y-y_w)
            
    def mouseReleaseEvent(self, event):
        self.leftClick = False