Beispiel #1
0
class OffsetRow(QWidget):
    def __init__(self):
        super(OffsetRow, self).__init__()
        self.layout = QHBoxLayout()
        self.layout.setContentsMargins(0,0,0,0)
        self.sign = QComboBox()
        self.sign.addItems(['-', '+'])
        self.amount = QLineEdit()
        self.amount.setInputMask('99999999')
        self.unit = QComboBox()
        self.unit.addItems(['sec', 'min', 'hrs', 'day'])
        self.layout.addWidget(self.sign)
        self.layout.addWidget(self.amount, stretch = 1)
        self.layout.addWidget(self.unit)

    def show(self):
        self.sign.show()
        self.amount.show()
        self.unit.show()

    def hide(self):
        self.sign.hide()
        self.amount.hide()
        self.unit.hide()

    def set_values(self, sign, amount, unit):
        self.sign.setCurrentText(sign)
        self.amount.setText(str(amount))
        self.unit.setCurrentText(unit)
 def __addSinglesLine(self):
     """
     Private slot to add a line of entry widgets for single characters.
     """
     hbox = QWidget(self.singlesItemsBox)
     hboxLayout = QHBoxLayout(hbox)
     hboxLayout.setContentsMargins(0, 0, 0, 0)
     hboxLayout.setSpacing(6)
     hbox.setLayout(hboxLayout)
     cb1 = QComboBox(hbox)
     cb1.setEditable(False)
     self.__populateCharTypeCombo(cb1, True)
     hboxLayout.addWidget(cb1)
     le1 = QLineEdit(hbox)
     le1.setValidator(self.charValidator)
     hboxLayout.addWidget(le1)
     cb1a = QComboBox(hbox)
     cb1a.setEditable(False)
     cb1a.setSizeAdjustPolicy(QComboBox.AdjustToContents)
     hboxLayout.addWidget(cb1a)
     cb1a.hide()
     cb2 = QComboBox(hbox)
     cb2.setEditable(False)
     self.__populateCharTypeCombo(cb2, True)
     hboxLayout.addWidget(cb2)
     le2 = QLineEdit(hbox)
     le2.setValidator(self.charValidator)
     hboxLayout.addWidget(le2)
     cb2a = QComboBox(hbox)
     cb2a.setEditable(False)
     cb2a.setSizeAdjustPolicy(QComboBox.AdjustToContents)
     hboxLayout.addWidget(cb2a)
     cb2a.hide()
     self.singlesItemsBoxLayout.addWidget(hbox)
     
     cb1.activated[int].connect(self.__singlesCharTypeSelected)
     cb2.activated[int].connect(self.__singlesCharTypeSelected)
     hbox.show()
     
     self.singlesItemsBox.adjustSize()
     
     self.singlesEntries.append([cb1, le1, cb1a])
     self.singlesEntries.append([cb2, le2, cb2a])
Beispiel #3
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()
Beispiel #4
0
class Example(QWidget):
    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):
        self.okButton = QPushButton("查询")
        self.cancelButton = QPushButton("退出")

        hbox = QHBoxLayout()  # 水平布局
        hbox.addStretch(1)  # 伸展因子
        hbox.addWidget(self.okButton)  # 添加按钮
        hbox.addWidget(self.cancelButton)  # 添加按钮

        vbox = QVBoxLayout()  # 垂直布局
        vbox.addStretch(1)

        vbox.addLayout(hbox)

        self.cancelButton.clicked.connect(QCoreApplication.instance().quit)

        self.setLayout(vbox)

        self.lbl1 = QLabel("起始地", self)
        self.lbl1.resize(self.lbl1.sizeHint())
        self.lbl1.move(50, 20)

        self.lbl2 = QLabel("目的地", self)
        self.lbl2.resize(self.lbl1.sizeHint())
        self.lbl2.move(300, 20)

        self.textbox1 = QLineEdit(self)
        self.textbox1.move(50, 40)
        self.textbox1.resize(self.textbox1.sizeHint())

        self.textbox2 = QLineEdit(self)
        self.textbox2.move(300, 40)
        self.textbox2.resize(self.textbox2.sizeHint())

        self.okButton.clicked.connect(self.search)
        # self.cancelButton.clicked.connect(self.cancel)

        self.combobox = QComboBox(self)
        self.combobox.move(50, 400)
        self.combobox.addItem("出发最早")
        self.combobox.addItems(["出发最晚", "时长最短"])
        self.combobox.hide()

        self.setGeometry(300, 300, 1000, 500)
        self.setWindowTitle('高铁动车查询')
        self.center()
        self.show()

    def center(self):
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    def closeEvent(self, event):
        reply = QMessageBox.question(self, "Message", "Are you sure to exit",
                                     QMessageBox.Yes | QMessageBox.No,
                                     QMessageBox.No)

        if reply == QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()
        self.conn.close()

    def search(self):
        # print(1)
        start = self.textbox1.text()
        stop = self.textbox2.text()
        print("正在搜索")
        print(start)
        print(stop)
        import json
        with conn.cursor() as cursor:
            with open("G:\软件工程课程设计\全国高铁信息\高铁车站出发信息.json",
                      "r",
                      encoding="utf-8") as jf:
                results = json.load(jf)
                stations = list(results.keys())
                # print(stations)
                if start in stations:
                    sql = search_table_station.replace("example", start)
                    cursor.execute(sql)
                    results = cursor.fetchall()
                    train_list = []
                    for trains in results:
                        # print(trains)
                        if stop in trains:
                            train_list.append(trains[0])
                    if len(train_list) == 0:
                        # print("没有从" + start + "到" + stop + "的高铁动车")
                        self.stop_no_train(start, stop)
                        # pass
                        # for station_train in trains:
                        #     print(station_train)
                        #     if stop in station_train:
                        #         train_list.append(trains[0])
                    travels = []
                    for train in train_list:
                        sql = search_table_train.replace("example", train)
                        cursor.execute(sql)
                        results = cursor.fetchall()

                        travel = {}
                        for train_station in results:
                            if start in train_station:
                                train_id = train_station[1]
                                start_station = train_station[2]
                                start_time = train_station[4]
                            if stop in train_station:
                                arrival_time = train_station[3]
                                time_start = start_time.split(":")
                                time_arrival = arrival_time.split(":")
                                # print(time_start)
                                # print(time_arrival)
                                time_total = []

                                if int(time_start[0]) <= int(
                                        time_arrival[0]) and int(
                                            time_start[1]) < int(
                                                time_arrival[1]):

                                    time_total.append(
                                        int(time_arrival[0]) -
                                        int(time_start[0]))
                                    time_total.append(
                                        int(time_arrival[1]) -
                                        int(time_start[1]))
                                if int(time_start[0]) <= int(
                                        time_arrival[0]) and int(
                                            time_start[1]) > int(
                                                time_arrival[1]):

                                    time_total.append(
                                        int(time_arrival[0]) -
                                        int(time_start[0]) - 1)
                                    time_total.append(
                                        int(time_arrival[1]) -
                                        int(time_start[1]) + 60)

                                if int(time_start[0]) > int(
                                        time_arrival[0]) and int(
                                            time_start[1]) < int(
                                                time_arrival[1]):
                                    time_total.append(
                                        int(time_arrival[0]) -
                                        int(time_start[0]) + 24)
                                    time_total.append(
                                        int(time_arrival[1]) -
                                        int(time_start[1]))
                                if int(time_start[0]) > int(
                                        time_arrival[0]) and int(
                                            time_start[1]) > int(
                                                time_arrival[1]):
                                    time_total.append(
                                        int(time_arrival[0]) -
                                        int(time_start[0]) + 24 - 1)
                                    time_total.append(
                                        int(time_arrival[1]) -
                                        int(time_start[1]) + 60)
                                else:
                                    pass
                                total_time = "{}:{}".format(
                                    time_total[0], time_total[1])
                                travel = {
                                    "train_id": train_id,
                                    "start_station": start_station,
                                    "start_time": start_time,
                                    "arrival_time": arrival_time,
                                    "stop": stop,
                                    "total_time": total_time
                                }
                        travels.append(travel)

                    self.show_trains(travels)

                else:
                    self.station_no_train(start)

    def show_trains(self, travels):

        self.tableWidget = QTableWidget(self)  # 创建一个表格
        self.tableWidget.setEditTriggers(QTableWidget.NoEditTriggers)
        self.tableWidget.move(50, 100)
        self.tableWidget.resize(700, 250)

        self.tableWidget.setRowCount(len(travels))
        self.tableWidget.setColumnCount(6)

        self.tableWidget.setHorizontalHeaderLabels(
            ['列车', '出发站', '出发时间', '到达时间', '到达站', '总时长'])

        if self.combobox.currentText() == "出发最早":
            start_times = []
            for travel in travels:
                start_time = travel["start_time"].split(":")
                start_time = int(start_time[0] + start_time[1])
                start_times.append(start_time)
            time_time = dict(zip(range(len(travels)), start_times))
            # start_times = list(time_time.values())
            # start_times.sort()
            results = sorted(time_time.items(),
                             key=lambda item: item[1],
                             reverse=False)
            sort_time = []
            for result in results:
                sort_time.append(result[0])

            for result in results:
                list = []
                list.append(travels[result[0]]["train_id"])
                list.append(travels[result[0]]["start_station"])
                list.append(travels[result[0]]["start_time"])
                list.append(travels[result[0]]["arrival_time"])
                list.append(travels[result[0]]["stop"])
                list.append(travels[result[0]]["total_time"])
                for info in list:
                    self.tableWidget.setItem(sort_time.index(result[0]),
                                             list.index(info),
                                             QTableWidgetItem(info))

        elif self.combobox.currentText() == "出发最晚":
            start_times = []
            for travel in travels:
                start_time = travel["start_time"].split(":")
                start_time = int(start_time[0] + start_time[1])
                start_times.append(start_time)
            time_time = dict(zip(range(len(travels)), start_times))

            results = sorted(time_time.items(),
                             key=lambda item: item[1],
                             reverse=True)
            sort_time = []
            for result in results:
                sort_time.append(result[0])

            for result in results:
                list = []
                list.append(travels[result[0]]["train_id"])
                list.append(travels[result[0]]["start_station"])
                list.append(travels[result[0]]["start_time"])
                list.append(travels[result[0]]["arrival_time"])
                list.append(travels[result[0]]["stop"])
                list.append(travels[result[0]]["total_time"])
                for info in list:
                    self.tableWidget.setItem(sort_time.index(result[0]),
                                             list.index(info),
                                             QTableWidgetItem(info))

        elif self.combobox.currentText() == "时长最短":
            start_times = []
            for travel in travels:
                start_time = travel["total_time"].split(":")
                start_time = int(start_time[0] + start_time[1])
                start_times.append(start_time)
            time_time = dict(zip(range(len(travels)), start_times))

            results = sorted(time_time.items(),
                             key=lambda item: item[1],
                             reverse=False)
            sort_time = []
            for result in results:
                sort_time.append(result[0])

            for result in results:
                list = []
                list.append(travels[result[0]]["train_id"])
                list.append(travels[result[0]]["start_station"])
                list.append(travels[result[0]]["start_time"])
                list.append(travels[result[0]]["arrival_time"])
                list.append(travels[result[0]]["stop"])
                list.append(travels[result[0]]["total_time"])
                for info in list:
                    self.tableWidget.setItem(sort_time.index(result[0]),
                                             list.index(info),
                                             QTableWidgetItem(info))
        self.combobox.show()
        self.tableWidget.show()

    def choose_soft(self, combobox_current_index, travels):
        print("已经被调用")
        print(combobox_current_index)
        if combobox_current_index == 0:
            start_times = []
            for travel in travels:
                start_time = travel["start_time"].split(":")
                start_time = int(start_time[0] + start_time[1])
                start_times.append(start_time)
            time_time = dict(zip(range(len(travels)), start_times))

            results = sorted(time_time.items(), key=lambda item: item[1])
            sort_time = []
            for result in results:
                sort_time.append(result[0])

            for result in results:
                list = []
                list.append(travels[result[0]]["train_id"])
                list.append(travels[result[0]]["start_station"])
                list.append(travels[result[0]]["start_time"])
                list.append(travels[result[0]]["arrival_time"])
                list.append(travels[result[0]]["stop"])
                for info in list:
                    self.tableWidget.setItem(sort_time.index(result[0]),
                                             list.index(info),
                                             QTableWidgetItem(info))
            self.tableWidget.show()

    def cancel(self):
        self.show()

    def station_no_train(self, start):
        self.tableWidget.hide()
        # if self.tableWidget:
        #     self.tableWidget.hide()
        self.lable = QLabel(start + "车站无高铁经过", self)
        self.lable.move(50, 100)
        self.lable.resize(self.lable.sizeHint())
        self.lable.show()

    def stop_no_train(self, start, stop):
        self.tableWidget.hide()
        self.lable = QLabel("没有从" + start + "到" + stop + "的高铁动车", self)
        self.lable.move(50, 100)
        self.lable.show()
Beispiel #5
0
from PyQt5.QtWidgets import QWidget, QPushButton, QLabel, QComboBox, QLineEdit, QTableWidget, QTableWidgetItem, \
Beispiel #6
0
class Example(QMainWindow):
    def __init__(self):
        super(Example, self).__init__()
        self.tmr = QTimer()
        self.tmr.timeout.connect(self.on_timer)
        self.alarm_class = Alarm(0, 0)
        self.status = False
        self.h_m_list = [None, None]
        self.color_frame = (0, 0, 0)
        self.old_pos = None
        self.text = ['00', '00']
        self.initUI()

    def initUI(self):
        # Генерация окна
        self.setWindowTitle('Clock')
        self.setGeometry(100, 100, 260, 160)
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.setObjectName('MainWidget')
        self.setStyleSheet("#MainWidget {background-color: #272727;}")

        # Кнопка закрытие окна
        self.btn_close = QPushButton(self, clicked=self.close)
        self.btn_close.setIcon(QtGui.QIcon(QtGui.QPixmap('pngs/cross.png')))
        self.btn_close.setFlat(True)
        self.btn_close.resize(17, 17)
        self.btn_close.move(242, 1)
        self.btn_close.show()

        # Кнопка возрата в general
        self.btn_gn = QPushButton(self, clicked=self.general)
        self.btn_gn.setIcon(QtGui.QIcon(QtGui.QPixmap('pngs/back.png')))
        self.btn_gn.setFlat(True)
        self.btn_gn.resize(20, 20)
        self.btn_gn.move(1, 1)
        self.btn_gn.show()

        # Кнопка входа в settings
        self.btn_st = QPushButton(self, clicked=self.settings)
        self.btn_st.setIcon(QtGui.QIcon(QtGui.QPixmap("pngs/gear.png")))
        self.btn_st.setFlat(True)
        self.btn_st.resize(15, 15)
        self.btn_st.move(3, 3)
        self.btn_st.show()

        # Кнопка будильника
        self.alarmB = QPushButton(self, clicked=self.alarm_st)
        self.alarmB.setIcon(QtGui.QIcon(QtGui.QPixmap("pngs/alarmN.png")))
        self.alarmB.setFlat(True)
        self.alarmB.resize(25, 25)
        self.alarmB.move(204, 39)
        self.alarmB.show()

        # Кнопка включения будильника
        self.alVKL = QPushButton('Включить', self, clicked=self.alarm_status)
        self.alVKL.resize(65, 20)
        self.alVKL.setObjectName('a')
        self.alVKL.setStyleSheet(
            "#a {background-color: white; border-radius: 2px;}")
        self.alVKL.move(98, 110)

        # Синхронизация системного времени
        self.sinT = QPushButton('Синхронизация\nсистемного\nвремени',
                                self,
                                clicked=set_server_time)
        self.sinT.resize(90, 50)
        self.sinT.move(120, 28)

        # Дисплей для будильника
        self.lcdA = QLCDNumber(self)
        self.lcdA.resize(150, 75)
        self.lcdA.move(55, 30)
        self.lcdA.setSegmentStyle(QLCDNumber.Flat)
        self.lcdA.setObjectName("LCDA")
        self.lcdA.setStyleSheet(
            "#LCDA {background-image: url(pngs/фон.png); border: 2px solid #4c4c4c;}"
        )
        self.lcdA.display(':'.join(self.text))

        # Слайдер выбора часа
        self.sldH = QSlider(Qt.Vertical, self)
        self.sldH.setMaximum(23)
        self.sldH.move(46, 30)
        self.sldH.resize(9, 75)
        self.sldH.valueChanged.connect(self.slider)

        # Слайдер выбора минут
        self.sldM = QSlider(Qt.Vertical, self)
        self.sldM.setMaximum(59)
        self.sldM.move(206, 30)
        self.sldM.resize(9, 75)
        self.sldM.valueChanged.connect(self.slider2)

        # Дисплей часов
        self.lcd = QLCDNumber(self)
        self.lcd.resize(150, 75)
        self.lcd.setSegmentStyle(QLCDNumber.Flat)
        self.lcd.move(55, 40)
        self.lcd.display(make_time_for_lcd())
        self.lcd.setObjectName("LCD")
        self.lcd.setStyleSheet(
            "#LCD {background-image: url(pngs/фон.png); border: 2px solid #4c4c4c;}"
        )

        # Комбобокс для стилизации
        self.combo = QComboBox(self)
        self.combo.setStyleSheet('border-radius: 3px, 3px, 2px, 1px;')
        self.combo.resize(75, 20)
        self.combo.addItems([
            "Stylization", "Color", "Olds", "Matrix", "Sofa", "Low Poly",
            "Anime", "Pony", "Савок"
        ])
        self.combo.activated[str].connect(self.onActivated)
        self.combo.move(30, 30)

        # Кнопка отключения будильника
        self.gm = QPushButton('ОТКЛЮЧИТЬ\nБУДИЛЬНИК',
                              self,
                              clicked=self.play_stop)
        self.gm.setObjectName('x')
        self.gm.setStyleSheet("#x {background-color: rgb(0, 255, 0);}")
        self.gm.resize(90, 50)
        self.gm.move(85, 55)

        self.general()

    # Сцена часов
    def general(self):
        try:
            self.btn_st.show()
            self.btn_gn.hide()
            self.combo.hide()
            self.alarmB.show()
            self.lcd.show()
            self.sldH.hide()
            self.sldM.hide()
            self.lcdA.hide()
            self.alVKL.hide()
            self.sinT.hide()
            self.gm.hide()
        except AttributeError:
            pass

    # Сцена настроек
    def settings(self):
        self.btn_gn.show()
        self.btn_st.hide()
        self.combo.show()
        self.alarmB.hide()
        self.lcd.hide()
        self.sldH.hide()
        self.sldM.hide()
        self.lcdA.hide()
        self.alVKL.hide()
        self.sinT.show()
        self.gm.hide()

    def alarm_st(self):
        self.btn_gn.show()
        self.btn_st.hide()
        self.alarmB.hide()
        self.lcd.hide()
        self.sldH.show()
        self.sldM.show()
        self.sldH.setValue(get_local_time()['hours'])
        self.sldM.setValue(get_local_time()['minutes'])
        self.lcdA.show()
        self.alVKL.show()
        self.sinT.hide()

    def good_morning(self):
        self.gm.show()
        self.btn_gn.hide()
        self.btn_st.hide()
        self.alarmB.hide()
        self.lcd.hide()
        self.sldH.hide()
        self.sldM.hide()
        self.lcdA.hide()
        self.alVKL.hide()
        self.sinT.hide()

    def play_stop(self):
        self.alarm_class.stop_sound()
        self.alarm_status()
        self.general()

    # Изменение фона окна
    def palette(self):
        color = QColorDialog.getColor()
        if color.isValid():
            self.setStyleSheet("#MainWidget {background-color: %s;}" %
                               color.name())
            self.paintEvent(self, clr=self.hex_to_rgb(color.name()))

    # рисование окна
    def paintEvent(self, event: QtGui.QPaintEvent, clr=(0, 0, 0)):
        painter = QtGui.QPainter(self)
        painter.setPen(
            QtGui.QPen(
                QtGui.QColor(int(fabs(clr[0] - 75)), int(fabs(clr[1] - 75)),
                             int(fabs(clr[2] - 75))), 2))
        painter.drawRect(self.rect())

    # нужна для перемещёния окна
    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.old_pos = event.pos()

    # вызывается всякий раз, когда мышь перемещается
    def mouseMoveEvent(self, event):
        if not self.old_pos:
            return
        delta = event.pos() - self.old_pos
        self.move(self.pos() + delta)

    # перевод их hex в rgb
    def hex_to_rgb(self, value):
        value = value.lstrip('#')
        lv = len(value)
        return tuple(
            int(value[i:i + lv // 3], 16) for i in range(0, lv, lv // 3))

    def onActivated(self, val):
        backgrounds = {
            'Stylization': '#272727',
            'Olds': 'pngs/olds.png',
            'Matrix': 'pngs/matrix.png',
            'Sofa': 'pngs/диван.jpg',
            'Low Poly': 'pngs/bg.png',
            "Anime": 'pngs/anime.jpg',
            "Pony": 'pngs/pony.jpg',
            "Савок": 'pngs/фоник.png'
        }
        if val == 'Color':
            self.palette()
        elif val == 'Stylization':
            self.setStyleSheet("#MainWidget {background-color: #272727;}")
        elif val != 'Color':
            self.setStyleSheet("#MainWidget {background-image: url(%s);}" %
                               backgrounds[val])
            self.paintEvent(self)

    def slider(self, n):
        self.h_m_list[0] = n
        if len(str(n)) == 1:
            n = '0' + str(n)
        self.text[0] = str(n)
        self.lcdA.display(':'.join(self.text))

    def slider2(self, n):
        self.h_m_list[1] = n
        if len(str(n)) == 1:
            n = '0' + str(n)
        self.text[1] = str(n)
        self.lcdA.display(':'.join(self.text))

    def on_timer(self):
        """ timer handler """
        self.lcd.display(make_time_for_lcd())
        if self.status:
            t = get_local_time()
            if t['hours'] == self.h_m_list[0] and t[
                    'minutes'] == self.h_m_list[1]:
                self.alarm_class.start_sound()
                self.good_morning()

    def alarm_status(self):
        if not self.status:
            self.status = True
            self.alarmB.setIcon(QtGui.QIcon(QtGui.QPixmap("pngs/alarmA.png")))
            self.alVKL.setText('Выключить')
            self.alarm_class.set(self.h_m_list[0], self.h_m_list[1])
        elif self.status:
            self.status = False
            self.alarmB.setIcon(QtGui.QIcon(QtGui.QPixmap("pngs/alarmN.png")))
            self.alVKL.setText('Включить')
        self.alarm_class.tracked = self.status
Beispiel #7
0
class ActionBar(QFrame):
    """
    SIGNALS:
    @changeCurrent(PyQt_PyObject)
    @runFile(QString)
    @reopenTab(QString)
    @recentTabsModified()
    """
    changeCurrent = pyqtSignal('QObject*', int)
    runFile = pyqtSignal(str)
    reopenTab = pyqtSignal(str)
    recentTabsModified = pyqtSignal()
    closeFile = pyqtSignal()# closeSplit
    editorSplited = pyqtSignal(bool)# splitEditor, hasSplitEditor
    addToProject = pyqtSignal(str)
    showFileInExplorer = pyqtSignal(str)
    goToSymbol = pyqtSignal(int)
    dockWidget = pyqtSignal("QObject*")
    undockWidget = pyqtSignal()
    undockEditor = pyqtSignal()

    class ORIENTATION:
        Horizontal = 0
        Vertical = 1

    Q_ENUMS(ORIENTATION)
            
    def __init__(self, main_combo=False):
        super(ActionBar, self).__init__()
        self.setObjectName("actionbar")
        hbox = QHBoxLayout(self)
        hbox.setContentsMargins(1, 1, 1, 1)
        hbox.setSpacing(1)

        self.lbl_checks = QLabel('')
        self.lbl_checks.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.lbl_checks.setFixedWidth(48)
        self.lbl_checks.setVisible(False)
        hbox.addWidget(self.lbl_checks)

        self.combo = ComboFiles()#self)
        self.combo.setIconSize(QSize(16, 16))
        #model = QStandardItemModel()
        #self.combo.setModel(model)
        #self.combo.view().setDragDropMode(QAbstractItemView.InternalMove)
        self.combo.setMaximumWidth(300)
        self.combo.setObjectName("combotab")
        self.combo.currentIndexChanged[int].connect(self.current_changed)
        self.combo.setToolTip(translations.TR_COMBO_FILE_TOOLTIP)
        self.combo.setContextMenuPolicy(Qt.CustomContextMenu)
        self.combo.customContextMenuRequested['const QPoint &'].connect(self._context_menu_requested)
        hbox.addWidget(self.combo)
        #QTimer.singleShot(50000, lambda: print("singleShot", self.combo.showPopup()))

        self.symbols_combo = QComboBox()
        self.symbols_combo.setIconSize(QSize(16, 16))
        self.symbols_combo.setObjectName("combo_symbols")
        self.symbols_combo.activated[int].connect(self.current_symbol_changed)
        hbox.addWidget(self.symbols_combo)

        self.code_navigator = CodeNavigator()
        hbox.addWidget(self.code_navigator)

        self._pos_text = "Line: %d, Col: %d"
        # self.lbl_position = QLabel(self._pos_text % (0, 0))
        # self.lbl_position.setObjectName("position")
        # self.lbl_position.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        # hbox.addWidget(self.lbl_position)
        # hbox.addSpacerItem(QSpacerItem(10,10, QSizePolicy.Expanding))
        hbox.addSpacing(100)

        self.btn_close = QPushButton(
            self.style().standardIcon(QStyle.SP_DialogCloseButton), '')
        self.btn_close.setIconSize(QSize(16, 16))
        if main_combo:
            self.btn_close.setObjectName('navigation_button')
            self.btn_close.setToolTip(translations.TR_CLOSE_FILE)
            self.btn_close.clicked['bool'].connect(lambda s: self.about_to_close_file())
        else:
            self.btn_close.setObjectName('close_split')
            self.btn_close.setToolTip(translations.TR_CLOSE_SPLIT)
            self.btn_close.clicked['bool'].connect(self.close_split)
        self.btn_close.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        hbox.addWidget(self.btn_close)

    def resizeEvent(self, event):
        super(ActionBar, self).resizeEvent(event)
        if event.size().width() < 350:
            self.symbols_combo.hide()
            self.code_navigator.hide()
            # self.lbl_position.hide()
        else:
            self.symbols_combo.show()
            self.code_navigator.show()
            # self.lbl_position.show()

    def add_item(self, text, neditable):
        """Add a new item to the combo and add the neditable data."""
        self.combo.addItem(text, neditable)
        self.combo.setCurrentIndex(self.combo.count() - 1)

    def get_editables(self):
        editables = []
        for index in range(self.combo.count()):
            neditable = self.combo.itemData(index)
            editables.append(neditable)
        return editables

    def add_symbols(self, symbols):
        """Add the symbols to the symbols's combo."""
        self.symbols_combo.clear()
        for symbol in symbols:
            data = symbol[1]
            if data[1] == 'f':
                icon = QIcon(":img/function")
            else:
                icon = QIcon(":img/class")
            self.symbols_combo.addItem(icon, data[0])

    def set_current_symbol(self, index):
        self.symbols_combo.setCurrentIndex(index)

    def update_item_icon(self, neditable, icon):
        index = self.combo.findData(neditable)
        self.combo.setItemIcon(index, icon)

    def update_item_text(self, neditable, text):
        index = self.combo.findData(neditable)
        self.combo.setItemText(index, text)

    def current_changed(self, index):
        """Change the current item in the combo."""
        neditable = self.combo.itemData(index)
        self.changeCurrent.emit(neditable, index)

    def current_symbol_changed(self, index):
        """Change the current symbol in the combo."""
        self.goToSymbol.emit(index)

    def update_line_col(self, line, col):
        """Update the line and column position."""
        #self.lbl_position.setText(self._pos_text % (line, col))
        IDE.getInstance().showMessageStatus(self._pos_text % (line, col))

    def _context_menu_requested(self, point):
        """Display context menu for the combo file."""
        if self.combo.count() == 0:
            # If there is not an Editor opened, don't show the menu
            return
        menu = QMenu()

        actionAdd = menu.addAction(translations.TR_ADD_TO_PROJECT)
        actionRun = menu.addAction(translations.TR_RUN_FILE)
        menuSyntax = menu.addMenu(translations.TR_CHANGE_SYNTAX)
        self._create_menu_syntax(menuSyntax)
        menu.addSeparator()
        actionClose = menu.addAction(translations.TR_CLOSE_FILE)
        actionCloseAll = menu.addAction(translations.TR_CLOSE_ALL_FILES)
        actionCloseAllNotThis = menu.addAction(
            translations.TR_CLOSE_OTHER_FILES)
        menu.addSeparator()
        actionSplitH = menu.addAction(translations.TR_SPLIT_VERTICALLY)
        actionSplitV = menu.addAction(translations.TR_SPLIT_HORIZONTALLY)
        menu.addSeparator()
        actionCopyPath = menu.addAction(
            translations.TR_COPY_FILE_PATH_TO_CLIPBOARD)
        actionShowFileInExplorer = menu.addAction(
            translations.TR_SHOW_FILE_IN_EXPLORER)
        actionReopen = menu.addAction(translations.TR_REOPEN_FILE)
        actionUndock = menu.addAction(translations.TR_UNDOCK_EDITOR)
        if len(settings.LAST_OPENED_FILES) == 0:
            actionReopen.setEnabled(False)
        #Connect actions
        actionSplitH.triggered['bool'].connect(lambda s: self._split(self.ORIENTATION.Horizontal))
        actionSplitV.triggered['bool'].connect(lambda s: self._split(self.ORIENTATION.Vertical))
        actionRun.triggered['bool'].connect(lambda s: self._run_this_file())
        actionAdd.triggered['bool'].connect(lambda s: self._add_to_project())
        actionClose.triggered['bool'].connect(lambda s: self.about_to_close_file())
        actionCloseAllNotThis.triggered['bool'].connect(lambda s: self._close_all_files_except_this())
        actionCloseAll.triggered['bool'].connect(lambda s: self._close_all_files())
        actionCopyPath.triggered['bool'].connect(lambda s: self._copy_file_location())
        actionShowFileInExplorer.triggered['bool'].connect(lambda s: self._show_file_in_explorer())
        actionReopen.triggered['bool'].connect(lambda s: self._reopen_last_tab())
        actionUndock.triggered['bool'].connect(lambda s: self._undock_editor())

        menu.exec_(QCursor.pos())

    def _create_menu_syntax(self, menuSyntax):
        """Create Menu with the list of syntax supported."""
        syntax = list(settings.SYNTAX.keys())
        syntax.sort()
        for syn in syntax:
            act = menuSyntax.addAction(syn)
            act.triggered['bool'].connect(lambda s: QMessageBox.critical(self, "Beta Info", "Can not construct this segment!"))#self._reapply_syntax

    def _reapply_syntax(self, syntaxAction):
        #TODO
        if [self.combo.currentIndex(), syntaxAction] != self._resyntax:
            self._resyntax = [self.combo.currentIndex(), syntaxAction]
            self.syntaxChangedemit(self.currentWidget(), syntaxAction.text())

    def set_current_file(self, neditable):
        index = self.combo.findData(neditable)
        self.combo.setCurrentIndex(index)

    def set_current_by_index(self, index):
        self.combo.setCurrentIndex(index)

    def about_to_close_file(self, index=None):
        """Close the NFile object."""
        if index is None:
            index = self.combo.currentIndex()
        neditable = self.combo.itemData(index)
        if neditable:
            print("\n\nabout_to_close_file:", self.combo.count(), index, self.combo.currentIndex())
            neditable.nfile.close()

    def close_split(self):
        self.closeFile.emit()

    def close_file(self, neditable):
        """Receive the confirmation to close the file."""
        index = self.combo.findData(neditable)
        self.combo.removeItem(index)
        return index

    def _run_this_file(self):
        """Execute the current file."""
        neditable = self.combo.itemData(self.combo.currentIndex())
        self.runFile.emit(neditable.file_path)

    def _add_to_project(self):
        """Emit a signal to let someone handle the inclusion of the file
        inside a project."""
        neditable = self.combo.itemData(self.combo.currentIndex())
        self.addToProject.emit(neditable.file_path)

    def _show_file_in_explorer(self):
        '''Triggered when the "Show File in Explorer" context
        menu action is selected. Emits the "showFileInExplorer(QString)"
        signal with the current file's full path as argument.'''
        neditable = self.combo.itemData(self.combo.currentIndex())
        self.showFileInExplorer.emit(neditable.file_path)

    def _reopen_last_tab(self):
        self.reopenTab.emit(settings.LAST_OPENED_FILES.pop())
        self.recentTabsModified.emit()

    def _undock_editor(self):
        self.undockEditor.emit()

    def _split(self, orientation):
        self.editorSplited.emit(orientation)

    def _copy_file_location(self):
        """Copy the path of the current opened file to the clipboard."""
        neditable = self.combo.itemData(self.combo.currentIndex())
        QApplication.clipboard().setText(neditable.file_path,
                                         QClipboard.Clipboard)

    def _close_all_files(self):
        """Close all the files opened."""
        for i in range(self.combo.count()):
            self.about_to_close_file(0)

    def _close_all_files_except_this(self):
        """Close all the files except the current one."""
        neditable = self.combo.itemData(self.combo.currentIndex())
        for i in reversed(list(range(self.combo.count()))):
            ne = self.combo.itemData(i)
            if ne is not neditable:
                self.about_to_close_file(i)
Beispiel #8
0
class SongsTableToolbar(QWidget):
    play_all_needed = pyqtSignal()
    filter_albums_needed = pyqtSignal([list])
    filter_text_changed = pyqtSignal([str])

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

        self.play_all_btn = QPushButton('Play All', self)
        self.play_all_btn.clicked.connect(self.play_all_needed.emit)

        # album filters
        self.filter_albums_combobox = QComboBox(self)
        self.filter_albums_combobox.addItems(['所有专辑', '标准', '单曲与EP', '现场', '合辑'])
        self.filter_albums_combobox.currentIndexChanged.connect(
            self.on_albums_filter_changed)
        # 8 works on macOS, don't know if it works on various Linux DEs
        self.filter_albums_combobox.setMinimumContentsLength(8)
        self.filter_albums_combobox.hide()
        self._setup_ui()

    def before_change_mode(self):
        """filter all filter buttons"""
        self.filter_albums_combobox.hide()
        self.play_all_btn.hide()

    def albums_mode(self):
        self.before_change_mode()
        self.filter_albums_combobox.show()

    def songs_mode(self):
        self.before_change_mode()
        self.play_all_btn.show()

    def enter_state_playall_start(self):
        self.play_all_btn.setEnabled(False)
        # currently, this is called only when feeluown is fetching songs,
        # so when we enter state_playall_start, we set play all btn text
        # to this.
        self.play_all_btn.setText('正在获取全部歌曲...')

    def enter_state_playall_end(self):
        self.play_all_btn.setText('正在获取全部歌曲...done')
        self.play_all_btn.setEnabled(True)
        self.play_all_btn.setText('播放全部')

    def _setup_ui(self):
        self._layout = QHBoxLayout(self)
        # left margin of meta widget is 30, we align with it
        # bottom margin of meta widget is 15, we should be larger than that
        self._layout.setContentsMargins(30, 0, 30, 20)
        self._layout.addWidget(self.play_all_btn)
        self._layout.addStretch(0)
        self._layout.addWidget(self.filter_albums_combobox)

    def on_albums_filter_changed(self, index):
        # ['所有', '专辑', '单曲与EP', '现场', '合辑']
        if index == 0:
            types = []
        elif index == 1:
            types = [AlbumType.standard]
        elif index == 2:
            types = [AlbumType.single, AlbumType.ep]
        elif index == 3:
            types = [AlbumType.live]
        else:
            types = [AlbumType.compilation, AlbumType.retrospective]
        self.filter_albums_needed.emit(types)
class SettingsPopUp(QDialog):
    def __init__(self,
                 sender,
                 pass1_needed=True,
                 pass2_needed=False,
                 add_list=None,
                 delete_list=None):
        super(SettingsPopUp, self).__init__()
        self.initUI(pass1_needed, pass2_needed, add_list, delete_list)

    def initUI(self, pass1_needed, pass2_needed, add_list, delete_list):
        self.ltTop = QGridLayout()
        self.ldt_pass1 = QLineEdit()
        self.ldt_pass2 = QLineEdit()
        self.lbl_pass1 = QLabel(self)
        self.lbl_pass2 = QLabel(self)
        self.cbx_keys_to_add = QComboBox()
        self.cbx_keys_to_delete = QComboBox()
        self.btn_OK = QPushButton('OK', self)
        self.btn_showhide1 = QPushButton('', self)
        self.btn_showhide2 = QPushButton('', self)
        self.lbl_pass1.setText("Enter any existing password:"******"Enter new password:")
        self.btn_showhide1.setIcon(QIcon('images/showhide.png'))
        self.btn_showhide2.setIcon(QIcon('images/showhide.png'))
        self.ldt_pass1.setEchoMode(QLineEdit.Password)
        self.ldt_pass2.setEchoMode(QLineEdit.Password)
        self.btn_OK.clicked.connect(self.close)
        self.btn_showhide1.clicked.connect(
            lambda: self.ldt_pass1.setEchoMode(QLineEdit.Normal)
            if self.ldt_pass1.echoMode() == QLineEdit.Password else self.
            ldt_pass1.setEchoMode(QLineEdit.Password))
        self.btn_showhide2.clicked.connect(
            lambda: self.ldt_pass2.setEchoMode(QLineEdit.Normal)
            if self.ldt_pass2.echoMode() == QLineEdit.Password else self.
            ldt_pass2.setEchoMode(QLineEdit.Password))
        self.ltTop.addWidget(self.lbl_pass1, 0, 0, 1, 4)
        self.ltTop.addWidget(self.lbl_pass2, 1, 0, 1, 4)
        self.ltTop.addWidget(self.ldt_pass1, 0, 4, 1, 3)
        self.ltTop.addWidget(self.ldt_pass2, 1, 4, 1, 3)
        self.ltTop.addWidget(self.btn_showhide1, 0, 7, 1, 1)
        self.ltTop.addWidget(self.btn_showhide2, 1, 7, 1, 1)
        self.ltTop.addWidget(self.cbx_keys_to_add, 2, 0, 1, 8)
        self.ltTop.addWidget(self.cbx_keys_to_delete, 3, 0, 1, 8)
        self.ltTop.addWidget(self.btn_OK, 4, 3, 1, 2)
        self.setLayout(self.ltTop)
        if pass1_needed == False:
            self.ldt_pass1.hide()
            self.btn_showhide1.hide()
            self.lbl_pass1.hide()
        else:
            self.ldt_pass1.show()
            self.btn_showhide1.show()
            self.lbl_pass1.show()
        if pass2_needed == False:
            self.ldt_pass2.hide()
            self.btn_showhide2.hide()
            self.lbl_pass2.hide()
        else:
            self.ldt_pass2.show()
            self.btn_showhide2.show()
            self.lbl_pass2.show()
        if add_list != None:
            self.cbx_keys_to_add.addItems(add_list)
            self.cbx_keys_to_add.show()
        else:
            self.cbx_keys_to_add.hide()
        if delete_list != None:
            self.cbx_keys_to_delete.addItems(delete_list)
            self.cbx_keys_to_delete.show()
        else:
            self.cbx_keys_to_delete.hide()
Beispiel #10
0
class Painter(QMainWindow):

    def __init__(self, width=640, height=480, color=QColor('white'), name='', objects=None):

        super().__init__()

        if objects is None:
            objects = []
        self.objects = objects

        self.file_name = name

        self.height = height
        self.width = width
        self.color = color

        self.temp = []
        self.history = [[]]
        self.history_flag = False
        self.state_number = 0

        self.click = False
        self.instrument = None
        self.cur_object = None

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

        self.edit_fl = False
        self.is_moving = False

        self.make_forms()

        self.gr_x1 = None
        self.gr_x2 = None
        self.gr_y1 = None
        self.gr_y2 = None

        self.line_color = QColor('blue')
        self.fill_color = None

    def make_forms(self):
        self.instruments = QComboBox(self)
        self.instruments.addItems(["Line", "Hand", "Rectangle", "Circle", "Select"])
        self.instruments.move(10, 50)
        self.instruments.resize(200, 70)
        self.instruments.currentIndexChanged.connect(self.instrumentChanged)

        self.color_button = QPushButton('COLOR', self)
        self.color_button.move(220, 50)
        self.color_button.resize(150, 70)
        self.color_button.clicked.connect(self.color_picker)

        self.thick_button = QSpinBox(self)
        self.thick_button.move(530, 50)
        self.thick_button.resize(100, 70)
        self.thick_button.setMinimum(2)
        self.thick_button.setMaximum(60)
        self.thick_button.valueChanged.connect(self.spinboxChanged)

        self.thick_lbl = QLabel('Thickness', self)
        self.thick_lbl.move(530, -10)
        self.thick_lbl.resize(120, 70)

        self.combine_button = QPushButton('COMBINE', self)
        self.combine_button.move(640, 50)
        self.combine_button.resize(150, 70)
        self.combine_button.clicked.connect(self.combine)
        self.combine_button.hide()

        self.delete_button = QPushButton('DELETE', self)
        self.delete_button.move(800, 50)
        self.delete_button.resize(100, 70)
        self.delete_button.clicked.connect(self.delete)
        self.delete_button.hide()

        self.change_color_button = QPushButton('COLOR', self)
        self.change_color_button.move(220, 50)
        self.change_color_button.resize(150, 70)
        self.change_color_button.clicked.connect(self.change_color)
        self.change_color_button.hide()

        self.background_button = QPushButton('BACKGROUND', self)
        self.background_button.move(2500, 50)
        self.background_button.resize(200, 70)
        self.background_button.clicked.connect(self.settings)

        self.fill_button = QPushButton('FILL', self)
        self.fill_button.move(910, 50)
        self.fill_button.resize(100, 70)
        self.fill_button.clicked.connect(self.fill)
        self.fill_button.hide()

        self.save_button = QPushButton('SAVE', self)
        self.save_button.move(1500, 50)
        self.save_button.resize(100, 70)
        self.save_button.clicked.connect(self.save)
        self.save_button.show()

        self.grad_instruments = QComboBox(self)
        self.grad_instruments.addItems(["Linear", "Radial"])
        self.grad_instruments.move(10, 50)
        self.grad_instruments.resize(1300, 70)
        self.grad_instruments.hide()

    def save(self):
        from SVGParser import SVGParser as svg

        s = svg(self.file_name).save2svg(self)

    def instrumentChanged(self):
        self.get_instrument()
        for o in self.objects:
            if o.selected:
                o.deselect()
        self.is_moving = False
        self.click = False
        self.cur_object = None
        self.update()

    def set_instrument(self, o):
        if isinstance(o, Circle):
            self.instrument = 'Circle'
        elif isinstance(o, Rectangle):
            self.instrument = 'Rectangle'
        elif isinstance(o, Line):
            self.instrument = 'Line'
        elif isinstance(o, Hand):
            self.instrument = 'Hand'
        elif isinstance(o, Object):
            self.instrument = 'Object'

    def edit(self):
        for i in self.objects:
            if i.selected:
                self.cur_object = i
                break
        if self.cur_object is not None:
            self.edit_fl = True
            self.click = True
            self.set_instrument(self.cur_object)

    def edit_ok(self):
        self.edit_fl = False
        self.cur_object.deselect()
        self.cur_object.stop_moving()
        self.instrument = 'Select'
        self.cur_object = None
        self.click = False
        self.is_moving = False

    def settings(self):
        form = Form(self)
        form.setFocus()

        vbox = QVBoxLayout()
        vbox.addWidget(form)
        self.setLayout(vbox)

        form.setGeometry(500, 500, 500, 800)
        form.show()

    def get_line_thick(self):
        th = int(self.thick_button.text())
        return th

    def color_picker(self):
        self.line_color = QColorDialog.getColor()

    def change_thick(self, th):

        for e in self.objects:
            if e.selected:
                e.set_thickness(th)
        self.history_flag = True
        self.update()

    def fill(self):

        form = FillForm(self)
        form.setFocus()

        vbox = QVBoxLayout()
        vbox.addWidget(form)
        self.setLayout(vbox)

        form.setGeometry(500, 500, 500, 800)
        form.show()
        form.exec()

        for e in self.objects:
            if e.selected:
                e.fill(self.fill_color)
        self.history_flag = True
        self.fill_color = None
        self.update()

    def spinboxChanged(self, value):
        self.change_thick(value)

    def change_color(self):
        self.color_picker()
        for e in self.objects:
            if e.selected:
                e.deselect()
                e.set_color(self.line_color)
        self.history_flag = True
        self.update()

    def get_instrument(self):
        self.instrument = self.instruments.currentText()
        if self.instrument == "Select":

            self.instruments.show()
            self.thick_button.show()
            self.change_color_button.show()
            self.combine_button.show()
            self.delete_button.show()
            self.fill_button.show()
            self.color_button.hide()

        elif self.instrument == 'Line' \
                or self.instrument == "Hand" \
                or self.instrument == "Rectangle" \
                or self.instrument == "Circle":
            self.combine_button.hide()

            self.change_color_button.hide()
            self.combine_button.hide()
            self.delete_button.hide()
            self.fill_button.hide()

            self.instruments.show()
            self.thick_button.show()
            self.color_button.show()
        self.update()

    def in_bounds(self, x, y):

        if self.is_moving and (
                self.cur_object is not None) and (
                not self.cur_object.in_bounds(self.width, self.height)):

            self.edit_ok()
            return False

        return 40 <= x + self.get_line_thick() / 2 <= self.width + 40 and (
                150 <= y + self.get_line_thick() / 2 <= 150 + self.height) and (
                40 <= x - self.get_line_thick() / 2 <= self.width + 40) and (
                150 <= y - self.get_line_thick() / 2 <= 150 + self.height)

    def mousePressEvent(self, event):

        x, y = event.pos().x(), event.pos().y()

        if not self.in_bounds(x, y):
            return

        if not self.edit_fl:
            self.get_instrument()
        self.get_line_thick()

        if self.instrument != "Select":

            if self.click and self.is_moving and self.cur_object is not None:
                self.edit_ok()
                self.click = False
                return

            self.history = self.history[:self.state_number + 1]
            self.history_flag = True

            if self.click:
                self.click = False

                if self.in_bounds(x, y):
                    if self.instrument == 'Circle' and self.cur_object is not None:
                        if self.circle_in_bounds(x, y):
                            if self.cur_object is not None:
                                if self.is_moving:
                                    self.cur_object.move(x, y)
                                else:
                                    self.cur_object.set_end_coord(x, y)
                    else:

                        if self.cur_object is not None:
                            if self.is_moving:

                                self.cur_object.move(x, y)
                            else:
                                self.cur_object.set_end_coord(x, y)

                    if not self.edit_fl:
                        self.objects.append(self.cur_object)
                    self.cur_object.set_color(self.line_color)
                    self.cur_object.set_thickness(self.get_line_thick())

                    if self.edit_fl:
                        self.edit_ok()
            else:
                if self.in_bounds(x, y):
                    self.click = True
                    if self.instrument == "Line":
                        self.cur_object = Line(x, y)
                    elif self.instrument == "Hand":
                        self.cur_object = Hand(x, y)
                    elif self.instrument == 'Rectangle':
                        self.cur_object = Rectangle(x, y)
                    elif self.instrument == 'Circle':
                        self.cur_object = Circle(x, y)

        else:

            self.history_flag = False
            for f in self.objects:
                if f.is_coord_on_figure(x, y):
                    if f.selected:
                        f.move_or_deselect(x, y)
                        if f.selected:
                            self.is_moving = True
                            self.edit()
                    else:
                        f.select()
                        self.is_moving = True
        self.update()

    def circle_in_bounds(self, x2, y2):

        if self.is_moving and not self.cur_object.in_bounds(self.width, self.height):
            return False
        xr = self.cur_object.x1
        yr = self.cur_object.y1
        x = x2 - xr
        y = y2 - yr
        rad = sqrt(x * x + y * y)
        return self.in_bounds(xr + rad, yr) and (
                self.in_bounds(xr - rad, yr)) and (
                self.in_bounds(xr, yr + rad)) and (
                self.in_bounds(xr, yr - rad))

    def mouseMoveEvent(self, e):
        y = e.pos().y()
        x = e.pos().x()

        if self.cur_object is not None and self.click:

            if self.in_bounds(x, y):
                if self.instrument == 'Circle' and self.cur_object is not None:
                    if self.circle_in_bounds(x, y):
                        if self.is_moving:
                            self.cur_object.move(x, y)
                        else:
                            self.cur_object.set_end_coord(x, y)
                else:
                    if self.is_moving:
                        self.cur_object.move(x, y)
                    else:
                        self.cur_object.set_end_coord(x, y)

            self.temp.append(self.cur_object)

        self.update()

    def get_max_x(self):
        return 40 + self.width

    def get_max_y(self):
        return 150 + self.height

    def draw_current_image(self):
        painter = QPainter(self)

        painter.fillRect(380, 50, 140, 70, self.line_color)
        painter.fillRect(40, 150, self.width, self.height, self.color)

        for e in self.objects:
            if e is not None:
                e.draw(painter, None, None, self.get_max_x(), self.get_max_y())
            else:
                self.objects.remove(e)
        for e in self.temp:
            if e is not None:
                e.draw(painter, self.line_color, self.get_line_thick(), None, None)
        self.temp = []

    def store_current_state(self):
        if self.history_flag and not self.click:
            self.history.append(deepcopy(self.objects))
            self.history_flag = False
            self.state_number += 1

    def paintEvent(self, e):

        self.draw_current_image()
        self.store_current_state()

    def keyPressEvent(self, event):

        key = event.key()
        if key == Qt.Key_Right:
            if self.state_number + 1 < len(self.history):
                self.state_number += 1
                self.objects = deepcopy(self.history[self.state_number])
                self.update()

        if key == Qt.Key_Left:
            if self.state_number - 1 >= 0:
                self.was_back = True
                self.state_number -= 1
                self.objects = deepcopy(self.history[self.state_number])
                self.update()

    def combine(self):
        li = []
        o = []
        obj = None
        for e in self.objects:
            if e.selected:
                e.deselect()
                if e is Object and obj is not None:
                    obj = e
                else:
                    li.append(e)
            else:
                o.append(e)
        self.history_flag = True
        o.append(Combiner.combine(li, obj))
        self.objects = o
        self.update()

    def delete(self):
        o = []
        for e in self.objects:
            if not e.selected:
                o.append(e)
        self.history_flag = True
        self.objects = o
        self.update()
Beispiel #11
0
class ActionBar(QFrame):
    """
    SIGNALS:
    @changeCurrent(PyQt_PyObject)
    @runFile(QString)
    @reopenTab(QString)
    @recentTabsModified()
    """
    change_current = pyqtSignal('PyQt_PyObject', int)
    splitEditor = pyqtSignal(bool)
    runFile = pyqtSignal('QString')
    closeSplit = pyqtSignal()
    addToProject = pyqtSignal('QString')
    showFileInExplorer = pyqtSignal('QString')
    goToSymbol = pyqtSignal(int)
    undockEditor = pyqtSignal()
    reopenTab = pyqtSignal('QString')
    closeImageViewer = pyqtSignal(int)
    needUpdateFocus = pyqtSignal()

    def __init__(self, main_combo=False):
        super(ActionBar, self).__init__()
        self.setAutoFillBackground(True)
        self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        self.setObjectName("actionbar")
        hbox = QHBoxLayout(self)
        hbox.setContentsMargins(1, 0, 0, 0)
        hbox.setSpacing(1)

        # self.lbl_checks = QLabel('')
        # self.lbl_checks.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        # self.lbl_checks.setFixedWidth(48)
        # self.lbl_checks.setVisible(False)
        # hbox.addWidget(self.lbl_checks)

        self.combo_files = ComboFiles(self)
        self.combo_files.setObjectName("combotab")
        # self.combo_files.setSizePolicy(
        #     QSizePolicy.Expanding, QSizePolicy.Fixed)
        self.combo_files.setSizeAdjustPolicy(
            QComboBox.AdjustToMinimumContentsLengthWithIcon)
        self.combo_files.setMaximumWidth(400)
        self.combo_files.currentIndexChanged[int].connect(self.current_changed)
        self.combo_files.setToolTip(translations.TR_COMBO_FILE_TOOLTIP)
        self.combo_files.setContextMenuPolicy(Qt.CustomContextMenu)
        self.combo_files.customContextMenuRequested.connect(
            self._context_menu_requested)
        hbox.addWidget(self.combo_files)
        self.symbols_combo = QComboBox()
        self.symbols_combo.setObjectName("combo_symbols")
        # For correctly style sheet
        self.symbols_combo.setItemDelegate(QStyledItemDelegate())
        self.symbols_combo.setModel(Model([]))
        self.symbols_combo.setSizeAdjustPolicy(
            QComboBox.AdjustToMinimumContentsLengthWithIcon)
        self.symbols_combo.activated[int].connect(self.current_symbol_changed)
        hbox.addWidget(self.symbols_combo)

        # Code Navigator actions
        self.code_navigator = CodeNavigator()
        hbox.addWidget(self.code_navigator)
        # Image Viewer actions
        self.image_viewer_controls = ImageViewerControls()
        self.image_viewer_controls.setSizePolicy(
            QSizePolicy.Expanding, QSizePolicy.Fixed)
        self.image_viewer_controls.setVisible(False)
        hbox.addWidget(self.image_viewer_controls)

        self._pos_text = "Line: %d, Col: %d"
        self.lbl_position = QLabel()
        self.lbl_position.setObjectName("position")
        self.lbl_position.setText(self._pos_text % (0, 0))
        margin = self.style().pixelMetric(
            QStyle.PM_LayoutHorizontalSpacing) / 2
        self.lbl_position.setContentsMargins(margin, 0, margin, 0)
        self.lbl_position.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        hbox.addWidget(self.lbl_position)
        self.btn_close = QPushButton()
        self.btn_close.setIcon(
            self.style().standardIcon(QStyle.SP_DialogCloseButton))

        if main_combo:
            self.btn_close.setObjectName('close_button_combo')
            self.btn_close.setToolTip(translations.TR_CLOSE_FILE)
            self.btn_close.clicked.connect(self.about_to_close_file)
        else:
            self.btn_close.setObjectName('close_split')
            self.btn_close.setToolTip(translations.TR_CLOSE_SPLIT)
            self.btn_close.clicked.connect(lambda: self.closeSplit.emit())
        self.btn_close.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Minimum)
        hbox.addWidget(self.btn_close)

        # Added for set language
        # self._setter_language = set_language.SetLanguageFile()

    # def _on_lbl_position_clicked(self):
    #    main_container = IDE.get_service("main_container")
    #    editor_widget = main_container.get_current_editor()
        # self._go_to_line_widget.set_line_count(editor_widget.line_count())
        # self._go_to_line_widget.show()

    def resizeEvent(self, event):
        super(ActionBar, self).resizeEvent(event)
        if event.size().width() < 400:
            self.symbols_combo.hide()
            self.code_navigator.hide()
            self.lbl_position.hide()
        elif not self.image_viewer_controls.isVisible():
            self.symbols_combo.show()
            self.code_navigator.show()
            self.lbl_position.show()

    def add_item(self, text, neditable):
        """Add a new item to the combo and add the neditable data."""

        self.combo_files.addItem(text, neditable)
        self.combo_files.setCurrentIndex(self.combo_files.count() - 1)

    def get_editables(self):
        editables = []
        for index in range(self.combo_files.count()):
            neditable = self.combo_files.itemData(index)
            editables.append(neditable)
        return editables

    def add_symbols(self, symbols):
        """Add the symbols to thcurrente symbols's combo."""

        mo = Model(symbols)
        self.symbols_combo.setModel(mo)
        # self.symbols_combo.clear()
        # for symbol in symbols:
        #    data = symbol[1]
        #    if data[1] == 'f':
        #        icon = QIcon(":img/function")
        #    else:
        #        icon = QIcon(":img/class")
        #    self.symbols_combo.addItem(icon, data[0])

    def set_current_symbol(self, index):
        self.symbols_combo.setCurrentIndex(index + 1)

    def update_item_icon(self, neditable, icon):
        index = self.combo_files.findData(neditable)
        self.combo_files.setItemIcon(index, icon)

    def update_item_text(self, neditable, text):
        index = self.combo_files.findData(neditable)
        self.combo_files.setItemText(index, text)

    def current_changed(self, index):
        """Change the current item in the combo."""
        if index != -1:
            neditable = self.combo_files.itemData(index)
            self.change_current.emit(neditable, index)

    def current_symbol_changed(self, index):
        """Change the current symbol in the combo."""
        if index == 0:
            return
        self.goToSymbol.emit(index - 1)

    def set_language_combo_changed(self, index):
        """Change the current language of editor."""
        self._setter_language.set_language_to_editor(index)

    def update_line_col(self, line, col):
        """Update the line and column position."""
        self.lbl_position.setText(self._pos_text % (line, col))

    def _context_menu_requested(self, point):
        """Display context menu for the combo file."""
        if self.combo_files.count() == 0:
            # If there is not an Editor opened, don't show the menu
            return
        menu = QMenu()
        action_add = menu.addAction(translations.TR_ADD_TO_PROJECT)
        action_run = menu.addAction(translations.TR_RUN_FILE)
        # menuSyntax = menu.addMenu(translations.TR_CHANGE_SYNTAX)
        action_show_folder = menu.addAction(
            translations.TR_SHOW_CONTAINING_FOLDER)
        # self._create_menu_syntax(menuSyntax)
        menu.addSeparator()
        action_close = menu.addAction(translations.TR_CLOSE_FILE)
        action_close_all = menu.addAction(translations.TR_CLOSE_ALL_FILES)
        action_close_all_not_this = menu.addAction(
           translations.TR_CLOSE_OTHER_FILES)
        menu.addSeparator()
        # actionSplitH = menu.addAction(translations.TR_SPLIT_VERTICALLY)
        # actionSplitV = menu.addAction(translations.TR_SPLIT_HORIZONTALLY)
        # menu.addSeparator()
        action_copy_path = menu.addAction(
           translations.TR_COPY_FILE_PATH_TO_CLIPBOARD)
        action_show_file_in_explorer = menu.addAction(
           translations.TR_SHOW_FILE_IN_EXPLORER)
        action_reopen = menu.addAction(translations.TR_REOPEN_FILE)
        action_undock = menu.addAction(translations.TR_UNDOCK_EDITOR)

        main_container = IDE.get_service("main_container")
        if not main_container.last_opened_files:
            action_reopen.setEnabled(False)

        # set language action
        # menu_set_language = menu.addMenu(translations.TR_SET_LANGUAGE)
        # self._set_list_languages(menu_set_language)

        # Connect actions
        action_close.triggered.connect(self.about_to_close_file)
        action_close_all.triggered.connect(self._close_all_files)
        action_close_all_not_this.triggered.connect(
            self._close_all_files_except_this)
        action_run.triggered.connect(self._run_this_file)
        action_undock.triggered.connect(self._undock_editor)
        action_show_folder.triggered.connect(self._show_containing_folder)
        action_copy_path.triggered.connect(self._copy_file_location)
        action_show_file_in_explorer.triggered.connect(
            self._show_file_in_explorer)
        action_add.triggered.connect(self._add_to_project)
        action_reopen.triggered.connect(self._reopen_last_tab)
        # self.connect(actionSplitH, SIGNAL("triggered()"),
        #             lambda: self._split(False))
        # self.connect(actionSplitV, SIGNAL("triggered()"),
        #             lambda: self._split(True))

        menu.exec_(QCursor.pos())

    def _set_list_languages(self, menu_set_language):
        for l in self._setter_language.get_list_of_language():
            if l is None:
                continue
            action = menu_set_language.addAction(l)
            action.triggered.connect(lambda checked, language=l:
                                     self._set_language_action(language))

    def _set_language_action(self, language):
        self._setter_language.set_language_to_editor(language)

    def _show_containing_folder(self):
        main_container = IDE.get_service("main_container")
        editor_widget = main_container.get_current_editor()
        filename = editor_widget.file_path
        file_manager.show_containing_folder(filename)

    def _create_menu_syntax(self, menuSyntax):
        """Create Menu with the list of syntax supported."""
        syntax = list(settings.SYNTAX.keys())
        syntax.sort()
        for syn in syntax:
            menuSyntax.addAction(syn)
            # self.connect(menuSyntax, SIGNAL("triggered(QAction*)"),
            #             self._reapply_syntax)

    def _reapply_syntax(self, syntaxAction):
        # TODO
        if [self.currentIndex(), syntaxAction] != self._resyntax:
            self._resyntax = [self.currentIndex(), syntaxAction]
            # self.emit(SIGNAL("syntaxChanged(QWidget, QString)"),
            #          self.currentWidget(), syntaxAction.text())

    def set_current_file(self, neditable):
        index = self.combo_files.findData(neditable)
        self.combo_files.setCurrentIndex(index)

    def set_current_by_index(self, index):
        self.combo_files.setCurrentIndex(index)

    @pyqtSlot()
    def about_to_close_file(self, index=None):
        """Close the NFile or ImageViewer object."""

        parent = self.parent().parentWidget()  # Splitter
        if parent.count() > 1:
            return
        if index is None:
            index = self.combo_files.currentIndex()
            if index == -1:
                return
        neditable = self.combo_files.itemData(index)
        if neditable:
            neditable.nfile.close()
        else:
            # Image viewer
            self.combo_files.removeItem(index)
            self.closeImageViewer.emit(index)

    def close_split(self):
        self.closeSplit.emit()

    def close_file(self, neditable):
        """Receive the confirmation to close the file."""
        index = self.combo_files.findData(neditable)
        self.combo_files.removeItem(index)
        return index

    def _run_this_file(self):
        """Execute the current file"""
        neditable = self.combo_files.itemData(self.combo_files.currentIndex())
        self.runFile.emit(neditable.file_path)

    def _add_to_project(self):
        """Emit a signal to let someone handle the inclusion of the file
        inside a project."""
        neditable = self.combo_files.itemData(self.combo_files.currentIndex())
        self.addToProject.emit(neditable.file_path)

    def _show_file_in_explorer(self):
        """Triggered when the "Show File in Explorer" context
        menu action is selected. Emits the "showFileInExplorer(QString)"
        signal with the current file's full path as argument."""
        neditable = self.combo_files.itemData(self.combo_files.currentIndex())
        self.showFileInExplorer.emit(neditable.file_path)

    def _reopen_last_tab(self):
        main_container = IDE.get_service("main_container")
        last_closed = main_container.last_opened_files[0]
        self.reopenTab.emit(last_closed)

    def _undock_editor(self):
        self.undockEditor.emit()

    def _split(self, orientation):
        print("emitir splitEditor")
        # self.emit(SIGNAL("splitEditor(bool)"), orientation)

    def _copy_file_location(self):
        """Copy the path of the current opened file to the clipboard."""

        neditable = self.combo_files.itemData(self.combo_files.currentIndex())
        QApplication.clipboard().setText(neditable.file_path,
                                         QClipboard.Clipboard)

    def _close_all_files(self):
        """Close all the files opened."""
        for i in range(self.combo_files.count()):
            self.about_to_close_file(0)

    def _close_all_files_except_this(self):
        """Close all the files except the current one."""
        neditable = self.combo_files.itemData(self.combo_files.currentIndex())
        for i in reversed(list(range(self.combo_files.count()))):
            ne = self.combo_files.itemData(i)
            if ne is not neditable:
                self.about_to_close_file(i)
class ReceiveView(QWidget):
    _qr_window: Optional[QR_Window] = None

    def __init__(self, main_window: 'ElectrumWindow', account_id: int) -> None:
        super().__init__(main_window)

        self._main_window = weakref.proxy(main_window)
        self._account_id = account_id
        self._account = main_window._wallet.get_account(account_id)
        self._logger = logs.get_logger(f"receive-view[{self._account_id}]")

        self._receive_key_id: Optional[int] = None

        self._request_list_toolbar_layout = TableTopButtonLayout()
        self._request_list_toolbar_layout.refresh_signal.connect(
            self._main_window.refresh_wallet_display)
        self._request_list_toolbar_layout.filter_signal.connect(
            self._filter_request_list)

        form_layout = self.create_form_layout()
        self._request_list = RequestList(self, main_window)
        request_container = self.create_request_list_container()

        vbox = QVBoxLayout(self)
        vbox.addLayout(form_layout)
        vbox.addSpacing(20)
        vbox.addWidget(request_container, 1)
        self.setLayout(vbox)

    def clean_up(self) -> None:
        # If there are no accounts there won't be a receive QR code object created yet.
        if self._receive_qr is not None:
            self._receive_qr.clean_up()
        if self._qr_window is not None:
            self._qr_window.close()

    def create_form_layout(self) -> QHBoxLayout:
        # A 4-column grid layout.  All the stretch is in the last column.
        # The exchange rate plugin adds a fiat widget in column 2
        grid = QGridLayout()
        grid.setSpacing(8)
        grid.setColumnStretch(3, 1)

        self._receive_destination_e = ButtonsLineEdit()
        self._receive_destination_e.addCopyButton(app_state.app)
        self._receive_destination_e.setReadOnly(True)
        msg = _(
            'Bitcoin SV payment destination where the payment should be received. '
            'Note that each payment request uses a different Bitcoin SV payment destination.'
        )
        receive_address_label = HelpLabel(_('Receiving destination'), msg)
        self._receive_destination_e.textChanged.connect(
            self._update_receive_qr)
        self._receive_destination_e.setFocusPolicy(Qt.NoFocus)
        grid.addWidget(receive_address_label, 0, 0)
        grid.addWidget(self._receive_destination_e, 0, 1, 1, -1)

        self._receive_message_e = QLineEdit()
        grid.addWidget(QLabel(_('Description')), 1, 0)
        grid.addWidget(self._receive_message_e, 1, 1, 1, -1)
        self._receive_message_e.textChanged.connect(self._update_receive_qr)

        self._receive_amount_e = BTCAmountEdit()
        grid.addWidget(QLabel(_('Requested amount')), 2, 0)
        grid.addWidget(self._receive_amount_e, 2, 1)
        self._receive_amount_e.textChanged.connect(self._update_receive_qr)

        self._fiat_receive_e = AmountEdit(
            app_state.fx.get_currency if app_state.fx else '')
        if not app_state.fx or not app_state.fx.is_enabled():
            self._fiat_receive_e.setVisible(False)
        grid.addWidget(self._fiat_receive_e, 2, 2, Qt.AlignLeft)
        self._main_window.connect_fields(self._receive_amount_e,
                                         self._fiat_receive_e)

        self._expires_combo = QComboBox()
        self._expires_combo.addItems([i[0] for i in expiration_values])
        self._expires_combo.setCurrentIndex(3)
        self._expires_combo.setFixedWidth(self._receive_amount_e.width())
        msg = ' '.join([
            _('Expiration date of your request.'),
            _('This information is seen by the recipient if you send them '
              'a signed payment request.'),
            _('Expired requests have to be deleted manually from your list, '
              'in order to free the corresponding Bitcoin SV addresses.'),
            _('The Bitcoin SV address never expires and will always be part '
              'of this ElectrumSV wallet.'),
        ])
        grid.addWidget(HelpLabel(_('Request expires'), msg), 3, 0)
        grid.addWidget(self._expires_combo, 3, 1)
        self._expires_label = QLineEdit('')
        self._expires_label.setReadOnly(1)
        self._expires_label.setFocusPolicy(Qt.NoFocus)
        self._expires_label.hide()
        grid.addWidget(self._expires_label, 3, 1)

        self._save_request_button = EnterButton(_('Save request'),
                                                self._save_form_as_request)
        self._new_request_button = EnterButton(_('New'),
                                               self._new_payment_request)

        self._receive_qr = QRCodeWidget(fixedSize=200)
        self._receive_qr.link_to_window(self._toggle_qr_window)

        buttons = QHBoxLayout()
        buttons.addStretch(1)
        buttons.addWidget(self._save_request_button)
        buttons.addWidget(self._new_request_button)
        grid.addLayout(buttons, 4, 1, 1, 2)

        vbox_g = QVBoxLayout()
        vbox_g.addLayout(grid)
        vbox_g.addStretch()

        hbox = QHBoxLayout()
        hbox.addLayout(vbox_g)
        hbox.addWidget(self._receive_qr)

        return hbox

    def create_request_list_container(self) -> QGroupBox:
        layout = QVBoxLayout()
        layout.setSpacing(0)
        layout.setContentsMargins(6, 0, 6, 6)
        layout.addLayout(self._request_list_toolbar_layout)
        layout.addWidget(self._request_list)

        request_box = QGroupBox()
        request_box.setTitle(_('Requests'))
        request_box.setAlignment(Qt.AlignCenter)
        request_box.setContentsMargins(0, 0, 0, 0)
        request_box.setLayout(layout)
        return request_box

    def update_widgets(self) -> None:
        self._request_list.update()

    def update_destination(self) -> None:
        text = ""
        if self._receive_key_id is not None:
            script_template = self._account.get_script_template_for_id(
                self._receive_key_id)
            if script_template is not None:
                text = script_template_to_string(script_template)
        self._receive_destination_e.setText(text)

    def update_contents(self) -> None:
        self._expires_label.hide()
        self._expires_combo.show()
        if self._account.is_deterministic():
            fresh_key = self._account.get_fresh_keys(RECEIVING_SUBPATH, 1)[0]
            self.set_receive_key(fresh_key)

    def update_for_fx_quotes(self) -> None:
        if self._account_id is not None:
            edit = (self._fiat_receive_e if self._fiat_receive_e.is_last_edited
                    else self._receive_amount_e)
            edit.textEdited.emit(edit.text())

    # Bound to text fields in `_create_receive_form_layout`.
    def _update_receive_qr(self) -> None:
        if self._receive_key_id is None:
            return

        amount = self._receive_amount_e.get_amount()
        message = self._receive_message_e.text()
        self._save_request_button.setEnabled((amount is not None)
                                             or (message != ""))

        script_template = self._account.get_script_template_for_id(
            self._receive_key_id)
        address_text = script_template_to_string(script_template)

        uri = web.create_URI(address_text, amount, message)
        self._receive_qr.setData(uri)
        if self._qr_window and self._qr_window.isVisible():
            self._qr_window.set_content(self._receive_destination_e.text(),
                                        amount, message, uri)

    def _toggle_qr_window(self, event: QEvent) -> None:
        if self._receive_key_id is None:
            self.show_message(_("No available receiving destination."))
            return

        if not self._qr_window:
            self._qr_window = QR_Window(self)
            self._qr_window.setVisible(True)
            self._qr_window_geometry = self._qr_window.geometry()
        else:
            if not self._qr_window.isVisible():
                self._qr_window.setVisible(True)
                self._qr_window.setGeometry(self._qr_window_geometry)
            else:
                self._qr_window_geometry = self._qr_window.geometry()
                self._qr_window.setVisible(False)

        self._update_receive_qr()

    def set_fiat_ccy_enabled(self, flag: bool) -> None:
        self._fiat_receive_e.setVisible(flag)

    def get_bsv_edits(self) -> List[BTCAmountEdit]:
        return [self._receive_amount_e]

    def _save_form_as_request(self) -> None:
        if not self._receive_key_id:
            self._main_window.show_error(_('No receiving payment destination'))
            return

        amount = self._receive_amount_e.get_amount()
        message = self._receive_message_e.text()
        if not message and not amount:
            self._main_window.show_error(_('No message or amount'))
            return

        def callback(exc_value: Optional[Exception] = None) -> None:
            if exc_value is not None:
                raise exc_value  # pylint: disable=raising-bad-type
            self._request_list.update_signal.emit()

        i = self._expires_combo.currentIndex()
        expiration = [x[1] for x in expiration_values][i]
        row = self._account.requests.get_request_for_key_id(
            self._receive_key_id)
        if row is None:
            row = self._account.requests.create_request(
                self._receive_key_id, PaymentFlag.UNPAID, amount, expiration,
                message, callback)
        else:
            # Expiration is just a label, so we don't use the value.
            self._account.requests.update_request(row.paymentrequest_id,
                                                  row.state, amount,
                                                  row.expiration, message,
                                                  callback)
        self._save_request_button.setEnabled(False)

    def _new_payment_request(self) -> None:
        keyinstances: List[KeyInstanceRow] = []
        if self._account.is_deterministic():
            keyinstances = self._account.get_fresh_keys(RECEIVING_SUBPATH, 1)
        if not len(keyinstances):
            if not self._account.is_deterministic():
                msg = [
                    _('No more payment destinations in your wallet.'),
                    _('You are using a non-deterministic account, which '
                      'cannot create new payment destinations.'),
                    _('If you want to create new payment destinations, '
                      'use a deterministic account instead.')
                ]
                self._main_window.show_message(' '.join(msg))
                return
            self._main_window.show_message(
                _('Your wallet is broken and could not allocate a new payment destination.'
                  ))

        self.update_contents()

        self._new_request_button.setEnabled(False)
        self._receive_message_e.setFocus(1)

    def get_receive_key_id(self) -> Optional[int]:
        return self._receive_key_id

    # Only called from key list menu.
    def receive_at_id(self, key_id: int) -> None:
        self._receive_key_id = key_id
        self._new_request_button.setEnabled(True)
        self.update_destination()

        self._main_window.show_receive_tab()

    def set_receive_key_id(self, key_id: int) -> None:
        self._receive_key_id = key_id

    def set_receive_key(self, keyinstance: KeyInstanceRow) -> None:
        self._receive_key_id = keyinstance.keyinstance_id
        self._receive_message_e.setText("")
        self._receive_amount_e.setAmount(None)
        self.update_destination()

    def set_form_contents(self,
                          address_text: str,
                          value: int,
                          description: Optional[str] = None,
                          expires_description: str = "") -> None:
        self._receive_destination_e.setText(address_text)
        self._receive_message_e.setText(description or "")
        self._receive_amount_e.setAmount(value)
        self._expires_combo.hide()
        self._expires_label.show()
        self._expires_label.setText(expires_description)
        self._new_request_button.setEnabled(True)

    def set_new_button_enabled(self, flag: bool) -> None:
        self._new_request_button.setEnabled(flag)

    def _filter_request_list(self, text: str) -> None:
        self._request_list.filter(text)
Beispiel #13
0
class Menu(QWidget):
    def __init__(self, option=None):
        super().__init__()

        self.setBackground(QImage("Images/menu/biohazard.jpg"), self.width(),
                           self.height())

        self.combo = QComboBox(self)
        self.combo.addItem("SIR")
        self.combo.addItem("SEIHFR")
        self.combo.addItem("SEIHFBR")
        self.combo.addItem("SEIRS")
        self.combo.addItem("Dispersion spatiale")
        self.combo.addItem("Effet du vaccin")
        self.combo.addItem("Map")

        self.comboMap = QComboBox(self)
        self.comboMap.addItem("PlateCarree")
        self.comboMap.addItem("Miller")
        self.comboMap.addItem("Mollweide")
        self.comboMap.addItem("EckertIII")
        self.comboMap.addItem("EuroPP")
        self.comboMap.hide()

        self.combo.currentIndexChanged.connect(
            lambda: self.showNewCombo() if self.combo.currentIndex() == 6 else
            self.comboMap.hide() if not self.comboMap.isHidden() else None)

        self.button = QPushButton("GO", self)
        self.button.clicked.connect(self.choose_model)
        self.button.keyPressEvent = self.keyPressEvent

        self.hbox = QHBoxLayout()
        self.hbox.addWidget(self.button)
        self.hbox.addWidget(self.combo)
        self.hbox.setAlignment(Qt.AlignCenter)

        #  vbox = QVBoxLayout(self)
        #  vbox.addStretch(1)
        #  vbox.addWidget(self.button2)
        #  vbox.addLayout(hbox)
        self.setLayout(self.hbox)

        if option is not None:
            if option == "SIR":
                self.choose_model(model_name="SIR")
            elif option == "SEIRS":
                self.choose_model(model_name="SEIRS")
            elif option == "SEIHFR":
                self.choose_model(model_name="SEIHFR")
            elif option == "SEIHFBR":
                self.choose_model(model_name="SEIHFBR")
            elif option == "spa":
                self.choose_model(model_name="Dispersion spatiale")
            elif option == "vac":
                self.choose_model(model_name="Effet du vaccin")
            elif option == "map":
                self.choose_model(model_name="Map")
            else:
                self.showMaximized()
        else:
            self.showMaximized()

    def setBackground(self, aimage, width=None, height=None):
        image = aimage.scaled(width, height, Qt.IgnoreAspectRatio,
                              Qt.SmoothTransformation)
        sImage = image.scaled(QSize(width, height))
        palette = QPalette()
        palette.setBrush(QPalette.Window, QBrush(sImage))
        self.setPalette(palette)

    def keyPressEvent(self, e):
        if e.key() == 16777220:
            self.choose_model()

    def choose_model(self, notUsed=None, model_name=None):
        from GUI_pyqt import App

        if model_name is None:
            model_name = self.combo.currentText()

        self.close()
        if model_name == "SIR":
            from GUI_pyqt import SIR
            self.app2 = App(SIR())
        elif model_name == "SEIRS":
            from GUI_pyqt import SEIRS
            self.app2 = App(SEIRS())
        elif model_name == "SEIHFR":
            from GUI_pyqt import SEIHFR
            self.app2 = App(SEIHFR())
        elif model_name == "SEIHFBR":
            from GUI_pyqt import SEIHFBR
            self.app2 = App(SEIHFBR())
        elif model_name == "Dispersion spatiale":
            from PixelGrid import PixelGridWindow
            self.app2 = PixelGridWindow()
        elif model_name == "Effet du vaccin":
            from VaccineGrid import PixelGridWindowVaccined
            self.app2 = PixelGridWindowVaccined()
        elif model_name == "Map":
            from map import MapWindow

            self.app2 = MapWindow("ccrs." + self.comboMap.currentText() + "()")

    def showNewCombo(self):
        self.hbox.addWidget(self.comboMap)
        self.comboMap.show()
Beispiel #14
0
class SongsTableToolbar(QWidget):
    _desc_btn_checked_text = '折叠'
    _desc_btn_unchecked_text = '展开描述'

    play_all_needed = pyqtSignal()
    show_songs_needed = pyqtSignal()
    show_albums_needed = pyqtSignal()
    show_contributed_albums_needed = pyqtSignal()
    # show_videos_needed = pyqtSignal()

    filter_albums_needed = pyqtSignal([list])

    toggle_desc_needed = pyqtSignal()

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

        self.play_all_btn = QPushButton('播放全部', self)
        self.show_songs_btn = QPushButton('歌曲', parent=self)
        self.show_albums_btn = QPushButton('专辑', parent=self)
        self.show_contributed_albums_btn = QPushButton('参与作品', parent=self)
        # self.show_videos_btn = QPushButton(parent=self)
        self.desc_btn = QPushButton(self._desc_btn_unchecked_text, self)
        self.play_all_btn.clicked.connect(self.play_all_needed.emit)
        self.show_songs_btn.clicked.connect(self.show_songs_needed.emit)
        self.show_albums_btn.clicked.connect(self.show_albums_needed.emit)
        self.show_contributed_albums_btn.clicked.connect(
            self.show_contributed_albums_needed.emit)
        # self.show_videos_btn.clicked.connect(self.show_videos_needed.emit)
        self.desc_btn.clicked.connect(self.on_desc_btn_toggled)

        # album filters
        self.filter_albums_combobox = QComboBox(self)
        self.filter_albums_combobox.addItems(
            ['所有专辑', '标准', '单曲与EP', '现场', '合辑'])
        self.filter_albums_combobox.currentIndexChanged.connect(
            self.on_albums_filter_changed)
        # 8 works on macOS, don't know if it works on various Linux DEs
        self.filter_albums_combobox.setMinimumContentsLength(8)
        self.show_songs_btn.hide()
        self.show_albums_btn.hide()
        self.show_contributed_albums_btn.hide()
        self.desc_btn.hide()
        self.filter_albums_combobox.hide()
        self._setup_ui()

    def before_change_mode(self):
        """filter all filter buttons"""
        self.filter_albums_combobox.hide()

    def artist_mode(self):
        self.before_change_mode()
        self.play_all_btn.show()
        self.show_songs_btn.show()
        self.show_albums_btn.show()
        self.show_contributed_albums_btn.show()

    def albums_mode(self):
        self.before_change_mode()
        self.play_all_btn.hide()
        # self.show_albums_btn.show()
        self.filter_albums_combobox.show()

    def songs_mode(self):
        self.before_change_mode()
        self.play_all_btn.show()

    def pure_songs_mode(self):
        """playlist/collections mode"""
        self.before_change_mode()
        self.show_contributed_albums_btn.hide()
        self.show_albums_btn.hide()
        self.show_songs_btn.hide()
        self.play_all_btn.show()

    def enter_state_playall_start(self):
        self.play_all_btn.setEnabled(False)
        # currently, this is called only when feeluown is fetching songs,
        # so when we enter state_playall_start, we set play all btn text
        # to this.
        self.play_all_btn.setText('正在获取全部歌曲...')

    def enter_state_playall_end(self):
        self.play_all_btn.setText('正在获取全部歌曲...done')
        self.play_all_btn.setEnabled(True)
        self.play_all_btn.setText('播放全部')

    def _setup_ui(self):
        self._layout = QHBoxLayout(self)
        self._layout.setContentsMargins(0, 0, 0, 0)
        self._layout.setSpacing(0)

        self._layout.addWidget(self.play_all_btn)
        self._layout.addSpacing(5)
        self._layout.addWidget(self.show_songs_btn)
        self._layout.addSpacing(5)
        self._layout.addWidget(self.show_albums_btn)
        self._layout.addSpacing(5)
        self._layout.addWidget(self.show_contributed_albums_btn)

        self._layout.addStretch(1)

        self._layout.addWidget(self.filter_albums_combobox)

        self._layout.addStretch(1)

        self._layout.addWidget(self.desc_btn)
        self._layout.addStretch(1)

    def on_desc_btn_toggled(self, checked):
        if checked:
            self.play_all_btn.hide()
            self.desc_btn.setText(self._desc_btn_checked_text)
        else:
            self.play_all_btn.show()
            self.desc_btn.setText(self._desc_btn_unchecked_text)
        self.toggle_desc_needed.emit()

    def on_albums_filter_changed(self, index):
        # ['所有', '专辑', '单曲与EP', '现场', '合辑']
        if index == 0:
            types = []
        elif index == 1:
            types = [AlbumType.standard]
        elif index == 2:
            types = [AlbumType.single, AlbumType.ep]
        elif index == 3:
            types = [AlbumType.live]
        else:
            types = [AlbumType.compilation, AlbumType.retrospective]
        self.filter_albums_needed.emit(types)
Beispiel #15
0
class VideoFinderAddLink(AddLinkWindow):
    running_thread = None
    threadPool = {}

    def __init__(self, parent, receiver_slot, settings, video_dict={}):
        super().__init__(parent, receiver_slot, settings, video_dict)
        self.setWindowTitle(
            QCoreApplication.translate("ytaddlink_src_ui_tr", 'Video Finder'))
        self.size_label.hide()

        # empty lists for no_audio and no_video and video_audio files
        self.no_audio_list = []
        self.no_video_list = []
        self.video_audio_list = []

        self.media_title = ''

        # add support for other languages
        locale = str(self.persepolis_setting.value('settings/locale'))
        QLocale.setDefault(QLocale(locale))
        self.translator = QTranslator()
        if self.translator.load(':/translations/locales/ui_' + locale, 'ts'):
            QCoreApplication.installTranslator(self.translator)

        # extension_label
        self.extension_label = QLabel(self.link_frame)
        self.change_name_horizontalLayout.addWidget(self.extension_label)

        # Fetch Button
        self.url_submit_pushButtontton = QPushButton(self.link_frame)
        self.link_horizontalLayout.addWidget(self.url_submit_pushButtontton)

        # Status Box
        self.status_box_textEdit = QTextEdit(self.link_frame)
        self.status_box_textEdit.setMaximumHeight(150)
        self.link_verticalLayout.addWidget(self.status_box_textEdit)

        # Select format horizontal layout
        select_format_horizontalLayout = QHBoxLayout()

        # Selection Label
        self.select_format_label = QLabel(self.link_frame)
        select_format_horizontalLayout.addWidget(self.select_format_label)

        # Selection combobox
        self.media_comboBox = QComboBox(self.link_frame)
        self.media_comboBox.setMinimumWidth(200)
        select_format_horizontalLayout.addWidget(self.media_comboBox)

        # Duration label
        self.duration_label = QLabel(self.link_frame)
        select_format_horizontalLayout.addWidget(self.duration_label)

        self.format_selection_frame = QFrame(self)
        self.format_selection_frame.setLayout(select_format_horizontalLayout)
        self.link_verticalLayout.addWidget(self.format_selection_frame)

        # advanced_format_selection_checkBox
        self.advanced_format_selection_checkBox = QCheckBox(self)
        self.link_verticalLayout.addWidget(
            self.advanced_format_selection_checkBox)

        # advanced_format_selection_frame
        self.advanced_format_selection_frame = QFrame(self)
        self.link_verticalLayout.addWidget(
            self.advanced_format_selection_frame)

        advanced_format_selection_horizontalLayout = QHBoxLayout(
            self.advanced_format_selection_frame)

        # video_format_selection
        self.video_format_selection_label = QLabel(
            self.advanced_format_selection_frame)
        self.video_format_selection_comboBox = QComboBox(
            self.advanced_format_selection_frame)

        # audio_format_selection
        self.audio_format_selection_label = QLabel(
            self.advanced_format_selection_frame)
        self.audio_format_selection_comboBox = QComboBox(
            self.advanced_format_selection_frame)

        for widget in [
                self.video_format_selection_label,
                self.video_format_selection_comboBox,
                self.audio_format_selection_label,
                self.audio_format_selection_comboBox
        ]:
            advanced_format_selection_horizontalLayout.addWidget(widget)

        # Set Texts
        self.url_submit_pushButtontton.setText(
            QCoreApplication.translate("ytaddlink_src_ui_tr",
                                       'Fetch Media List'))
        self.select_format_label.setText(
            QCoreApplication.translate("ytaddlink_src_ui_tr",
                                       'Select a format'))

        self.video_format_selection_label.setText(
            QCoreApplication.translate("ytaddlink_src_ui_tr", 'Video format:'))
        self.audio_format_selection_label.setText(
            QCoreApplication.translate("ytaddlink_src_ui_tr", 'Audio format:'))

        self.advanced_format_selection_checkBox.setText(
            QCoreApplication.translate("ytaddlink_src_ui_tr",
                                       'Advanced options'))

        # Add Slot Connections
        self.url_submit_pushButtontton.setEnabled(False)
        self.change_name_lineEdit.setEnabled(False)
        self.ok_pushButton.setEnabled(False)
        self.download_later_pushButton.setEnabled(False)

        self.format_selection_frame.setEnabled(True)
        self.advanced_format_selection_frame.setEnabled(False)
        self.advanced_format_selection_checkBox.toggled.connect(
            self.advancedFormatFrame)

        self.url_submit_pushButtontton.clicked.connect(self.submitClicked)

        self.media_comboBox.activated.connect(
            partial(self.mediaSelectionChanged, 'video_audio'))

        self.video_format_selection_comboBox.activated.connect(
            partial(self.mediaSelectionChanged, 'video'))

        self.audio_format_selection_comboBox.activated.connect(
            partial(self.mediaSelectionChanged, 'audio'))

        self.link_lineEdit.textChanged.disconnect(
            super().linkLineChanged)  # Should be disconnected.
        self.link_lineEdit.textChanged.connect(self.linkLineChangedHere)

        self.setMinimumSize(650, 480)

        self.status_box_textEdit.hide()
        self.format_selection_frame.hide()
        self.advanced_format_selection_frame.hide()
        self.advanced_format_selection_checkBox.hide()

        if 'link' in video_dict.keys() and video_dict['link']:
            self.link_lineEdit.setText(video_dict['link'])
            self.url_submit_pushButtontton.setEnabled(True)
        else:
            # check clipboard
            clipboard = QApplication.clipboard()
            text = clipboard.text()
            if (("tp:/" in text[2:6]) or ("tps:/" in text[2:7])):
                self.link_lineEdit.setText(str(text))

            self.url_submit_pushButtontton.setEnabled(True)

    def advancedFormatFrame(self, button):
        if self.advanced_format_selection_checkBox.isChecked():

            self.advanced_format_selection_frame.setEnabled(True)
            self.format_selection_frame.setEnabled(False)
            self.mediaSelectionChanged(
                'video',
                int(self.video_format_selection_comboBox.currentIndex()))

        else:
            self.advanced_format_selection_frame.setEnabled(False)
            self.format_selection_frame.setEnabled(True)
            self.mediaSelectionChanged('video_audio',
                                       int(self.media_comboBox.currentIndex()))

    def getReadableSize(self, size):
        try:
            return '{:1.2f} MB'.format(int(size) / 1048576)
        except:
            return str(size)

    def getReadableDuration(self, seconds):
        try:
            seconds = int(seconds)
            hours = seconds // 3600
            seconds = seconds % 3600
            minutes = seconds // 60
            seconds = seconds % 60
            return '{:02d}:{:02d}:{:02d}'.format(hours, minutes, seconds)
        except:
            return str(seconds)

    # Define native slots

    def urlChanged(self, value):
        if ' ' in value or value == '':
            self.url_submit_pushButtontton.setEnabled(False)
            self.url_submit_pushButtontton.setToolTip(
                QCoreApplication.translate("ytaddlink_src_ui_tr",
                                           'Please enter a valid video link'))
        else:
            self.url_submit_pushButtontton.setEnabled(True)
            self.url_submit_pushButtontton.setToolTip('')

    def submitClicked(self, button=None):
        # Clear media list
        self.media_comboBox.clear()
        self.format_selection_frame.hide()
        self.advanced_format_selection_checkBox.hide()
        self.advanced_format_selection_frame.hide()
        self.video_format_selection_comboBox.clear()
        self.audio_format_selection_comboBox.clear()
        self.change_name_lineEdit.clear()
        self.threadPool.clear()
        self.change_name_checkBox.setChecked(False)
        self.video_audio_list.clear()
        self.no_video_list.clear()
        self.no_audio_list.clear()
        self.url_submit_pushButtontton.setEnabled(False)
        self.status_box_textEdit.setText(
            QCoreApplication.translate("ytaddlink_src_ui_tr",
                                       'Fetching Media Info...'))
        self.status_box_textEdit.show()
        self.ok_pushButton.setEnabled(False)
        self.download_later_pushButton.setEnabled(False)

        dictionary_to_send = deepcopy(self.plugin_add_link_dictionary)
        # More options
        more_options = self.collectMoreOptions()
        for k in more_options.keys():
            dictionary_to_send[k] = more_options[k]
        dictionary_to_send['link'] = self.link_lineEdit.text()

        fetcher_thread = MediaListFetcherThread(self.fetchedResult,
                                                dictionary_to_send, self)
        self.parent.threadPool.append(fetcher_thread)
        self.parent.threadPool[len(self.parent.threadPool) - 1].start()

    def fileNameChanged(self, value):
        if value.strip() == '':
            self.ok_pushButton.setEnabled(False)

    def mediaSelectionChanged(self, combobox, index):
        try:
            if combobox == 'video_audio':
                if self.media_comboBox.currentText() == 'Best quality':
                    self.change_name_lineEdit.setText(self.media_title)
                    self.extension_label.setText('.' +
                                                 self.no_audio_list[-1]['ext'])

                else:
                    self.change_name_lineEdit.setText(self.media_title)
                    self.extension_label.setText(
                        '.' + self.video_audio_list[index]['ext'])

                self.change_name_checkBox.setChecked(True)

            elif combobox == 'video':
                if self.video_format_selection_comboBox.currentText(
                ) != 'No video':
                    self.change_name_lineEdit.setText(self.media_title)
                    self.extension_label.setText('.' +
                                                 self.no_audio_list[index -
                                                                    1]['ext'])
                    self.change_name_checkBox.setChecked(True)

                else:

                    if self.audio_format_selection_comboBox.currentText(
                    ) != 'No audio':
                        self.change_name_lineEdit.setText(self.media_title)
                        self.extension_label.setText('.' + self.no_video_list[
                            int(self.audio_format_selection_comboBox.
                                currentIndex()) - 1]['ext'])

                        self.change_name_checkBox.setChecked(True)
                    else:
                        self.change_name_lineEdit.setChecked(False)

            elif combobox == 'audio':
                if self.audio_format_selection_comboBox.currentText(
                ) != 'No audio' and self.video_format_selection_comboBox.currentText(
                ) == 'No video':
                    self.change_name_lineEdit.setText(self.media_title)
                    self.extension_label.setText('.' +
                                                 self.no_video_list[index -
                                                                    1]['ext'])

                    self.change_name_checkBox.setChecked(True)

                elif (self.audio_format_selection_comboBox.currentText()
                      == 'No audio'
                      and self.video_format_selection_comboBox.currentText() !=
                      'No video') or (
                          self.audio_format_selection_comboBox.currentText() !=
                          'No audio' and
                          self.video_format_selection_comboBox.currentText() !=
                          'No video'):
                    self.change_name_lineEdit.setText(self.media_title)
                    self.extension_label.setText('.' + self.no_audio_list[
                        int(self.video_format_selection_comboBox.currentIndex(
                        )) - 1]['ext'])

                    self.change_name_checkBox.setChecked(True)

                elif self.audio_format_selection_comboBox.currentText(
                ) == 'No audio' and self.video_format_selection_comboBox.currentText(
                ) == 'No video':
                    self.change_name_checkBox.setChecked(False)

        except Exception as ex:
            logger.sendToLog(ex, "ERROR")

    def fetchedResult(self, media_dict):

        self.url_submit_pushButtontton.setEnabled(True)
        if 'error' in media_dict.keys():

            self.status_box_textEdit.setText('<font color="#f11">' +
                                             str(media_dict['error']) +
                                             '</font>')
            self.status_box_textEdit.show()
        else:  # Show the media list

            # add no audio and no video options to the comboboxes
            self.video_format_selection_comboBox.addItem('No video')
            self.audio_format_selection_comboBox.addItem('No audio')

            self.media_title = media_dict['title']
            if 'formats' not in media_dict.keys(
            ) and 'entries' in media_dict.keys():
                formats = media_dict['entries']
                formats = formats[0]
                media_dict['formats'] = formats['formats']
            elif 'formats' not in media_dict.keys(
            ) and 'format' in media_dict.keys():
                media_dict['formats'] = [media_dict.copy()]

            try:
                i = 0
                for f in media_dict['formats']:
                    no_audio = False
                    no_video = False
                    text = ''
                    if 'acodec' in f.keys():
                        # only video, no audio
                        if f['acodec'] == 'none':
                            no_audio = True

                        # resolution
                        if 'height' in f.keys():
                            text = text + ' ' + '{}p'.format(f['height'])

                    if 'vcodec' in f.keys():
                        #                         if f['vcodec'] == 'none' and f['acodec'] != 'none':
                        #                             continue

                        # No video, show audio bit rate
                        if f['vcodec'] == 'none':
                            text = text + '{}kbps'.format(f['abr'])
                            no_video = True

                    if 'ext' in f.keys():
                        text = text + ' ' + '.{}'.format(f['ext'])

                    if 'filesize' in f.keys() and f['filesize']:
                        # Youtube api does not supply file size for some formats, so check it.
                        text = text + ' ' + '{}'.format(
                            self.getReadableSize(f['filesize']))

                    else:  # Start spider to find file size
                        input_dict = deepcopy(self.plugin_add_link_dictionary)

                        input_dict['link'] = f['url']
                        more_options = self.collectMoreOptions()

                        for key in more_options.keys():
                            input_dict[key] = more_options[key]

                        size_fetcher = FileSizeFetcherThread(input_dict, i)
                        self.threadPool[str(i)] = {
                            'thread': size_fetcher,
                            'item_id': i
                        }
                        self.parent.threadPool.append(size_fetcher)
                        self.parent.threadPool[len(self.parent.threadPool) -
                                               1].start()
                        self.parent.threadPool[len(self.parent.threadPool) -
                                               1].FOUND.connect(
                                                   self.findFileSize)

                    # Add current format to the related comboboxes
                    if no_audio:
                        self.no_audio_list.append(f)
                        self.video_format_selection_comboBox.addItem(text)

                    elif no_video:
                        self.no_video_list.append(f)
                        self.audio_format_selection_comboBox.addItem(text)

                    else:
                        self.video_audio_list.append(f)
                        self.media_comboBox.addItem(text)

                    i = i + 1

                self.status_box_textEdit.hide()

                if 'duration' in media_dict.keys():
                    self.duration_label.setText(
                        'Duration ' +
                        self.getReadableDuration(media_dict['duration']))

                self.format_selection_frame.show()
                self.advanced_format_selection_checkBox.show()
                self.advanced_format_selection_frame.show()
                self.ok_pushButton.setEnabled(True)
                self.download_later_pushButton.setEnabled(True)

                # if we have no options for seperate audio and video, then hide advanced_format_selection...
                if len(self.no_audio_list) == 0 and len(
                        self.no_video_list) == 0:
                    self.advanced_format_selection_checkBox.hide()
                    self.advanced_format_selection_frame.hide()

                # set index of comboboxes on best available quality.
                if len(self.no_audio_list) != 0 and len(
                        self.no_video_list) != 0:
                    self.media_comboBox.addItem('Best quality')
                    self.media_comboBox.setCurrentIndex(
                        len(self.video_audio_list))

                elif len(self.video_audio_list) != 0:
                    self.media_comboBox.setCurrentIndex(
                        len(self.video_audio_list) - 1)

                if len(self.no_audio_list) != 0:
                    self.video_format_selection_comboBox.setCurrentIndex(
                        len(self.no_audio_list))

                if len(self.no_video_list) != 0:
                    self.audio_format_selection_comboBox.setCurrentIndex(
                        len(self.no_video_list))

                # if we have only audio or we have only video then hide media_comboBox
                if len(self.video_audio_list) == 0:
                    self.media_comboBox.hide()
                    self.select_format_label.hide()

                    # only video
                    if len(self.no_video_list) != 0 and len(
                            self.no_audio_list) == 0:
                        self.mediaSelectionChanged(
                            'video',
                            int(self.video_format_selection_comboBox.
                                currentIndex()))
                        self.advanced_format_selection_checkBox.setChecked(
                            True)
                        self.advanced_format_selection_checkBox.hide()

                    # only audio
                    elif len(self.no_video_list) == 0 and len(
                            self.no_audio_list) != 0:
                        self.mediaSelectionChanged(
                            'audio',
                            int(self.audio_format_selection_comboBox.
                                currentIndex()))
                        self.advanced_format_selection_checkBox.setChecked(
                            True)
                        self.advanced_format_selection_checkBox.hide()

                    # audio and video
                    else:
                        self.mediaSelectionChanged(
                            'video_audio',
                            int(self.media_comboBox.currentIndex()))

            except Exception as ex:
                logger.sendToLog(ex, "ERROR")

    def findFileSize(self, result):
        try:
            item_id = self.threadPool[str(result['thread_key'])]['item_id']
            if result['file_size'] and result['file_size'] != '0':
                text = self.media_comboBox.itemText(item_id)
                self.media_comboBox.setItemText(
                    item_id, '{} - {}'.format(text, result['file_size']))
        except Exception as ex:
            logger.sendToLog(ex, "ERROR")

    def linkLineChangedHere(self, lineEdit):
        if str(lineEdit) == '':
            self.url_submit_pushButtontton.setEnabled(False)
        else:
            self.url_submit_pushButtontton.setEnabled(True)

    # This method collects additional information like proxy ip, user, password etc.
    def collectMoreOptions(self):
        options = {
            'ip': None,
            'port': None,
            'proxy_user': None,
            'proxy_passwd': None,
            'download_user': None,
            'download_passwd': None
        }
        if self.proxy_checkBox.isChecked():
            options['ip'] = self.ip_lineEdit.text()
            options['port'] = self.port_spinBox.value()
            options['proxy_user'] = self.proxy_user_lineEdit.text()
            options['proxy_passwd'] = self.proxy_pass_lineEdit.text()
        if self.download_checkBox.isChecked():
            options['download_user'] = self.download_user_lineEdit.text()
            options['download_passwd'] = self.download_pass_lineEdit.text()

        # These info (keys) are required for spider to find file size, because spider() does not check if key exists.
        additional_info = [
            'header', 'load_cookies', 'user_agent', 'referer', 'out'
        ]
        for i in additional_info:
            if i not in self.plugin_add_link_dictionary.keys():
                options[i] = None
        return options

    # user commited information by pressing ok_pushButton, so get information
    # from VideoFinderAddLink window and return them to the mainwindow with callback!
    def okButtonPressed(self, button, download_later):

        link_list = []
        # seperate audio format and video format is selected.
        if self.advanced_format_selection_checkBox.isChecked():

            if self.video_format_selection_comboBox.currentText(
            ) == 'No video' and self.audio_format_selection_comboBox.currentText(
            ) != 'No audio':

                # only audio link must be added to the link_list
                audio_link = self.no_video_list[
                    self.audio_format_selection_comboBox.currentIndex() -
                    1]['url']
                link_list.append(audio_link)

            elif self.video_format_selection_comboBox.currentText(
            ) != 'No video' and self.audio_format_selection_comboBox.currentText(
            ) == 'No audio':

                # only video link must be added to the link_list
                video_link = self.no_audio_list[
                    self.video_format_selection_comboBox.currentIndex() -
                    1]['url']
                link_list.append(video_link)

            elif self.video_format_selection_comboBox.currentText(
            ) != 'No video' and self.audio_format_selection_comboBox.currentText(
            ) != 'No audio':

                # video and audio links must be added to the link_list
                audio_link = self.no_video_list[
                    self.audio_format_selection_comboBox.currentIndex() -
                    1]['url']
                video_link = self.no_audio_list[
                    self.video_format_selection_comboBox.currentIndex() -
                    1]['url']
                link_list = [video_link, audio_link]

            elif self.video_format_selection_comboBox.currentText(
            ) == 'No video' and self.audio_format_selection_comboBox.currentText(
            ) == 'No audio':

                # no video and no video selected! REALY?!. user is DRUNK! close the window! :))
                self.close()
        else:
            if self.media_comboBox.currentText() == 'Best quality':

                # the last item in no_video_list and no_audio_list are the best.
                video_link = self.no_audio_list[-1]['url']
                audio_link = self.no_video_list[-1]['url']

                link_list = [video_link, audio_link]

            else:
                audio_and_video_link = self.video_audio_list[
                    self.media_comboBox.currentIndex()]['url']
                link_list.append(audio_and_video_link)

        # write user's new inputs in persepolis_setting for next time :)
        self.persepolis_setting.setValue('add_link_initialization/ip',
                                         self.ip_lineEdit.text())
        self.persepolis_setting.setValue('add_link_initialization/port',
                                         self.port_spinBox.value())
        self.persepolis_setting.setValue('add_link_initialization/proxy_user',
                                         self.proxy_user_lineEdit.text())
        self.persepolis_setting.setValue(
            'add_link_initialization/download_user',
            self.download_user_lineEdit.text())

        # get proxy information
        if not (self.proxy_checkBox.isChecked()):
            ip = None
            port = None
            proxy_user = None
            proxy_passwd = None
        else:
            ip = self.ip_lineEdit.text()
            if not (ip):
                ip = None
            port = self.port_spinBox.value()
            if not (port):
                port = None
            proxy_user = self.proxy_user_lineEdit.text()
            if not (proxy_user):
                proxy_user = None
            proxy_passwd = self.proxy_pass_lineEdit.text()
            if not (proxy_passwd):
                proxy_passwd = None

        # get download username and password information
        if not (self.download_checkBox.isChecked()):
            download_user = None
            download_passwd = None
        else:
            download_user = self.download_user_lineEdit.text()
            if not (download_user):
                download_user = None
            download_passwd = self.download_pass_lineEdit.text()
            if not (download_passwd):
                download_passwd = None

        # check that if user limits download speed.
        if not (self.limit_checkBox.isChecked()):
            limit = 0
        else:
            if self.limit_comboBox.currentText() == "KiB/s":
                limit = str(self.limit_spinBox.value()) + str("K")
            else:
                limit = str(self.limit_spinBox.value()) + str("M")

        # get start time for download if user set that.
        if not (self.start_checkBox.isChecked()):
            start_time = None
        else:
            start_time = self.start_time_qDataTimeEdit.text()

        # get end time for download if user set that.
        if not (self.end_checkBox.isChecked()):
            end_time = None
        else:
            end_time = self.end_time_qDateTimeEdit.text()

        # set name for file(s)
        if self.change_name_checkBox.isChecked():
            name = str(self.change_name_lineEdit.text())
            if name == '':
                name = 'video_finder_file'
        else:
            name = 'video_finder_file'

        # video finder always finds extension
        # but if it can't find file extension
        # use mp4 for extension.
        if str(self.extension_label.text()) == '':
            extension = '.mp4'
        else:
            extension = str(self.extension_label.text())

        # did user select seperate audio and video?
        if len(link_list) == 2:
            video_name = name + extension
            audio_name = name + '.' + \
                str(self.no_video_list[self.audio_format_selection_comboBox.currentIndex() - 1]['ext'])

            name_list = [video_name, audio_name]
        else:
            name_list = [name + extension]

        # get number of connections
        connections = self.connections_spinBox.value()

        # get download_path
        download_path = self.download_folder_lineEdit.text()

        # referer
        if self.referer_lineEdit.text() != '':
            referer = self.referer_lineEdit.text()
        else:
            referer = None

        # header
        if self.header_lineEdit.text() != '':
            header = self.header_lineEdit.text()
        else:
            header = None

        # user_agent
        if self.user_agent_lineEdit.text() != '':
            user_agent = self.user_agent_lineEdit.text()
        else:
            user_agent = None

        # load_cookies
        if self.load_cookies_lineEdit.text() != '':
            load_cookies = self.load_cookies_lineEdit.text()
        else:
            load_cookies = None

        add_link_dictionary_list = []
        if len(link_list) == 1:
            # save information in a dictionary(add_link_dictionary).
            add_link_dictionary = {
                'referer': referer,
                'header': header,
                'user_agent': user_agent,
                'load_cookies': load_cookies,
                'out': name_list[0],
                'start_time': start_time,
                'end_time': end_time,
                'link': link_list[0],
                'ip': ip,
                'port': port,
                'proxy_user': proxy_user,
                'proxy_passwd': proxy_passwd,
                'download_user': download_user,
                'download_passwd': download_passwd,
                'connections': connections,
                'limit_value': limit,
                'download_path': download_path
            }

            add_link_dictionary_list.append(add_link_dictionary)

        else:
            video_add_link_dictionary = {
                'referer': referer,
                'header': header,
                'user_agent': user_agent,
                'load_cookies': load_cookies,
                'out': name_list[0],
                'start_time': start_time,
                'end_time': end_time,
                'link': link_list[0],
                'ip': ip,
                'port': port,
                'proxy_user': proxy_user,
                'proxy_passwd': proxy_passwd,
                'download_user': download_user,
                'download_passwd': download_passwd,
                'connections': connections,
                'limit_value': limit,
                'download_path': download_path
            }

            audio_add_link_dictionary = {
                'referer': referer,
                'header': header,
                'user_agent': user_agent,
                'load_cookies': load_cookies,
                'out': name_list[1],
                'start_time': None,
                'end_time': end_time,
                'link': link_list[1],
                'ip': ip,
                'port': port,
                'proxy_user': proxy_user,
                'proxy_passwd': proxy_passwd,
                'download_user': download_user,
                'download_passwd': download_passwd,
                'connections': connections,
                'limit_value': limit,
                'download_path': download_path
            }

            add_link_dictionary_list = [
                video_add_link_dictionary, audio_add_link_dictionary
            ]

        # get category of download
        category = str(self.add_queue_comboBox.currentText())

        del self.plugin_add_link_dictionary

        # return information to mainwindow
        self.callback(add_link_dictionary_list, download_later, category)

        # close window
        self.close()
Beispiel #16
0
class ActionBar(ui_tools.StyledBar):
    """
    SIGNALS:
    @changeCurrent(PyQt_PyObject)
    @runFile(QString)
    @reopenTab(QString)
    @recentTabsModified()
    """
    change_current = pyqtSignal('PyQt_PyObject', int)
    splitEditor = pyqtSignal(bool)
    runFile = pyqtSignal('QString')
    closeSplit = pyqtSignal()
    addToProject = pyqtSignal('QString')
    showFileInExplorer = pyqtSignal('QString')
    goToSymbol = pyqtSignal(int)
    undockEditor = pyqtSignal()
    reopenTab = pyqtSignal('QString')

    def __init__(self, main_combo=False):
        super(ActionBar, self).__init__()
        # self.setObjectName("actionbar")
        self.setProperty('gradient', True)
        hbox = QHBoxLayout(self)
        hbox.setContentsMargins(0, 0, 0, 0)
        hbox.setSpacing(0)

        # self.lbl_checks = QLabel('')
        # self.lbl_checks.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        # self.lbl_checks.setFixedWidth(48)
        # self.lbl_checks.setVisible(False)
        # hbox.addWidget(self.lbl_checks)
        # self.combo = ComboFiles()
        self.combo_files = QComboBox()
        self.combo_files.setProperty("border", True)
        # self.combo_files.setProperty("border_bottom", True)
        self.combo_files.setProperty("gradient", True)
        self.combo_files.setSizeAdjustPolicy(
            QComboBox.AdjustToMinimumContentsLengthWithIcon)
        # self.combo.setIconSize(QSize(16, 16))
        # model = QStandardItemModel()
        # self.combo.setModel(model)
        # self.combo.view().setDragDropMode(QAbstractItemView.InternalMove)
        self.combo_files.setMaximumWidth(300)
        self.combo_files.currentIndexChanged[int].connect(self.current_changed)
        # self.combo.setObjectName("combotab")
        # self.connect(self.combo, SIGNAL("currentIndexChanged(int)"),
        #             self.current_changed)
        self.combo_files.setToolTip(translations.TR_COMBO_FILE_TOOLTIP)
        self.combo_files.setContextMenuPolicy(Qt.CustomContextMenu)
        self.combo_files.customContextMenuRequested.connect(
            self._context_menu_requested)
        hbox.addWidget(self.combo_files)

        self.symbols_combo = QComboBox()
        # self.symbols_combo.setStyleSheet("QComboBox { combobox-popup: 0; }")
        self.symbols_combo.setProperty("border", True)
        # self.symbols_combo.setProperty("border_bottom", True)
        self.symbols_combo.setProperty("gradient", True)
        self.symbols_combo.setSizeAdjustPolicy(
            QComboBox.AdjustToMinimumContentsLengthWithIcon)
        # self.symbols_combo.setIconSize(QSize(16, 16))
        self.symbols_combo.setObjectName("combo_symbols")
        self.symbols_combo.activated[int].connect(self.current_symbol_changed)
        # self.connect(self.symbols_combo, SIGNAL("activated(int)"),
        #             self.current_symbol_changed)
        hbox.addWidget(self.symbols_combo)

        self.code_navigator = CodeNavigator()
        hbox.addWidget(self.code_navigator)
        # FIXME: set property for other themes
        self._pos_text = "Line: %d, Col: %d"
        # self.lbl_position = QLabel(self._pos_text % (0, 0))
        # self._go_to_line_widget = go_to_line.GoToLine(self)
        # self.lbl_position = ui_tools.ClickeableLabel(self._pos_text % (0, 0))
        self.lbl_position = QLabel()
        # self.lbl_position.setProperty("border_bottom", True)
        self.lbl_position.setProperty("gradient", True)
        self.lbl_position.setText(self._pos_text % (0, 0))
        # self.lbl_position.setAutoFillBackground(True)
        # self.lbl_position.clicked.connect(self._on_lbl_position_clicked)
        # FIXME: falla con split. ARREGLADO
        margin = self.style().pixelMetric(
            QStyle.PM_LayoutHorizontalSpacing) / 2
        self.lbl_position.setContentsMargins(margin, 0, margin, 0)
        self.lbl_position.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        hbox.addWidget(self.lbl_position)

        # self.btn_close = QPushButton(
        #    self.style().standardIcon(QStyle.SP_DialogCloseButton), '')
        # self.btn_close.setIconSize(QSize(16, 16))
        self.btn_close = QToolButton()
        # self.btn_close.setProperty("border_bottom", True)
        self.btn_close.setProperty("gradient", True)
        # self.btn_close.setAutoRaise(True)
        # self.btn_close.setFixedHeight(24)
        # self.btn_close.setIcon(QIcon(":img/close"))

        self.btn_close.setIcon(
            self.style().standardIcon(QStyle.SP_DialogCloseButton))
            # ui_tools.colored_icon(
            #    ":img/close",
            #    NTheme.get_color('IconBaseColor')))
        if main_combo:
            # self.btn_close.setObjectName('navigation_button')
            self.btn_close.setToolTip(translations.TR_CLOSE_FILE)
            self.btn_close.clicked.connect(self.about_to_close_file)
            # self.connect(self.btn_close, SIGNAL("clicked()"),
            #             self.about_to_close_file)
        else:
            # self.btn_close.setObjectName('close_split')
            self.btn_close.setToolTip(translations.TR_CLOSE_SPLIT)
            self.btn_close.clicked.connect(self.close_split)
            # self.connect(self.btn_close, SIGNAL("clicked()"),
            #             self.close_split)
        self.btn_close.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        hbox.addWidget(self.btn_close)

    # def _on_lbl_position_clicked(self):
    #    main_container = IDE.get_service("main_container")
    #    editor_widget = main_container.get_current_editor()
        # self._go_to_line_widget.set_line_count(editor_widget.line_count())
        # self._go_to_line_widget.show()

    def resizeEvent(self, event):
        super(ActionBar, self).resizeEvent(event)
        if event.size().width() < 400:
            self.symbols_combo.hide()
            self.code_navigator.hide()
            self.lbl_position.hide()
        else:
            self.symbols_combo.show()
            self.code_navigator.show()
            self.lbl_position.show()

    def add_item(self, text, neditable):
        """Add a new item to the combo and add the neditable data."""

        self.combo_files.addItem(text, neditable)
        self.combo_files.setCurrentIndex(self.combo_files.count() - 1)

    def get_editables(self):
        editables = []
        for index in range(self.combo_files.count()):
            neditable = self.combo_files.itemData(index)
            editables.append(neditable)
        return editables

    def add_symbols(self, symbols):
        """Add the symbols to the symbols's combo."""

        mo = Model(symbols)
        self.symbols_combo.setModel(mo)
        # self.symbols_combo.clear()
        # for symbol in symbols:
        #    data = symbol[1]
        #    if data[1] == 'f':
        #        icon = QIcon(":img/function")
        #    else:
        #        icon = QIcon(":img/class")
        #    self.symbols_combo.addItem(icon, data[0])

    def set_current_symbol(self, index):
        self.symbols_combo.setCurrentIndex(index + 1)

    def update_item_icon(self, neditable, icon):
        index = self.combo_files.findData(neditable)
        self.combo_files.setItemIcon(index, icon)

    def update_item_text(self, neditable, text):
        index = self.combo_files.findData(neditable)
        self.combo_files.setItemText(index, text)

    def current_changed(self, index):
        """Change the current item in the combo."""
        neditable = self.combo_files.itemData(index)
        self.change_current.emit(neditable, index)
        # self.emit(SIGNAL("changeCurrent(PyQt_PyObject, int)"), neditable, index)

    def current_symbol_changed(self, index):
        """Change the current symbol in the combo."""
        if index == 0:
            return
        self.goToSymbol.emit(index - 1)

    def update_line_col(self, line, col):
        """Update the line and column position."""
        self.lbl_position.setText(self._pos_text % (line, col))

    def _context_menu_requested(self, point):
        """Display context menu for the combo file."""
        if self.combo_files.count() == 0:
            # If there is not an Editor opened, don't show the menu
            return
        menu = QMenu()
        # actionAdd = menu.addAction(translations.TR_ADD_TO_PROJECT)
        # actionRun = menu.addAction(translations.TR_RUN_FILE)
        # menuSyntax = menu.addMenu(translations.TR_CHANGE_SYNTAX)
        show_folder = menu.addAction("Show Containing Folder")
        # self._create_menu_syntax(menuSyntax)
        menu.addSeparator()
        # actionClose = menu.addAction(translations.TR_CLOSE_FILE)
        # actionCloseAll = menu.addAction(translations.TR_CLOSE_ALL_FILES)
        # actionCloseAllNotThis = menu.addAction(
        #    translations.TR_CLOSE_OTHER_FILES)
        # menu.addSeparator()
        # actionSplitH = menu.addAction(translations.TR_SPLIT_VERTICALLY)
        # actionSplitV = menu.addAction(translations.TR_SPLIT_HORIZONTALLY)
        # menu.addSeparator()
        # actionCopyPath = menu.addAction(
        #    translations.TR_COPY_FILE_PATH_TO_CLIPBOARD)
        # actionShowFileInExplorer = menu.addAction(
        #    translations.TR_SHOW_FILE_IN_EXPLORER)
        # actionReopen = menu.addAction(translations.TR_REOPEN_FILE)
        action_undock = menu.addAction(translations.TR_UNDOCK_EDITOR)
        # if len(settings.LAST_OPENED_FILES) == 0:
        #    actionReopen.setEnabled(False)

        # Connect actions
        action_undock.triggered.connect(self._undock_editor)
        show_folder.triggered.connect(self._show_containing_folder)
        # self.connect(actionSplitH, SIGNAL("triggered()"),
        #             lambda: self._split(False))
        # self.connect(actionSplitV, SIGNAL("triggered()"),
        #             lambda: self._split(True))
        # self.connect(actionRun, SIGNAL("triggered()"),
        #             self._run_this_file)
        # self.connect(actionAdd, SIGNAL("triggered()"),
        #             self._add_to_project)
        # self.connect(actionClose, SIGNAL("triggered()"),
        #             self.about_to_close_file)
        # self.connect(actionCloseAllNotThis, SIGNAL("triggered()"),
        #             self._close_all_files_except_this)
        # self.connect(actionCloseAll, SIGNAL("triggered()"),
        #             self._close_all_files)
        # self.connect(actionCopyPath, SIGNAL("triggered()"),
        #             self._copy_file_location)
        # self.connect(actionShowFileInExplorer, SIGNAL("triggered()"),
        #             self._show_file_in_explorer)
        # self.connect(actionReopen, SIGNAL("triggered()"),
        #             self._reopen_last_tab)
        # self.connect(actionUndock, SIGNAL("triggered()"),
        #             self._undock_editor)

        menu.exec_(QCursor.pos())

    def _show_containing_folder(self):
        # FIXME: mover y cross platform
        main_container = IDE.get_service("main_container")
        editor_widget = main_container.get_current_editor()
        filename = editor_widget.file_path
        import subprocess
        from ninja_ide.core.file_handling import file_manager
        folder = file_manager.get_folder(filename)
        subprocess.call(["xdg-open", folder])

    def _create_menu_syntax(self, menuSyntax):
        """Create Menu with the list of syntax supported."""
        syntax = list(settings.SYNTAX.keys())
        syntax.sort()
        for syn in syntax:
            menuSyntax.addAction(syn)
            # self.connect(menuSyntax, SIGNAL("triggered(QAction*)"),
            #             self._reapply_syntax)

    def _reapply_syntax(self, syntaxAction):
        # TODO
        if [self.currentIndex(), syntaxAction] != self._resyntax:
            self._resyntax = [self.currentIndex(), syntaxAction]
            # self.emit(SIGNAL("syntaxChanged(QWidget, QString)"),
            #          self.currentWidget(), syntaxAction.text())

    def set_current_file(self, neditable):
        index = self.combo_files.findData(neditable)
        self.combo_files.setCurrentIndex(index)

    def set_current_by_index(self, index):
        self.combo_files.setCurrentIndex(index)

    @pyqtSlot()
    def about_to_close_file(self, index=None):
        """Close the NFile object."""

        if index is None:
            index = self.combo_files.currentIndex()
        neditable = self.combo_files.itemData(index)
        if neditable:
            neditable.nfile.close()

    def close_split(self):
        self.closeSplit.emit()
        # self.emit(SIGNAL("closeSplit()"))

    def close_file(self, neditable):
        """Receive the confirmation to close the file."""
        index = self.combo_files.findData(neditable)
        self.combo_files.removeItem(index)
        return index

    def _run_this_file(self):
        """Execute the current file."""
        neditable = self.combo.itemData(self.combo.currentIndex())
        print("Emitir runFile")
        # self.emit(SIGNAL("runFile(QString)"), neditable.file_path)

    def _add_to_project(self):
        """Emit a signal to let someone handle the inclusion of the file
        inside a project."""
        neditable = self.combo.itemData(self.combo.currentIndex())
        print("Emitir adToProject")
        # self.emit(SIGNAL("addToProject(QString)"), neditable.file_path)

    def _show_file_in_explorer(self):
        '''Triggered when the "Show File in Explorer" context
        menu action is selected. Emits the "showFileInExplorer(QString)"
        signal with the current file's full path as argument.'''
        neditable = self.combo.itemData(self.combo.currentIndex())
        print("Emitir showFileInExplorer")
        # self.emit(SIGNAL("showFileInExplorer(QString)"), neditable.file_path)

    def _reopen_last_tab(self):
        print("Emitir reopenTab y recentTabsModified")
        # self.emit(SIGNAL("reopenTab(QString)"),
        #          settings.LAST_OPENED_FILES.pop())
        # self.emit(SIGNAL("recentTabsModified()"))

    def _undock_editor(self):
        self.undockEditor.emit()

    def _split(self, orientation):
        print("emitir splitEditor")
        # self.emit(SIGNAL("splitEditor(bool)"), orientation)

    def _copy_file_location(self):
        """Copy the path of the current opened file to the clipboard."""
        neditable = self.combo.itemData(self.combo.currentIndex())
        QApplication.clipboard().setText(neditable.file_path,
                                         QClipboard.Clipboard)

    def _close_all_files(self):
        """Close all the files opened."""
        for i in range(self.combo.count()):
            self.about_to_close_file(0)

    def _close_all_files_except_this(self):
        """Close all the files except the current one."""
        neditable = self.combo.itemData(self.combo.currentIndex())
        for i in reversed(list(range(self.combo.count()))):
            ne = self.combo.itemData(i)
            if ne is not neditable:
                self.about_to_close_file(i)
class LaserRangeFinder(PluginBase):
    def __init__(self, *args):
        super().__init__(BrickletLaserRangeFinder, *args)

        self.lrf = self.device

        # the firmware version of a EEPROM Bricklet can (under common circumstances)
        # not change during the lifetime of an EEPROM Bricklet plugin. therefore,
        # it's okay to make final decisions based on it here
        self.has_sensor_hardware_version_api = self.firmware_version >= (2, 0, 3)
        self.has_configuration_api = self.firmware_version >= (2, 0, 3)

        self.cbe_distance = CallbackEmulator(self.lrf.get_distance,
                                             None,
                                             self.cb_distance,
                                             self.increase_error_count)
        self.cbe_velocity = CallbackEmulator(self.lrf.get_velocity,
                                             None,
                                             self.cb_velocity,
                                             self.increase_error_count)

        self.current_distance = CurveValueWrapper() # int, cm
        self.current_velocity = CurveValueWrapper() # float, m/s

        plots_distance = [('Distance', Qt.red, self.current_distance, format_distance)]
        plots_velocity = [('Velocity', Qt.red, self.current_velocity, '{:.2f} m/s'.format)]
        self.plot_widget_distance = PlotWidget('Distance [cm]', plots_distance, y_resolution=1.0)
        self.plot_widget_velocity = PlotWidget('Velocity [m/s]', plots_velocity, y_resolution=0.01)

        self.mode_label = QLabel('Mode:')
        self.mode_combo = QComboBox()
        self.mode_combo.addItem("Distance: 1cm resolution, 40m max")
        self.mode_combo.addItem("Velocity: 0.10 m/s resolution, 12.70m/s max")
        self.mode_combo.addItem("Velocity: 0.25 m/s resolution, 31.75m/s max")
        self.mode_combo.addItem("Velocity: 0.50 m/s resolution, 63.50m/s max")
        self.mode_combo.addItem("Velocity: 1.00 m/s resolution, 127.00m/s max")
        self.mode_combo.currentIndexChanged.connect(self.mode_changed)
        self.mode_combo.hide()

        self.label_average_distance = QLabel('Moving Average for Distance:')

        self.spin_average_distance = QSpinBox()
        self.spin_average_distance.setMinimum(0)
        self.spin_average_distance.setMaximum(50)
        self.spin_average_distance.setSingleStep(1)
        self.spin_average_distance.setValue(10)
        self.spin_average_distance.editingFinished.connect(self.spin_average_finished)

        self.label_average_velocity = QLabel('Moving Average for Velocity:')

        self.spin_average_velocity = QSpinBox()
        self.spin_average_velocity.setMinimum(0)
        self.spin_average_velocity.setMaximum(50)
        self.spin_average_velocity.setSingleStep(1)
        self.spin_average_velocity.setValue(10)
        self.spin_average_velocity.editingFinished.connect(self.spin_average_finished)

        self.enable_laser = QCheckBox("Enable Laser")
        self.enable_laser.stateChanged.connect(self.enable_laser_changed)

        self.label_acquisition_count = QLabel('Acquisition Count:')
        self.spin_acquisition_count = QSpinBox()
        self.spin_acquisition_count.setMinimum(1)
        self.spin_acquisition_count.setMaximum(255)
        self.spin_acquisition_count.setSingleStep(1)
        self.spin_acquisition_count.setValue(128)

        self.enable_qick_termination = QCheckBox("Quick Termination")

        self.label_threshold = QLabel('Threshold:')
        self.threshold = QCheckBox("Automatic Threshold")

        self.spin_threshold = QSpinBox()
        self.spin_threshold.setMinimum(1)
        self.spin_threshold.setMaximum(255)
        self.spin_threshold.setSingleStep(1)
        self.spin_threshold.setValue(1)

        self.label_frequency = QLabel('Frequency [Hz]:')
        self.frequency = QCheckBox("Automatic Frequency (Disable for Velocity)")

        self.spin_frequency = QSpinBox()
        self.spin_frequency.setMinimum(10)
        self.spin_frequency.setMaximum(500)
        self.spin_frequency.setSingleStep(1)
        self.spin_frequency.setValue(10)

        self.spin_acquisition_count.editingFinished.connect(self.configuration_changed)
        self.enable_qick_termination.stateChanged.connect(self.configuration_changed)
        self.spin_threshold.editingFinished.connect(self.configuration_changed)
        self.threshold.stateChanged.connect(self.configuration_changed)
        self.spin_frequency.editingFinished.connect(self.configuration_changed)
        self.frequency.stateChanged.connect(self.configuration_changed)

        layout_h1 = QHBoxLayout()
        layout_h1.addWidget(self.plot_widget_distance)
        layout_h1.addWidget(self.plot_widget_velocity)

        layout_h2 = QHBoxLayout()
        layout_h2.addWidget(self.mode_label)
        layout_h2.addWidget(self.mode_combo)
        layout_h2.addWidget(self.label_average_distance)
        layout_h2.addWidget(self.spin_average_distance)
        layout_h2.addWidget(self.label_average_velocity)
        layout_h2.addWidget(self.spin_average_velocity)
        layout_h2.addStretch()
        layout_h2.addWidget(self.enable_laser)

        layout_h3 = QHBoxLayout()
        layout_h3.addWidget(self.label_frequency)
        layout_h3.addWidget(self.spin_frequency)
        layout_h3.addWidget(self.frequency)
        layout_h3.addStretch()
        layout_h3.addWidget(self.enable_qick_termination)

        layout_h4 = QHBoxLayout()
        layout_h4.addWidget(self.label_threshold)
        layout_h4.addWidget(self.spin_threshold)
        layout_h4.addWidget(self.threshold)
        layout_h4.addStretch()
        layout_h4.addWidget(self.label_acquisition_count)
        layout_h4.addWidget(self.spin_acquisition_count)

        self.widgets_distance = [self.plot_widget_distance, self.spin_average_distance, self.label_average_distance]
        self.widgets_velocity = [self.plot_widget_velocity, self.spin_average_velocity, self.label_average_velocity]

        for w in self.widgets_distance:
            w.hide()

        for w in self.widgets_velocity:
            w.hide()

        line = QFrame()
        line.setObjectName("line")
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)

        layout = QVBoxLayout(self)
        layout.addLayout(layout_h1)
        layout.addWidget(line)
        layout.addLayout(layout_h2)
        layout.addLayout(layout_h3)
        layout.addLayout(layout_h4)

    def start(self):
        if self.has_sensor_hardware_version_api:
            async_call(self.lrf.get_sensor_hardware_version, None, self.get_sensor_hardware_version_async, self.increase_error_count)
        else:
            self.get_sensor_hardware_version_async(1)

        if self.has_configuration_api:
            async_call(self.lrf.get_configuration, None, self.get_configuration_async, self.increase_error_count)

        async_call(self.lrf.get_mode, None, self.get_mode_async, self.increase_error_count)
        async_call(self.lrf.is_laser_enabled, None, self.enable_laser.setChecked, self.increase_error_count)
        async_call(self.lrf.get_moving_average, None, self.get_moving_average_async, self.increase_error_count)

        self.cbe_distance.set_period(25)
        self.cbe_velocity.set_period(25)

        self.plot_widget_distance.stop = False
        self.plot_widget_velocity.stop = False

    def stop(self):
        self.cbe_distance.set_period(0)
        self.cbe_velocity.set_period(0)

        self.plot_widget_distance.stop = True
        self.plot_widget_velocity.stop = True

    def destroy(self):
        pass

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickletLaserRangeFinder.DEVICE_IDENTIFIER

    def enable_laser_changed(self, state):
        if state == Qt.Checked:
            self.lrf.enable_laser()
        else:
            self.lrf.disable_laser()

    def mode_changed(self, value):
        if value < 0 or value > 4:
            return

        self.lrf.set_mode(value)
        if value == 0:
            for w in self.widgets_velocity:
                w.hide()
            for w in self.widgets_distance:
                w.show()
        else:
            for w in self.widgets_distance:
                w.hide()
            for w in self.widgets_velocity:
                w.show()

    def cb_distance(self, distance):
        self.current_distance.value = distance

    def cb_velocity(self, velocity):
        self.current_velocity.value = velocity / 100.0

    def configuration_changed(self):
        acquisition_count = self.spin_acquisition_count.value()
        enable_quick_termination = self.enable_qick_termination.isChecked()

        if self.threshold.isChecked():
            threshold = 0
        else:
            threshold = self.spin_threshold.value()

        if self.frequency.isChecked():
            frequency = 0
            for w in self.widgets_velocity:
                w.hide()
        else:
            frequency = self.spin_frequency.value()
            for w in self.widgets_velocity:
                w.show()

        self.spin_threshold.setDisabled(threshold == 0)
        self.spin_frequency.setDisabled(frequency == 0)

        self.lrf.set_configuration(acquisition_count, enable_quick_termination, threshold, frequency)

    def get_configuration_async(self, conf):
        self.spin_acquisition_count.blockSignals(True)
        self.spin_acquisition_count.setValue(conf.acquisition_count)
        self.spin_acquisition_count.blockSignals(False)

        self.enable_qick_termination.blockSignals(True)
        self.enable_qick_termination.setChecked(conf.enable_quick_termination)
        self.enable_qick_termination.blockSignals(False)

        self.spin_threshold.blockSignals(True)
        self.spin_threshold.setValue(conf.threshold_value)
        self.spin_threshold.setDisabled(conf.threshold_value == 0)
        self.spin_threshold.blockSignals(False)

        self.spin_frequency.blockSignals(True)
        self.spin_frequency.setValue(conf.measurement_frequency)
        self.spin_frequency.setDisabled(conf.measurement_frequency == 0)
        self.spin_frequency.blockSignals(False)

        self.threshold.blockSignals(True)
        self.threshold.setChecked(conf.threshold_value == 0)
        self.threshold.blockSignals(False)

        self.frequency.blockSignals(True)
        self.frequency.setChecked(conf.measurement_frequency == 0)
        self.frequency.blockSignals(False)

        self.configuration_changed()

    def get_sensor_hardware_version_async(self, value):
        if value == 1:
            self.mode_combo.show()
            self.mode_label.show()
            self.label_acquisition_count.hide()
            self.spin_acquisition_count.hide()
            self.enable_qick_termination.hide()
            self.label_threshold.hide()
            self.spin_threshold.hide()
            self.threshold.hide()
            self.label_frequency.hide()
            self.spin_frequency.hide()
            self.frequency.hide()
        else:
            self.mode_combo.hide()
            self.mode_label.hide()
            self.label_acquisition_count.show()
            self.spin_acquisition_count.show()
            self.enable_qick_termination.show()
            self.label_threshold.show()
            self.spin_threshold.show()
            self.threshold.show()
            self.label_frequency.show()
            self.spin_frequency.show()
            self.frequency.show()

            for w in self.widgets_distance:
                w.show()
            for w in self.widgets_velocity:
                w.show()

    def get_mode_async(self, value):
        self.mode_combo.setCurrentIndex(value)
        self.mode_changed(value)

    def get_moving_average_async(self, avg):
        self.spin_average_distance.setValue(avg.distance_average_length)
        self.spin_average_velocity.setValue(avg.velocity_average_length)

    def spin_average_finished(self):
        self.lrf.set_moving_average(self.spin_average_distance.value(), self.spin_average_velocity.value())
Beispiel #18
0
class Layout(QMainWindow):
    
    def __init__(self):
        super().__init__()
        self.pos = conf.position
        self.res = conf.resize
        self.statusText = 'Kullanıma Hazır !'
        self.initUI()

    def setURL(self,code):
        if len(code) == 11 :
            return conf.app.youTube_host + code

    def codeURL(self,url):
        url_data = urllib.parse.urlparse(url)
        query = urllib.parse.parse_qs(url_data.query)
        if len(query["v"][0]) and len(query["v"][0]) == 11 :
            return self.setURL(query["v"][0])
        return False


    def getSearch(self):
        searchTerm = self.searchBox.text()
        self.searchBtn.setDisabled(True)
        if len(searchTerm) == 0 :
            print('Temizlendi')
            self.infoClear()
        elif len(searchTerm) != 0 and self.searchBtn.isEnabled() == False :
            self.searchBtn.setDisabled(False)
            if len(searchTerm) == 11 :
                code = self.setURL(searchTerm)
                self.getVideo(code)

            elif len(searchTerm) == 43 :
                code = self.codeURL(searchTerm)
                if code == False :
                    self.statusBar().showMessage('Lütfen geçerli bir Youtube bağlantısı yada Video kodu girin !')
                self.getVideo(code)

            elif len(searchTerm) == 83 :
                code = self.codeURL(searchTerm)
                if code == False :
                    self.statusBar().showMessage('Lütfen geçerli bir Youtube bağlantısı yada Video kodu girin !')
                self.getVideo(code)

            else :
                self.statusBar().showMessage('Lütfen geçerli bir Youtube bağlantısı yada Video kodu girin !')
    def getVideo(self,code):
        self.setDisabled(True)
        self.statusBar().showMessage('Yükleniyor !')
        self.yt = YouTube(code)
        videos = self.yt.get_videos()
        quality = ['Kalite']
        for v in videos :
            if v.extension == 'mp4' :
                quality.append( v.resolution)
        quality = sorted(set(quality),reverse=True)
        self.quality.clear()
        self.quality.addItems(quality)
        self.quality.model().item(0).setEnabled(False)
        self.quality.show()
        self.filename = self.yt.filename
        self.info.setText(self.yt.filename)
        self.downloadBtn.show()
        self.statusBar().showMessage('Yüklendi !')
        self.setDisabled(False)

    def infoClear(self):
            self.downloadBtn.setDisabled(True)
            self.quality.clear()
            self.quality.hide()
            self.info.clear()
            self.downloadBtn.setDisabled(True)
            self.downloadBtn.hide()

    def searchChange(self):
        searchTerm = self.searchBox.text()
        if len(searchTerm) == 0 :
            self.infoClear()
            self.searchBtn.setDisabled(True)
            self.searchBtn.setDisabled(True)
            self.statusBar().showMessage(self.statusText)
        elif len(searchTerm) != 0 :
            self.statusBar().showMessage('Kullanıma Hazır !')
            self.searchBtn.setDisabled(False)


    def toolBarButtons(self):
        # Search Button
        self.searchBtn = QPushButton(conf.app.toolBar.searchBtn.title,self)
        self.searchBtn.clicked.connect(self.getSearch)
        self.searchBtn.setDisabled(True)
        self.searchBtn.move(conf.app.toolBar.searchBtn.pos.x,conf.app.toolBar.searchBtn.pos.y)
        # Download Button
        # downloadBtn = QPushButton(conf.app.toolBar.downloadBtn.title,self)
        # downloadBtn.move(conf.app.toolBar.downloadBtn.pos.x,conf.app.toolBar.downloadBtn.pos.y)

    def toolBar(self):
        self.toolBarButtons()
        self.searchBox = QLineEdit(self)
        self.searchBox.setFocus(True)
        self.searchBox.setFixedSize(conf.app.toolBar.searchBox.size.w,conf.app.toolBar.searchBox.size.h)
        self.searchBox.setClearButtonEnabled(True)
        self.searchBox.returnPressed.connect(self.searchChange)
        self.searchBox.textEdited.connect(self.searchChange)
        self.searchBox.setPlaceholderText(conf.app.toolBar.searchBox.placeholder)
        self.searchBox.move(conf.app.toolBar.searchBox.pos.x,conf.app.toolBar.searchBox.pos.y)


    def setStatusBar(self):
        self.statusBar().showMessage(self.statusText)
        # self.downloadBtn.setDisabled(False)


    def selectedQuality(self,text):
        infoText = self.filename
        self.info.setText(infoText + ' ' + text)
        self.downloadBtn.setDisabled(False)

    def disabledAll(self):
        self.setDisabled(True)

    def enableAll(self):
        self.setEnabled(True)

    def completed(self,path):
        self.enableAll()
        self.statusBar().showMessage(conf.app.download_dir + self.filename + '.mp4 indirildi !')
        self.infoClear()
        self.searchBtn.setDisabled(True)
        self.searchBox.clear()
        self.searchBox.setFocus(True)

    def downloadVideo(self):
        self.disabledAll()
        self.statusBar().showMessage('İndiriliyor...!')
        if self.isEnabled() == False :
            video = self.yt.get(conf.app.video.type,self.quality.currentText())
            sleep(5)
            video.download(path=conf.app.download_dir,force_overwrite=True,on_finish=self.completed)


    def initUI(self):
        self.toolBar()
        self.setStatusBar()
        self.info = QLabel(self)
        self.info.move(120,50)
        self.info.setMinimumWidth(450)

        self.quality = QComboBox(self)
        self.quality.move(120,80)
        self.quality.hide()
        self.quality.activated[str].connect(self.selectedQuality)

        self.downloadBtn = QPushButton('İndir',self)
        self.downloadBtn.move(250,80)
        self.downloadBtn.setDisabled(True)
        self.downloadBtn.hide()
        self.downloadBtn.clicked.connect(self.downloadVideo)

        self.setGeometry(self.pos.x,self.pos.y,self.res.w,self.res.h)
        self.setMaximumSize(self.res.w,self.res.h)
        self.setMinimumSize(self.res.w,self.res.h)
        self.setWindowTitle(conf.app.title + " - " + conf.app.version)
        self.show()
Beispiel #19
0
class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.lineinp = QLineEdit(self)
        self.lineinp.setPlaceholderText("Enter the site's URL here")

        self.boxinp = QComboBox(self)
        self.boxinp.addItems(['LiveLib', 'ReadRate',
                              'Libs', 'Readly'])

        self.prsbtn = QPushButton('Parse!', self)
        self.prsbtn.clicked.connect(self.prsbuttonClicked)

        self.wtfbtn = QPushButton('WTF', self)
        self.wtfbtn.clicked.connect(self.wtfbuttonClicked)

        self.datalist = QListWidget(self)

        self.msgbox = QMessageBox()
        self.msgbtn = QPushButton('Попробовать снова')
        self.msgbox.addButton(self.msgbtn, QMessageBox.DestructiveRole)
        self.msgbox.setWindowTitle('Ой, что-то не так')
        self.msgbox.setWindowIcon(QIcon('sad.png'))
        self.center(self.msgbox)

        grid = QGridLayout()
        grid.addWidget(self.lineinp, 1, 0, 1, 2)
        grid.addWidget(self.boxinp, 2, 0, 1, 2)
        grid.addWidget(self.prsbtn, 3, 0)
        grid.addWidget(self.wtfbtn, 3, 1)
        grid.addWidget(self.datalist, 4, 0, 4, 2)

        self.setLayout(grid)

        self.boxinp.hide()

        self.resize(600, 600)
        self.center(self)
        self.setWindowTitle('My big fully-functional parser')
        self.setWindowIcon(QIcon('www.png'))
        self.show()

    def center(self, obj):
        qr = obj.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    def wtfbuttonClicked(self):
        if self.boxinp.isVisible():
            self.boxinp.hide()
            self.lineinp.show()
        else:
            self.boxinp.show()
            self.lineinp.hide()

    def prsbuttonClicked(self):
        self.datalist.clear()
        if self.lineinp.isVisible():
            self.setTopByLine()
        else:
            self.setTopByBox()

    def connection_try(self, currentsite):
        try:
            data = currentsite.get_books_list()
        except requests.exceptions.ConnectionError:
            self.msgbox.setText('Ошибка сети')
            self.msgbox.setInformativeText('Проверьте подключение к интернету')
            self.msgbox.show()
        else:
            self.datalist.addItems(data)

    def setTopByBox(self):
        sitename = self.boxinp.currentText()
        currentsite = backend.sites[sitename]
        self.connection_try(currentsite)

    # На самом деле очевидно, что данный парсер с его архитектурой
    # весьма глупо реализовывать через ввод URL
    # данная возможность предусмотренна исключетельно ради примера использования QLineEdit

    def setTopByLine(self):
        siteurl = self.lineinp.text()
        if siteurl in backend.urls:
            currentsite = backend.urls[siteurl]
            self.connection_try(currentsite)
        else:
            self.msgbox.setText('Что такое?')
            self.msgbox.setInformativeText('Введите нормальный URL')
            self.msgbtn.clicked.connect(lambda: self.prsbtn.setText('Исправил, проверяйте'))
            self.msgbox.show()
Beispiel #20
0
class SongsTableToolbar(QWidget):
    play_all_needed = pyqtSignal()
    filter_albums_needed = pyqtSignal([list])
    filter_text_changed = pyqtSignal([str])

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

        self._tmp_buttons = []

        self.play_all_btn = TextButton('播放全部', self)
        self.play_all_btn.clicked.connect(self.play_all_needed.emit)

        self.play_all_btn.setObjectName('play_all')

        # album filters
        self.filter_albums_combobox = QComboBox(self)
        self.filter_albums_combobox.addItems(
            ['所有专辑', '标准', '单曲与EP', '现场', '合辑'])
        self.filter_albums_combobox.currentIndexChanged.connect(
            self.on_albums_filter_changed)
        # 8 works on macOS, don't know if it works on various Linux DEs
        self.filter_albums_combobox.setMinimumContentsLength(8)
        self.filter_albums_combobox.hide()
        self._setup_ui()

    def albums_mode(self):
        self._before_change_mode()
        self.filter_albums_combobox.show()

    def songs_mode(self):
        self._before_change_mode()
        self.play_all_btn.show()

    def artists_mode(self):
        self._before_change_mode()

    def enter_state_playall_start(self):
        self.play_all_btn.setEnabled(False)
        # currently, this is called only when feeluown is fetching songs,
        # so when we enter state_playall_start, we set play all btn text
        # to this.
        self.play_all_btn.setText('获取所有歌曲...')

    def enter_state_playall_end(self):
        self.play_all_btn.setText('获取所有歌曲...done')
        self.play_all_btn.setEnabled(True)
        self.play_all_btn.setText('播放全部')

    def add_tmp_button(self, button):
        """Append text button"""
        if button not in self._tmp_buttons:
            # FIXME(cosven): the button inserted isn't aligned with other buttons
            self._layout.insertWidget(len(self._tmp_buttons) + 1, button)
            self._tmp_buttons.append(button)

    def _setup_ui(self):
        self._layout = QHBoxLayout(self)
        # left margin of meta widget is 30, we align with it
        # bottom margin of meta widget is 15, we should be larger than that
        self._layout.setContentsMargins(30, 15, 30, 10)
        self._layout.addWidget(self.play_all_btn)
        self._layout.addStretch(0)
        self._layout.addWidget(self.filter_albums_combobox)

    def _before_change_mode(self):
        """filter all filter buttons"""
        for button in self._tmp_buttons:
            self._layout.removeWidget(button)
            button.close()
        self._tmp_buttons.clear()
        self.filter_albums_combobox.hide()
        self.play_all_btn.hide()

    def on_albums_filter_changed(self, index):
        # ['所有', '专辑', '单曲与EP', '现场', '合辑']
        if index == 0:
            types = []
        elif index == 1:
            types = [AlbumType.standard]
        elif index == 2:
            types = [AlbumType.single, AlbumType.ep]
        elif index == 3:
            types = [AlbumType.live]
        else:
            types = [AlbumType.compilation, AlbumType.retrospective]
        self.filter_albums_needed.emit(types)
Beispiel #21
0
class MainWindow(QWidget):
    """ This class contain the GUI and the functions for the Main window \n
    and uses all the other classes."""
    
    def __init__(self):
        super(MainWindow, self).__init__()
        """Overall layout of the main window."""
        self.setWindowTitle('Plot segmentation')
        self.resize(self.sizeHint())
        
        ## initialization
        self.field_image = None
        self.displaySize = 400
        self.threshold = 0.20
        self.noise = 200
        self.pix4D = None
        self.rawImgFold = None

        ## definition
        self.text_intro = QLabel('LOAD FIELD IMAGE')
        self.text_intro.setAlignment(Qt.AlignCenter)
        self.text_screenSize = QLabel('Select your screen resolution:')
        self.text_screenSize2 = QLabel('(If the size is not in the list, please choose a smaller size.)')
        self.comboBox_screenSize = QComboBox()
        self.comboBox_screenSize.addItem('1024 x 640 pixels')
        self.comboBox_screenSize.addItem('1280 x 800 pixels')
        self.comboBox_screenSize.addItem('1440 x 900 pixels')
        self.comboBox_screenSize.addItem('1680 x 1050 pixels')        
        self.comboBox_screenSize.addItem('2048 x 1152 pixels')
        self.comboBox_screenSize.addItem('2560 x 1140 pixels')
        self.comboBox_screenSize.addItem('3200 x 1800 pixels')
        self.text_fieldImage = QLabel('Choose the field image: ')
        self.button_fieldImage = QPushButton('Choose')
        self.text_image = QLabel('Image chosen:')
        self.text_imagePath = QLabel(str(self.field_image))
        self.button_drawField = QPushButton('Draw field shape')
        self.button_getBinary = QPushButton('Convert to binary')
        self.check_binary = QCheckBox('Check this if the chosen image is already a binary')
        self.text_threshold = QLabel('ExG threshold to create binary:')
        self.text_threshold2 = QLabel('0.20 usually works. Set to 1.00 for automatic.')
        self.spinbox_threshold = QDoubleSpinBox()
        self.spinbox_threshold.setRange(0.00, 1.00)
        self.spinbox_threshold.setSingleStep(0.05)
        self.spinbox_threshold.setValue(0.20)
        self.text_noise = QLabel('Minimum feature size for noise removal (px):')
        self.spinbox_noise = QSpinBox()
        self.spinbox_noise.setRange(1, 10000)
        self.spinbox_noise.setValue(200)
        
        self.text_plot = QLabel('PLOT PARAMETERS')
        self.text_plot.setAlignment(Qt.AlignCenter)
        self.text_nbOfRowPerPlot = QLabel('Number of plant rows per plot:')
        self.spinbox_nbOfRowPerPlot = QSpinBox()
        self.spinbox_nbOfRowPerPlot.setRange(1, 100)
        self.spinbox_nbOfRowPerPlot.setSingleStep(1)
        self.spinbox_nbOfRowPerPlot.setValue(1)
        self.text_nbOfColumnPerPlot = QLabel('Number of ranges per plot:')
        self.spinbox_nbOfColumnPerPlot = QSpinBox()
        self.spinbox_nbOfColumnPerPlot.setRange(1, 100)
        self.spinbox_nbOfColumnPerPlot.setSingleStep(1)
        self.spinbox_nbOfColumnPerPlot.setValue(1)
        self.text_plotArrangment = QLabel('Global orientation of the ranges:')
        self.radio_horizontal = QRadioButton('Horizontal\t\t\t')
        self.radio_horizontal.setChecked(True)
        self.radio_vertical = QRadioButton('Vertical')
        self.radio_vertical.setChecked(False)
        self.button_apply = QPushButton('Identify plots')

        self.text_intro_revCal = QLabel('CALCULATE PLOT COORDINATES IN RAW IMAGES')
        self.text_intro_revCal.setAlignment(Qt.AlignCenter)
        self.text_pix4D = QLabel('Pix4D project folder:')
        self.button_pix4D = QPushButton('Choose')
        self.text_rawImgFold = QLabel('Raw images folder:')
        self.button_rawImgFold = QPushButton('Choose')
        self.button_apply_revCal = QPushButton('Apply')
        
        ## connections
        self.button_fieldImage.clicked.connect(self.fieldImage_clicked)
        self.button_drawField.clicked.connect(self.drawField_clicked)
        self.comboBox_screenSize.activated.connect(self.ScreenSizeFunction)
        self.button_getBinary.clicked.connect(self.getBinary_clicked)
        self.button_apply.clicked.connect(self.application)
        self.button_pix4D.clicked.connect(self.button_pix4D_clicked)
        self.button_rawImgFold.clicked.connect(self.button_rawImgFold_clicked)
        self.button_apply_revCal.clicked.connect(self.button_apply_revCal_clicked)
        
        ## options
        self.text_screenSize.hide()
        self.text_screenSize2.hide()
        self.comboBox_screenSize.hide()
        self.check_binary.hide()
        self.text_threshold.hide()
        self.text_threshold2.hide()
        self.spinbox_threshold.hide()
        self.text_noise.hide()
        self.spinbox_noise.hide()
        self.button_drawField.hide()
        self.text_imagePath.hide()
        self.text_image.hide()
        self.text_plot.hide()
        self.button_getBinary.hide()
        self.text_nbOfColumnPerPlot.hide()
        self.spinbox_nbOfColumnPerPlot.hide()
        self.text_nbOfRowPerPlot.hide()
        self.spinbox_nbOfRowPerPlot.hide()
        self.button_apply.hide()
        self.text_plotArrangment.hide()
        self.radio_horizontal.hide()
        self.radio_vertical.hide()
        self.text_intro_revCal.hide()
        self.text_pix4D.hide()
        self.button_pix4D.hide()
        self.text_rawImgFold.hide()
        self.button_rawImgFold.hide()
        self.button_apply_revCal.hide()
        
        ## layout
        self.layout = QGridLayout()
        self.layout.addWidget(self.text_intro, 1, 0, 1, -1)
        self.layout.addWidget(self.text_fieldImage, 2, 0)
        self.layout.addWidget(self.button_fieldImage, 2, 1, 1, -1)
        self.layout.addWidget(self.text_image, 3, 0)
        self.layout.addWidget(self.text_imagePath, 3, 1, 1, -1)
        self.layout.addWidget(self.check_binary, 4, 1, 1, -1)
        self.layout.addWidget(self.text_noise, 5, 0)
        self.layout.addWidget(self.spinbox_noise, 5, 1)
        self.layout.addWidget(self.text_screenSize, 6, 0)
        self.layout.addWidget(self.comboBox_screenSize, 6, 1)
        self.layout.addWidget(self.text_screenSize2, 6, 2, 1, 3)
        self.layout.addWidget(self.button_drawField, 7, 0, 1, -1)
        
        self.layout.addWidget(self.text_threshold, 8, 0)
        self.layout.addWidget(self.spinbox_threshold, 8, 1)
        self.layout.addWidget(self.text_threshold2, 8, 2, 1, -1)
        self.layout.addWidget(self.button_getBinary, 9, 0, 1, -1)
        
        self.layout.addWidget(self.text_plot,10, 0, 1, -1)
        self.layout.addWidget(self.text_nbOfRowPerPlot, 11, 0)
        self.layout.addWidget(self.spinbox_nbOfRowPerPlot, 11, 1, 1, -1)
        self.layout.addWidget(self.text_nbOfColumnPerPlot, 12, 0)
        self.layout.addWidget(self.spinbox_nbOfColumnPerPlot, 12, 1, 1, -1)
        self.layout.addWidget(self.text_plotArrangment, 13, 0)
        self.layout.addWidget(self.radio_horizontal, 13, 1)
        self.layout.addWidget(self.radio_vertical, 13, 2)
        self.layout.addWidget(self.button_apply, 14, 0, 1, -1)
        
        self.layout.addWidget(self.text_intro_revCal, 15, 0, 1, -1)
        self.layout.addWidget(self.text_pix4D, 16, 0)
        self.layout.addWidget(self.button_pix4D, 16, 1, 1, -1)
        self.layout.addWidget(self.text_rawImgFold, 17, 0)
        self.layout.addWidget(self.button_rawImgFold, 17, 1, 1, -1)
        self.layout.addWidget(self.button_apply_revCal, 18, 0, 1, -1)
        self.setLayout(self.layout)  
        
        self.show()


    def ScreenSizeFunction(self):
        """ This function is part of the class 'MainWindow'. \n
        It is linked to the change of the combo box self.comboBox_screenSize \n
        It decides the maximum size for the display of pictures depending on the
        inputted size of the screen """
        if self.comboBox_screenSize.currentText() == '1024 x 640 pixels':
            self.displaySize = 600
        if self.comboBox_screenSize.currentText() == '1280 x 800 pixels':
            self.displaySize = 800
        if self.comboBox_screenSize.currentText() == '1440 x 900 pixels':
            self.displaySize = 900
        if self.comboBox_screenSize.currentText() == '1680 x 1050 pixels':
            self.displaySize = 1000
        if self.comboBox_screenSize.currentText() == '2048 x 1152 pixels':
            self.displaySize = 1100
        if self.comboBox_screenSize.currentText() == '2560 x 1140 pixels':
            self.displaySize = 1100
        if self.comboBox_screenSize.currentText() == '3200 x 1800 pixels':
            self.displaySize = 1700

    def fieldImage_clicked(self):
        """ This function is part of the class 'MainWindow' \n
        It is connected to the button button_fieldImage and allows the user to
        chose the image of the whole field on which all the program is based"""
        self.field_image, _ = QFileDialog.getOpenFileName(self, "Select the field image", "",".tif or .tiff or .jpg or .jpeg or .png (*.tif *.tiff *.TIF *.TIFF *.jpg *.jpeg *.JPG *.JPEG *.PNG *.png)", options=QFileDialog.DontUseNativeDialog)
        self.field_image = Path(self.field_image)
        self.text_imagePath.setText(str(self.field_image))
        if self.field_image.is_file():
            self.check_binary.show()
            self.text_noise.show()
            self.spinbox_noise.show()
            self.text_imagePath.show()
            self.text_image.show()
            self.text_screenSize.show()
            self.text_screenSize2.show()
            self.comboBox_screenSize.show()
            self.button_drawField.show()
        else:
            self.check_binary.hide()
            self.text_noise.hide()
            self.spinbox_noise.hide()
            self.text_imagePath.hide()
            self.text_image.hide()
            self.text_screenSize.hide()
            self.text_screenSize2.hide()
            self.comboBox_screenSize.hide()
            self.button_drawField.hide()
        self.coord = []
        self.text_threshold.hide()
        self.text_threshold2.hide()
        self.spinbox_threshold.hide()
        self.button_getBinary.hide()
        self.text_plot.hide()
        self.text_nbOfRowPerPlot.hide()
        self.spinbox_nbOfRowPerPlot.hide()
        self.text_nbOfColumnPerPlot.hide()
        self.spinbox_nbOfColumnPerPlot.hide()
        self.button_apply.hide()
        self.text_plotArrangment.hide()
        self.radio_horizontal.hide()
        self.radio_vertical.hide()
        self.text_intro_revCal.hide()
        self.text_pix4D.hide()
        self.button_pix4D.hide()
        self.text_rawImgFold.hide()
        self.button_rawImgFold.hide()
        self.button_apply_revCal.hide()

    def drawField_clicked(self):
        """This function is part of the class 'MainWindow' \n
        It is connected to the button button_drawField and opens the beforehand
        chosen image of fieldImage_clicked into a new window so the user can
        select the field points as they wish. The image is then binarized using
        ExGreen calculation and cropped to avoid useless data storage"""
        
        # instructions
        QMessageBox.about(self, 'Information', "A drawing window will appear. \nTo (Q)uit without saving, press Q.\nTo (R)estart, press R. \nWhen you are (D)one, press D. \n\nPlease mark the corners of the field. \nNo need to close the polygon.")
        
        # initialization
        self.coord = []
        self.YN_binary = self.check_binary.isChecked()
        self.img = cv2.imread(str(self.field_image))
        img_name = self.field_image.stem
        WindowsName = 'Mark the corners of the field. (Q)uit  (R)estart  (D)one'
 
        # make a repository
        self.main_folder = self.field_image.parent / str('Micro_plots_' + img_name)
        if self.main_folder.is_dir():
            rmtree(self.main_folder, ignore_errors = True)
        try:
            self.main_folder.mkdir()   
        except PermissionError:
            QMessageBox.about(self, 'Information', "Previous results for this image already existed and have been erased.")
            self.main_folder.mkdir()   
        except FileExistsError:
            QMessageBox.about(self, 'Information', "Results for this image already exist. Please delete or rename it and try again.")
            return
        
        # resize the image according to the screen size 
        if len(self.img[:, 0]) >= len(self.img[0,:]) : #if the picture's height is bigger than its width 
            self.H = self.displaySize
            coeff = self.H/len(self.img[:, 0])
            self.W = int(coeff*len(self.img[0, :]))
        else: # if width is bigger than height
            self.W = self.displaySize
            coeff = self.W/len(self.img[0, :])
            self.H = int(coeff*len(self.img[:, 0]))
        self.img = cv2.resize(self.img, (self.W, self.H)) 
        
        # if binary is [0,1], map 1's to 255
        if np.amax(self.img) == 1 :
            self.img [self.img == 1] = 255

        # display the picture in a new window
        cv2.namedWindow(WindowsName) 
        cv2.setMouseCallback(WindowsName, self.draw_point, param = None)
        
        # events while drawing (infinite loop)
        while (1):
            # show the image window
            cv2.imshow(WindowsName, self.img)
            key = cv2.waitKey(20) & 0xFF
            
            # to restart the drawing
            if key == ord('r') or key == ord('R'): 
                # reload the original image (without any points on it)
                self.img = cv2.imread(str(self.field_image))
                self.img = cv2.resize(self.img, (self.W, self.H)) 
                cv2.namedWindow(WindowsName, cv2.WINDOW_NORMAL) # define the name of the window again
                cv2.setMouseCallback(WindowsName, self.draw_point, param = None) # call the function 
                self.coord = [] # do not save any coordinates

            # to exit and stop the drawing mode
            if key == ord('q') or key == ord('Q'):
                self.coord = [] # no pixels are saved
                QMessageBox.about(self, 'Information', "No corners were selected.")
                # close the window
                cv2.destroyAllWindows()
                cv2.waitKey(1)
                self.text_threshold.hide()
                self.text_threshold2.hide()
                self.spinbox_threshold.hide()
                self.button_getBinary.hide()
                self.text_plot.hide()
                self.text_nbOfRowPerPlot.hide()
                self.spinbox_nbOfRowPerPlot.hide()
                self.text_nbOfColumnPerPlot.hide()
                self.spinbox_nbOfColumnPerPlot.hide()
                self.button_apply.hide()
                self.text_plotArrangment.hide()
                self.radio_horizontal.hide()
                self.radio_vertical.hide()
                self.text_intro_revCal.hide()
                self.text_pix4D.hide()
                self.button_pix4D.hide()
                self.text_rawImgFold.hide()
                self.button_rawImgFold.hide()
                self.button_apply_revCal.hide()
                return
            
            # to finish the drawing and save the points drawn
            if key == ord('d') or key == ord('D'): 
                # field must be at least rectangular
                if len(self.coord) < 3:
                    QMessageBox.about(self, 'Information', "Please select at least 3 points. \nIf you want to escape, press 'e' key.")
                else: 
                    ## when done, saving the images and producing exG + binary images
                    # close the drawing with the last magenta line
                    cv2.line(self.img, self.coord[-1], self.coord[0], (255, 0, 255), 1)
                    cv2.imshow(WindowsName, self.img)
                    QMessageBox.about(self, 'Information', "Selected points are: \n" + str(self.coord) + '\n\nThe image will be processed. \nPress OK and wait a few seconds.')
                    # save the coordinate image
                    cv2.imwrite(str(self.main_folder / 'Field_points.jpg'), self.img)
                    cv2.destroyWindow(WindowsName)
                    self.img = get_drawn_image(self.field_image, self.coord, coeff)
                    
                    if self.YN_binary:
                        # get rid of the useless black pixels
                        coords = np.argwhere(self.img)
                        y0, x0 = coords.min(axis = 0)
                        y1, x1 = coords.max(axis = 0) + 1
                        self.img = self.img[y0:y1, x0:x1]
                        # apply the noise removal
                        B = (self.img != 0)
                        self.img_binary = morphology.remove_small_objects(B, min_size = int(self.noise))*255
                        # save binary image
                        cv2.imwrite(str(self.main_folder / 'Binary_image.tiff'), self.img_binary)
                        # save the value of cutted black parts for the end of the program (shp files)
                        self.y_offset, self.x_offset = y0, x0
        
                        self.text_plot.show()
                        self.text_nbOfRowPerPlot.show()
                        self.spinbox_nbOfRowPerPlot.show()
                        self.text_nbOfColumnPerPlot.show()
                        self.spinbox_nbOfColumnPerPlot.show()
                        self.button_apply.show()
                        self.text_plotArrangment.show()
                        self.radio_horizontal.show()
                        self.radio_vertical.show()
                        self.text_threshold.hide()
                        self.text_threshold2.hide()
                        self.spinbox_threshold.hide()
                        self.button_getBinary.hide()
                    else:
                        self.text_threshold.show()
                        self.text_threshold2.show()
                        self.spinbox_threshold.show()
                        self.button_getBinary.show()
                    self.text_intro_revCal.hide()
                    self.text_pix4D.hide()
                    self.button_pix4D.hide()
                    self.text_rawImgFold.hide()
                    self.button_rawImgFold.hide()
                    self.button_apply_revCal.hide()
                    return
                    
    def getBinary_clicked(self):
        """This function is part of the class 'MainWindow' \n
        It is connected to the button button_getBinary and opens the beforehand
        chosen image of fieldImage_clicked into a new window so the user can
        select the field points as they wish. The image is then binarized using
        ExGreen calculation and cropped to avoid useless data storage"""
        
        self.threshold = self.spinbox_threshold.value()
        self.noise = self.spinbox_noise.value()
        # get coordinates of the first non-black pixels
        coords = np.argwhere(self.img)
        try:
            y0, x0, z = coords.min(axis = 0)
            y1, x1, z = coords.max(axis = 0) + 1
            # generate a binary image
            self.img_exG, self.img_binary = get_binary(self.img, self.noise, self.threshold)
           # cut all images according to avoid useless black pixels
            self.img = self.img[y0:y1, x0:x1]
            self.img_exG = self.img_exG[y0:y1, x0:x1]
            self.img_binary = self.img_binary[y0:y1, x0:x1]
            # save outputs
            cv2.imwrite(str(self.main_folder / 'ExcessGreen.tiff'), self.img_exG)
            cv2.imwrite(str(self.main_folder / 'Field_area.tiff'), self.img)
             # show binary and ask to accept/reject
            QMessageBox.about(self, 'Information', "The binary will be displayed. \nTo (A)ccept it, press A.\nTo (R)etry with a different threshold, press R.")
            while (1):
                # show the image window
                self.img_binary_show = cv2.resize(self.img_binary, (self.W, self.H)) 
                cv2.imshow('Binary. (A)ccept  (R)etry', self.img_binary_show)
                key = cv2.waitKey(20) & 0xFF
                # to retry with different values
                if key == ord('r') or key == ord('R'): 
                    cv2.destroyAllWindows()
                    self.text_plot.hide()
                    self.text_nbOfRowPerPlot.hide()
                    self.spinbox_nbOfRowPerPlot.hide()
                    self.text_nbOfColumnPerPlot.hide()
                    self.spinbox_nbOfColumnPerPlot.hide()
                    self.button_apply.hide()
                    self.text_plotArrangment.hide()
                    self.radio_horizontal.hide()
                    self.radio_vertical.hide()
                    self.text_intro_revCal.hide()
                    self.text_pix4D.hide()
                    self.button_pix4D.hide()
                    self.text_rawImgFold.hide()
                    self.button_rawImgFold.hide()
                    self.button_apply_revCal.hide()
                    return
                if key == ord('a') or key == ord('A'): 
                    cv2.destroyAllWindows()
                    break
        except ValueError:
            QMessageBox.about(self, 'Information', "It seems that your image is already a binary. It will be treated as a binary for the rest of the program.")
            self.YN_binary == True
            y0, x0 = coords.min(axis = 0)
            y1, x1 = coords.max(axis = 0) + 1
            self.img = self.img[y0:y1, x0:x1]
            # apply the noise removal
            B = (self.img != 0)
            self.img_binary = morphology.remove_small_objects(B, min_size = int(self.noise))*255
        
        # save the value of cutted black parts for the end of the program (shp files)
        self.y_offset, self.x_offset = y0, x0
        
        # displays buttons useful for next steps
        self.text_plot.show()
        self.text_nbOfRowPerPlot.show()
        self.spinbox_nbOfRowPerPlot.show()
        self.text_nbOfColumnPerPlot.show()
        self.spinbox_nbOfColumnPerPlot.show()
        self.button_apply.show()
        self.text_plotArrangment.show()
        self.radio_horizontal.show()
        self.radio_vertical.show()
        self.text_intro_revCal.hide()
        self.text_pix4D.hide()
        self.button_pix4D.hide()
        self.text_rawImgFold.hide()
        self.button_rawImgFold.hide()
        self.button_apply_revCal.hide()
            
    def draw_point (self, event, x, y, flags, param):
        """ This function is part of the class 'MainWindow' and is used in the
        function 'drawField_clicked'. 
        It draws a red circle everytime the right
        button of the mouse is clicked down. If there is more than one point, a 
        magenta line will link the two latest points clicked.
        
        Inputs : 5
            event : mouth clicked down
            x : position on the x-axis
            y : position on the y-axis (going down)
            flags : 
            param : None [could pass a specific color if needed]
            """
        if event == cv2.EVENT_LBUTTONDOWN: 
            #when the button is pushed, the first pixel is recorded and a circle is drawn on the picture
            self.coord.append((int(x), int(y)))
            cv2.circle(self.img, (x,y), 6, (0, 0, 255), -1) #draw the circle
            if len(self.coord) > 1:
                cv2.line(self.img, self.coord[-2], self.coord[-1], (255, 0, 255), 1)
                
    def application(self):
        """ This function is part of the class 'MainWindow'.
        It is linked to the button 'button_apply' and starts the image 
        processing (i.e. clustering, cropping, *.shp files, reverse calculation) 
        """
        if self.radio_horizontal.isChecked() == False and self.radio_vertical.isChecked() == False:
            QMessageBox.about(self, 'Information', "Please indicate if the ranges are more vertically or horizontally oriented. \nIf no particular orientation stands out, choose any.")
        else:
            img_raster = rasterio.open(self.field_image)
            aff = img_raster.transform
            self.crs = img_raster.crs
            if type(self.crs) == type(None):
                aff = 0
            img_raster.close()
            nbRow = self.spinbox_nbOfRowPerPlot.value()
            nbColumn = self.spinbox_nbOfColumnPerPlot.value()
            if self.radio_horizontal.isChecked() == True:
                orientation = 'H'
            elif self.radio_vertical.isChecked() == True:
                orientation = 'V'
            # inform the user the program is finished

            output = MPE(self.img_binary, self.main_folder, self.img, self.YN_binary,
                nbRow, nbColumn, orientation, self.noise,
                self.field_image, aff, self.y_offset, self.x_offset)
        
            if output == '1':
                QMessageBox.about(self, 'Information', 'Sorry, no range has been detected. Please change the input parameters and retry.')
                self.text_intro_revCal.hide()
                self.text_pix4D.hide()
                self.button_pix4D.hide()
                self.text_rawImgFold.hide()
                self.button_rawImgFold.hide()
                self.button_apply_revCal.hide()
            if output == '2':
                QMessageBox.about(self, 'Information', 'Sorry, no row has been detected. Please change the input parameters and retry.')
                self.text_intro_revCal.hide()
                self.text_pix4D.hide()
                self.button_pix4D.hide()
                self.text_rawImgFold.hide()
                self.button_rawImgFold.hide()
                self.button_apply_revCal.hide()
            elif output == 'OK' :
                QMessageBox.about(self, 'Information', '''Micro-plot extraction finished!''')
                # if the original image is georeferenced
                if type(self.crs) != type(None):
                    # unlock inputs for reverse calculation
                    self.text_intro_revCal.show()
                    self.text_pix4D.show()
                    self.button_pix4D.show()
                    self.text_rawImgFold.show()
                    self.button_rawImgFold.show()
                    self.button_apply_revCal.show()
                else :
                    QMessageBox.about(self, 'Information', 'The original image is not georeferenced. Thus, reverse calculation cannot be performed.')
                # make sure everything is unchecked/back to the original value
                self.spinbox_nbOfRowPerPlot.setValue(1)
                self.spinbox_nbOfColumnPerPlot.setValue(1)
                self.radio_horizontal.setChecked(True)
                self.radio_vertical.setChecked(False)

    def button_pix4D_clicked(self):
        self.pix4D = QFileDialog.getExistingDirectory(self, "Select the pix4D project folder")
        self.pix4D = Path(self.pix4D)
        
    def button_rawImgFold_clicked(self):
        self.rawImgFold = QFileDialog.getExistingDirectory(self, "Select the raw images folder")
        self.rawImgFold = Path(self.rawImgFold)

    def button_apply_revCal_clicked(self):
        if self.pix4D is None or self.rawImgFold is None:
            QMessageBox.about(self, 'Error', 'There are missing parameters. Please make sure you provided all the inputs.')
        else :

            revCal_csv = ReverseCalculation(self.main_folder, self.pix4D, self.rawImgFold)
                        
            QMessageBox.about(self, 'Information', 'Reverse calculation finished! Output: ' + 
                              str(revCal_csv))
            self.pix4D = None
            self.rawImgFold = None
Beispiel #22
0
class UiManagerWindow(QWidget):
    def __init__(self, login):
        super().__init__()
        self.user = login
        self.admin = False
        self.ok = 0
        self.ip = "0.0.0.0:5555"
        self.sockIn = network.connect_InSocket(address='0.0.0.0', port=5556)
        self.sockOut = network.connect_OutSocket(address=self.ip.split(':')[0],
                                                 port=int(
                                                     self.ip.split(':')[1]))
        self.choosen_functional = ""
        self.login_admins, self.admins, self.banned_admin = [[], [], []]
        self.init_functional_buttons()
        self.initUI()
        self.hide_all_widgets()
        self.check_filter_country_on = False
        self.check_filter_city_on = False

    def check_filter_country_change(self):
        if self.check_filter_country_on:
            self.check_filter_country_on = False
        else:
            self.check_filter_country_on = True
        self.show_hotel_funtional()

    def check_filter_city_change(self):
        if self.check_filter_city_on:
            self.check_filter_city_on = False
        else:
            self.check_filter_city_on = True
        self.show_hotel_funtional()

    def send_to_server(self, msg):
        msg = json.dumps(msg)
        network.sock_send(self.sockOut, msg)
        try:
            self.sockIn.settimeout(2)
            data, address = network.read_sock(self.sockIn)
            self.sockIn.settimeout(None)
        except socket.timeout:
            self.info('Сервер отключен! Проверьте соединение', True)
            return "Error"
        msg = json.loads(data)
        return msg

    def disconnect_server(self):
        # network.sock_send(self.sockOut, json.dumps({"key": "login"}))
        network.alive = False
        network.close_sock(self.sockIn)
        network.close_sock(self.sockOut)

    def closeEvent(self, QCloseEvent):
        self.disconnect_server()

    def info(self, inf, is_bad):
        self.info_label.setText(
            f"Инфо: {inf} ({str(datetime.now().strftime('%Y-%m-%d %H:%M').split()[1])})"
        )
        self.info_label.resize(self.info_label.sizeHint())
        if is_bad:
            self.info_label.setStyleSheet('color: red')
        else:
            self.info_label.setStyleSheet('color: green')

    def initUI(self):
        self.setGeometry(400, 400, 900, 600)
        self.setWindowTitle('Система отеля (управляющий)')

        self.info_label = QLabel("Инфо:", self)
        self.info_label.move(150, 10)
        self.info_label.resize(self.info_label.sizeHint())
        self.info_label.setAutoFillBackground(True)
        p = self.info_label.palette()
        p.setColor(self.info_label.backgroundRole(), Qt.gray)
        self.info_label.setPalette(p)

        # Управление администраторами гостиницы

        self.login_of_admin_label = QLabel("Логин:", self)
        self.login_of_admin_label.move(10, 70)
        self.login_of_admin_label.resize(self.login_of_admin_label.sizeHint())

        self.login_of_admin_linde_edit = QLineEdit(self)
        self.login_of_admin_linde_edit.move(175, 70)
        self.login_of_admin_linde_edit.resize(200, 20)

        self.password_admin_label = QLabel("Пароль:", self)
        self.password_admin_label.move(10, 100)
        self.password_admin_label.resize(self.password_admin_label.sizeHint())

        self.password_admin_linde_edit = QLineEdit(self)
        self.password_admin_linde_edit.move(175, 100)
        self.password_admin_linde_edit.resize(200, 20)

        self.password_admin_linde_edit2 = QLineEdit(self)
        self.password_admin_linde_edit2.move(395, 100)
        self.password_admin_linde_edit2.resize(200, 20)

        self.suname_admin_label = QLabel("Фамилия:", self)
        self.suname_admin_label.move(10, 130)
        self.suname_admin_label.resize(self.suname_admin_label.sizeHint())

        self.suname_admin_linde_edit = QLineEdit(self)
        self.suname_admin_linde_edit.move(175, 130)
        self.suname_admin_linde_edit.resize(200, 20)

        self.suname_admin_linde_edit2 = QLineEdit(self)
        self.suname_admin_linde_edit2.move(395, 130)
        self.suname_admin_linde_edit2.resize(200, 20)

        self.name_admin_label = QLabel("Имя:", self)
        self.name_admin_label.move(10, 160)
        self.name_admin_label.resize(self.name_admin_label.sizeHint())

        self.name_admin_linde_edit = QLineEdit(self)
        self.name_admin_linde_edit.move(175, 160)
        self.name_admin_linde_edit.resize(200, 20)

        self.name_admin_linde_edit2 = QLineEdit(self)
        self.name_admin_linde_edit2.move(395, 160)
        self.name_admin_linde_edit2.resize(200, 20)

        self.otchestvo_admin_label = QLabel("Отчество:", self)
        self.otchestvo_admin_label.move(10, 190)
        self.otchestvo_admin_label.resize(
            self.otchestvo_admin_label.sizeHint())

        self.otchestvo_admin_linde_edit = QLineEdit(self)
        self.otchestvo_admin_linde_edit.move(175, 190)
        self.otchestvo_admin_linde_edit.resize(200, 20)

        self.otchestvo_admin_linde_edit2 = QLineEdit(self)
        self.otchestvo_admin_linde_edit2.move(395, 190)
        self.otchestvo_admin_linde_edit2.resize(200, 20)

        self.number_of_prhone_admin_label = QLabel("Номер телефона:", self)
        self.number_of_prhone_admin_label.move(10, 220)
        self.number_of_prhone_admin_label.resize(
            self.number_of_prhone_admin_label.sizeHint())

        self.number_of_prhone_admin_linde_edit = QLineEdit(self)
        self.number_of_prhone_admin_linde_edit.move(175, 220)
        self.number_of_prhone_admin_linde_edit.resize(200, 20)

        self.number_of_prhone_admin_linde_edit2 = QLineEdit(self)
        self.number_of_prhone_admin_linde_edit2.move(395, 220)
        self.number_of_prhone_admin_linde_edit2.resize(200, 20)

        self.hotel_admin_label = QLabel("Гостиница:", self)
        self.hotel_admin_label.move(10, 250)
        self.hotel_admin_label.resize(self.hotel_admin_label.sizeHint())

        self.hotel_admin_linde_edit = QLineEdit(self)
        self.hotel_admin_linde_edit.move(175, 250)
        self.hotel_admin_linde_edit.resize(200, 20)

        self.hotel_admin_linde_edit2 = QLineEdit(self)
        self.hotel_admin_linde_edit2.move(395, 250)
        self.hotel_admin_linde_edit2.resize(200, 20)

        self.admin_list = QComboBox(self)
        self.admin_list.move(390, 65)
        self.admin_list.resize(200, 30)
        self.admin_list.currentTextChanged.connect(self.update_admins)

        # self.admin_list.addItems()

        self.admin_list2 = QComboBox(self)
        self.admin_list2.move(600, 65)
        self.admin_list2.resize(200, 30)
        # self.admin_list2.addItems()

        self.add_admin = QPushButton("Зарегистрировать\nадминистратора", self)
        self.add_admin.move(175, 270)
        self.add_admin.resize(200, 50)
        self.add_admin.pressed.connect(self.addadmin)

        self.download_admin = QPushButton(
            "Загрузить xls файл\nс администраторами", self)
        self.download_admin.move(10, 350)
        self.download_admin.resize(200, 50)
        self.download_admin.pressed.connect(self.downoladadmin)

        self.delete_admin = QPushButton("Удалить администратора", self)
        self.delete_admin.move(600, 90)
        self.delete_admin.resize(200, 30)
        self.delete_admin.pressed.connect(self.deleteadmin)

        self.remake_admin = QPushButton(
            "Обновить информацию\nоб администраторе", self)
        self.remake_admin.move(395, 270)
        self.remake_admin.resize(200, 50)
        self.remake_admin.pressed.connect(self.change_info_admin)

        self.tableWidget_admin = QTableWidget(self)
        self.tableWidget_admin.setColumnCount(9)
        self.tableWidget_admin.move(250, 350)
        self.tableWidget_admin.resize(800, 200)
        self.tableWidget_admin.setHorizontalHeaderItem(
            0, QTableWidgetItem('логин'))
        self.tableWidget_admin.setHorizontalHeaderItem(
            1, QTableWidgetItem('пароль'))
        self.tableWidget_admin.setHorizontalHeaderItem(
            2, QTableWidgetItem('фамилия'))
        self.tableWidget_admin.setHorizontalHeaderItem(3,
                                                       QTableWidgetItem('имя'))
        self.tableWidget_admin.setHorizontalHeaderItem(
            4, QTableWidgetItem('отчество'))
        self.tableWidget_admin.setHorizontalHeaderItem(
            5, QTableWidgetItem('номер_телефона'))
        self.tableWidget_admin.setHorizontalHeaderItem(
            6, QTableWidgetItem('гостиница'))
        self.tableWidget_admin.setHorizontalHeaderItem(
            7, QTableWidgetItem('заблокирован'))
        self.tableWidget_admin.setHorizontalHeaderItem(
            8, QTableWidgetItem('причина_блокировки'))

        # Гостиница

        self.number_of_hotel_label = QLabel("Номер гостиницы в сети:", self)
        self.number_of_hotel_label.move(10, 70)
        self.number_of_hotel_label.resize(
            self.number_of_hotel_label.sizeHint())

        self.number_of_hotel_linde_edit = QLineEdit(self)
        self.number_of_hotel_linde_edit.move(175, 70)
        self.number_of_hotel_linde_edit.resize(200, 20)

        self.level_hotel_label = QLabel("Количество этажей:", self)
        self.level_hotel_label.move(10, 100)
        self.level_hotel_label.resize(self.level_hotel_label.sizeHint())

        self.level_hotel_linde_edit = QLineEdit(self)
        self.level_hotel_linde_edit.move(175, 100)
        self.level_hotel_linde_edit.resize(200, 20)

        self.level_hotel_linde_edit2 = QLineEdit(self)
        self.level_hotel_linde_edit2.move(395, 100)
        self.level_hotel_linde_edit2.resize(200, 20)

        self.room_hotel_label = QLabel("Количество номеров:", self)
        self.room_hotel_label.move(10, 130)
        self.room_hotel_label.resize(self.room_hotel_label.sizeHint())

        self.room_hotel_linde_edit = QLineEdit(self)
        self.room_hotel_linde_edit.move(175, 130)
        self.room_hotel_linde_edit.resize(200, 20)

        self.room_hotel_linde_edit2 = QLineEdit(self)
        self.room_hotel_linde_edit2.move(395, 130)
        self.room_hotel_linde_edit2.resize(200, 20)

        self.country_hotel_label = QLabel("Страна:", self)
        self.country_hotel_label.move(10, 160)
        self.country_hotel_label.resize(self.country_hotel_label.sizeHint())

        self.country_hotel_linde_edit = QLineEdit(self)
        self.country_hotel_linde_edit.move(175, 160)
        self.country_hotel_linde_edit.resize(200, 20)

        self.country_hotel_linde_edit2 = QLineEdit(self)
        self.country_hotel_linde_edit2.move(395, 160)
        self.country_hotel_linde_edit2.resize(200, 20)

        self.city_hotel_label = QLabel("Город:", self)
        self.city_hotel_label.move(10, 190)
        self.city_hotel_label.resize(self.city_hotel_label.sizeHint())

        self.city_hotel_linde_edit = QLineEdit(self)
        self.city_hotel_linde_edit.move(175, 190)
        self.city_hotel_linde_edit.resize(200, 20)

        self.city_hotel_linde_edit2 = QLineEdit(self)
        self.city_hotel_linde_edit2.move(395, 190)
        self.city_hotel_linde_edit2.resize(200, 20)

        self.street_hotel_label = QLabel("Улица:", self)
        self.street_hotel_label.move(10, 220)
        self.street_hotel_label.resize(self.street_hotel_label.sizeHint())

        self.street_hotel_linde_edit = QLineEdit(self)
        self.street_hotel_linde_edit.move(175, 220)
        self.street_hotel_linde_edit.resize(200, 20)

        self.street_hotel_linde_edit2 = QLineEdit(self)
        self.street_hotel_linde_edit2.move(395, 220)
        self.street_hotel_linde_edit2.resize(200, 20)

        self.house_hotel_label = QLabel("Дом:", self)
        self.house_hotel_label.move(10, 250)
        self.house_hotel_label.resize(self.house_hotel_label.sizeHint())

        self.house_hotel_linde_edit = QLineEdit(self)
        self.house_hotel_linde_edit.move(175, 250)
        self.house_hotel_linde_edit.resize(200, 20)

        self.house_hotel_linde_edit2 = QLineEdit(self)
        self.house_hotel_linde_edit2.move(395, 250)
        self.house_hotel_linde_edit2.resize(200, 20)

        self.hotels_list = QComboBox(self)
        self.hotels_list.move(390, 65)
        self.hotels_list.resize(200, 30)
        self.hotels_list.currentTextChanged.connect(self.update_hotels)
        #self.hotels_list.addItems()

        self.hotels_list2 = QComboBox(self)
        self.hotels_list2.move(600, 65)
        self.hotels_list2.resize(200, 30)
        # self.hotels_list2.addItems()

        self.add_hotel = QPushButton("Создать гостиницу", self)
        self.add_hotel.move(175, 270)
        self.add_hotel.resize(200, 30)
        self.add_hotel.pressed.connect(self.addhotel)

        self.delete_hotel = QPushButton("Удалить гостиницу", self)
        self.delete_hotel.move(600, 90)
        self.delete_hotel.resize(200, 30)
        self.delete_hotel.pressed.connect(self.deletehotel)

        self.remake_hotel = QPushButton("Редактировать гостиницу", self)
        self.remake_hotel.move(395, 270)
        self.remake_hotel.resize(200, 30)
        self.remake_hotel.pressed.connect(self.change_info_hotel)

        self.label_filter = QLabel("Фильтры:", self)
        self.label_filter.move(10, 350)
        self.label_filter.resize(self.label_filter.sizeHint())

        self.label_filter_country = QLabel("Страна:", self)
        self.label_filter_country.move(10, 380)
        self.label_filter_country.resize(self.label_filter.sizeHint())

        self.box_filter_country = QComboBox(self)
        self.box_filter_country.move(60, 375)
        self.box_filter_country.resize(100, 30)

        self.check_filter_country = QCheckBox(self)
        self.check_filter_country.move(170, 380)
        self.check_filter_country.resize(self.label_filter.sizeHint())
        self.check_filter_country.stateChanged.connect(
            self.check_filter_country_change)

        self.label_filter_city = QLabel("Город:", self)
        self.label_filter_city.move(10, 410)
        self.label_filter_city.resize(self.label_filter.sizeHint())

        self.box_filter_city = QComboBox(self)
        self.box_filter_city.move(60, 405)
        self.box_filter_city.resize(100, 30)

        self.check_filter_city = QCheckBox(self)
        self.check_filter_city.move(170, 410)
        self.check_filter_city.resize(self.label_filter.sizeHint())
        self.check_filter_city.stateChanged.connect(
            self.check_filter_city_change)

        # Блокировка

        self.admins_label = QLabel("Пользователи:", self)
        self.admins_label.move(20, 70)
        self.admins_label.resize(self.admins_label.sizeHint())

        self.admins_list = QComboBox(self)
        self.admins_list.move(115, 65)
        self.admins_list.resize(200, 30)
        self.admins_list.addItems(self.login_admins)

        self.button_block = QPushButton("Заблокировать пользователя", self)
        self.button_block.move(190, 100)
        self.button_block.resize(300, 30)
        self.button_block.pressed.connect(self.block_admin)

        self.prichina = QLabel("Причина:", self)
        self.prichina.move(330, 70)
        self.prichina.resize(self.prichina.sizeHint())

        self.prichina_line_edit = QLineEdit(self)
        self.prichina_line_edit.move(400, 68)
        self.prichina_line_edit.resize(200, 20)

        self.tableWidget_hotel = QTableWidget(self)
        self.tableWidget_hotel.setColumnCount(7)
        self.tableWidget_hotel.move(250, 350)
        self.tableWidget_hotel.resize(800, 200)
        self.tableWidget_hotel.setHorizontalHeaderItem(
            0, QTableWidgetItem('название гостиницы'))
        self.tableWidget_hotel.setHorizontalHeaderItem(
            1, QTableWidgetItem('количество этажей'))
        self.tableWidget_hotel.setHorizontalHeaderItem(
            2, QTableWidgetItem('количество номеров'))
        self.tableWidget_hotel.setHorizontalHeaderItem(
            3, QTableWidgetItem('страна'))
        self.tableWidget_hotel.setHorizontalHeaderItem(
            4, QTableWidgetItem('город'))
        self.tableWidget_hotel.setHorizontalHeaderItem(
            5, QTableWidgetItem('улица'))
        self.tableWidget_hotel.setHorizontalHeaderItem(6,
                                                       QTableWidgetItem('дом'))
        # неудачные попытки входа
        self.tableWidget_bt = QTableWidget(self)
        self.tableWidget_bt.setColumnCount(3)
        self.tableWidget_bt.move(10, 60)
        self.tableWidget_bt.resize(500, 400)
        self.tableWidget_bt.setHorizontalHeaderItem(0,
                                                    QTableWidgetItem('Логин'))
        self.tableWidget_bt.setHorizontalHeaderItem(1,
                                                    QTableWidgetItem('Пароль'))
        self.tableWidget_bt.setHorizontalHeaderItem(2,
                                                    QTableWidgetItem('Время'))

    def init_functional_buttons(self):
        self.label_functional = QLabel("Функционал:", self)
        self.label_functional.move(10, 10)
        self.label_functional.resize(self.label_functional.sizeHint())

        self.radio_button_1 = QRadioButton(
            "Управление администраторами гостиниц", self)
        self.radio_button_1.move(10, 30)

        self.radio_button_2 = QRadioButton("Гостиница", self)
        self.radio_button_2.move(310, 30)

        self.radio_button_3 = QRadioButton("Блокировка", self)
        self.radio_button_3.move(410, 30)

        self.radio_button_4 = QRadioButton("Просмотр неудачных попыток входа",
                                           self)
        self.radio_button_4.move(510, 30)

        self.button_group = QButtonGroup()
        self.button_group.addButton(self.radio_button_1)
        self.button_group.addButton(self.radio_button_2)
        self.button_group.addButton(self.radio_button_3)
        self.button_group.addButton(self.radio_button_4)
        self.button_group.buttonClicked.connect(self.choose)

    def choose(self, button):
        self.choosen_functional = button.text()
        self.hide_all_widgets()
        if self.choosen_functional == "Блокировка":
            self.show_block_funtional()
        elif self.choosen_functional == "Гостиница":
            self.show_hotel_funtional()
        elif self.choosen_functional == "Управление администраторами гостиниц":
            self.show_admin_funtional()
        elif self.choosen_functional == "Просмотр неудачных попыток входа":
            self.show_bad_try()

    def hide_all_widgets(self):
        self.admins_label.hide()
        self.admins_list.hide()
        self.button_block.hide()
        self.prichina.hide()
        self.prichina_line_edit.hide()

        self.label_filter.hide()
        self.number_of_hotel_label.hide()
        self.number_of_hotel_linde_edit.hide()
        self.level_hotel_label.hide()
        self.level_hotel_linde_edit.hide()
        self.room_hotel_label.hide()
        self.room_hotel_linde_edit.hide()
        self.country_hotel_label.hide()
        self.country_hotel_linde_edit.hide()
        self.city_hotel_label.hide()
        self.city_hotel_linde_edit.hide()
        self.street_hotel_label.hide()
        self.street_hotel_linde_edit.hide()
        self.house_hotel_label.hide()
        self.house_hotel_linde_edit.hide()
        self.remake_hotel.hide()
        self.delete_hotel.hide()
        self.add_hotel.hide()
        self.hotels_list2.hide()
        self.hotels_list.hide()
        self.level_hotel_linde_edit2.hide()
        self.room_hotel_linde_edit2.hide()
        self.country_hotel_linde_edit2.hide()
        self.city_hotel_linde_edit2.hide()
        self.street_hotel_linde_edit2.hide()
        self.house_hotel_linde_edit2.hide()
        self.tableWidget_hotel.hide()
        self.label_filter_country.hide()
        self.box_filter_country.hide()
        self.check_filter_country.hide()
        self.label_filter_city.hide()
        self.box_filter_city.hide()
        self.check_filter_city.hide()

        self.download_admin.hide()
        self.login_of_admin_label.hide()
        self.login_of_admin_linde_edit.hide()
        self.password_admin_label.hide()
        self.password_admin_linde_edit.hide()
        self.password_admin_linde_edit2.hide()
        self.suname_admin_label.hide()
        self.suname_admin_linde_edit.hide()
        self.suname_admin_linde_edit2.hide()
        self.name_admin_label.hide()
        self.name_admin_linde_edit.hide()
        self.name_admin_linde_edit2.hide()
        self.otchestvo_admin_label.hide()
        self.otchestvo_admin_linde_edit.hide()
        self.otchestvo_admin_linde_edit2.hide()
        self.number_of_prhone_admin_label.hide()
        self.number_of_prhone_admin_linde_edit.hide()
        self.number_of_prhone_admin_linde_edit2.hide()
        self.hotel_admin_label.hide()
        self.hotel_admin_linde_edit.hide()
        self.hotel_admin_linde_edit2.hide()
        self.admin_list.hide()
        self.admin_list2.hide()
        self.add_admin.hide()
        self.delete_admin.hide()
        self.remake_admin.hide()
        self.tableWidget_admin.hide()

        self.tableWidget_bt.hide()

    def show_hotel_funtional(self):
        answer = self.send_to_server({"key": 'hotels_download'})
        if answer != "Error":
            self.name_hotel, self.hotels = answer
            hotels = self.hotels
            if self.check_filter_country_on:
                hotels = [
                    i for i in hotels
                    if i[3] == self.box_filter_country.currentText()
                ]
            if self.check_filter_city_on:
                hotels = [
                    i for i in hotels
                    if i[4] == self.box_filter_city.currentText()
                ]
            self.tableWidget_hotel.show()
            self.tableWidget_hotel.setRowCount(len(hotels))
            for i in range(len(hotels)):
                for j in range(7):
                    itm = QTableWidgetItem(hotels[i][j])
                    itm.setFlags(QtCore.Qt.ItemIsEnabled)
                    self.tableWidget_hotel.setItem(i, j, itm)
            self.tableWidget_hotel.resizeColumnsToContents()
        self.hotels_list.clear()
        self.hotels_list.addItems(self.name_hotel)
        self.hotels_list2.clear()
        self.hotels_list2.addItems(self.name_hotel)
        self.box_filter_country.clear()
        self.box_filter_city.clear()
        self.box_filter_country.addItems([i[3] for i in self.hotels])
        self.box_filter_city.addItems([i[4] for i in self.hotels])
        hotel2 = "No"
        for i in self.hotels:
            if str(i[0]) == str(self.hotels_list.currentText()):
                hotel2 = i
        else:
            if hotel2 == "No":
                hotel2 = ['' for i in range(7)]
        hotel2 = [i if i else '' for i in hotel2]

        self.label_filter.show()
        self.label_filter_country.show()
        self.box_filter_country.show()
        self.check_filter_country.show()
        self.label_filter_city.show()
        self.box_filter_city.show()
        self.check_filter_city.show()
        self.number_of_hotel_label.show()
        self.number_of_hotel_linde_edit.show()
        self.level_hotel_label.show()
        self.level_hotel_linde_edit.show()
        self.room_hotel_label.show()
        self.room_hotel_linde_edit.show()
        self.country_hotel_label.show()
        self.country_hotel_linde_edit.show()
        self.city_hotel_label.show()
        self.city_hotel_linde_edit.show()
        self.street_hotel_label.show()
        self.street_hotel_linde_edit.show()
        self.house_hotel_label.show()
        self.house_hotel_linde_edit.show()
        self.remake_hotel.show()
        self.delete_hotel.show()
        self.add_hotel.show()
        self.hotels_list2.show()
        self.hotels_list.show()
        self.level_hotel_linde_edit2.show()
        self.level_hotel_linde_edit2.setText(str(hotel2[1]))
        self.room_hotel_linde_edit2.show()
        self.room_hotel_linde_edit2.setText(str(hotel2[2]))
        self.country_hotel_linde_edit2.show()
        self.country_hotel_linde_edit2.setText(str(hotel2[3]))
        self.city_hotel_linde_edit2.show()
        self.city_hotel_linde_edit2.setText(str(hotel2[4]))
        self.street_hotel_linde_edit2.show()
        self.street_hotel_linde_edit2.setText(str(hotel2[5]))
        self.house_hotel_linde_edit2.show()
        self.house_hotel_linde_edit2.setText(str(hotel2[6]))

    def show_admin_funtional(self):
        answer = self.send_to_server({"key": 'admin_download'})
        if answer != "Error":
            self.login_admins, self.admins, self.not_banned_admin = answer
            self.tableWidget_admin.show()
            self.tableWidget_admin.setRowCount(len(self.admins))
            for i in range(len(self.admins)):
                for j in range(9):
                    itm = QTableWidgetItem(self.admins[i][j])
                    itm.setFlags(QtCore.Qt.ItemIsEnabled)
                    self.tableWidget_admin.setItem(i, j, itm)
            self.tableWidget_admin.resizeColumnsToContents()
        self.admin_list2.clear()
        self.admin_list2.addItems(self.login_admins)
        self.admin_list.clear()
        self.admin_list.addItems(self.login_admins)
        admin = "No"
        for i in self.admins:
            if str(i[0]) == str(self.admin_list.currentText()):
                admin = i
        else:
            if admin == "No":
                admin = ['' for i in range(7)]
        admin = [i if i else '' for i in admin]

        self.login_of_admin_label.show()
        self.login_of_admin_linde_edit.show()
        self.password_admin_label.show()
        self.password_admin_linde_edit.show()
        self.password_admin_linde_edit2.show()
        self.password_admin_linde_edit2.setText(str(admin[1]))
        self.suname_admin_label.show()
        self.suname_admin_linde_edit.show()
        self.suname_admin_linde_edit2.show()
        self.suname_admin_linde_edit2.setText(str(admin[2]))
        self.name_admin_label.show()
        self.name_admin_linde_edit.show()
        self.name_admin_linde_edit2.show()
        self.name_admin_linde_edit2.setText(str(admin[3]))
        self.otchestvo_admin_label.show()
        self.download_admin.show()
        self.otchestvo_admin_linde_edit.show()
        self.otchestvo_admin_linde_edit2.show()
        self.otchestvo_admin_linde_edit2.setText(str(admin[4]))
        self.number_of_prhone_admin_label.show()
        self.number_of_prhone_admin_linde_edit.show()
        self.number_of_prhone_admin_linde_edit2.show()
        self.number_of_prhone_admin_linde_edit2.setText(str(admin[5]))
        self.hotel_admin_label.show()
        self.hotel_admin_linde_edit.show()
        self.hotel_admin_linde_edit2.show()
        self.hotel_admin_linde_edit2.setText(str(admin[6]))
        self.admin_list.show()
        self.admin_list2.show()
        self.add_admin.show()
        self.delete_admin.show()
        self.remake_admin.show()

    def addadmin(self):
        login = self.login_of_admin_linde_edit.text()
        password = self.password_admin_linde_edit.text()
        surname = self.suname_admin_linde_edit.text()
        name = self.name_admin_linde_edit.text()
        father_name = self.otchestvo_admin_linde_edit.text()
        number_of_phone = self.number_of_prhone_admin_linde_edit.text()
        hotel = self.hotel_admin_linde_edit.text()
        if login and password and surname and name and father_name and number_of_phone and hotel:
            admin = [
                login, password, surname, name, father_name, number_of_phone,
                hotel
            ]
            admin = "|||".join(admin)
            ok = self.send_to_server({"key": "add_admin", "login": admin})
            if ok:
                self.info("Администратор успешно зарегистрирован", False)
            else:
                self.info("Администратор не был зарегистрирован", True)
        else:
            self.info("Введенные данные некорректны", True)
        self.show_admin_funtional()

    def change_info_admin(self):
        login = self.admin_list.currentText()
        password = self.password_admin_linde_edit2.text()
        surname = self.suname_admin_linde_edit2.text()
        name = self.name_admin_linde_edit2.text()
        father_name = self.otchestvo_admin_linde_edit2.text()
        number_of_phone = self.number_of_prhone_admin_linde_edit2.text()
        hotel = self.hotel_admin_linde_edit2.text()
        if login and password and surname and name and father_name and number_of_phone and hotel:
            admin = [
                login, password, surname, name, father_name, number_of_phone,
                hotel
            ]
            admin = "|||".join(admin)
            ok = self.send_to_server({
                "key": "change_info_admin",
                "login": admin
            })
            if ok:
                self.info("Информация об администраторе успешно обновлена",
                          False)
            else:
                self.info("Информация об администраторе не обновлена", True)
        else:
            self.info("Введенные данные некорректны", True)
        self.show_admin_funtional()

    def addhotel(self):
        name = self.number_of_hotel_linde_edit.text()
        levels = self.level_hotel_linde_edit2.text()
        rooms = self.room_hotel_linde_edit2.text()
        country = self.country_hotel_linde_edit2.text()
        city = self.city_hotel_linde_edit2.text()
        street = self.street_hotel_linde_edit2.text()
        house = self.house_hotel_linde_edit2.text()
        if name and levels and rooms and country and city and street and house:
            hotel = [name, levels, rooms, country, city, street, house]
            hotel = "|||".join(hotel)
            ok = self.send_to_server({"key": "add_hotel", "name": hotel})
            if ok:
                self.info("Гостиница успешно добавлена", False)
            else:
                self.info("Гостиница не была добавлена", True)
        else:
            self.info("Введенные данные некорректны", True)
        self.show_hotel_funtional()

    def change_info_hotel(self):
        name = self.hotels_list.currentText()
        levels = self.level_hotel_linde_edit2.text()
        rooms = self.room_hotel_linde_edit2.text()
        country = self.country_hotel_linde_edit2.text()
        city = self.city_hotel_linde_edit2.text()
        street = self.street_hotel_linde_edit2.text()
        house = self.house_hotel_linde_edit2.text()
        if name and levels and rooms and country and city and street and house:
            hotel = [name, levels, rooms, country, city, street, house]
            hotel = "|||".join(hotel)
            ok = self.send_to_server({
                "key": "change_info_hotel",
                "name": hotel
            })
            if ok:
                self.info("Информация о гостинице успешно обновлена", False)
            else:
                self.info("Информация о гостинице не обновлена", True)
        else:
            self.info("Введенные данные некорректны", True)
        self.show_hotel_funtional()

    def block_admin(self):
        admin = self.admins_list.currentText()
        reason = self.prichina_line_edit.text()
        ok = self.send_to_server({
            "key": "ban_admin",
            "login": admin,
            "reason": reason
        })
        if ok:
            self.info("Пользователь успешно добавлен в список заблокированных",
                      False)
        else:
            self.info("Пользователь не добавлен в список заблокированных",
                      True)
        self.show_block_funtional()

    def deleteadmin(self):
        admin = self.admin_list2.currentText()
        ok = self.send_to_server({"key": "delete_admin", "login": admin})
        if ok:
            self.info("Администратор успешно удален", False)
        else:
            self.info("Администратор не удален", True)

        self.show_admin_funtional()

    def deletehotel(self):
        name = self.hotels_list2.currentText()
        rooms = self.send_to_server({"key": "rooms"})
        for i in rooms:
            if i[0] == name:
                self.info(
                    "Гостиница не удалена, так как она связана с номерами",
                    True)
                return

        ok = self.send_to_server({"key": "delete_hotel", "name": name})
        if ok:
            self.info("Гостиница успешно удалена", False)
        else:
            self.info("Гостиница не удалена", True)
        self.show_hotel_funtional()

    def show_block_funtional(self):
        answer = self.send_to_server({"key": 'admin_download'})
        if answer != "Error":
            self.login_admins, self.admins, self.not_banned_admin = answer
        self.admins_list.clear()
        self.admins_list.addItems(self.not_banned_admin)
        self.admins_label.show()
        self.admins_list.show()
        self.button_block.show()
        self.prichina.show()
        self.prichina_line_edit.show()

    def update_admins(self):
        admin = "No"
        for i in self.admins:
            if str(i[0]) == str(self.admin_list.currentText()):
                admin = i
        else:
            if admin == "No":
                admin = ['' for i in range(7)]
        admin = [i if i else '' for i in admin]
        self.password_admin_linde_edit2.setText(str(admin[1]))
        self.suname_admin_linde_edit2.setText(str(admin[2]))
        self.name_admin_linde_edit2.setText(str(admin[3]))
        self.otchestvo_admin_linde_edit2.setText(str(admin[4]))
        self.number_of_prhone_admin_linde_edit2.setText(str(admin[5]))
        self.hotel_admin_linde_edit2.setText(str(admin[6]))

    def update_hotels(self):
        hotel2 = "No"
        for i in self.hotels:
            if str(i[0]) == str(self.hotels_list.currentText()):
                hotel2 = i
        else:
            if hotel2 == "No":
                hotel2 = ['' for i in range(7)]
        hotel2 = [i if i else '' for i in hotel2]
        self.level_hotel_linde_edit2.setText(str(hotel2[1]))
        self.room_hotel_linde_edit2.setText(str(hotel2[2]))
        self.country_hotel_linde_edit2.setText(str(hotel2[3]))
        self.city_hotel_linde_edit2.setText(str(hotel2[4]))
        self.street_hotel_linde_edit2.setText(str(hotel2[5]))
        self.house_hotel_linde_edit2.setText(str(hotel2[6]))

    def downoladadmin(self):
        location = QFileDialog.getOpenFileName(self, 'Open file')[0]
        try:
            admins = read_info_about_administrators(location)
        except:
            self.info("Возникла ошибка при загрузке данных", True)
            return
        oks = []
        for i in admins:
            if all(i):
                admin = "|||".join(i)
                ok = self.send_to_server({"key": "add_admin", "login": admin})
                oks.append(ok)
        if all(oks):
            self.info("Информация загружена успешна", False)
        else:
            self.info("Не вся информация была загружена", True)
        self.show_admin_funtional()

    def show_bad_try(self):
        answer = self.send_to_server({"key": 'bad_try_download'})
        if answer != "Error":
            self.bad_try = answer
            self.tableWidget_bt.show()
            self.tableWidget_bt.setRowCount(len(self.bad_try))
            for i in range(len(self.bad_try)):
                for j in range(3):
                    itm = QTableWidgetItem(self.bad_try[i][j])
                    itm.setFlags(QtCore.Qt.ItemIsEnabled)
                    self.tableWidget_bt.setItem(i, j, itm)
            self.tableWidget_bt.resizeColumnsToContents()
class MainView(base, form):
    def __init__(self, pipeline, parent=None):

        super(base, self).__init__(parent)
        self.setupUi(self)
        self.pipeline = pipeline
        self.pip_widgets = []
        self.default_pips = []

        self.draw_ui()
        self.connect_ui()

    def register_observers(self):
        pass

    def connect_ui(self):
        """
        This function connects the ui using signals from the
        ui elements and its method counterparts.
        """
        self.input_btn.clicked.connect(self.set_input_url)
        self.output_btn.clicked.connect(self.set_output_url)
        self.save_btn.clicked.connect(self.save_pipeline)
        self.load_favorite_pipelines()
        self.fav_pips_combo_box.activated.connect(self.select_default_pip)
        self.run_btn.clicked.connect(self.run)
        self.delete_btn.clicked.connect(self.trash_pipeline)
        self.add_btn.clicked.connect(lambda: self.add_pipe_entry_new())

    def draw_ui(self):
        """
        This function draws all additional UI elements. If you want the
        application to display any additional things like a button you can
        either add it in the QtDesigner or declare it here.
        """

        # *TODO* Create these ones with Qt Designer and put them into select_cat_alg_vbox_layout. I failed
        self.ComboxCategories = QComboBox()
        self.stackedWidgetComboxesAlgorithms = QStackedWidget()
        self.select_cat_alg_vbox_layout.addWidget(self.ComboxCategories)
        self.select_cat_alg_vbox_layout.addWidget(self.stackedWidgetComboxesAlgorithms)
        self.ComboxCategories.hide()


        """
        This function is concerned with drawing all non static elements  into the
        GUI.
        """
        """self.set_pip_title("A. Junius2")

        self.set_preset(["A.Junius", "test", "test", "test"])


        self.add_pip_entry("../assets/images/P.png", "Preprocessing - adaptive trehsold watershed")
        self.add_pip_entry("../assets/images/P.png", "Preprocessing - adaptive trehsold watershed")
        self.add_pip_entry("../assets/images/P.png", "Preprocessing - adaptive trehsold watershed")
        self.add_pip_entry("../assets/images/P.png", "Preprocessing - adaptive trehsold watershed")
        self.add_pip_entry("../assets/images/P.png", "Preprocessing - adaptive trehsold watershed")
        self.add_pip_entry("../assets/images/P.png", "Preprocessing - adaptive trehsold watershed")
        self.add_pip_entry("../assets/images/P.png", "Preprocessing - adaptive trehsold watershed")
        self.add_cat_image("../assets/images/seg_fav.jpeg", "Preprocessing")
        self.add_cat_image("../assets/images/wing.jpeg", "Preprocessing")
        self.add_cat_image("../assets/images/wing.jpeg", "Preprocessing")
        self.add_cat_image("../assets/images/wing.jpeg", "Preprocessing")
        self.add_cat_image("../assets/images/wing.jpeg", "Preprocessing")
        self.add_cat_image("../assets/images/wing.jpeg", "Preprocessing")
        self.add_cat_image("../assets/images/wing.jpeg", "Preprocessing")

        self.main_image_label.setPixmap(QtGui.QPixmap("wing.jpeg"))

        category_combo_box = ComboBoxWidget("type")
        category_combo_box.add_item("Preprocessing", "../assets/images/P.png")
        category_combo_box.add_item("Segmentation", "../assets/images/S.png")
        category_combo_box.add_item("Graph Detection", "../assets/images/D.png")
        category_combo_box.add_item("Graph Filtering", "../assets/images/F.png")

        alg_combo_box = ComboBoxWidget("algorithm")
        alg_combo_box.add_item("Otsus")
        alg_combo_box.add_item("Guo Hall")
        alg_combo_box.add_item("Adaptive Treshold")

        slider_1 = SliderWidget("slider1das", 0, 10, 1, 4, True)
        slider_2 = SliderWidget("slider1", 0, 10, 2, 4, False)
        slider_3 = SliderWidget("sliderböadsad", 0, 10, 1, 4, True)
        slider_4 = SliderWidget("sliderböadsad", 0, 10, 1, 4, True)
        slider_5 = SliderWidget("sliderböadsad", 0, 10, 1, 4, True)
        checkbox_1 = CheckBoxWidget("checkbox1", True)

        self.setting_widget_vbox_layout.addWidget(category_combo_box)
        self.setting_widget_vbox_layout.addWidget(alg_combo_box)
        self.setting_widget_vbox_layout.addWidget(slider_1)
        self.setting_widget_vbox_layout.addWidget(slider_2)
        self.setting_widget_vbox_layout.addWidget(slider_3)
        self.setting_widget_vbox_layout.addWidget(slider_4)
        self.setting_widget_vbox_layout.addWidget(slider_5)
        self.setting_widget_vbox_layout.addWidget(checkbox_1)
        self.setting_widget_vbox_layout.setAlignment(Qt.AlignTop)"""

    def set_pip_title(self, title):
        """
        Sets the title of the current selected pipeline in the ui.

        Args:
            | *title*: the title of the pipeline
            | *label_ref*: the reference to the label.
        """
        self.current_pip_label.setText(title)

    def load_dark_theme(self, application):
        """
        This function is called to load the white theme with
        all its icons for the buttons and the css file.
        Args:
            application: the cureent app instance
        """
        # load buttons
        pixmap_icon = QtGui.QPixmap("./assets/images/add_white.png")
        q_icon = QtGui.QIcon(pixmap_icon)
        self.add_btn.setIcon(q_icon)

        pixmap_icon = QtGui.QPixmap("./assets/images/trash_white.png")
        q_icon = QtGui.QIcon(pixmap_icon)
        self.delete_btn.setIcon(q_icon)

        pixmap_icon = QtGui.QPixmap("./assets/images/diskette_white.png")
        q_icon = QtGui.QIcon(pixmap_icon)
        self.save_btn.setIcon(q_icon)

        pixmap_icon = QtGui.QPixmap("./assets/images/up-arrow_white.png")
        q_icon = QtGui.QIcon(pixmap_icon)
        self.input_btn.setIcon(q_icon)

        pixmap_icon = QtGui.QPixmap("./assets/images/folder_white.png")
        q_icon = QtGui.QIcon(pixmap_icon)
        self.output_btn.setIcon(q_icon)

    @pyqtSlot(int)
    def select_default_pip(self, index):
        """
        This is the slot for the Pipeline combobox in the ui
        Args:
            index: index of the option currently selected
        """

        # delete current pipeline

        self.trash_pipeline()

        # get url and name
        name, url = self.default_pips[index - 1]

        # parse the json in the model
        self.pipeline.load_pipeline_json(url)

        print("PARSER" + str(self.pipeline.executed_cats[0].active_algorithm))
        print("PARSER" + str(self.pipeline.executed_cats[1].active_algorithm))

        # set the title
        self.set_pip_title(name)

        # Create an entry in the pipeline widget for every step in the pipeline
        for i in range(0, len(self.pipeline.executed_cats)):
            self.add_pipe_entry_new(i)
            self.scroll_down_pip()

            """for widget in alg_widgets:
                self.setting_widget_vbox_layout.addWidget(widget)"""

    def trash_pipeline(self):
        """
        This method clears the complete pipeline while users clicked the trash
        button.
        """
        # remove all entries in the pipeline list

        while self.pip_widget_vbox_layout.count():
            child = self.pip_widget_vbox_layout.takeAt(0)
            child.widget().deleteLater()

        while self.stackedWidget_Settings.currentWidget() is not None:
            self.stackedWidget_Settings.removeWidget(self.stackedWidget_Settings.currentWidget())
            self.settings_collapsable.setTitle("")

        # remove the pipeline name
        self.set_pip_title("")

        # remove all entries int the executed_cats of the model pipeline
        del self.pipeline.executed_cats[:]

        # remove all widgets
        del self.pip_widgets[:]

        # remove category algorith dropdown
        self.remove_cat_alg_dropdown()

        # remove all entries from the pipeline model

        del self.pipeline.executed_cats[:]

    @pyqtSlot()
    def run(self):
        """
        This method runs the the pipeline by calling the process methode
        in pipeline
        """

        self.pipeline.process()

    @pyqtSlot()
    def set_input_url(self):
        """
        This method sets the url for the input image in the pipeline.
        """
        url = QtWidgets.QFileDialog.getOpenFileNames()
        if url[0]:
            print(url[0])
            print(url[0][0])
            self.lineEdit.setText(url[0][0])
            self.pipeline.set_input(url[0][0])


    @pyqtSlot()
    def set_output_url(self):
        """
        This method sets the url for the output folder in the pipeline.
        Args:
            url: the url to the output folder a user selected in the ui
        """
        url = QtWidgets.QFileDialog.getExistingDirectory()
        if url:
            print(url)
            print(url)
            self.custom_line_edit.setText(url)
            self.pipeline.set_output_dir(url)

    def load_favorite_pipelines(self):
        """
        Scans the directory for default pipelines to display all available items
        """
        self.fav_pips_combo_box.addItem("Please Select")

        # scan the directory for default pipelines
        for file in os.listdir("./_default_pipelines"):
            if file.endswith(".json"):
                name = file.split(".")[0]
                url = os.path.abspath("./_default_pipelines" + "/" + file)
                self.default_pips.append([name, url])
                self.fav_pips_combo_box.addItem(name)

    @pyqtSlot()
    def save_pipeline(self):
        """
        Saves the pipeline as a json at the users file system.
        """
        url = str(QtWidgets.QFileDialog.getSaveFileName()[0])

        split_list = url.split("/")
        name = split_list[len(split_list) - 1].split(".")[0]
        del split_list[len(split_list) - 1]
        url = url.replace(name, "")
        self.pipeline.save_pipeline_json(name, url)

    @pyqtSlot(int)
    def remove_pip_entry(self, pipe_entry_widget, settings_widget, cat=None):
        """
        Removes the pip entry at the given position in the ui
        Args:
            pipeline_index (object):
            settings_widget:
            position: position at which the pip entry gets removed
        """

        # remove pipeline entry widget from ui
        self.pip_widget_vbox_layout.removeWidget(pipe_entry_widget)
        pipe_entry_widget.deleteLater()

        # remove it settings widgets from ui
        if settings_widget is not None:
            if self.stackedWidget_Settings.currentWidget() == settings_widget:
                self.stackedWidget_Settings.hide()
                self.remove_cat_alg_dropdown()
                self.settings_collapsable.setTitle("Settings")

            self.stackedWidget_Settings.removeWidget(settings_widget)

        # remove in model
        if cat is not None:
            print("Remove entry at pos " + str(self.pipeline.get_index(cat)) + " " + str(cat))
            self.pipeline.delete_category(self.pipeline.get_index(cat))

    def change_pip_entry_alg(self, position, new_category, new_algorithm, pipe_entry_widget, settings_widget):
        """
        Changes the selected algorithm of the pipeline entry at the position.
        Afterwards create all widgets for this algorithm instance
        Args:
            position: the position of the pipeline entry
            algorithm: the selected algorithm for this category
        """
        print("Position to be changed:" + str(position))
        print("Pipeline length: " + str(len(self.pipeline.executed_cats)))

        old_cat = self.pipeline.executed_cats[position]
        old_alg = old_cat.active_algorithm
        print("Old Cat found in pipeline: " + str(old_cat))
        print("Old Alg: found in pipeline:" + str(old_alg))

        print("New Category given:" + str(new_category))
        print("New Algorithm given:" + str(new_algorithm))

        # set in model
        self.pipeline.change_category(new_category, position)
        self.pipeline.change_algorithm(new_algorithm, position)

        new_cat = self.pipeline.executed_cats[position]
        new_alg = new_cat.active_algorithm

        # change settings widgets
        self.remove_pip_entry(pipe_entry_widget, settings_widget)
        (new_pipe_entry_widget, new_settings_widget) = self.add_pipe_entry_new(position)

        self.stackedWidget_Settings.show()
        self.stackedWidget_Settings.setCurrentIndex(position)
        self.settings_collapsable.setTitle(new_alg.get_name() + " Settings")

        self.remove_cat_alg_dropdown()
        self.create_cat_alg_dropdown(position, new_pipe_entry_widget, new_settings_widget)
        self.set_cat_alg_dropdown(new_cat, new_alg)


        print("New Cat found in pipeline: " + str(new_cat))
        print("New Alg found in pipeline: " + str(new_alg))


    def load_settings_widgets_from_pipeline_groupbox(self, position):
        """
        Extracts all widgets from a single algorithm and returns a QBoxLayout
        Args:
            alg: the alg instance we extract from

        Returns: a QBoxLayout containing all widgets for this particular alg.

        """

        alg = self.pipeline.executed_cats[position].active_algorithm

        print("alg " + str(alg))
        print("cat " + str(self.pipeline.executed_cats[position]))

        empty_flag = True

        groupOfSliders = QGroupBox()
        sp = QSizePolicy()
        sp.setVerticalPolicy(QSizePolicy.Preferred)
        # groupOfSliders.setSizePolicy(sp)
        groupOfSliderssLayout = QBoxLayout(QBoxLayout.TopToBottom)
        groupOfSliderssLayout.setContentsMargins(0, -0, -0, 0)
        groupOfSliderssLayout.setAlignment(Qt.AlignTop)
        groupOfSliderssLayout.setSpacing(0)

        print("Build Slider @ "+ str(position))

        # create integer sliders
        for slider in alg.integer_sliders:
            empty_flag = False
            print("slider.value " + str(slider.value))
            print("slider " + str(slider))
            #print(alg.get_name() + ": add slider (int).")
            groupOfSliderssLayout.addWidget(
                SliderWidget(slider.name, slider.lower, slider.upper, slider.step_size, slider.value,
                             slider.set_value, False))

        # create float sliders
        for slider in alg.float_sliders:
            empty_flag = False
            #print(alg.get_name() + ": add slider (float).")
            groupOfSliderssLayout.addWidget(
                SliderWidget(slider.name, slider.lower, slider.upper, slider.step_size, slider.value,
                             slider.set_value, True), 0, Qt.AlignTop)

        # create checkboxes
        for checkbox in alg.checkboxes:
            empty_flag = False
            #print(alg.get_name() + ": add checkbox.")
            groupOfSliderssLayout.addWidget(CheckBoxWidget(checkbox.name, checkbox.value, checkbox.set_value), 0,
                                            Qt.AlignTop)

        # create dropdowns
        for combobox in alg.drop_downs:
            empty_flag = False
            #print(alg.get_name() + ": add combobox.")
            groupOfSliderssLayout.addWidget(
                ComboBoxWidget(combobox.name, combobox.options, combobox.set_value, combobox.value), 0, Qt.AlignTop)

        if empty_flag:
            label = QLabel()
            label.setText("This algorithm has no Settings.")
            groupOfSliderssLayout.addWidget(label, 0, Qt.AlignHCenter)

        groupOfSliders.setLayout(groupOfSliderssLayout)

        return groupOfSliders

    def create_cat_alg_dropdown(self, cat_position, pipe_entry_widget, settings_widget):

        """
        Args:
            last_cat (object):
        """
        layout = self.select_cat_alg_vbox_layout
        cat = self.pipeline.executed_cats[cat_position]

        last_cat = None

        # Show only allowed categories in dropdown
        if len(self.pipeline.executed_cats) > 1:
            last_cat = self.pipeline.executed_cats[cat_position - 1]

        # Combobox for selecting Category
        self.ComboxCategories.show()
        self.ComboxCategories.setFixedHeight(30)
        self.ComboxCategories.addItem("<Please Select Category>")

        self.stackedWidgetComboxesAlgorithms = QStackedWidget()
        self.stackedWidgetComboxesAlgorithms.setFixedHeight(30)
        self.stackedWidgetComboxesAlgorithms.hide()

        def setCurrentIndexCat(index):
            #print("Set Cat")
            if self.ComboxCategories.currentIndex() == 0:
                self.stackedWidgetComboxesAlgorithms.hide()
            else:
                self.stackedWidgetComboxesAlgorithms.show()
                self.stackedWidgetComboxesAlgorithms.setCurrentIndex(index - 1)

        for category_name in self.pipeline.report_available_cats(last_cat):

            # Add Category to combobox
            self.ComboxCategories.addItem(category_name)
            tmp1 = QComboBox()
            tmp1.addItem("<Please Select Algorithm>")
            tmp1.setFixedHeight(30)
            category = self.pipeline.get_category(category_name)
            #self.current_index = -1

            def setCurrentIndexAlg(index):
                if self.ComboxCategories.currentIndex() == 0 or self.stackedWidgetComboxesAlgorithms.currentWidget().currentIndex() == 0:
                    pass
                else: #self.current_index != index:
                    self.change_pip_entry_alg(self.pipeline.get_index(cat), self.ComboxCategories.currentText(),
                                              self.stackedWidgetComboxesAlgorithms.currentWidget().currentText(),
                                              pipe_entry_widget, settings_widget)
                    #self.current_index = index

            tmp1.activated.connect(setCurrentIndexAlg)

            for algorithm_name in self.pipeline.get_all_algorithm_list(category):
                tmp1.addItem(algorithm_name)

            self.stackedWidgetComboxesAlgorithms.addWidget(tmp1)

        layout.addWidget(self.ComboxCategories)
        layout.addWidget(self.stackedWidgetComboxesAlgorithms)

        self.ComboxCategories.activated.connect(setCurrentIndexCat)

    def set_cat_alg_dropdown(self, category, algorithm):

        indexC = self.ComboxCategories.findText(category.get_name())
        #print("IndexC " + str(indexC))
        self.ComboxCategories.setCurrentIndex(indexC)
        self.stackedWidgetComboxesAlgorithms.show()
        self.stackedWidgetComboxesAlgorithms.setCurrentIndex(indexC - 1)
        indexA = self.stackedWidgetComboxesAlgorithms.currentWidget().findText(algorithm.get_name())
        #print("IndexA " + str(indexA))
        self.stackedWidgetComboxesAlgorithms.currentWidget().setCurrentIndex(indexA)

    def remove_cat_alg_dropdown(self):

        """

        Returns:
            object:
        """
        self.ComboxCategories.clear()

        while self.stackedWidgetComboxesAlgorithms.currentWidget() is not None:
            self.stackedWidgetComboxesAlgorithms.removeWidget(self.stackedWidgetComboxesAlgorithms.currentWidget())

        while self.select_cat_alg_vbox_layout.count():
            child = self.select_cat_alg_vbox_layout.takeAt(0)
            child.widget().hide()

    def scroll_down_pip(self):
        self.pip_scroll.verticalScrollBar().setSliderPosition(self.pip_scroll.verticalScrollBar().maximum())

    def add_pipe_entry_new(self, position=None):
        """
            Creates a entry in the ui pipeline with a given position in pipeline.
            It also creates the corresponding settings widget.
            """
        # create an widget that displays the pip entry in the ui and connect the remove button

        pip_main_widget = QWidget()
        pip_main_widget.setFixedHeight(70)
        pip_main_widget.setFixedWidth(300)
        pip_main_layout = QHBoxLayout()
        pip_main_widget.setLayout(pip_main_layout)

        new_marker = False

        if position is None:
            position = len(self.pipeline.executed_cats)
            cat = self.pipeline.new_category(position)
            label = "<Click to specify new step>"
            icon = None
            new_marker = True
        else:
            cat = self.pipeline.executed_cats[position]
            alg = cat.active_algorithm
            label = alg.get_name()
            icon = cat.get_icon()
            new_marker = False

        pixmap = QPixmap(icon)
        pixmap_scaled_keeping_aspec = pixmap.scaled(30, 30, QtCore.Qt.KeepAspectRatio)
        pixmap_label = QtWidgets.QLabel()
        pixmap_label.setPixmap(pixmap_scaled_keeping_aspec)

        pip_up_down = QWidget()
        pip_up_down.setFixedHeight(70)
        pip_up_down_layout = QVBoxLayout()
        pip_up_down.setLayout(pip_up_down_layout)

        up_btn = QToolButton()
        dw_btn = QToolButton()

        up_btn.setArrowType(Qt.UpArrow)
        up_btn.setFixedHeight(25)
        dw_btn.setArrowType(Qt.DownArrow)
        dw_btn.setFixedHeight(25)

        pip_up_down_layout.addWidget(up_btn)
        pip_up_down_layout.addWidget(dw_btn)

        string_label = QLabel()
        string_label.setText(label)
        string_label.setFixedWidth(210)

        btn = QtWidgets.QPushButton()
        btn.setFixedSize(20, 20)

        pixmap_icon = QtGui.QPixmap("./assets/images/delete_x_white.png")
        q_icon = QtGui.QIcon(pixmap_icon)
        btn.setIcon(q_icon)

        pip_main_layout.addWidget(pip_up_down, Qt.AlignVCenter)
        pip_main_layout.addWidget(pixmap_label, Qt.AlignVCenter)
        pip_main_layout.addWidget(string_label, Qt.AlignLeft)
        pip_main_layout.addWidget(btn, Qt.AlignVCenter)

        self.pip_widget_vbox_layout.insertWidget(position, pip_main_widget)

        # Create the corresponding settings widget and connect it
        self.settings_collapsable.setTitle("Settings")
        self.stackedWidget_Settings.hide()
        settings_main_widget = None
        if not new_marker:
            settings_main_widget = self.load_settings_widgets_from_pipeline_groupbox(position)
            self.stackedWidget_Settings.insertWidget(position, settings_main_widget)

        def show_settings():
            # Set background color while widget is selected. Doesn't work because of theme? *TODO*
            p = pip_main_widget.palette()
            p.setColor(pip_main_widget.backgroundRole(), Qt.red)
            pip_main_widget.setPalette(p)

            if not new_marker:
                self.stackedWidget_Settings.show()
                self.stackedWidget_Settings.setCurrentIndex(self.pipeline.get_index(cat))
                self.settings_collapsable.setTitle(alg.get_name() + " Settings")
            else:
                self.stackedWidget_Settings.hide()

            # Create drop down for cats and algs
            self.remove_cat_alg_dropdown()
            self.create_cat_alg_dropdown(self.pipeline.get_index(cat), pip_main_widget, settings_main_widget)

            if not new_marker:
                self.set_cat_alg_dropdown(cat, alg)

        # Connect Button to remove step from pipeline
        def delete_button_clicked():
            self.remove_cat_alg_dropdown()
            self.remove_pip_entry(pip_main_widget, settings_main_widget, cat)

        self.clickable(pixmap_label).connect(show_settings)
        self.clickable(string_label).connect(show_settings)
        btn.clicked.connect(delete_button_clicked)


        return (pip_main_widget, settings_main_widget)



    def add_pip_entry_empty(self):
        """
        Creates an blank entry in the ui pipeline since the user still needs to specify
        a type and an algorithm of the category.
        It also creates the corresponding settings widget.
        """
        # create an widget that displays the pip entry in the ui and connect the remove button
        pip_main_widget = QWidget()
        pip_main_widget.setFixedHeight(70)
        pip_main_widget.setFixedWidth(300)
        pip_main_layout = QHBoxLayout()
        pip_main_widget.setLayout(pip_main_layout)

        label = "<Click to specify new step>"
        icon = None

        pixmap = QPixmap(icon)
        pixmap_scaled_keeping_aspec = pixmap.scaled(30, 30, QtCore.Qt.KeepAspectRatio)
        pixmap_label = QtWidgets.QLabel()
        pixmap_label.setPixmap(pixmap_scaled_keeping_aspec)

        pip_up_down = QWidget()
        pip_up_down.setFixedHeight(70)
        pip_up_down_layout = QVBoxLayout()
        pip_up_down.setLayout(pip_up_down_layout)

        up_btn = QToolButton()
        dw_btn = QToolButton()

        up_btn.setArrowType(Qt.UpArrow)
        up_btn.setFixedHeight(25)
        dw_btn.setArrowType(Qt.DownArrow)
        dw_btn.setFixedHeight(25)

        pip_up_down_layout.addWidget(up_btn)
        pip_up_down_layout.addWidget(dw_btn)

        string_label = QLabel()
        string_label.setText(label)
        string_label.setFixedWidth(210)

        btn = QtWidgets.QPushButton()
        btn.setFixedSize(20, 20)

        pixmap_icon = QtGui.QPixmap("./assets/images/delete_x_white.png")
        q_icon = QtGui.QIcon(pixmap_icon)
        btn.setIcon(q_icon)

        pip_main_layout.addWidget(pip_up_down, Qt.AlignVCenter)
        pip_main_layout.addWidget(pixmap_label, Qt.AlignVCenter)
        pip_main_layout.addWidget(string_label, Qt.AlignLeft)
        pip_main_layout.addWidget(btn, Qt.AlignVCenter)

        cat_position = len(self.pipeline.executed_cats)

        self.pip_widget_vbox_layout.insertWidget(cat_position, pip_main_widget)
        index = self.pip_widget_vbox_layout.indexOf(pip_main_widget)
        #print(index)

        # Create the corresponding empty settings widget and connect it
        # settings = self.load_widgets_from_cat_groupbox(cat_position) *TODO* EMPTY

        self.settings_collapsable.setTitle("Settings")
        self.stackedWidget_Settings.hide()

        # Add new step to pipeline
        new_category = self.pipeline.new_category(cat_position)

        print("Create new entry " + str(new_category))
        print("Pipeline length: " + str(len(self.pipeline.executed_cats)) + ".")

        settings_main_widget = None

        # Connect pipeline entry with corresponding settings widget
        def show_settings():
            #print("click")
            self.stackedWidget_Settings.show()

            self.remove_cat_alg_dropdown()

            # Create drop down for cats and algs
            self.create_cat_alg_dropdown(self.pipeline.get_index(new_category), pip_main_widget, settings_main_widget)
            self.stackedWidget_Settings.hide()

        # Connect Button to remove step from pipeline
        def delete_button_clicked():
            self.remove_cat_alg_dropdown()
            self.remove_pip_entry(pip_main_widget, settings_main_widget, new_category)

        self.clickable(pixmap_label).connect(show_settings)
        self.clickable(string_label).connect(show_settings)
        btn.clicked.connect(delete_button_clicked)

        self.scroll_down_pip()

    def add_pip_entry(self, cat_position):
        """
        Creates a entry in the ui pipeline with a given position in pipeline.
        It also creates the corresponding settings widget.
        """
        # create an widget that displays the pip entry in the ui and connect the remove button

        pip_main_widget = QWidget()
        pip_main_widget.setFixedHeight(70)
        pip_main_widget.setFixedWidth(300)
        pip_main_layout = QHBoxLayout()
        pip_main_widget.setLayout(pip_main_layout)

        cat = self.pipeline.executed_cats[cat_position]
        alg = cat.active_algorithm
        label = alg.get_name()
        icon = cat.get_icon()

        pixmap = QPixmap(icon)
        pixmap_scaled_keeping_aspec = pixmap.scaled(30, 30, QtCore.Qt.KeepAspectRatio)
        pixmap_label = QtWidgets.QLabel()
        pixmap_label.setPixmap(pixmap_scaled_keeping_aspec)

        pip_up_down = QWidget()
        pip_up_down.setFixedHeight(70)
        pip_up_down_layout = QVBoxLayout()
        pip_up_down.setLayout(pip_up_down_layout)

        up_btn = QToolButton()
        dw_btn = QToolButton()

        up_btn.setArrowType(Qt.UpArrow)
        up_btn.setFixedHeight(25)
        dw_btn.setArrowType(Qt.DownArrow)
        dw_btn.setFixedHeight(25)

        pip_up_down_layout.addWidget(up_btn)
        pip_up_down_layout.addWidget(dw_btn)

        string_label = QLabel()
        string_label.setText(label)
        string_label.setFixedWidth(210)

        btn = QtWidgets.QPushButton()
        btn.setFixedSize(20, 20)

        pixmap_icon = QtGui.QPixmap("./assets/images/delete_x_white.png")
        q_icon = QtGui.QIcon(pixmap_icon)
        btn.setIcon(q_icon)

        pip_main_layout.addWidget(pip_up_down, Qt.AlignVCenter)
        pip_main_layout.addWidget(pixmap_label, Qt.AlignVCenter)
        pip_main_layout.addWidget(string_label, Qt.AlignLeft)
        pip_main_layout.addWidget(btn, Qt.AlignVCenter)

        self.pip_widget_vbox_layout.insertWidget(cat_position, pip_main_widget)
        index = self.pip_widget_vbox_layout.indexOf(pip_main_widget)
        #print(index)

        # Create the corresponding settings widget and connect it
        settings_main_widget = self.load_settings_widgets_from_pipeline_groupbox(cat_position)

        self.settings_collapsable.setTitle("Settings")
        self.stackedWidget_Settings.hide()
        self.stackedWidget_Settings.insertWidget(cat_position, settings_main_widget)

        #print("Read from pipeline entry " + str(cat))
        #print("Pipeline length: " + str(len(self.pipeline.executed_cats)) + ".")

        def show_settings():
            # Set background color while widget is selected. Doesn't work because of theme? *TODO*
            p = pip_main_widget.palette()
            p.setColor(pip_main_widget.backgroundRole(), Qt.red)
            pip_main_widget.setPalette(p)

            self.stackedWidget_Settings.show()
            self.stackedWidget_Settings.setCurrentIndex(self.pipeline.get_index(cat))
            self.settings_collapsable.setTitle(alg.get_name() + " Settings")

            self.remove_cat_alg_dropdown()

            # Create drop down for cats and algs
            self.create_cat_alg_dropdown(self.pipeline.get_index(cat), pip_main_widget, settings_main_widget)
            #print(cat)
            #print(alg)
            self.set_cat_alg_dropdown(cat, alg)

        # Connect Button to remove step from pipeline
        def delete_button_clicked():
            self.remove_pip_entry(pip_main_widget, settings_main_widget, cat)

        self.clickable(pixmap_label).connect(show_settings)
        self.clickable(string_label).connect(show_settings)
        btn.clicked.connect(delete_button_clicked)

        return (pip_main_widget, settings_main_widget)

    # https://wiki.python.org/moin/PyQt/Making%20non-clickable%20widgets%20clickable
    def clickable(self, widget):
        """
        Convert any widget to a clickable widget.
        """

        class Filter(QObject):

            clicked = pyqtSignal()

            def eventFilter(self, obj, event):

                if obj == widget:
                    if event.type() == QEvent.MouseButtonPress:
                        if obj.rect().contains(event.pos()):
                            self.clicked.emit()
                            # The developer can opt for .emit(obj) to get the object within the slot.
                            return True

                return False

        filter = Filter(widget)
        widget.installEventFilter(filter)
        return filter.clicked
Beispiel #24
0
class userWindow(QWidget):
    def __init__(self, con):
        super().__init__()
        self.con = con
        self.setGeometry(1500, 400, 900, 500)
        self.setFixedSize(self.size())
        self.setWindowTitle('Пользователи')

        self.add_btn = QPushButton('Добавить пользователя', self)
        self.add_btn.move(20, 460)
        self.add_btn.resize(200, 30)
        self.add_btn.clicked.connect(self.add_clicked)

        self.delete_btn = QPushButton('Удалить пользователя', self)
        self.delete_btn.move(320, 460)
        self.delete_btn.resize(200, 30)
        self.delete_btn.clicked.connect(self.delete_clicked)

        self.title_label = QLabel('', self)
        self.title_label.move(580, 30)
        self.title_label.setFont(QFont('Helvetica', 18))

        self.title_label_delete = QLabel('', self)
        self.title_label_delete.move(630, 30)
        self.title_label_delete.setFont(QFont('Helvetica', 18))

        self.login_label = QLabel('Логин', self)
        self.login_label.move(570, 100)

        self.password_label = QLabel('Пароль', self)
        self.password_label.move(570, 150)

        self.log_id_combobox = QComboBox(self)
        self.log_id_combobox.move(675, 100)
        self.log_id_combobox.resize(163, 20)
        self.log_id_edit = QLineEdit(self)
        self.log_id_edit.move(680, 300)
        self.log_id_edit.resize(150, 20)

        self.password = QLineEdit(self)
        self.password.move(680, 150)
        self.password.resize(150, 20)

        self.login = QLineEdit(self)
        self.login.move(680, 100)
        self.login.resize(150, 20)

        self.apply_btn1 = QPushButton('', self)
        self.apply_btn1.move(670, 200)
        self.apply_btn1.resize(165, 30)

        self.commit_btn = QPushButton('Сохранить', self)
        self.commit_btn.move(570, 460)
        self.commit_btn.resize(150, 30)
        self.commit_btn.clicked.connect(self.commit_clicked)

        self.rollback_btn = QPushButton('Отменить', self)
        self.rollback_btn.move(740, 460)
        self.rollback_btn.resize(150, 30)
        self.rollback_btn.clicked.connect(self.rollback_clicked)
        self.apply_btn1.clicked.connect(self.apply1_clicked)

        self.table = QTableWidget(self)
        self.table.setColumnCount(3)
        self.table.resize(520, 450)
        self.table.setColumnWidth(0, 30)
        self.table.setColumnWidth(1, 220)
        self.table.setColumnWidth(2, 250)
        self.update_table()
        self.update_combobox()
        self.hide_all()

    def update_table(self):
        cur = self.con.cursor()
        cur.execute('select count(*) from Users_GUI')
        self.N_ROWS = cur.fetchone()[0]
        self.table.setRowCount(self.N_ROWS)
        self.table.setHorizontalHeaderLabels(['ID', 'Логин', 'Хеш пароля'])
        cur.execute('select * from Users_GUI')

        l = cur.fetchall()
        ll = []
        for el in l:
            ll.append(list(el))
        for i in range(0, self.N_ROWS):
            for j in range(0, 3):
                self.table.setItem(i, j, QTableWidgetItem(str(ll[i][j])))

    def add_clicked(self):
        self.hide_all()

        self.title_label.setText('Введите нового пользователя')
        self.title_label.show()
        self.login_label.show()
        self.password_label.show()

        self.login.show()
        self.password.show()

        self.apply_btn1.setText('Добавить')
        self.rollback_btn.setText('Отменить')
        self.apply_btn1.show()
        self.rollback_btn.show()
        self.commit_btn.show()
        ##self.update_combobox()

    def delete_clicked(self):
        self.hide_all()

        self.title_label_delete.setText('Удалите пользователя')

        self.title_label_delete.show()

        self.login_label.show()

        self.log_id_combobox.show()

        self.apply_btn1.setText('Удалить')
        self.rollback_btn.setText('Отменить')

        self.apply_btn1.show()

        self.rollback_btn.show()
        self.commit_btn.show()
        self.update_combobox()

    def update_combobox(self):
        cur = self.con.cursor()
        self.log_id_combobox.clear()
        cur.execute("select id, user_name from users_gui order by id")
        l = cur.fetchall()
        for id in l:
            self.log_id_combobox.addItem('{} - {}'.format(id[0], id[1]))

        self.log_id_combobox.setCurrentIndex(0)

    def hide_all(self):
        self.title_label.setVisible(False)
        self.title_label_delete.setVisible(False)

        self.login_label.setVisible(False)
        self.password_label.setVisible(False)

        self.log_id_combobox.hide()
        self.password.hide()
        self.login.hide()
        self.log_id_edit.hide()

        self.apply_btn1.hide()
        self.rollback_btn.hide()
        self.commit_btn.hide()

    ##self.update_table()

    def apply1_clicked(self):
        if self.apply_btn1.text() == 'Добавить':
            self.add_user()
        elif self.apply_btn1.text() == 'Удалить':
            self.delete_user()

    def commit_clicked(self):
        self.con.commit()

    def rollback_clicked(self):
        self.con.rollback()
        self.update_table()
        self.update_combobox()

    def delete_user(self):
        try:
            cur = self.con.cursor()
            query = r"DELETE from Users_GUI " \
                    r"where id = {}".format(self.log_id_combobox.currentText().split()[0])

            cur.execute(query)
            self.update_table()
            self.update_combobox()
            self.update_table()
        except:
            error_d = QMessageBox()
            error_d.setIcon(QMessageBox.Critical)
            error_d.setText("Ошибка удаления данных")
            error_d.setWindowTitle("Ошибка!")
            error_d.exec_()

    def add_user(self):
        try:
            curs = self.con.cursor()
            query =r"INSERT INTO Users_GUI (user_name, password_user)  " \
                   r"VALUES ('{}', ORA_HASH('{}'))".format(self.login.text(), self.password.text())

            curs.execute(query)
            self.update_table()
        except:
            error_d = QMessageBox()
            error_d.setIcon(QMessageBox.Critical)
            error_d.setWindowTitle("Ошибка!")
            error_d.setText("Такой пользователь уже есть в базе данных!")
            error_d.exec_()
            return
Beispiel #25
0
class ActionBar(QFrame):
    """
    SIGNALS:
    @changeCurrent(PyQt_PyObject)
    @runFile(QString)
    @reopenTab(QString)
    @recentTabsModified()
    """
    change_current = pyqtSignal('PyQt_PyObject', int)
    splitEditor = pyqtSignal(bool)
    runFile = pyqtSignal('QString')
    closeSplit = pyqtSignal()
    addToProject = pyqtSignal('QString')
    showFileInExplorer = pyqtSignal('QString')
    goToSymbol = pyqtSignal(int)
    undockEditor = pyqtSignal()
    reopenTab = pyqtSignal('QString')
    closeImageViewer = pyqtSignal(int)
    needUpdateFocus = pyqtSignal()

    def __init__(self, main_combo=False):
        super(ActionBar, self).__init__()
        self.setAutoFillBackground(True)
        self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        self.setObjectName("actionbar")
        hbox = QHBoxLayout(self)
        hbox.setContentsMargins(1, 0, 0, 0)
        hbox.setSpacing(1)

        self.combo_files = ComboFiles(self)
        self.combo_files.setObjectName("combotab")
        # self.combo_files.setSizePolicy(
        #     QSizePolicy.Expanding, QSizePolicy.Fixed)
        self.combo_files.setSizeAdjustPolicy(
            QComboBox.AdjustToMinimumContentsLengthWithIcon)
        self.combo_files.setMaximumWidth(400)
        self.combo_files.currentIndexChanged[int].connect(self.current_changed)
        self.combo_files.setToolTip(translations.TR_COMBO_FILE_TOOLTIP)
        self.combo_files.setContextMenuPolicy(Qt.CustomContextMenu)
        self.combo_files.customContextMenuRequested.connect(
            self._context_menu_requested)
        hbox.addWidget(self.combo_files)
        self.symbols_combo = QComboBox()
        self.symbols_combo.setObjectName("combo_symbols")
        # For correctly style sheet
        self.symbols_combo.setItemDelegate(QStyledItemDelegate())
        self.symbols_combo.setModel(Model([]))
        self.symbols_combo.setSizeAdjustPolicy(
            QComboBox.AdjustToMinimumContentsLengthWithIcon)
        self.symbols_combo.activated[int].connect(self.current_symbol_changed)
        hbox.addWidget(self.symbols_combo)

        # Code Navigator actions
        self.code_navigator = CodeNavigator()
        hbox.addWidget(self.code_navigator)
        # Image Viewer actions
        self.image_viewer_controls = ImageViewerControls()
        self.image_viewer_controls.setSizePolicy(
            QSizePolicy.Expanding, QSizePolicy.Fixed)
        self.image_viewer_controls.setVisible(False)
        hbox.addWidget(self.image_viewer_controls)

        self._pos_text = "Line: %d, Col: %d"
        self.lbl_position = QLabel()
        self.lbl_position.setObjectName("position")
        self.lbl_position.setText(self._pos_text % (0, 0))
        margin = self.style().pixelMetric(
            QStyle.PM_LayoutHorizontalSpacing) / 2
        self.lbl_position.setContentsMargins(margin, 0, margin, 0)
        self.lbl_position.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        hbox.addWidget(self.lbl_position)
        self.btn_close = QPushButton()
        self.btn_close.setIcon(
            self.style().standardIcon(QStyle.SP_DialogCloseButton))

        if main_combo:
            self.btn_close.setObjectName('close_button_combo')
            self.btn_close.setToolTip(translations.TR_CLOSE_FILE)
            self.btn_close.clicked.connect(self.about_to_close_file)
        else:
            self.btn_close.setObjectName('close_split')
            self.btn_close.setToolTip(translations.TR_CLOSE_SPLIT)
            self.btn_close.clicked.connect(lambda: self.closeSplit.emit())
        self.btn_close.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Minimum)
        hbox.addWidget(self.btn_close)

        # Added for set language

    def resizeEvent(self, event):
        super(ActionBar, self).resizeEvent(event)
        if event.size().width() < 400:
            self.symbols_combo.hide()
            self.code_navigator.hide()
            self.lbl_position.hide()
        elif not self.image_viewer_controls.isVisible():
            self.symbols_combo.show()
            self.code_navigator.show()
            self.lbl_position.show()

    def add_item(self, text, neditable):
        """Add a new item to the combo and add the neditable data."""

        self.combo_files.addItem(text, neditable)
        self.combo_files.setCurrentIndex(self.combo_files.count() - 1)

    def get_editables(self):
        editables = []
        for index in range(self.combo_files.count()):
            neditable = self.combo_files.itemData(index)
            editables.append(neditable)
        return editables

    def add_symbols(self, symbols):
        """Add the symbols to thcurrente symbols's combo."""

        mo = Model(symbols)
        self.symbols_combo.setModel(mo)

    def set_current_symbol(self, index):
        self.symbols_combo.setCurrentIndex(index + 1)

    def update_item_icon(self, neditable, icon):
        index = self.combo_files.findData(neditable)
        self.combo_files.setItemIcon(index, icon)

    def update_item_text(self, neditable, text):
        index = self.combo_files.findData(neditable)
        self.combo_files.setItemText(index, text)

    def current_changed(self, index):
        """Change the current item in the combo."""
        if index != -1:
            neditable = self.combo_files.itemData(index)
            self.change_current.emit(neditable, index)

    def current_symbol_changed(self, index):
        """Change the current symbol in the combo."""
        if index == 0:
            return
        self.goToSymbol.emit(index - 1)

    def set_language_combo_changed(self, index):
        """Change the current language of editor."""
        self._setter_language.set_language_to_editor(index)

    def update_line_col(self, line, col):
        """Update the line and column position."""
        self.lbl_position.setText(self._pos_text % (line, col))

    def _context_menu_requested(self, point):
        """Display context menu for the combo file."""
        if self.combo_files.count() == 0:
            # If there is not an Editor opened, don't show the menu
            return
        menu = QMenu()
        action_add = menu.addAction(translations.TR_ADD_TO_PROJECT)
        action_run = menu.addAction(translations.TR_RUN_FILE)
        action_show_folder = menu.addAction(
            translations.TR_SHOW_CONTAINING_FOLDER)
        menu.addSeparator()
        action_close = menu.addAction(translations.TR_CLOSE_FILE)
        action_close_all = menu.addAction(translations.TR_CLOSE_ALL_FILES)
        action_close_all_not_this = menu.addAction(
            translations.TR_CLOSE_OTHER_FILES)
        menu.addSeparator()
        action_copy_path = menu.addAction(
            translations.TR_COPY_FILE_PATH_TO_CLIPBOARD)
        action_show_file_in_explorer = menu.addAction(
            translations.TR_SHOW_FILE_IN_EXPLORER)
        action_reopen = menu.addAction(translations.TR_REOPEN_FILE)
        action_undock = menu.addAction(translations.TR_UNDOCK_EDITOR)

        main_container = IDE.get_service("main_container")
        if not main_container.last_opened_files:
            action_reopen.setEnabled(False)

        # set language action

        # Connect actions
        action_close.triggered.connect(self.about_to_close_file)
        action_close_all.triggered.connect(self._close_all_files)
        action_close_all_not_this.triggered.connect(
            self._close_all_files_except_this)
        action_run.triggered.connect(self._run_this_file)
        action_undock.triggered.connect(self._undock_editor)
        action_show_folder.triggered.connect(self._show_containing_folder)
        action_copy_path.triggered.connect(self._copy_file_location)
        action_show_file_in_explorer.triggered.connect(
            self._show_file_in_explorer)
        action_add.triggered.connect(self._add_to_project)
        action_reopen.triggered.connect(self._reopen_last_tab)
        # self.connect(actionSplitH, SIGNAL("triggered()"),
        #             lambda: self._split(False))
        # self.connect(actionSplitV, SIGNAL("triggered()"),
        #             lambda: self._split(True))

        menu.exec_(QCursor.pos())

    def _set_list_languages(self, menu_set_language):
        for lang in self._setter_language.get_list_of_language():
            if lang is None:
                continue
            action = menu_set_language.addAction(lang)
            action.triggered.connect(lambda checked, language=lang:
                                     self._set_language_action(language))

    def _set_language_action(self, language):
        self._setter_language.set_language_to_editor(language)

    def _show_containing_folder(self):
        main_container = IDE.get_service("main_container")
        editor_widget = main_container.get_current_editor()
        filename = editor_widget.file_path
        file_manager.show_containing_folder(filename)

    def _create_menu_syntax(self, menuSyntax):
        """Create Menu with the list of syntax supported."""
        syntax = sorted(settings.SYNTAX.keys())
        for syn in syntax:
            menuSyntax.addAction(syn)
            # self.connect(menuSyntax, SIGNAL("triggered(QAction*)"),
            #             self._reapply_syntax)

    def _reapply_syntax(self, syntaxAction):
        # TODO
        if [self.currentIndex(), syntaxAction] != self._resyntax:
            self._resyntax = [self.currentIndex(), syntaxAction]
            # self.emit(SIGNAL("syntaxChanged(QWidget, QString)"),
            #          self.currentWidget(), syntaxAction.text())

    def set_current_file(self, neditable):
        index = self.combo_files.findData(neditable)
        self.combo_files.setCurrentIndex(index)

    def set_current_by_index(self, index):
        self.combo_files.setCurrentIndex(index)

    @pyqtSlot()
    def about_to_close_file(self, index=None):
        """Close the NFile or ImageViewer object."""

        parent = self.parent().parentWidget()  # Splitter
        if parent.count() > 1:
            return
        if index is None:
            index = self.combo_files.currentIndex()
            if index == -1:
                return
        neditable = self.combo_files.itemData(index)
        if neditable:
            neditable.nfile.close()
        else:
            # Image viewer
            self.combo_files.removeItem(index)
            self.closeImageViewer.emit(index)

    def close_split(self):
        self.closeSplit.emit()

    def close_file(self, neditable):
        """Receive the confirmation to close the file."""
        index = self.combo_files.findData(neditable)
        self.combo_files.removeItem(index)
        return index

    def _run_this_file(self):
        """Execute the current file"""
        neditable = self.combo_files.itemData(self.combo_files.currentIndex())
        self.runFile.emit(neditable.file_path)

    def _add_to_project(self):
        """Emit a signal to let someone handle the inclusion of the file
        inside a project."""
        neditable = self.combo_files.itemData(self.combo_files.currentIndex())
        self.addToProject.emit(neditable.file_path)

    def _show_file_in_explorer(self):
        """Triggered when the "Show File in Explorer" context
        menu action is selected. Emits the "showFileInExplorer(QString)"
        signal with the current file's full path as argument."""
        neditable = self.combo_files.itemData(self.combo_files.currentIndex())
        self.showFileInExplorer.emit(neditable.file_path)

    def _reopen_last_tab(self):
        main_container = IDE.get_service("main_container")
        last_closed = main_container.last_opened_files[0]
        self.reopenTab.emit(last_closed)

    def _undock_editor(self):
        self.undockEditor.emit()

    def _split(self, orientation):
        print("emitir splitEditor")

    def _copy_file_location(self):
        """Copy the path of the current opened file to the clipboard."""

        neditable = self.combo_files.itemData(self.combo_files.currentIndex())
        QApplication.clipboard().setText(neditable.file_path,
                                         QClipboard.Clipboard)

    def _close_all_files(self):
        """Close all the files opened."""
        for i in range(self.combo_files.count()):
            self.about_to_close_file(0)

    def _close_all_files_except_this(self):
        """Close all the files except the current one."""
        neditable = self.combo_files.itemData(self.combo_files.currentIndex())
        for i in reversed(list(range(self.combo_files.count()))):
            ne = self.combo_files.itemData(i)
            if ne is not neditable:
                self.about_to_close_file(i)
Beispiel #26
0
class ConfigTab(TraceDocks):
    
    ## The constructor
    #  initialize the super-class, assign a name and first configItems       
    def __init__(self,parent):
        super(ConfigTab, self).__init__(parent,'ConfigTab')
        self.tabName = 'ConfigTab'
        self.logger.logEvent('Creating Tab now: '+ self.tabName)
        
        # Set a couple of default-values, in case the configParser does not work
        self.snifferConfig.configBaud = 1000000
        self.snifferConfig.configCom = 'COM4'
        self.snifferConfig.configMode = 'Singleshot'
        self.snifferConfig.configParity = 'None'
        self.snifferConfig.configStopBits = 0
        self.snifferConfig.configTimeBytes = 2
        self.snifferConfig.configTrigger = 'Start'
        self.snifferConfig.configLogCheck = 0
        self.snifferConfig.configIncTimeCheck = 0
        self.snifferConfig.configTickToMsLine = 1000
        self.snifferConfig.configSingleDurLine = 3000
        self.snifferConfig.configMaxTickCountVal = 65536
        self.snifferConfig.configUpDownState = 'Up'
        self.snifferConfig.configCurrentTheme = 'Dark'
                
        # By parsing the config now, we assure that we re-load everything
        # the way we left it
        self.snifferConfig.parseConfigFromFile()
        
        # Create necessary Lists
        self.COMList = OsSniffer.OS_SerialPortList()
        self.BAUDList = ['110','300','600','1200','2400','4800','9600','14400','19200','38400','57600','115200','128000','256000','921600','1000000','2000000']
        self.STOPList = ['0','1','2']
        self.PARITYList = ['None','Even','Odd']
        self.MODEList = ['Singleshot','Continuous','Trigger']
        self.TRIGGERList = []
        for triggers in Globals.tspDict.items():
            self.TRIGGERList.append(triggers[1][0])
            
        self.INACTIVEList = ['INACTIVE']
        # We need a list for the items and one for the actual Values
        
        
    ## Create the visible UI            
    def setConfigTabLayout(self):
        
        # Create Configurations Tab --------------------###    
        # Create Layouts
        self.Vlayout = QVBoxLayout()
        self.H1layout = QHBoxLayout()
        self.H1layout.setSpacing(10)
        self.H1SubV1Layout = QVBoxLayout()
        self.H1SubV1H1Layout = QHBoxLayout()
        self.H1SubV1H2Layout = QHBoxLayout()
        self.H1SubV1H3Layout = QHBoxLayout()
        self.H1SubV1H4Layout = QHBoxLayout()
        self.H1SubV1H5Layout = QHBoxLayout()
        self.H1SubV2Layout = QVBoxLayout()
        self.H1SubV2H1Layout = QHBoxLayout()
        self.H1SubV2H2Layout = QHBoxLayout()
        self.H1SubV2H3Layout = QHBoxLayout()
        self.H1SubV2H4Layout = QHBoxLayout()
        self.H1SubV2H5Layout = QHBoxLayout()
        self.H1SubV2H6Layout = QHBoxLayout()
        self.H1SubV2H7Layout = QHBoxLayout()
        self.H1SubV2H8Layout = QHBoxLayout()
            
        #------------------------------------
        
        # Create Widgets TextBox
        #------------------------------------
        
        # First Buttons
        self.saveLogButt = QPushButton('Save Logfile')
        self.saveConfigButt = QPushButton('Save Configuration')
        self.toggleThemeButt = QPushButton('Toggle Theme')
        self.refreshComButt = QPushButton('Refresh COM')
        
        # Then Checkbox and Comboboxes
        self.saveLogCheck = QCheckBox('Activate Logging')
        self.saveIncTimeCheck = QCheckBox('Save Inc_Tick Data')
        
        self.labelSerial = QLabel('Serial Configuration')
        self.labelCOM = QLabel('COM-PORT')
        self.labelBAUD = QLabel('BAUD-RATE')
        self.labelSTOP= QLabel('STOP-BITS')
        self.labelPARITY= QLabel('PARITY')
        self.labelMeasure = QLabel('Measurement Configuration')
        self.labelMODE = QLabel('MEASUREMENT MODE')
        self.labelSINGLETIME = QLabel('MEASUREMENT TIME')
        self.labelTRIGGER = QLabel('TRIGGER TYPE')
        self.labelRATIO = QLabel('TICK TO MS RATIO')
        self.labelMaxTickCount = QLabel('MAX TICKOUT VAL')
        self.labelUpDownCount = QLabel('SELECT UP OR DOWN COUNTER')
        
        self.inputSingleDurBox = QLineEdit()
        self.inputSingleDurBox.setText('Duration(ticks)')
        #self.inputSingleDurBox.setMaximumWidth(20)
        
        self.inputTickToMsBox = QLineEdit()
        self.inputTickToMsBox.setText('Set Ticks to Ms Ratio')
        #self.inputTickToMsBox.setMaximumWidth(200)

        self.inputMaxTickCount = QLineEdit()
        self.inputMaxTickCount.setText('Set Maximum Tickcount Val')
        
        self.comboMODE = QComboBox()
        self.comboMODE.addItems(self.MODEList)  
        self.comboCOM = QComboBox()
        self.comboCOM.setSizeAdjustPolicy(QComboBox.AdjustToContents)
        self.comboCOM.addItems(self.COMList)   
        self.comboBAUD = QComboBox()
        self.comboBAUD.addItems(self.BAUDList)
        self.comboBAUD.setEditable(True)
        self.comboSTOP = QComboBox()
        self.comboSTOP.addItems(self.STOPList)    
        self.comboPARITY = QComboBox()
        self.comboPARITY.addItems(self.PARITYList)      
        self.comboTRIGGER = QComboBox()
        self.comboTRIGGER.addItems(self.TRIGGERList)     

        self.upCountRadio = QRadioButton('Up',self)
        self.downCountRadio = QRadioButton('Down', self)
        
        # We need to sync the UI before connecting any slots in order to prevent accidental stateChanges.
        self.syncUiToConfig() 
        
        #--- SIGNAL/SLOT CONNECTIONS ---#
        # Button Signal/Slot connections
        self.saveLogButt.clicked.connect(self.saveLog)
        for keys, values in dockDict.items(): # We need to connect EVERY tab in order to save the ConfigurationData
            self.saveConfigButt.clicked.connect(values.snifferConfig.saveConfigToFile)  
        self.saveConfigButt.clicked.connect(self.snifferConfig.saveConfigToFile)
        self.toggleThemeButt.clicked.connect(self.toggleTheme)
        self.refreshComButt.clicked.connect(self.refreshCom)
        
        # Checkbox Signal/Slot connections
        self.saveLogCheck.stateChanged.connect(self.checkSaveLogChanged)
        self.saveIncTimeCheck.stateChanged.connect(self.checkSaveInctimeChanged)
        
        # Lineedit Signal/Slot connections
        self.inputSingleDurBox.textChanged.connect(self.lineSingleDurChanged)
        self.inputTickToMsBox.textChanged.connect(self.lineTickToMsChanged)
        self.inputMaxTickCount.textChanged.connect(self.lineMaxTickCountChanged)
        
        # Combobox Signal/Slot connections
        self.comboMODE.currentIndexChanged[int].connect(self.comboModeChanged)     
        self.comboCOM.currentIndexChanged[int].connect(self.comboComChanged)
        self.comboBAUD.currentIndexChanged[int].connect(self.comboBaudChanged) 
        self.comboBAUD.currentTextChanged.connect(self.comboBaudChanged)
        self.comboSTOP.currentIndexChanged[int].connect(self.comboStopBitsChanged)
        self.comboPARITY.currentIndexChanged[int].connect(self.comboParityChanged) 
        self.comboTRIGGER.currentIndexChanged[int].connect(self.comboTriggerChanged)

        # Radio button connections
        self.upCountRadio.clicked.connect(self.upCountRadioSelected)
        self.downCountRadio.clicked.connect(self.downCountRadioSelected)
                
        # Add the Widgets to the corresponding Layouts
        self.H1SubV1H1Layout.addWidget(self.labelCOM)
        self.H1SubV1H1Layout.addWidget(self.refreshComButt)
        self.H1SubV1H1Layout.addWidget(self.comboCOM)
        self.H1SubV1H2Layout.addWidget(self.labelBAUD)
        self.H1SubV1H2Layout.addWidget(self.comboBAUD)
        self.H1SubV1H3Layout.addWidget(self.labelSTOP)
        self.H1SubV1H3Layout.addWidget(self.comboSTOP)
        self.H1SubV1H4Layout.addWidget(self.labelPARITY)
        self.H1SubV1H4Layout.addWidget(self.comboPARITY)
        
        self.H1SubV1Layout.addWidget(self.labelSerial)
        self.H1SubV1Layout.addLayout(self.H1SubV1H1Layout)
        self.H1SubV1Layout.addLayout(self.H1SubV1H2Layout)
        self.H1SubV1Layout.addLayout(self.H1SubV1H3Layout)
        self.H1SubV1Layout.addLayout(self.H1SubV1H4Layout)
        self.H1SubV1Layout.addStretch()
        
        self.H1SubV2H1Layout.addWidget(self.labelMODE)
        self.H1SubV2H1Layout.addWidget(self.comboMODE)
        self.H1SubV2H2Layout.addWidget(self.labelSINGLETIME)
        self.H1SubV2H2Layout.addWidget(self.inputSingleDurBox)
        self.H1SubV2H3Layout.addWidget(self.labelTRIGGER)
        self.H1SubV2H3Layout.addWidget(self.comboTRIGGER)
        self.H1SubV2H5Layout.addWidget(self.saveIncTimeCheck)
        self.H1SubV2H5Layout.addWidget(self.saveLogCheck)
        self.H1SubV2H5Layout.addWidget(self.saveLogButt)
        self.H1SubV2H5Layout.addWidget(self.toggleThemeButt)
        self.H1SubV2H6Layout.addWidget(self.labelRATIO)
        self.H1SubV2H6Layout.addWidget(self.inputTickToMsBox)
        self.H1SubV2H7Layout.addWidget(self.labelMaxTickCount)
        self.H1SubV2H7Layout.addWidget(self.inputMaxTickCount)
        self.H1SubV2H8Layout.addWidget(self.labelUpDownCount)
        self.H1SubV2H8Layout.addWidget(self.upCountRadio)
        self.H1SubV2H8Layout.addWidget(self.downCountRadio)
        
        self.H1SubV2Layout.addWidget(self.labelMeasure)
        self.H1SubV2Layout.addLayout(self.H1SubV2H1Layout)
        self.H1SubV2Layout.addLayout(self.H1SubV2H2Layout)
        self.H1SubV2Layout.addLayout(self.H1SubV2H3Layout)
        self.H1SubV2Layout.addLayout(self.H1SubV2H4Layout)
        self.H1SubV2Layout.addLayout(self.H1SubV2H5Layout)
        self.H1SubV2Layout.addLayout(self.H1SubV2H6Layout)
        self.H1SubV2Layout.addLayout(self.H1SubV2H7Layout)
        self.H1SubV2Layout.addLayout(self.H1SubV2H8Layout)
        self.H1SubV2Layout.addStretch()
        
        self.H1layout.addLayout(self.H1SubV1Layout)
        self.H1layout.addStretch()
        self.H1layout.addLayout(self.H1SubV2Layout)
        self.Vlayout.addLayout(self.H1layout)
        self.Vlayout.addStretch()
        self.Vlayout.addWidget(self.saveConfigButt)
        self.dockContents.setLayout(self.Vlayout)  
    
    # -- ! We need callbacks to update the actual Values ! --#
    
    #---CREATE COMBOBOX Callbacks---#
    ## CB: comboCOM // Serial COM-Port
    def comboComChanged(self):
        self.snifferConfig.configCom = self.COMList[self.comboCOM.currentIndex()]
        self.logger.logEvent('changed COM-Port to - '+ self.snifferConfig.configCom)  
    ## CB: comboBAUD // Serial BAUD-Rate  
    def comboBaudChanged(self):
        self.snifferConfig.configBaud = self.comboBAUD.currentText()
        self.logger.logEvent('changed BAUD-Rate to - '+ self.snifferConfig.configBaud)
    ## CB: comboSTOP // Serial STOP-bit count
    def comboStopBitsChanged(self):
        self.snifferConfig.configStopBits = self.STOPList[self.comboSTOP.currentIndex()]
        self.logger.logEvent('changed STOP-Bits to - '+ self.snifferConfig.configStopBits) 
    ## CB: comboPARTIY // Serial Parity-bit (odd/even/none)   
    def comboParityChanged(self):
        self.snifferConfig.configParity = self.PARITYList[self.comboPARITY.currentIndex()]
        self.logger.logEvent('changed PARITY to - '+ self.snifferConfig.configParity)   
    ## CB: comboMODE // Measurement mode
    def comboModeChanged(self):
        # Check which box is checked in order to show the user the necessary info
        self.snifferConfig.configMode = self.MODEList[self.comboMODE.currentIndex()]
        if self.snifferConfig.configMode == self.MODEList[0]:
            self.inputSingleDurBox.show()
            self.labelSINGLETIME.show()
            self.comboTRIGGER.hide()
            self.labelTRIGGER.hide()
        if self.snifferConfig.configMode == self.MODEList[1]:
            self.inputSingleDurBox.hide()
            self.labelSINGLETIME.hide()
            self.comboTRIGGER.hide()
            self.labelTRIGGER.hide()
        if self.snifferConfig.configMode == self.MODEList[2]:
            self.inputSingleDurBox.show()
            self.labelSINGLETIME.show()
            self.comboTRIGGER.show()
            self.labelTRIGGER.show()
        self.logger.logEvent('changed Measurement-mode to - '+ self.snifferConfig.configMode)
    ## CB: comboTRIGGER // the Trigger the measurement waits for (only in TRIGGER-measmode)
    def comboTriggerChanged(self):
        self.snifferConfig.configTrigger = self.TRIGGERList[self.comboTRIGGER.currentIndex()]
        self.logger.logEvent('changed TriggerType to - '+ self.snifferConfig.configTrigger)
    
    #---CREATE THEME Callbacks---#    
    ## CB: Toggles the theme between dark and light mode
    #  @details This happens by calling the appropriate function of the parent (QMainwindow), so that the theme
    #  is changed globally
    def toggleTheme(self):
        if(self.snifferConfig.configCurrentTheme == 'Light'):
            self.parent.loadTheme('Dark')
            #self.parent.tabStart.startStopAnalyzingButt.setStyleSheet('QPushButton:focus {border: 2px solid; border-color: limegreen; background-color: #31363b; border-radius:100px}')
        else:
            self.parent.loadTheme('Light')
            #self.parent.tabStart.startStopAnalyzingButt.setStyleSheet('QPushButton:focus {border: 2px solid; border-color: limegreen; background-color: white; border-radius:100px}')
        #self.parent.setStartStopButtonStyle()   
    
    #---CREATE CHECKBOX Callbacks---#   
    ## CB: Handle the SaveLog checkbox event (Toggle)
    def checkSaveLogChanged(self):
        self.snifferConfig.configLogCheck ^= 1  
        if(self.snifferConfig.configLogCheck == 1):   
            self.logger.enableLogs()   
        else:
            self.logger.disableLogs()
        self.logger.logEvent('changed LogCheckbox to - '+ str(self.snifferConfig.configLogCheck))
        
    ## CB: Handle the SaveInctime checkbox event (Toggle)         
    def checkSaveInctimeChanged(self):
        self.snifferConfig.configIncTimeCheck ^= 1 
        self.logger.logEvent('changed Save Time-Increment Checkbox to - '+ str(self.snifferConfig.configIncTimeCheck))

    #---CREATE LINEEDIT Callbacks---#
    ## CB: Handle the SingleDur lineedit callback (adjust singleshot duration)        
    def lineSingleDurChanged(self):
        self.snifferConfig.configSingleDurLine = self.inputSingleDurBox.text()
        self.logger.logEvent('changed Singleshot Duration to - '+ str(self.snifferConfig.configSingleDurLine))
        
    ## CB: Handle the TickToMs lineedit callback (adjust ticks per ms)       
    def lineTickToMsChanged(self):
        self.snifferConfig.configTickToMsLine = self.inputTickToMsBox.text()
        self.logger.logEvent('changed Tick To Ms Ratio to - '+ str(self.snifferConfig.configTickToMsLine))

    ## CB: Handle the MaxTickCount lineedit callback (adjust maximum tickcount value)
    def lineMaxTickCountChanged(self):
        self.snifferConfig.configMaxTickCountVal = self.inputMaxTickCount.text()
        self.logger.logEvent('changed Max Tickcount Value to - '+ str(self.snifferConfig.configTickToMsLine))
    
    #---CREATE PUSHBUTTON Callbacks---#    
    ## CB: Handle the refreshCOM pushbutton callback (refresh all com-ports)      
    def refreshCom(self):
        self.COMList = OsSniffer.OS_SerialPortList()
        self.comboCOM.clear()
        self.comboCOM.addItems(self.COMList)
        self.snifferConfig.configCom = self.COMList[self.comboCOM.currentIndex()]

    #---CREATE RADIO Callbacks---#
    ## Select upCount
    def upCountRadioSelected(self):
        self.snifferConfig.configUpDownState = 'Up'
        self.logger.logEvent('changed Up/Down Radio to - '+ str(self.snifferConfig.configUpDownState))
    
    ## Select downCount
    def downCountRadioSelected(self):
        self.snifferConfig.configUpDownState = 'Down'
        self.logger.logEvent('changed Up/Down Radio to - '+ str(self.snifferConfig.configUpDownState))
      
    #---CONTENT FUNCTIONS---#
    ## CB: Saves all logs saved in the logList to a output-file
    def saveLog(self):
        print('Trying to save logs')
        if(len(snifferLogList) == 0):
            self.displayException('Global Logging List empty. Did you enable the checkbox?')
        else:
            self.saveLogDirectory, self.purge = QFileDialog.getSaveFileName(self, 'Save File', '', 'Logfile (*.slog)')
            print(self.saveLogDirectory)
            self.logFile = open(self.saveLogDirectory,'a+')
            for logTuple in snifferLogList:
                self.logFile.write(str(logTuple[0])+', '+str(logTuple[1])+'\n')
            self.logFile.close()
            
    # --- MANDATORY UI FUNCTIONS --- #
    # -------------------------------#
    ## Read out all components of snifferConfig and set the UI elements according to
    #  the saved values.           
    def syncUiToConfig(self):
        self.inputSingleDurBox.setText(str(self.snifferConfig.configSingleDurLine))
        self.inputTickToMsBox.setText(str(self.snifferConfig.configTickToMsLine))
        self.inputMaxTickCount.setText(str(self.snifferConfig.configMaxTickCountVal))
        
        self.saveLogCheck.setChecked(self.snifferConfig.configLogCheck)
        self.saveIncTimeCheck.setChecked(self.snifferConfig.configIncTimeCheck)

        if self.snifferConfig.configUpDownState == 'Up':
            self.upCountRadio.click()
        elif self.snifferConfig.configUpDownState == 'Down':
            self.downCountRadio.click()
        else:
            print('Error, neither up nor down in config')

        try:
            self.comboCOM.setCurrentIndex(self.COMList.index(self.snifferConfig.configCom))
        except Exception as valException:
            print('Exception when syncing UI in Configtab: comboCOM - snifferConfig Error')
            self.comboCOM.setCurrentIndex(0)
        try:
            self.comboMODE.setCurrentIndex(self.MODEList.index(self.snifferConfig.configMode))
        except Exception as valException:
            print('Exception when syncing UI in Configtab: comboMODE - snifferConfig Error')
            self.comboMODE.setCurrentIndex(0)
        try:
            self.comboBAUD.setCurrentIndex(self.BAUDList.index(str(self.snifferConfig.configBaud)))
        except Exception as valException:
            print('Exception when syncing UI in Configtab: comboBAUD - snifferConfig Error')
            self.comboBAUD.setCurrentIndex(0)
        try:
            self.comboPARITY.setCurrentIndex(self.PARITYList.index(self.snifferConfig.configParity))
        except Exception as valException:
            print('Exception when syncing UI in Configtab: comboPARITY - snifferConfig Error')
            self.comboPARITY.setCurrentIndex(0)
        try:
            self.comboSTOP.setCurrentIndex(self.STOPList.index(str(self.snifferConfig.configStopBits)))
        except Exception as valException:
            print('Exception when syncing UI in Configtab: comboSTOP - snifferConfig Error')
            self.comboSTOP.setCurrentIndex(0)
        try:
            self.comboTRIGGER.setCurrentIndex(self.TRIGGERList.index(self.snifferConfig.configTrigger.upper()))
        except Exception as valException:
            print('Exception when syncing UI in Configtab: comboTRIGGER - snifferConfig Error')
            self.comboTRIGGER.setCurrentIndex(0)