Beispiel #1
0
class ToolBar(QToolBar):
    back_button_clicked = pyqtSignal(name="backClicked")
    forward_button_clicked = pyqtSignal(name="forwardClicked")
    stop_reload_button_clicked = pyqtSignal(int, name="stopReloadClicked")
    address_changed = pyqtSignal(QUrl, name="addressChanged")
    dom_tree_viewer_clicked = pyqtSignal(name="domTreeViewerClicked")

    def __init__(self):
        QToolBar.__init__(self)
        self.setMovable(False)
        self.toggleViewAction().setEnabled(False)
        self.le = QLineEdit()
        self.init_ui()

    def init_ui(self):
        back_action = QAction(self)
        back_action.setShortcut(QKeySequence(Qt.Key_Back))
        back_action.setIcon(QIcon("images/go-previous.png"))
        self.addAction(back_action)
        back_action.triggered.connect(self.back_button_clicked)

        forward_action = QAction(self)
        forward_action.setShortcut(QKeySequence(Qt.Key_Forward))
        forward_action.setIcon(QIcon("images/go-next.png"))
        self.addAction(forward_action)
        forward_action.triggered.connect(self.forward_button_clicked)

        self.stop_reload_action = QAction(self)
        self.stop_reload_action.setShortcut(QKeySequence(Qt.Key_F5))
        self.stop_reload_action.setIcon(QIcon("images/view-refresh.png"))
        self.stop_reload_action.setData(QWebEnginePage.Reload)
        self.addAction(self.stop_reload_action)
        self.stop_reload_action.triggered.connect(
            lambda: self.stop_reload_button_clicked.emit(
                QWebEnginePage.WebAction(self.stop_reload_action.data())))

        fav_action = QAction(self)
        self.le.addAction(fav_action, QLineEdit.LeadingPosition)
        self.le.setClearButtonEnabled(True)
        self.addWidget(self.le)
        self.le.editingFinished.connect(
            lambda: self.address_changed.emit(QUrl(self.le.text())))

        self.addSeparator()
        self.dom_tree_viewer = QAction(self)
        self.dom_tree_viewer.setIcon(QIcon("images/view-dom_tree.png"))
        self.dom_tree_viewer.triggered.connect(self.dom_tree_viewer_clicked)
        self.addAction(self.dom_tree_viewer)


    @pyqtSlot(bool, name="changeStopReload")
    def change_stop_reload(self, state):
        if state:
            self.stop_reload_action.setShortcut(QKeySequence(Qt.Key_F5))
            self.stop_reload_action.setIcon(QIcon("images/view-refresh.png"))
            self.stop_reload_action.setData(QWebEnginePage.Reload)
        else:
            self.stop_reload_action.setShortcut(QKeySequence(Qt.Key_Escape))
            self.stop_reload_action.setIcon(QIcon("images/process-stop.png"))
            self.stop_reload_action.setData(QWebEnginePage.Stop)
class Line(QDialog):
    '''
    单词拼写检查
    '''
    def __init__(self):
        '''
        一些初始设置
        '''
        super().__init__()
        self.Ui()

    def Ui(self):
        '''
        界面初始设置
        '''
        self.resize(450, 100)
        self.setWindowTitle('微信公众号:学点编程吧--单词拼写检查')
        self.line = QLineEdit(self)
        self.line.move(20, 20)
        action = QAction(self)
        action.setIcon(QIcon('check.ico'))
        action.triggered.connect(self.Check)
        self.line.addAction(action, QLineEdit.TrailingPosition)  # 部件显示在文本右侧
        self.show()

    def Check(self):
        '''
        检查下你写的是什么单词
        '''
        word = self.line.text()
        if correct(word) != word:
            QMessageBox.information(self, '提示信息',
                                    '你或许想要表达的单词是:' + correct(word))
        else:
            QMessageBox.information(self, '提示信息', '你填写的单词是:' + word)
Beispiel #3
0
class Toolbar(QToolBar):
    back_button_clicked = pyqtSignal(name="backButtonClicked")
    forward_button_clicked = pyqtSignal(name="forwardButtonClicked")
    stop_reload_button_clicked = pyqtSignal(int,
                                            name="stopReloadButtonClicked")
    address_changed = pyqtSignal(str, name="addressChanged")

    def __init__(self):
        QToolBar.__init__(self)
        self.setMovable(False)
        self.toggleViewAction().setEnabled(False)
        self.setIconSize(QSize(24, 24))

        # 뒤로가기 버튼
        self.back_action = QAction(self)
        self.back_action.setShortcut(QKeySequence(Qt.Key_Back))
        self.back_action.setIcon(QIcon("assets/svg/left.svg"))
        self.addAction(self.back_action)
        self.back_action.triggered.connect(self.back_button_clicked)

        # 앞으로가기 버튼
        self.forward_action = QAction(self)
        self.forward_action.setShortcut(QKeySequence(Qt.Key_Forward))
        self.forward_action.setIcon(QIcon("assets/svg/right.svg"))
        self.addAction(self.forward_action)
        self.forward_action.triggered.connect(self.forward_button_clicked)

        # 새로고침 취소 액션
        self.stop_reload_action = QAction(self)
        self.stop_reload_action.setShortcut(QKeySequence(Qt.Key_F5))
        self.stop_reload_action.setIcon(QIcon("assets/svg/reload.svg"))
        self.stop_reload_action.setData(QWebEnginePage.Reload)
        self.addAction(self.stop_reload_action)
        self.stop_reload_action.triggered.connect(
            lambda: self.stop_reload_button_clicked.emit(
                QWebEnginePage.WebAction(self.stop_reload_action.data())))

        # 주소창
        self.le = QLineEdit()
        fav_action = QAction(self)
        self.le.addAction(fav_action, QLineEdit.LeadingPosition)
        self.le.setClearButtonEnabled(True)
        self.le.setContentsMargins(8, 8, 8, 8)
        self.addWidget(self.le)
        self.le.editingFinished.connect(
            lambda: self.address_changed.emit(self.le.text()))

    @pyqtSlot(bool, name="changeStopReload")
    def change_stop_reload(self, state):
        if state:
            self.stop_reload_action.setShortcut(QKeySequence(Qt.Key_F5))
            self.stop_reload_action.setIcon(QIcon("assets/svg/reload.svg"))
            self.stop_reload_action.setData(QWebEnginePage.Reload)
        else:
            self.stop_reload_action.setShortcut(QKeySequence(Qt.Key_Escape))
            self.stop_reload_action.setIcon(QIcon("assets/svg/close.svg"))
            self.stop_reload_action.setData(QWebEnginePage.Stop)
        class Page(QWizardPage):
            def __init__(self):
                super().__init__()
                vbox = QVBoxLayout(self)
                self.setTitle("Python Project")
                frame = QFrame()
                frame.setLineWidth(2)
                vbox.addStretch(1)
                frame.setFrameShape(QFrame.StyledPanel)
                vbox.addWidget(frame)
                box = QGridLayout(frame)
                box.addWidget(QLabel("Project Name:"), 0, 0)
                self._line_project_name = QLineEdit()
                self.registerField("name*", self._line_project_name)
                box.addWidget(self._line_project_name, 0, 1)
                box.addWidget(QLabel("Create in:"), 1, 0)
                self.line = QLineEdit()
                self.registerField("path", self.line)
                choose_dir_action = self.line.addAction(
                    QIcon(self.style().standardPixmap(
                        self.style().SP_DirIcon)), QLineEdit.TrailingPosition)
                box.addWidget(self.line, 1, 1)
                box.addWidget(QLabel("Interpreter:"), 2, 0)
                line_interpreter = QComboBox()
                line_interpreter.setEditable(True)
                line_interpreter.addItems(utils.get_python())
                box.addWidget(line_interpreter, 2, 1)
                choose_dir_action.triggered.connect(self._choose_dir)
                self.line.setText(utils.get_home_dir())

            def _choose_dir(self):
                directory = QFileDialog.getExistingDirectory(
                    self, "Choose Directory", "~")
                if directory:
                    self.line.setText(directory)
Beispiel #5
0
class FirstPage(QWizardPage):

    def __init__(self, parent=None):
        super().__init__(parent)
        self.setTitle("Nueva Base de Datos de Pireal")
        self.setSubTitle("A continuación elija el nombre y el destino de la DB")

        # Widgets
        box = QVBoxLayout(self)
        hbox = QHBoxLayout()
        hbox.addWidget(QLabel(self.tr("Database Name:")))
        self._database_name_line = QLineEdit()
        hbox.addWidget(self._database_name_line)
        box.addLayout(hbox)
        hbox = QHBoxLayout()
        hbox.addWidget(QLabel(self.tr("Location:")))
        self._database_location_line = QLineEdit()
        # Left action to change db location
        change_location_action = self._database_location_line.addAction(
            self.style().standardIcon(QStyle.SP_DirIcon), 1)
        self._database_location_line.setReadOnly(True)
        hbox.addWidget(self._database_location_line)
        box.addLayout(hbox)
        hbox = QHBoxLayout()
        hbox.addWidget(QLabel(self.tr("Filename:")))
        self._database_filename_line = QLineEdit()
        self._database_filename_line.setReadOnly(True)
        hbox.addWidget(self._database_filename_line)
        box.addLayout(hbox)

        # Register fields
        self.registerField("dbname*", self._database_name_line)
        self.registerField("dblocation", self._database_location_line)
        self.registerField("dbfilename", self._database_filename_line)

        self.__location_folder = settings.PIREAL_DATABASES
        self._database_filename_line.setText(self.__location_folder)
        self._database_location_line.setText(self.__location_folder)

        # Conexiones
        self._database_name_line.textChanged.connect(self._update_filename)
        change_location_action.triggered.connect(self.__select_location)

    @pyqtSlot()
    def __select_location(self):
        location = QFileDialog.getExistingDirectory(self,
                                                    self.tr("Select Folder"))
        if not location:
            return

        self._database_location_line.setText(location)
        self.__location_folder = os.path.join(self.__location_folder, location)

        self._database_filename_line.setText(os.path.join(
            location, self._database_name_line.text()))

    @pyqtSlot('QString')
    def _update_filename(self, filename):
        new_filename = os.path.join(self.__location_folder, filename)
        self._database_filename_line.setText(new_filename + '.pdb')
Beispiel #6
0
class Line(QDialog):
    def Ui(self):
        self.line = QLineEdit(self)
        self.line.move(20, 20)
        action = QAction(self)
        action.setIcon(QIcon('check.ico'))
        action.triggered.connect(self.Check)
        self.line.addAction(action, QLineEdit.TrailingPosition)

    def Check(self):
        word = self.line.text()
        if correct(word) != word:
            QMessageBox.information(self, '提示信息',
                                    '你或许想要表达的单词是:' + correct(word))
        else:
            QMessageBox.information(self, '提示信息', '你填写的单词是:' + word)
Beispiel #7
0
    def setAction(self, action, position=LeftPosition):
        """
        Set `action` to be displayed at `position`. Existing action
        (if present) will be removed.

        Parameters
        ----------
        action : :class:`QAction`
        position : int
            Position where to set the action (default: ``LeftPosition``).

        """

        curr = self.actionAt(position)
        if curr is not None:
            self.removeAction(position)

        # Add the action using QWidget.addAction (for shortcuts)
        QLineEdit.addAction(self, action)

        button = LineEditButton(self)
        button.setToolButtonStyle(Qt.ToolButtonIconOnly)
        button.setDefaultAction(action)
        button.setVisible(self.isVisible())
        button.show()
        button.setCursor(Qt.ArrowCursor)

        button.triggered.connect(self.triggered)
        button.triggered.connect(self.__onTriggered)

        slot = _ActionSlot(position, action, button, False)
        self.__actions[position - 1] = slot

        if not self.testAttribute(Qt.WA_Resized):
            # Need some sensible height to do the layout.
            self.adjustSize()

        self.__layoutActions()
        class Page(QWizardPage):

            def __init__(self):
                super().__init__()
                vbox = QVBoxLayout(self)
                self.setTitle("Python Project")
                frame = QFrame()
                frame.setLineWidth(2)
                vbox.addStretch(1)
                frame.setFrameShape(QFrame.StyledPanel)
                vbox.addWidget(frame)
                box = QGridLayout(frame)
                box.addWidget(QLabel("Project Name:"), 0, 0)
                self._line_project_name = QLineEdit()
                self.registerField("name*", self._line_project_name)
                box.addWidget(self._line_project_name, 0, 1)
                box.addWidget(QLabel("Create in:"), 1, 0)
                self.line = QLineEdit()
                self.registerField("path", self.line)
                choose_dir_action = self.line.addAction(
                    QIcon(self.style().standardPixmap(
                        self.style().SP_DirIcon)), QLineEdit.TrailingPosition)
                box.addWidget(self.line, 1, 1)
                box.addWidget(QLabel("Interpreter:"), 2, 0)
                line_interpreter = QComboBox()
                line_interpreter.setEditable(True)
                line_interpreter.addItems(utils.get_python())
                box.addWidget(line_interpreter, 2, 1)
                # from ninja_ide.utils import utils
                choose_dir_action.triggered.connect(self._choose_dir)
                self.line.setText(utils.get_home_dir())

            def _choose_dir(self):
                directory = QFileDialog.getExistingDirectory(
                    self, "Choose Directory", "~")
                if directory:
                    self.line.setText(directory)
Beispiel #9
0
class MainWindow(QMainWindow):
    def __init__(self):
        try:
            with open('favs.yaml', 'r') as yaml_stream:
                self.fav_list = yaml.load(yaml_stream, Loader=yaml.SafeLoader)
        except:
            print("Cannot read yaml config file, check formatting.")
            self.fav_list = None

        super(MainWindow, self).__init__()
        self.setGeometry(0, 0, 700, 400)
        self.setContentsMargins(6, 6, 6, 6)
        self.setWindowTitle("pyRadioQt")
        self.setWindowIcon(QIcon('./icon/icon.png'))

        self.uiGenreCombo()
        self.uiSearchField()

        self.path = './icon/icon.png'
        self.pix = QPixmap(self.path)
        self.label_image = QLabel()
        self.label_image.setPixmap(QPixmap(self.pix))

        self.field = QPlainTextEdit()
        self.field.setContextMenuPolicy(Qt.CustomContextMenu)
        self.field.customContextMenuRequested.connect(self.contextMenuRequested)
        self.field.cursorPositionChanged.connect(self.selectLine)
        self.field.setWordWrapMode(QTextOption.NoWrap)

        self.saveButton = QPushButton("Save as txt")
        self.saveButton.setIcon(QIcon.fromTheme("document-save"))
        self.saveButton.clicked.connect(self.saveStations)
        self.savePlaylistButton = QPushButton("Save as m3u")
        self.savePlaylistButton.setIcon(QIcon.fromTheme("document-save"))
        self.savePlaylistButton.clicked.connect(self.savePlaylist)

        # Toolbar
        self.tb = self.addToolBar("tools")
        self.tb.setContextMenuPolicy(Qt.PreventContextMenu)
        self.tb.setMovable(False)
        self.tb.addWidget(self.searchField)
        self.tb.addWidget(self.saveButton)
        self.tb.addWidget(self.savePlaylistButton)
        self.tb.addSeparator()
        self.tb.addWidget(self.genreCombo)

        # Main Layout
        self.createFavoriteLayout()
        self.mainWidget = QWidget(self)
        self.mainLayout = QVBoxLayout(self.mainWidget)

        self.centerLayout = QHBoxLayout()
        self.centerLayout.addWidget(self.label_image)
        self.centerLayout.addWidget(self.field)
        self.mainLayout.addLayout(self.centerLayout)

        self.mainLayout.addWidget(self.horizontalGroupBox)
        self.mainWidget.setLayout(self.mainLayout)

        self.setCentralWidget(self.mainWidget)

        # player ###
        self.player = QMediaPlayer()
        self.player.metaDataChanged.connect(self.metaDataChanged)
        self.startButton = QPushButton("Play")
        self.startButton.setIcon(QIcon.fromTheme("media-playback-start"))
        self.startButton.clicked.connect(self.getURLtoPlay)
        self.stopButton = QPushButton("Stop")
        self.stopButton.setIcon(QIcon.fromTheme("media-playback-stop"))
        self.stopButton.clicked.connect(self.stopPlayer)
        self.statusBar().addPermanentWidget(self.startButton)
        self.statusBar().addPermanentWidget(self.stopButton)
        # actions
        self.getNameAction = QAction(QIcon.fromTheme("edit-copy"), "copy Station Name", self, triggered=self.getName)
        self.getUrlAction = QAction(QIcon.fromTheme("edit-copy"), "copy Station URL", self, triggered=self.getURL)
        self.getNameAndUrlAction = QAction(QIcon.fromTheme("edit-copy"), "copy Station Name,URL", self, triggered=self.getNameAndUrl)
        self.getURLtoPlayAction = QAction(QIcon.fromTheme("media-playback-start"), "play Station", self, shortcut="F6", triggered=self.getURLtoPlay)
        self.addAction(self.getURLtoPlayAction)
        self.stopPlayerAction = QAction(QIcon.fromTheme("media-playback-stop"), "stop playing", self, shortcut="F7", triggered=self.stopPlayer)
        self.addAction(self.stopPlayerAction)
        self.helpAction = QAction(QIcon.fromTheme("help-info"), "Help", self, shortcut="F1", triggered=self.showHelp)
        self.addAction(self.helpAction)
        self.statusBar().showMessage("Welcome", 0)

    def uiGenreCombo(self):
        self.genreList = genres.splitlines()

        self.genreCombo = QComboBox()
        self.genreCombo.setFixedWidth(150)
        self.genreCombo.currentIndexChanged.connect(self.genreSearch)

        self.genreCombo.addItem("choose Genre")
        for m in self.genreList:
            self.genreCombo.addItem(m)

    def uiSearchField(self):
        self.searchField = QLineEdit()
        self.searchField.setFixedWidth(250)
        self.searchField.addAction(QIcon.fromTheme("edit-find"), 0)
        self.searchField.setPlaceholderText("type search term and press RETURN ")
        self.searchField.returnPressed.connect(self.findStations)

    def createFavoriteLayout(self):
        self.horizontalGroupBox = QGroupBox("Favorites")
        layout = QHBoxLayout()
        if self.fav_list is not None:
            self.buttongroup = QButtonGroup()
            self.buttongroup.buttonClicked[int].connect(self.handleButtonClicked)

            i = 1
            for station in self.fav_list:
                #print(station)
                self.button = QPushButton(station, self)
                self.buttongroup.addButton(self.button, i)
                i = i + 1
                layout.addWidget(self.button)
        else:
            l1 = QLabel()
            l1.setText("No Favorites")
            layout.addWidget(l1)

        self.horizontalGroupBox.setLayout(layout)

    def handleButtonClicked(self, id):
        for button in self.buttongroup.buttons():
            if button is self.buttongroup.button(id):
                #print(button.text() + " Was Clicked ")
                for station, url in self.fav_list.items():
                    if station == button.text():
                        #print(url[0])
                        self.getURLtoPlay(True, station, url[0])

    def genreSearch(self):
        if self.genreCombo.currentIndex() > 0:
            self.searchField.setText(self.genreCombo.currentText())
            self.findStations()

    def getName(self):
        t = self.field.textCursor().selectedText().partition(",")[0]
        clip = QApplication.clipboard()
        clip.setText(t)

    def getURL(self):
        t = self.field.textCursor().selectedText().partition(",")[2]
        clip = QApplication.clipboard()
        clip.setText(t)

    def getNameAndUrl(self):
        t = self.field.textCursor().selectedText()
        clip = QApplication.clipboard()
        clip.setText(t)

    def selectLine(self):
        tc = self.field.textCursor()
        tc.select(QTextCursor.LineUnderCursor)
        tc.movePosition(QTextCursor.StartOfLine, QTextCursor.MoveAnchor)
        tc.movePosition(QTextCursor.EndOfBlock, QTextCursor.KeepAnchor)
        self.field.setTextCursor(tc)

    def showHelp(self):
        QMessageBox.information(self, "Information", "F6 -> play Station (from line where cursor is)\n\
                                                      F7 -> stop playing")

    def stopPlayer(self):
        self.player.stop()
        self.statusBar().showMessage("Player stopped", 0)

    # QPlainTextEdit contextMenu
    def contextMenuRequested(self, point):
        cmenu = QMenu()
        if not self.field.toPlainText() == "":
            cmenu.addAction(self.getNameAction)
            cmenu.addAction(self.getUrlAction)
            cmenu.addAction(self.getNameAndUrlAction)
            cmenu.addSeparator()
            cmenu.addAction(self.getURLtoPlayAction)
            cmenu.addAction(self.stopPlayerAction)
            cmenu.addSeparator()
            cmenu.addAction(self.helpAction)
        cmenu.exec_(self.field.mapToGlobal(point))

    def getURLtoPlay(self, fav=False, name="", url_fav=""):
        url = ""
        stext = ""
        if fav:
            # print("url_fav=",url_fav)
            # print("name in func:", name)
            stext = name
            url = url_fav
        else:
            tc = self.field.textCursor()
            rtext = tc.selectedText().partition(",")[2]
            stext = tc.selectedText().partition(",")[0]
            if rtext.endswith(".pls"):
                url = self.getURLfromPLS(rtext)
            elif rtext.endswith(".m3u"):
                url = self.getURLfromM3U(rtext)
            else:
                url = rtext
        # print("stream url=", url)

        self.player.setMedia(QMediaContent(QUrl(url)))
        self.player.play()
        self.statusBar().showMessage("%s %s" % ("playing", stext), 0)

    def metaDataChanged(self):
        if self.player.isMetaDataAvailable():
            trackInfo = (self.player.metaData("Title"))
            trackInfo2 = (self.player.metaData("Comment"))
            if trackInfo is not None:
                self.statusBar().showMessage(trackInfo, 0)
                if trackInfo2 is not None:
                    self.statusBar().showMessage("%s %s" % (trackInfo, trackInfo2))

    def getURLfromPLS(self, inURL):
        if "&" in inURL:
            inURL = inURL.partition("&")[0]
        response = request.urlopen(inURL)
        html = response.read().decode("utf-8").splitlines()
        if len(html) > 3:
            if "http" in str(html[1]):
                t = str(html[1])
            elif "http" in str(html[2]):
                t = str(html[2])
            elif "http" in str(html[3]):
                t = str(html[3])
        elif len(html) > 2:
            if "http" in str(html[1]):
                t = str(html[1])
            elif "http" in str(html[2]):
                t = str(html[2])
        else:
            t = str(html[0])
        url = t.partition("=")[2].partition("'")[0]
#        print(url)
        return (url)

    def getURLfromM3U(self, inURL):
        if "?u=" in inURL:
            inURL = inURL.partition("?u=")[2]
        if "&" in inURL:
            inURL = inURL.partition("&")[0]
        response = request.urlopen(inURL)
        html = response.read().splitlines()
        if len(html) > 1:
            if "http" in str(html[1]):
                t = str(html[1])
            else:
                t = str(html[0])
        else:
            t = str(html[0])
        url = t.partition("'")[2].partition("'")[0]
#        print(url)

        return (url)

    def findStations(self):
        self.field.setPlainText("")
        mysearch = self.searchField.text()
        self.statusBar().showMessage("searching ...")
        rb = RadioBrowser()
        myparams = {'name': 'search', 'nameExact': 'false'}

        for key in myparams.keys():
            if key == "name":
                myparams[key] = mysearch

        self.r = rb.station_search(params=myparams)

        n = ""
        m = ""
        for i in range(len(self.r)):
            for key, value in self.r[i].items():
                if str(key) == "favicon":
                    self.path = value
                    print(self.path)
                if str(key) == "name":
                    n = value.replace(",", " ")
        #            print (n)
                if str(key) == "url":
                    m = value
                    self.field.appendPlainText("%s,%s" % (n, m))
#        self.combo.setCurrentIndex(0)
        if not self.field.toPlainText() == "":
            self.statusBar().showMessage("found " + str(self.field.toPlainText().count('\n')+1) + " '" +
                                         self.searchField.text() + "' Stations")
        else:
            self.statusBar().showMessage("nothing found", 0)
#        self.field.textCursor().movePosition(QTextCursor.Start, Qt.MoveAnchor)

    def saveStations(self):
        if not self.field.toPlainText() == "":
            path, _ = QFileDialog.getSaveFileName(None, "RadioStations", self.searchField.text() +
                                                  ".txt", "Text Files (*.txt)")
            if path:
                s = self.field.toPlainText()
                with open(path, 'w') as f:
                    f.write(s)
                    f.close()
                    self.statusBar().showMessage("saved!", 0)

    def savePlaylist(self):
        if not self.field.toPlainText() == "":
            path, _ = QFileDialog.getSaveFileName(None, "RadioStations", self.searchField.text() + ".m3u",
                                                  "Playlist Files (*.m3u)")
            if path:
                result = ""
                s = self.field.toPlainText()
                st = []
                for line in s.splitlines():
                    st.append(line)
                result += "#EXTM3U"
                result += '\n'
                for x in range(len(st)):
                    result += "#EXTINF:" + str(x) + "," + st[x].partition(",")[0]
                    result += '\n'
                    result += st[x].partition(",")[2]
                    result += '\n'
                with open(path, 'w') as f:
                    f.write(result)
                    f.close()
                    self.statusBar().showMessage("saved!", 0)
class MyWindow_2(QMainWindow):
    def __init__(self, aPath, parent=None):
        super(MyWindow_2, self).__init__(parent)
        #        QIcon.setThemeName('gnome')
        QMetaObject.connectSlotsByName(self)
        self.delimit = '\t'
        self.mycolumn = 0
        self.MaxRecentFiles = 5
        self.windowList = []
        self.recentFileActs = []
        self.settings = QSettings('Axel Schneider', 'CSVEditor')
        self.setAttribute(Qt.WA_DeleteOnClose)
        self.isChanged = False
        self.fileName = ""
        self.fname = "Liste"
        self.mytext = ""
        self.colored = False
        self.copiedRow = []
        self.copiedColumn = []
        ### QTableView seetings
        self.tableView = TableWidgetDragRows()
        #        self.tableView.horizontalHeader().setStretchLastSection(True)
        self.tableView.setGridStyle(1)
        self.tableView.setCornerButtonEnabled(False)
        self.tableView.setShowGrid(True)
        self.tableView.selectionModel().selectionChanged.connect(
            self.makeAllWhite)
        self.tableView.itemClicked.connect(self.getItem)
        self.tableView.setEditTriggers(QAbstractItemView.DoubleClicked)
        self.tableView.cellChanged.connect(self.finishedEdit)
        self.tableView.setDropIndicatorShown(True)

        self.findBar = QLineEdit()
        self.findBar.addAction(QIcon.fromTheme("gtk-find"), 0)
        self.findBar.setPlaceholderText("find")
        self.findBar.setFixedWidth(200)
        self.findBar.returnPressed.connect(self.findText)

        self.editLine = QLineEdit()
        self.editLine.setToolTip("edit and press ENTER")
        self.editLine.setStatusTip("edit and press ENTER")
        self.editLine.returnPressed.connect(self.updateCell)

        grid = QGridLayout()
        grid.setSpacing(1)
        grid.addWidget(self.editLine, 0, 0)
        grid.addWidget(self.findBar, 0, 1)
        grid.addWidget(self.tableView, 1, 0, 1, 3)

        mywidget = QWidget()
        mywidget.setLayout(grid)
        self.setCentralWidget(mywidget)
        self.isChanged = False
        self.createActions()
        self.createMenuBar()
        self.setStyleSheet(stylesheet(self))
        self.readSettings()
        self.msg("Welcome to CSV Reader")

        if len(sys.argv) > 1:
            print(sys.argv[1])
            self.fileName = sys.argv[1]
            self.loadCsvOnOpen(self.fileName)
            self.msg(self.fileName + "loaded")
        else:
            self.msg("Ready")
            self.addRow()
            self.isChanged = False

    def changeSelection(self):
        self.tableView.setSelectionMode(QAbstractItemView.ExtendedSelection)

    def updateCell(self):
        if self.tableView.selectionModel().hasSelection():
            row = self.selectedRow()
            column = self.selectedColumn()
            newtext = QTableWidgetItem(self.editLine.text())
            self.tableView.setItem(row, column, newtext)

    def getItem(self):
        item = self.tableView.selectedItems()[0]
        row = self.selectedRow()
        column = self.selectedColumn()
        if not item == None:
            name = item.text()
        else:
            name = ""
        self.msg("'" + name + "' on Row " + str(row + 1) + " Column " +
                 str(column + 1))
        self.editLine.setText(name)

    def selectedRow(self):
        if self.tableView.selectionModel().hasSelection():
            row = self.tableView.selectionModel().selectedIndexes()[0].row()
            return int(row)

    def selectedColumn(self):
        column = self.tableView.selectionModel().selectedIndexes()[0].column()
        return int(column)

    def findText(self):
        self.findTableItems()
        self.changeSelection()

    def findTableItems(self):
        #        self.tableView.setSelectionMode(QAbstractItemView.MultiSelection)
        findText = self.findBar.text()
        self.tableView.clearSelection()
        #        if findText.isnumeric():
        #            items = self.tableView.findItems(findText, Qt.MatchExactly)
        #        else:
        items = self.tableView.findItems(findText, Qt.MatchContains)
        if items:
            self.colored = True
            self.makeAllWhite()
            for item in items:
                item.setBackground(Qt.yellow)
            self.colored = True
            self.isChanged = False

    def findThis(self):
        #        self.tableView.setSelectionMode(QAbstractItemView.MultiSelection)
        self.tableView.clearSelection()
        items = self.tableView.findItems(self.mytext, Qt.MatchContains)
        if items:
            self.colored = True
            self.makeAllWhite()
            for item in items:
                item.setBackground(Qt.yellow)
                item.setForeground(Qt.blue)
            self.colored = True
            self.isChanged = False

    def msgbox(self, message):
        QMessageBox.warning(self, "Message", message)

    def createMenuBar(self):
        bar = self.menuBar()
        self.filemenu = bar.addMenu("File")
        self.separatorAct = self.filemenu.addSeparator()
        self.filemenu.addAction(QIcon.fromTheme("document-new"), "New",
                                self.newCsv, QKeySequence.New)
        self.filemenu.addAction(QIcon.fromTheme("document-open"), "Open",
                                self.loadCsv, QKeySequence.Open)
        self.filemenu.addAction(QIcon.fromTheme("document-save"), "Save",
                                self.saveOnQuit, QKeySequence.Save)
        self.filemenu.addAction(QIcon.fromTheme("document-save-as"),
                                "Save as ...", self.writeCsv,
                                QKeySequence.SaveAs)
        self.filemenu.addSeparator()
        self.filemenu.addAction(QIcon.fromTheme("document-print-preview"),
                                "Print Preview", self.handlePreview,
                                "Shift+Ctrl+P")
        self.filemenu.addAction(QIcon.fromTheme("document-print"), "Print",
                                self.handlePrint, QKeySequence.Print)
        self.filemenu.addSeparator()
        for i in range(self.MaxRecentFiles):
            self.filemenu.addAction(self.recentFileActs[i])
        self.updateRecentFileActions()
        self.filemenu.addSeparator()
        self.clearRecentAct = QAction("clear Recent Files List",
                                      self,
                                      triggered=self.clearRecentFiles)
        self.clearRecentAct.setIcon(QIcon.fromTheme("edit-clear"))
        self.filemenu.addAction(self.clearRecentAct)
        self.filemenu.addSeparator()
        self.filemenu.addAction(QIcon.fromTheme("application-exit"), "Exit",
                                self.handleQuit, QKeySequence.Quit)

        self.editmenu = bar.addMenu("Edit")
        self.editmenu.addAction(self.actionUndo)
        self.editmenu.addAction(self.actionRedo)
        self.editmenu.addSeparator()
        self.editmenu.addAction(QIcon.fromTheme("edit"),
                                "first row to headers", self.setHeaders)
        self.editmenu.addAction(QIcon.fromTheme("edit"),
                                "headers to first row",
                                self.setHeadersToFirstRow)
        self.editmenu.addSeparator()
        self.editmenu.addAction(QIcon.fromTheme("edit-copy"), "copy Cell",
                                self.copyByContext, QKeySequence.Copy)
        self.editmenu.addAction(QIcon.fromTheme("edit-paste"), "paste Cell",
                                self.pasteByContext, QKeySequence.Paste)
        self.editmenu.addAction(QIcon.fromTheme("edit-cut"), "cut Cell",
                                self.cutByContext, QKeySequence.Cut)
        self.editmenu.addAction(QIcon.fromTheme("edit-delete"), "delete Cell",
                                self.deleteCell, QKeySequence.Delete)
        self.editmenu.addSeparator()
        self.editmenu.addAction(QIcon.fromTheme("edit-copy"), "copy Row",
                                self.copyRow)
        self.editmenu.addAction(QIcon.fromTheme("edit-paste"), "paste Row",
                                self.pasteRow)
        self.editmenu.addSeparator()
        self.editmenu.addAction(QIcon.fromTheme("edit-copy"), "copy Column",
                                self.copyColumn)
        self.editmenu.addAction(QIcon.fromTheme("edit-paste"), "paste Column",
                                self.pasteColumn)
        self.editmenu.addSeparator()
        self.editmenu.addAction(QIcon.fromTheme("add"), "add Row", self.addRow)
        self.editmenu.addAction(QIcon.fromTheme("edit-delete"), "remove Row",
                                self.removeRow)
        self.editmenu.addSeparator()
        self.editmenu.addAction(QIcon.fromTheme("add"), "add Column",
                                self.addColumn)
        self.editmenu.addAction(QIcon.fromTheme("edit-delete"),
                                "remove Column", self.removeColumn)
        self.editmenu.addSeparator()
        self.editmenu.addAction(QIcon.fromTheme("edit-clear"), "clear List",
                                self.clearList)
        self.editmenu.addSeparator()
        self.editmenu.addAction(QIcon.fromTheme("pane-show-symbolic"),
                                "toggle horizontal Headers",
                                self.toggleHorizHeaders)
        self.editmenu.addAction(QIcon.fromTheme("pane-hide-symbolic"),
                                "toggle vertical Headers",
                                self.toggleVertHeaders)
        self.editmenu.addAction(self.whiteAction)

        self.editmenu = bar.addMenu("Help")

    def deleteCell(self):
        row = self.selectedRow()
        col = self.selectedColumn()
        self.tableView.takeItem(row, col)

    def toggleHorizHeaders(self):
        if self.tableView.horizontalHeader().isVisible():
            self.tableView.horizontalHeader().setVisible(False)
        else:
            self.tableView.horizontalHeader().setVisible(True)

    def toggleVertHeaders(self):
        if self.tableView.verticalHeader().isVisible():
            self.tableView.verticalHeader().setVisible(False)
        else:
            self.tableView.verticalHeader().setVisible(True)

    def createActions(self):
        self.actionUndo = QAction(self)
        icon = QIcon.fromTheme("edit-undo")
        self.actionUndo.setText("Undo")
        self.actionUndo.setIcon(icon)
        self.actionUndo.setObjectName("actionUndo")
        self.actionUndo.setShortcut(QKeySequence.Undo)
        self.actionRedo = QAction(self)
        icon = QIcon.fromTheme("edit-redo")
        self.actionRedo.setText("Redo")
        self.actionRedo.setIcon(icon)
        self.actionRedo.setObjectName("actionRedo")
        self.actionRedo.setShortcut(QKeySequence.Redo)
        # all items white BG
        self.whiteAction = QAction(QIcon.fromTheme("pane-hide-symbolic"),
                                   "all items white background", self)
        self.whiteAction.triggered.connect(lambda: self.makeAllWhite())
        for i in range(self.MaxRecentFiles):
            self.recentFileActs.append(
                QAction(self, visible=False, triggered=self.openRecentFile))

    def openRecentFile(self):
        action = self.sender()
        if action:
            if self.isChanged == True:
                quit_msg = "<b>The Document was changed.<br>Do you want to save changes?</ b>"
                reply = QMessageBox.question(self, 'Save Confirmation',
                                             quit_msg, QMessageBox.Yes,
                                             QMessageBox.No)
                if reply == QMessageBox.Yes:
                    self.saveOnQuit()
            file = action.data()
            if QFile.exists(file):
                self.loadCsvOnOpen(file)
            else:
                self.msg("File not exists")

    def handleQuit(self):
        quit()

    def loadCsvOnOpen(self, fileName):
        if fileName:
            f = open(fileName, 'r', encoding='utf-8')
            mystring = f.read()
            ### comma
            if mystring.count(",") > mystring.count('\t'):
                if mystring.count(",") > mystring.count(';'):
                    self.delimit = ","
                elif mystring.count(";") > mystring.count(','):
                    self.delimit = ";"
                else:
                    self.delimit = "\t"
            elif mystring.count(";") > mystring.count('\t'):
                self.delimit = ';'
            else:
                self.delimit = "\t"
            # print(mystring)
            f.close()
            f = open(fileName, 'r', encoding='utf-8')
            self.tableView.setRowCount(0)
            self.tableView.setColumnCount(0)
            for rowdata in csv.reader(f, delimiter=self.delimit):
                row = self.tableView.rowCount()
                self.tableView.insertRow(row)
                if len(rowdata) == 0:
                    self.tableView.setColumnCount(len(rowdata) + 1)
                else:
                    self.tableView.setColumnCount(len(rowdata))
                for column, data in enumerate(rowdata):
                    item = QTableWidgetItem(data)
                    self.tableView.setItem(row, column, item)
        self.tableView.selectRow(0)
        self.isChanged = False
        self.setCurrentFile(fileName)
        self.tableView.resizeColumnsToContents()
        self.tableView.resizeRowsToContents()
        self.msg(fileName + " loaded")

    def loadCsv(self):
        if self.isChanged == True:
            quit_msg = "<b>The Document was changed.<br>Do you want to save changes?</ b>"
            reply = QMessageBox.question(self, 'Save Confirmation', quit_msg,
                                         QMessageBox.Yes, QMessageBox.No)
            if reply == QMessageBox.Yes:
                self.saveOnQuit()
        fileName, _ = QFileDialog.getOpenFileName(
            self, "Open CSV", (QDir.homePath() + "/Dokumente/CSV"),
            "CSV (*.csv *.tsv *.txt)")
        if fileName:
            self.loadCsvOnOpen(fileName)

    def newCsv(self):
        if self.isChanged == True:
            quit_msg = "<b>The Document was changed.<br>Do you want to save changes?</ b>"
            reply = QMessageBox.question(self, 'Save Confirmation', quit_msg,
                                         QMessageBox.Yes, QMessageBox.No)
            if reply == QMessageBox.Yes:
                self.saveOnQuit()
        i = 0
        for row in range(self.tableView.rowCount()):
            self.tableView.removeRow(i)
            i = +1
        j = 0
        for column in range(self.tableView.columnCount()):
            self.tableView.removeColumn(j)
            j = +1
        self.tableView.clearContents()
        self.fileName = ""
        self.setWindowTitle('New' + "[*]")
        self.isChanged = False

    def writeCsv(self):
        path, _ = QFileDialog.getSaveFileName(self, 'Save File',
                                              QDir.homePath() + "/export.csv",
                                              "CSV Files(*.csv *.txt)")
        if path:
            with open(path, 'w') as stream:
                print("saving", path)
                writer = csv.writer(stream, delimiter=self.delimit)
                for row in range(self.tableView.rowCount()):
                    rowdata = []
                    for column in range(self.tableView.columnCount()):
                        item = self.tableView.item(row, column)
                        if item is not None:
                            rowdata.append(item.text())
                        else:
                            rowdata.append('')
                    writer.writerow(rowdata)
        self.isChanged = False
        self.setCurrentFile(path)

    def handlePrint(self):
        if self.tableView.rowCount() == 0:
            self.msg("no rows")
        else:
            dialog = QtPrintSupport.QPrintDialog()
            if dialog.exec_() == QDialog.Accepted:
                self.handlePaintRequest(dialog.printer())
                self.msg("Document printed")

    def handlePreview(self):
        if self.tableView.rowCount() == 0:
            self.msg("no rows")
        else:
            dialog = QtPrintSupport.QPrintPreviewDialog()
            dialog.setFixedSize(1000, 700)
            dialog.paintRequested.connect(self.handlePaintRequest)
            dialog.exec_()
            self.msg("Print Preview closed")

    def handlePaintRequest(self, printer):
        printer.setDocName(self.fname)
        document = QTextDocument()
        cursor = QTextCursor(document)
        model = self.tableView.model()
        tableFormat = QTextTableFormat()
        tableFormat.setBorder(0.2)
        tableFormat.setBorderStyle(3)
        tableFormat.setCellSpacing(0)
        tableFormat.setTopMargin(0)
        tableFormat.setCellPadding(4)
        table = cursor.insertTable(model.rowCount() + 1, model.columnCount(),
                                   tableFormat)
        model = self.tableView.model()
        ### get headers
        myheaders = []
        for i in range(0, model.columnCount()):
            myheader = model.headerData(i, Qt.Horizontal)
            cursor.insertText(str(myheader))
            cursor.movePosition(QTextCursor.NextCell)
        ### get cells
        for row in range(0, model.rowCount()):
            for col in range(0, model.columnCount()):
                index = model.index(row, col)
                cursor.insertText(str(index.data()))
                cursor.movePosition(QTextCursor.NextCell)
        document.print_(printer)

    def removeRow(self):
        if self.tableView.rowCount() > 0:
            row = self.selectedRow()
            tableView.removeRow(row)
            self.isChanged = True

    def addRow(self):
        if self.tableView.rowCount() > 0:
            if self.tableView.selectionModel().hasSelection():
                row = self.selectedRow()
                item = QTableWidgetItem("")
                self.tableView.insertRow(row, 0, item)
            else:
                row = 0
                item = QTableWidgetItem("")
                self.tableView.insertRow(row, 0, item)
                self.tableView.selectRow(0)
        else:
            self.tableView.setRowCount(1)
        if self.tableView.columnCount() == 0:
            self.addColumn()
            self.tableView.selectRow(0)
        self.isChanged = True

    def clearList(self):
        self.tableView.clear()
        self.isChanged = True

    def removeColumn(self):
        self.tableView.removeColumn(self.selectedColumn())
        self.isChanged = True

    def addColumn(self):
        count = self.tableView.columnCount()
        self.tableView.setColumnCount(count + 1)
        self.tableView.resizeColumnsToContents()
        self.isChanged = True
        if self.tableView.rowCount() == 0:
            self.addRow()
            self.tableView.selectRow(0)

    def makeAllWhite(self):
        if self.colored == True:
            for row in range(self.tableView.rowCount()):
                for column in range(self.tableView.columnCount()):
                    item = self.tableView.item(row, column)
                    if item is not None:
                        item.setForeground(Qt.black)
                        item.setBackground(QColor("#fbfbfb"))
        self.colored = False

    def finishedEdit(self):
        self.isChanged = True

    def contextMenuEvent(self, event):
        self.menu = QMenu(self)
        if self.tableView.selectionModel().hasSelection():
            # copy
            copyAction = QAction(QIcon.fromTheme("edit-copy"), 'Copy Cell',
                                 self)
            copyAction.triggered.connect(lambda: self.copyByContext())
            # paste
            pasteAction = QAction(QIcon.fromTheme("edit-paste"), 'Paste Cell',
                                  self)
            pasteAction.triggered.connect(lambda: self.pasteByContext())
            # cut
            cutAction = QAction(QIcon.fromTheme("edit-cut"), 'Cut Cell', self)
            cutAction.triggered.connect(lambda: self.cutByContext())
            # delete selected Row
            removeAction = QAction(QIcon.fromTheme("edit-delete"),
                                   'delete Row', self)
            removeAction.triggered.connect(
                lambda: self.deleteRowByContext(event))
            # add Row after
            addAction = QAction(QIcon.fromTheme("add"), 'insert new Row after',
                                self)
            addAction.triggered.connect(lambda: self.addRowByContext(event))
            # add Row before
            addAction2 = QAction(QIcon.fromTheme("add"),
                                 'insert new Row before', self)
            addAction2.triggered.connect(lambda: self.addRowByContext2(event))
            # add Column before
            addColumnBeforeAction = QAction(QIcon.fromTheme("add"),
                                            'insert new Column before', self)
            addColumnBeforeAction.triggered.connect(
                lambda: self.addColumnBeforeByContext(event))
            # add Column after
            addColumnAfterAction = QAction(QIcon.fromTheme("add"),
                                           'insert new Column after', self)
            addColumnAfterAction.triggered.connect(
                lambda: self.addColumnAfterByContext(event))
            # delete Column
            deleteColumnAction = QAction(QIcon.fromTheme("edit-delete"),
                                         'delete Column', self)
            deleteColumnAction.triggered.connect(
                lambda: self.deleteColumnByContext(event))
            # replace all
            row = self.selectedRow()
            col = self.selectedColumn()
            myitem = self.tableView.item(row, col)
            if myitem is not None:
                self.mytext = myitem.text()
            replaceThisAction = QAction(
                QIcon.fromTheme("edit-find-and-replace"),
                "replace all occurrences of '" + self.mytext + "'", self)
            replaceThisAction.triggered.connect(lambda: self.replaceThis())
            # find all
            findThisAction = QAction(
                QIcon.fromTheme("edit-find"),
                "find all rows contains '" + self.mytext + "'", self)
            findThisAction.triggered.connect(lambda: self.findThis())
            ###
            self.menu.addAction(copyAction)
            self.menu.addAction(pasteAction)
            self.menu.addAction(cutAction)
            self.menu.addSeparator()
            self.menu.addAction(QIcon.fromTheme("edit-delete"), "delete",
                                self.deleteCell, QKeySequence.Delete)
            self.menu.addSeparator()
            self.menu.addAction(QIcon.fromTheme("edit-copy"), "copy Row",
                                self.copyRow)
            self.menu.addAction(QIcon.fromTheme("edit-paste"), "paste Row",
                                self.pasteRow)
            self.menu.addSeparator()
            self.menu.addAction(QIcon.fromTheme("edit-copy"), "copy Column",
                                self.copyColumn)
            self.menu.addAction(QIcon.fromTheme("edit-paste"), "paste Column",
                                self.pasteColumn)
            self.menu.addSeparator()
            self.menu.addAction(addAction)
            self.menu.addAction(addAction2)
            self.menu.addSeparator()
            self.menu.addAction(addColumnBeforeAction)
            self.menu.addAction(addColumnAfterAction)
            self.menu.addSeparator()
            self.menu.addAction(removeAction)
            self.menu.addAction(deleteColumnAction)
            self.menu.addSeparator()
            self.menu.addAction(replaceThisAction)
            self.menu.addAction(findThisAction)
            self.menu.addSeparator()
            self.menu.addAction(self.whiteAction)
            self.menu.popup(QCursor.pos())

    def replaceThis(self):
        row = self.selectedRow()
        col = self.selectedColumn()
        myitem = self.tableView.item(row, col)
        if myitem is not None:
            mytext = myitem.text()
            dlg = QInputDialog()
            newtext, ok = dlg.getText(
                self, "Replace all",
                "replace all <b>" + mytext + " </b> with:", QLineEdit.Normal,
                "", Qt.Dialog)
            if ok:
                items = self.tableView.findItems(mytext, Qt.MatchExactly)
                if items:
                    for item in items:
                        newItem = QTableWidgetItem(newtext)
                        self.tableView.setItem(item.row(), item.column(),
                                               newItem)

    def deleteRowByContext(self, event):
        row = self.selectedRow()
        self.tableView.removeRow(row)
        self.msg("Row " + str(row) + " deleted")
        self.tableView.selectRow(row)
        self.isChanged = True

    def addRowByContext(self, event):
        if self.tableView.columnCount() == 0:
            self.tableView.setColumnCount(1)
        if self.tableView.rowCount() == 0:
            self.tableView.setRowCount(1)
            self.tableView.selectRow(0)
        else:
            row = self.selectedRow()
            self.tableView.insertRow(row + 1)
            self.msg("Row at " + str(row) + " inserted")
            self.tableView.selectRow(row + 1)
        self.isChanged = True

    def addRowByContext2(self, event):
        if self.tableView.columnCount() == 0:
            self.tableView.setColumnCount(1)
        if self.tableView.rowCount() == 0:
            self.tableView.setRowCount(1)
            self.tableView.selectRow(0)
        else:
            row = self.selectedRow()
            self.tableView.insertRow(row)
            self.msg("Row at " + str(row) + " inserted")
            self.tableView.selectRow(row)
        self.isChanged = True

    def addColumnBeforeByContext(self, event):
        if self.tableView.columnCount() == 0:
            self.tableView.setColumnCount(1)
        else:
            col = self.selectedColumn()
            self.tableView.insertColumn(col)
            self.msg("Column at " + str(col) + " inserted")
        if self.tableView.rowCount() == 0:
            self.tableView.setRowCount(1)
        self.isChanged = True

    def addColumnAfterByContext(self, event):
        if self.tableView.columnCount() == 0:
            self.tableView.setColumnCount(1)
        else:
            col = self.selectedColumn() + 1
            self.tableView.insertColumn(col)
            self.msg("Column at " + str(col) + " inserted")
        if self.tableView.rowCount() == 0:
            self.tableView.setRowCount(1)
        self.isChanged = True

    def deleteColumnByContext(self, event):
        col = self.selectedColumn()
        self.tableView.removeColumn(col)
        self.msg("Column at " + str(col) + " removed")
        self.isChanged = True

    def copyByContext(self):
        row = self.selectedRow()
        col = self.selectedColumn()
        myitem = self.tableView.item(row, col)
        if myitem is not None:
            clip = QApplication.clipboard()
            clip.setText(myitem.text())

    def pasteByContext(self):
        row = self.selectedRow()
        col = self.selectedColumn()
        clip = QApplication.clipboard()
        newItem = QTableWidgetItem(clip.text())
        self.tableView.setItem(row, col, newItem)
        self.tableView.resizeColumnsToContents()
        self.isChanged = True

    def cutByContext(self):
        row = self.selectedRow()
        col = self.selectedColumn()
        myitem = self.tableView.item(row, col)
        if myitem is not None:
            clip = QApplication.clipboard()
            clip.setText(myitem.text())
            newItem = QTableWidgetItem("")
            self.tableView.setItem(row, col, newItem)
            self.isChanged = True

    def closeEvent(self, event):
        if self.isChanged == True:
            quit_msg = "<b>The document was changed.<br>Do you want to save the changes?</ b>"
            reply = QMessageBox.question(self, 'Save Confirmation', quit_msg,
                                         QMessageBox.Yes, QMessageBox.No)
            if reply == QMessageBox.Yes:
                event.accept()
                self.saveOnQuit()
        self.saveSettings()
        print("Goodbye ...")

    def readSettings(self):
        print("reading settings")
        if self.settings.contains("geometry"):
            self.setGeometry(self.settings.value('geometry'))
        if self.settings.contains("horHeader"):
            if self.settings.value('horHeader') == "true":
                self.tableView.horizontalHeader().setVisible(True)
            else:
                self.tableView.horizontalHeader().setVisible(False)
        if self.settings.contains("vertHeader"):
            if self.settings.value('vertHeader') == "true":
                self.tableView.verticalHeader().setVisible(True)
            else:
                self.tableView.verticalHeader().setVisible(False)

    def saveSettings(self):
        print("saving settings")
        self.settings.setValue('geometry', self.geometry())
        self.settings.setValue('horHeader',
                               self.tableView.horizontalHeader().isVisible())
        self.settings.setValue('vertHeader',
                               self.tableView.verticalHeader().isVisible())

    def saveOnQuit(self):
        if self.fileName == "":
            self.writeCsv()
        else:
            path = self.fileName
            with open(path, 'w') as stream:
                print("saving", path)
                writer = csv.writer(stream, delimiter=self.delimit)
                for row in range(self.tableView.rowCount()):
                    rowdata = []
                    for column in range(self.tableView.columnCount()):
                        item = self.tableView.item(row, column)
                        if item is not None:
                            rowdata.append(item.text())
                        else:
                            rowdata.append('')
                    writer.writerow(rowdata)
        self.isChanged = False

    def setCurrentFile(self, fileName):
        self.fileName = fileName
        self.fname = os.path.splitext(str(fileName))[0].split("/")[-1]
        if self.fileName:
            self.setWindowTitle(self.strippedName(self.fileName) + "[*]")
        else:
            self.setWindowTitle("no File")

        files = self.settings.value('recentFileList', [])

        try:
            files.remove(fileName)
        except ValueError:
            pass

        files.insert(0, fileName)
        del files[self.MaxRecentFiles:]

        self.settings.setValue('recentFileList', files)

        for widget in QApplication.topLevelWidgets():
            if isinstance(widget, MyWindow_2):
                widget.updateRecentFileActions()

    def updateRecentFileActions(self):
        mytext = ""
        files = self.settings.value('recentFileList', [])
        numRecentFiles = min(len(files), self.MaxRecentFiles)

        for i in range(numRecentFiles):
            text = "&%d %s" % (i + 1, self.strippedName(files[i]))
            self.recentFileActs[i].setText(text)
            self.recentFileActs[i].setData(files[i])
            self.recentFileActs[i].setVisible(True)
            self.recentFileActs[i].setIcon(
                QIcon.fromTheme("gnome-mime-text-x"))

        for j in range(numRecentFiles, self.MaxRecentFiles):
            self.recentFileActs[j].setVisible(False)

        self.separatorAct.setVisible((numRecentFiles > 0))

    def clearRecentFiles(self, fileName):
        #        self.settings.clear()
        mf = []
        self.settings.setValue('recentFileList', mf)
        self.updateRecentFileActions()

    def strippedName(self, fullFileName):
        return QFileInfo(fullFileName).fileName()

    def msg(self, message):
        self.statusBar().showMessage(message)

    def setHeaders(self):
        self.tableView.selectRow(0)
        self.copyRow()
        for column in range(self.tableView.columnCount()):
            newItem = QTableWidgetItem(self.copiedRow[column])
            self.tableView.setHorizontalHeaderItem(column, newItem)
        self.tableView.removeRow(0)
        self.tableView.resizeColumnsToContents()

    def setHeadersToFirstRow(self):
        self.tableView.insertRow(0)
        for column in range(self.tableView.columnCount()):
            newItem = QTableWidgetItem(
                self.tableView.horizontalHeaderItem(column))
            ind = QTableWidgetItem(str(column + 1))
            self.tableView.setHorizontalHeaderItem(column, ind)
            self.tableView.setItem(0, column, newItem)

    def copyRow(self):
        row = self.selectedRow()
        for column in range(self.tableView.columnCount()):
            if not self.tableView.item(row, column) == None:
                self.copiedRow.append(self.tableView.item(row, column).text())
                #        print(self.copiedRow)

    def pasteRow(self):
        row = self.selectedRow()
        for column in range(self.tableView.columnCount()):
            newItem = QTableWidgetItem(self.copiedRow[column])
            self.tableView.setItem(row, column, newItem)

    def copyColumn(self):
        column = self.selectedColumn()
        for row in range(self.tableView.rowCount()):
            self.copiedColumn.append(self.tableView.item(row, column).text())
            #        print(self.copiedColumn)

    def pasteColumn(self):
        column = self.selectedColumn()
        for row in range(self.tableView.rowCount()):
            newItem = QTableWidgetItem(self.copiedColumn[row])
            self.tableView.setItem(row, column, newItem)
            self.tableView.resizeColumnsToContents()
class LineEditTableCellDelegate(QItemDelegate):
    """
    Used for enabling read-only and text selectable cells in QTableView widgets.
    """
    def __init__(self, parent, img_dir: str):
        QItemDelegate.__init__(
            self,
            parent,
        )
        self.img_dir = img_dir
        self.save_action = QAction('Save', self)
        self.set_icon(self.save_action, "*****@*****.**")
        self.save_action.triggered.connect(self.on_save_data)
        self.undo_action = QAction('Revert', self)
        self.set_icon(self.undo_action, "*****@*****.**")
        self.undo_action.triggered.connect(self.on_revert_data)
        self.editor = None
        self.old_data = ''
        self.cur_item_index = None
        self.data_history: Dict[QModelIndex, List[str]] = {}

    def set_icon(self, widget, ico_name):
        icon = QIcon()
        icon.addPixmap(QPixmap(os.path.join(self.img_dir, ico_name)))
        widget.setIcon(icon)

    def on_save_data(self):
        if self.editor:
            self.commitData.emit(self.editor)
            self.closeEditor.emit(self.editor)
            self.editor = None

    def on_revert_data(self):
        if self.editor and self.cur_item_index:
            sd = self.data_history.get(self.cur_item_index)
            if sd:
                sd.pop()
                if sd:
                    t = sd[-1]
                else:
                    t = ''
                self.editor.setText(t)

    def createEditor(self, parent, option, index):
        self.cur_item_index = index
        self.editor = QLineEdit(parent)
        self.editor.addAction(self.save_action, QLineEdit.TrailingPosition)
        if self.data_history.get(index):
            self.editor.addAction(self.undo_action, QLineEdit.TrailingPosition)
        return self.editor

    def setEditorData(self, editor, index):
        self.old_data = index.data()
        editor.setText(self.old_data)
        sd = self.data_history.get(index)
        if not sd:
            sd = []
            self.data_history[index] = sd
        if self.old_data:
            if not sd or sd[-1] != self.old_data:
                sd.append(self.old_data)

    def setModelData(self, editor, model, index):
        new_data = editor.text()
        if new_data != self.old_data:
            model.setData(index, new_data)
Beispiel #12
0
class Login(QDialog):
    def __init__(self):
        super(Login, self).__init__()
        self.setWindowIcon(QIcon('qt.ico'))
        self.setWindowFlags(Qt.FramelessWindowHint
                            | Qt.WindowMinimizeButtonHint)

        self.setWindowTitle(u"Mod")
        self.setFixedSize(300, 400)
        self.setObjectName('principal')
        self.createGUI()

    def createGUI(self):
        self.frame_window = QWidget(self)
        self.frame_window.setGeometry(0, 0, 300, 40)
        self.frame_window.setObjectName('frame_window')

        self.title_frame = QLabel(self.frame_window)
        self.title_frame.setGeometry(0, 0, 300, 40)
        self.title_frame.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
        self.title_frame.setFont(QFont("Tahoma", 20, QFont.Bold))
        self.title_frame.setText(u"Mod Login")
        self.title_frame.setObjectName('title_frame')

        self.container = QWidget(self)
        self.container.setGeometry(0, 0, 300, 400)
        self.container.setObjectName('container')

        # buttons
        clsfont = self.font() or QFont()
        clsfont.setFamily('Webdings')
        self.button_close = QPushButton('r', self.container, font=clsfont)
        self.button_close.setGeometry(260, 0, 40, 40)
        self.button_close.setObjectName('button_close')

        self.button_login = QPushButton(self.container)
        self.button_login.setGeometry(20, 300, 260, 40)
        self.button_login.setText(u'Login')
        self.button_login.setObjectName('button_login')
        self.button_login.setCursor(QCursor(Qt.PointingHandCursor))

        self.line_username = QLineEdit(self.container)
        self.line_username.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        self.line_username.setFont(QFont("Tahoma", 20, QFont.Bold))
        self.line_username.setGeometry(20, 180, 260, 40)
        self.line_username.setPlaceholderText(u'Username')
        self.line_username.setObjectName('line_username')
        self.ac_username = QAction()
        self.ac_username.setIcon(QIcon('username.png'))
        self.line_username.addAction(self.ac_username,
                                     QLineEdit.LeadingPosition)

        self.line_password = QLineEdit(self.container)
        self.line_password.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        self.line_password.setFont(QFont("Tahoma", 20, QFont.Bold))
        self.line_password.setGeometry(20, 230, 260, 40)
        self.line_password.setEchoMode(QLineEdit.Password)
        self.line_password.setPlaceholderText(u'Password')
        self.line_password.setObjectName('line_password')
        self.ac1_password = QAction()
        self.ac1_password.setIcon(QIcon('password.png'))
        self.ac2_password = QAction()
        self.ac2_password.setToolTip('Show Password')
        self.ac2_password.setIcon(QIcon('show_pw.png'))
        self.line_password.addAction(self.ac1_password,
                                     QLineEdit.LeadingPosition)
        self.line_password.addAction(self.ac2_password,
                                     QLineEdit.TrailingPosition)

        # conexiones
        self.button_close.clicked.connect(self.close)
        self.ac2_password.triggered.connect(self.show_pass)
        self.button_login.clicked.connect(self.handleLogin)
        # 初始化焦点位于哪个控件上
        self.button_login.setFocus()  #获取焦点

    def handleLogin(self):
        # self.accept()  # 关键
        if (self.line_username.text() == 'admin'
                and self.line_password.text() == '123456'):

            self.appmain = MainWindow()
            # self.accept()  # 关键
            self.hide()
            self.appmain.show()

        else:
            QMessageBox.warning(self, u'Prompt', u'User or Password Error',
                                QMessageBox.Ok)

    def mousePressEvent(self, event):
        self.offset = event.pos()

    def mouseMoveEvent(self, event):
        x = event.globalX()
        y = event.globalY()
        x_w = self.offset.x()
        y_w = self.offset.y()
        self.move(x - x_w, y - y_w)

    def keyPressEvent(self, event):
        if (event.key() == Qt.Key_Return):
            self.handleLogin()

    def show_pass(self):
        if self.line_password.echoMode() == QLineEdit.Password:
            self.line_password.setEchoMode(QLineEdit.Normal)
        else:
            self.line_password.setEchoMode(QLineEdit.Password)
Beispiel #13
0
class RenameDialog(QDialog):

    def __init__(self, parent: QWidget) -> None:
        super().__init__(parent)

        self._basename: str = ""

        self._build_gui()

    def _build_gui(self) -> None:
        self.resize(600, 100)
        self.setWindowTitle("RenameDialog")
        self.setWindowModality(Qt.WindowModal)

        # Widgets
        icon_label = QLabel()
        icon_label.setPixmap(QIcon.fromTheme("accessories-text-editor").pixmap(48))
        icon_label.setAlignment(Qt.AlignTop)

        self.label = QLabel("Rename ...")
        self.label.setTextInteractionFlags(Qt.TextSelectableByMouse)
        self.name_edit = QLineEdit(self)

        self.name_reload = self.name_edit.addAction(QIcon.fromTheme("reload"), QLineEdit.TrailingPosition)
        self.name_reload.setShortcut("F5")
        self.name_reload.setToolTip("Reset the filename to it's original name")

        self.button_box = QDialogButtonBox(self)

        self.btn_rename = QPushButton(QIcon.fromTheme("document-save-as"), "Rename")
        self.button_box.addButton(self.btn_rename, QDialogButtonBox.AcceptRole)
        self.btn_cancel = self.button_box.addButton(QDialogButtonBox.Cancel)
        self.btn_rename.setDefault(True)

        # layout
        self.vbox = QVBoxLayout()

        self.vbox.addWidget(self.label)
        self.vbox.addWidget(self.name_edit)
        self.vbox.addStretch()
        self.vbox.addWidget(self.button_box)

        hbox = QHBoxLayout()
        hbox.addWidget(icon_label)
        hbox.addLayout(self.vbox)
        self.setLayout(hbox)

        # signals
        self.name_edit.returnPressed.connect(self.accept)
        self.btn_rename.clicked.connect(self._on_rename_clicked)
        self.btn_cancel.clicked.connect(self._on_cancel_clicked)
        self.name_reload.triggered.connect(self._on_name_reload)

    def _on_rename_clicked(self) -> None:
        self.accept()

    def _on_cancel_clicked(self) -> None:
        self.reject()

    def _on_name_reload(self) -> None:
        self.name_edit.setText(self._basename)
        root, ext = os.path.splitext(self._basename)
        self.name_edit.setSelection(0, len(root))

    def get_old_basename(self) -> str:
        return self._basename

    def get_new_basename(self) -> str:
        return cast(str, self.name_edit.text())

    def set_basename(self, basename: str) -> None:
        self._basename = basename

        self.setWindowTitle("Rename \"{}\"".format(basename))
        self.label.setText("Rename \"{}\" to:".format(basename))

        self.name_edit.setText(basename)
        root, ext = os.path.splitext(basename)
        self.name_edit.setSelection(0, len(root))
class ProjectExecution(QWidget):
    """Project Execution widget class"""

    def __init__(self, parent):
        super(ProjectExecution, self).__init__()
        self._parent = parent
        grid = QGridLayout(self)

        grid.addWidget(QLabel(translations.TR_PROJECT_MAIN_FILE), 0, 0)
        # Main file
        self.path = QLineEdit()
        choose_main_file_action = QAction(self)
        choose_main_file_action.setIcon(
            self.style().standardIcon(self.style().SP_FileIcon))
        choose_main_file_action.setToolTip(
            translations.TR_PROJECT_SELECT_MAIN_FILE)
        self.path.addAction(
            choose_main_file_action, QLineEdit.TrailingPosition)
        clear_main_file_action = self.path.addAction(
            self.style().standardIcon(self.style().SP_LineEditClearButton),
            QLineEdit.TrailingPosition)
        clear_main_file_action.triggered.connect(self.path.clear)
        self.path.setPlaceholderText(
            os.path.join(os.path.expanduser("~"), 'path', 'to', 'main.py'))
        self.path.setText(self._parent.project.main_file)
        grid.addWidget(self.path, 0, 1)
        # this should be changed, and ALL pythonPath names to
        # python_custom_interpreter or something like that. this is NOT the
        # PYTHONPATH
        self.line_interpreter = QLineEdit()
        choose_interpreter = self.line_interpreter.addAction(
            self.style().standardIcon(self.style().SP_DirIcon),
            QLineEdit.TrailingPosition)
        self.line_interpreter.setText(self._parent.project.python_exec)
        completer = QCompleter(utils.get_python())
        completer.setCaseSensitivity(Qt.CaseInsensitive)
        completer.setFilterMode(Qt.MatchContains)
        self.line_interpreter.setCompleter(completer)
        self.line_interpreter.setPlaceholderText("python")
        grid.addWidget(QLabel(
            translations.TR_PROJECT_PYTHON_INTERPRETER), 1, 0)
        grid.addWidget(self.line_interpreter, 1, 1)
        # PYTHONPATH
        grid.addWidget(QLabel(translations.TR_PROJECT_PYTHON_PATH), 2, 0)
        self.txt_python_path = QPlainTextEdit()  # TODO : better widget
        self.txt_python_path.setPlainText(self._parent.project.python_path)
        self.txt_python_path.setToolTip(translations.TR_PROJECT_PATH_PER_LINE)
        grid.addWidget(self.txt_python_path, 2, 1)

        # Additional builtins/globals for pyflakes
        grid.addWidget(QLabel(translations.TR_PROJECT_BUILTINS), 3, 0)
        self.additional_builtins = QLineEdit()
        self.additional_builtins.setText(
            ' '.join(self._parent.project.additional_builtins))
        self.additional_builtins.setToolTip(
            translations.TR_PROJECT_BUILTINS_TOOLTIP)
        grid.addWidget(self.additional_builtins, 3, 1)
        # Pre script
        self._line_pre_exec = QLineEdit()
        choose_pre_exec = QAction(self)
        choose_pre_exec.setToolTip(
            "Choose Script to execute before run project")
        choose_pre_exec.setIcon(
            self.style().standardIcon(self.style().SP_FileIcon))
        self._line_pre_exec.addAction(
            choose_pre_exec, QLineEdit.TrailingPosition)
        clear_pre_action = self._line_pre_exec.addAction(
            self.style().standardIcon(self.style().SP_LineEditClearButton),
            QLineEdit.TrailingPosition)
        clear_pre_action.triggered.connect(self._line_pre_exec.clear)
        self._line_pre_exec.setReadOnly(True)
        self._line_pre_exec.setText(self._parent.project.pre_exec_script)
        self._line_pre_exec.setPlaceholderText(
            os.path.join(os.path.expanduser("~"), 'path', 'to', 'script.sh'))
        grid.addWidget(QLabel(translations.TR_PROJECT_PRE_EXEC), 4, 0)
        grid.addWidget(self._line_pre_exec, 4, 1)
        # Post script
        self._line_post_exec = QLineEdit()
        choose_post_exec = QAction(self)
        choose_post_exec.setToolTip(
            "Choose script to execute after run project")
        choose_post_exec.setIcon(
            self.style().standardIcon(self.style().SP_FileIcon))
        self._line_post_exec.addAction(
            choose_post_exec, QLineEdit.TrailingPosition)
        clear_post_action = self._line_post_exec.addAction(
            self.style().standardIcon(self.style().SP_LineEditClearButton),
            QLineEdit.TrailingPosition)
        clear_post_action.triggered.connect(self._line_post_exec.clear)
        self._line_post_exec.setReadOnly(True)
        self._line_post_exec.setText(self._parent.project.post_exec_script)
        self._line_post_exec.setPlaceholderText(
            os.path.join(os.path.expanduser("~"), 'path', 'to', 'script.sh'))
        grid.addWidget(QLabel(translations.TR_PROJECT_POST_EXEC), 5, 0)
        grid.addWidget(self._line_post_exec, 5, 1)

        # grid.addItem(QSpacerItem(5, 10, QSizePolicy.Expanding,
        #             QSizePolicy.Expanding), 6, 0)

        # Properties
        grid.addWidget(QLabel(translations.TR_PROJECT_PROPERTIES), 7, 0)
        self._line_params = QLineEdit()
        self._line_params.setToolTip(translations.TR_PROJECT_PARAMS_TOOLTIP)
        self._line_params.setText(self._parent.project.program_params)
        self._line_params.setPlaceholderText('verbose, debug, force')
        grid.addWidget(QLabel(translations.TR_PROJECT_PARAMS), 8, 0)
        grid.addWidget(self._line_params, 8, 1)
        # Widgets for virtualenv properties
        self.txtVenvPath = QLineEdit()
        # ui_tools.LineEditButton(
        #    self.txtVenvPath, self.txtVenvPath.clear,
        #    self.style().standardPixmap(self.style().SP_TrashIcon))
        self.txtVenvPath.setText(self._parent.project.venv)
        self._dir_completer = QCompleter()
        self._dir_completer.setModel(QDirModel(self._dir_completer))
        self.txtVenvPath.setCompleter(self._dir_completer)
        self.txtVenvPath.setPlaceholderText(
            os.path.join(os.path.expanduser("~"), 'path', 'to', 'virtualenv'))
        # self.btnVenvPath = QPushButton(QIcon(":img/open"), '')
        grid.addWidget(QLabel(translations.TR_PROJECT_VIRTUALENV), 9, 0)
        grid.addWidget(self.txtVenvPath, 9, 1)
        # grid.addWidget(self.btnVenvPath, 9, 2)

        choose_main_file_action.triggered.connect(self.select_file)
        choose_interpreter.triggered.connect(self._load_python_path)
        choose_pre_exec.triggered.connect(self.select_pre_exec_script)
        choose_post_exec.triggered.connect(self.select_post_exec_script)
        # self.connect(self.btnBrowse, SIGNAL("clicked()"), self.select_file)
        # self.connect(self.btnPythonPath, SIGNAL("clicked()"),
        #             self._load_python_path)
        # self.connect(self.btnVenvPath, SIGNAL("clicked()"),
        #             self._load_python_venv)
        # self.connect(self.btnPreExec, SIGNAL("clicked()"),
        #             self.select_pre_exec_script)
        # self.connect(self.btnPostExec, SIGNAL("clicked()"),
        #             self.select_post_exec_script)

    @property
    def main_file(self):
        return self.path.text()

    @property
    def interpreter(self):
        return self.line_interpreter.text()

    @property
    def pre_script(self):
        return self._line_pre_exec.text()

    @property
    def post_script(self):
        return self._line_post_exec.text()

    @property
    def params(self):
        return self._line_params.text()

    def _load_python_path(self):
        """Ask the user a python path and set its value"""
        path_interpreter = QFileDialog.getOpenFileName(
            self, translations.TR_PROJECT_SELECT_PYTHON_PATH)[0]
        if path_interpreter:
            self.line_interpreter.setText(path_interpreter)

    def _load_python_venv(self):
        """Ask the user a python venv and set its value"""
        venv = QFileDialog.getExistingDirectory(
            self, translations.TR_PROJECT_SELECT_VIRTUALENV)
        if sys.platform == 'win32':
            venv = os.path.join(venv, 'Scripts', 'python.exe')
        else:
            venv = os.path.join(venv, 'bin', 'python')
        # check if venv folder exists
        if not os.path.exists(venv):
            QMessageBox.information(
                self,
                translations.TR_PROJECT_SELECT_VIRTUALENV_MESSAGE_TITLE,
                translations.TR_PROJECT_SELECT_VIRTUALENV_MESSAGE_BODY)
            self.txtVenvPath.setText("")
        else:
            self.txtVenvPath.setText(venv)

    def select_file(self):
        """Ask the user a python main file and set its value"""
        filename, _ = QFileDialog.getOpenFileName(
            self, translations.TR_PROJECT_SELECT_MAIN_FILE,
            self._parent.project.path,
            'Python Files (*.py);;Python Bytecode (*.py[codw]);;All Files(*)')
        if filename:
            filename = file_manager.convert_to_relative(
                self._parent.project.path, filename)
            self.path.setText(filename)

    def select_pre_exec_script(self):
        """Ask the user a python pre-exec script and set its value"""
        filename = QFileDialog.getOpenFileName(
            self, translations.TR_PROJECT_SELECT_PRE_SCRIPT,
            self._parent.project.path,
            '*(*.*);;Bash(*.sh);;Python PY(*.py);;Python Bytecode(*.py[codw]);;'
            'Bat(*.bat);;Cmd(*.cmd);;Exe(*.exe);;Bin(*.bin);;App(*.app)')[0]
        if filename:
            filename = file_manager.convert_to_relative(
                self._parent.project.path, filename)
            self._line_pre_exec.setText(filename)

    def select_post_exec_script(self):
        """Ask the user a python post-exec script and set its value"""
        filename = QFileDialog.getOpenFileName(
            self, translations.TR_PROJECT_SELECT_POST_SCRIPT,
            self._parent.project.path,
            '*(*.*);;Bash(*.sh);;Python PY(*.py);;Python Bytecode(*.py[codw]);;'
            'Bat(*.bat);;Cmd(*.cmd);;Exe(*.exe);;Bin(*.bin);;App(*.app)')[0]
        if filename:
            filename = file_manager.convert_to_relative(
                self._parent.project.path, filename)
            self._line_post_exec.setText(filename)
Beispiel #15
0
class RDBPDBTool(QDialog):

    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle(self.tr("WinRDBI DB File to PDB"))
        self.setModal(True)
        self.setMinimumWidth(600)

        self._process = QProcess(self)
        self._process.setProgram("python")
        self._process.finished.connect(self._on_finished)

        vbox = QVBoxLayout(self)
        hbox = QHBoxLayout()
        hbox.addWidget(QLabel(self.tr("Ubicación del .rdb:")))
        self._line_location = QLineEdit()
        self._line_location.setReadOnly(True)
        choose_location = self._line_location.addAction(
            self.style().standardIcon(
                self.style().SP_DirIcon), QLineEdit.TrailingPosition)
        hbox.addWidget(self._line_location)
        vbox.addLayout(hbox)
        aviso = QLabel(
                self.tr(
                    "<b><i>El archivo será guardado en el mismo directorio "
                    "que el original.</i></b>"))
        f = aviso.font()
        f.setPointSize(10)
        aviso.setFont(f)
        vbox.addWidget(aviso)
        self._check_open = QCheckBox(self.tr("Abrir la BD al finalizar"))
        vbox.addWidget(self._check_open)

        hbox = QHBoxLayout()
        hbox.addStretch(1)
        start_btn = QPushButton(self.tr("Convertir!"))
        hbox.addWidget(start_btn)
        cancel_btn = QPushButton(self.tr("Salir"))
        hbox.addWidget(cancel_btn)
        vbox.addLayout(hbox)

        choose_location.triggered.connect(self._select_rdb_file)
        start_btn.clicked.connect(self._start_convertion)
        cancel_btn.clicked.connect(self.close)

    def _start_convertion(self):
        rdb_filename = self._line_location.text()

        tool = os.path.join(settings.ROOT_DIR, "rdb_to_pdb")

        args = [tool, rdb_filename]
        self._process.setArguments(args)
        self._process.start()

    def _on_finished(self, code, status):
        if status == QProcess.NormalExit == code:
            QMessageBox.information(
                self, self.tr("Completado!"),
                self.tr("Todo ha salido muy bien!"))
            if self._check_open.isChecked():
                central = Pireal.get_service("central")
                rdb = os.path.splitext(self._line_location.text())[0]
                pdb = rdb + ".pdb"
                central.open_database(pdb)
                self.close()
        else:
            QMessageBox.critical(
                self, "Error", "El proceso no se ha completado")

    def _select_rdb_file(self):
        filename = QFileDialog.getOpenFileName(
            self, self.tr("Selecciona el arhico RDB"),
            "~", "RDB Files (*.rdb)")[0]
        if filename:
            self._line_location.setText(filename)
Beispiel #16
0
class myEditor(QMainWindow):
    def __init__(self, parent=None):
        super(myEditor, self).__init__(parent)
        self.MaxRecentFiles = 5
        self.windowList = []
        self.recentFileActs = []
        self.setAttribute(Qt.WA_DeleteOnClose)
        # Editor Widget ...
        QIcon.setThemeName('Faenza-Dark')
        self.editor = QPlainTextEdit()
        self.editor.setStyleSheet(stylesheet2(self))
        self.editor.setFrameStyle(QFrame.NoFrame)
        self.editor.setTabStopWidth(14)
        self.extra_selections = []
        self.fname = ""
        self.filename = ""
        # Line Numbers ...
        self.numbers = NumberBar(self.editor)

        self.createActions()
        # Laying out...
        layoutH = QHBoxLayout()
        layoutH.setSpacing(1.5)
        layoutH.addWidget(self.numbers)
        layoutH.addWidget(self.editor)

        ### begin toolbar
        tb = QToolBar(self)
        tb.setWindowTitle("File Toolbar")

        self.newAct = QAction("&New",
                              self,
                              shortcut=QKeySequence.New,
                              statusTip="Create a new file",
                              triggered=self.newFile)
        self.newAct.setIcon(QIcon.fromTheme("document-new"))

        self.openAct = QAction("&Open",
                               self,
                               shortcut=QKeySequence.Open,
                               statusTip="open file",
                               triggered=self.openFile)
        self.openAct.setIcon(QIcon.fromTheme("document-open"))

        self.saveAct = QAction("&Save",
                               self,
                               shortcut=QKeySequence.Save,
                               statusTip="save file",
                               triggered=self.fileSave)
        self.saveAct.setIcon(QIcon.fromTheme("document-save"))

        self.saveAsAct = QAction("&Save as ...",
                                 self,
                                 shortcut=QKeySequence.SaveAs,
                                 statusTip="save file as ...",
                                 triggered=self.fileSaveAs)
        self.saveAsAct.setIcon(QIcon.fromTheme("document-save-as"))

        self.exitAct = QAction("Exit",
                               self,
                               shortcut=QKeySequence.Quit,
                               toolTip="Exit",
                               triggered=self.handleQuit)
        self.exitAct.setIcon(QIcon.fromTheme("application-exit"))

        ### find / replace toolbar
        self.tbf = QToolBar(self)
        self.tbf.setWindowTitle("Find Toolbar")
        self.findfield = QLineEdit()
        self.findfield.addAction(QIcon.fromTheme("edit-find"),
                                 QLineEdit.LeadingPosition)
        self.findfield.setClearButtonEnabled(True)
        self.findfield.setFixedWidth(150)
        self.findfield.setPlaceholderText("find")
        self.findfield.setToolTip("press RETURN to find")
        self.findfield.setText("")
        ft = self.findfield.text()
        self.findfield.returnPressed.connect(self.findText)
        self.tbf.addWidget(self.findfield)
        self.replacefield = QLineEdit()
        self.replacefield.addAction(QIcon.fromTheme("edit-find-and-replace"),
                                    QLineEdit.LeadingPosition)
        self.replacefield.setClearButtonEnabled(True)
        self.replacefield.setFixedWidth(150)
        self.replacefield.setPlaceholderText("replace with")
        self.replacefield.setToolTip("press RETURN to replace the first")
        self.replacefield.returnPressed.connect(self.replaceOne)
        self.tbf.addSeparator()
        self.tbf.addWidget(self.replacefield)
        self.tbf.addSeparator()

        self.tbf.addAction("replace all", self.replaceAll)
        self.tbf.addSeparator()

        layoutV = QVBoxLayout()

        bar = self.menuBar()

        self.filemenu = bar.addMenu("File")
        self.separatorAct = self.filemenu.addSeparator()
        self.filemenu.addAction(self.newAct)
        self.filemenu.addAction(self.openAct)
        self.filemenu.addAction(self.saveAct)
        self.filemenu.addAction(self.saveAsAct)
        self.filemenu.addSeparator()
        for i in range(self.MaxRecentFiles):
            self.filemenu.addAction(self.recentFileActs[i])
        self.updateRecentFileActions()
        self.filemenu.addSeparator()
        self.filemenu.addAction(self.exitAct)
        bar.setStyleSheet(stylesheet2(self))
        editmenu = bar.addMenu("Edit")
        editmenu.addAction(
            QAction(QIcon.fromTheme('edit-copy'),
                    "Copy",
                    self,
                    triggered=self.editor.copy,
                    shortcut=QKeySequence.Copy))
        editmenu.addAction(
            QAction(QIcon.fromTheme('edit-cut'),
                    "Cut",
                    self,
                    triggered=self.editor.cut,
                    shortcut=QKeySequence.Cut))
        editmenu.addAction(
            QAction(QIcon.fromTheme('edit-paste'),
                    "Paste",
                    self,
                    triggered=self.editor.paste,
                    shortcut=QKeySequence.Paste))
        editmenu.addAction(
            QAction(QIcon.fromTheme('edit-delete'),
                    "Delete",
                    self,
                    triggered=self.editor.cut,
                    shortcut=QKeySequence.Delete))
        editmenu.addSeparator()
        editmenu.addAction(
            QAction(QIcon.fromTheme('edit-select-all'),
                    "Select All",
                    self,
                    triggered=self.editor.selectAll,
                    shortcut=QKeySequence.SelectAll))

        layoutV.addWidget(bar)
        layoutV.addWidget(self.tbf)
        layoutV.addLayout(layoutH)

        ### main window
        mq = QWidget(self)
        mq.setLayout(layoutV)
        self.setCentralWidget(mq)

        # Event Filter ...
        self.installEventFilter(self)
        self.editor.setFocus()
        self.cursor = QTextCursor()
        self.editor.setPlainText("hello")
        self.editor.moveCursor(self.cursor.End)
        self.editor.document().modificationChanged.connect(
            self.setWindowModified)

        # Brackets ExtraSelection ...
        self.left_selected_bracket = QTextEdit.ExtraSelection()
        self.right_selected_bracket = QTextEdit.ExtraSelection()

    def createActions(self):
        for i in range(self.MaxRecentFiles):
            self.recentFileActs.append(
                QAction(self, visible=False, triggered=self.openRecentFile))

    def openRecentFile(self):
        action = self.sender()
        if action:
            if (self.maybeSave()):
                self.openFileOnStart(action.data())

        ### New File
    def newFile(self):
        if self.maybeSave():
            self.editor.clear()
            self.editor.setPlainText("")
            self.filename = ""
            self.setModified(False)
            self.editor.moveCursor(self.cursor.End)

    ### open File
    def openFileOnStart(self, path=None):
        if path:
            inFile = QFile(path)
            if inFile.open(QFile.ReadWrite | QFile.Text):
                text = inFile.readAll()

                try:
                    # Python v3.
                    text = str(text, encoding='utf8')
                except TypeError:
                    # Python v2.
                    text = str(text)
                self.editor.setPlainText(text)
                self.filename = path
                self.setModified(False)
                self.fname = QFileInfo(path).fileName()
                self.setWindowTitle(self.fname + "[*]")
                self.document = self.editor.document()
                self.setCurrentFile(self.filename)

        ### open File
    def openFile(self, path=None):
        if self.maybeSave():
            if not path:
                path, _ = QFileDialog.getOpenFileName(
                    self, "Open File",
                    QDir.homePath() + "/Documents/",
                    "Text Files (*.txt *.csv *.py);;All Files (*.*)")

            if path:
                inFile = QFile(path)
                if inFile.open(QFile.ReadWrite | QFile.Text):
                    text = inFile.readAll()

                    try:
                        # Python v3.
                        text = str(text, encoding='utf8')
                    except TypeError:
                        # Python v2.
                        text = str(text)
                    self.editor.setPlainText(text)
                    self.filename = path
                    self.setModified(False)
                    self.fname = QFileInfo(path).fileName()
                    self.setWindowTitle(self.fname + "[*]")
                    self.document = self.editor.document()
                    self.setCurrentFile(self.filename)

    def fileSave(self):
        if (self.filename != ""):
            file = QFile(self.filename)
            print(self.filename)
            if not file.open(QFile.WriteOnly | QFile.Text):
                QMessageBox.warning(
                    self, "Error", "Cannot write file %s:\n%s." %
                    (self.filename, file.errorString()))
                return

            outstr = QTextStream(file)
            QApplication.setOverrideCursor(Qt.WaitCursor)
            outstr << self.editor.toPlainText()
            QApplication.restoreOverrideCursor()
            self.setModified(False)
            self.fname = QFileInfo(self.filename).fileName()
            self.setWindowTitle(self.fname + "[*]")
            self.setCurrentFile(self.filename)

        else:
            self.fileSaveAs()

            ### save File
    def fileSaveAs(self):
        fn, _ = QFileDialog.getSaveFileName(self, "Save as...", self.filename,
                                            "Python files (*.py)")

        if not fn:
            print("Error saving")
            return False

        lfn = fn.lower()
        if not lfn.endswith('.py'):
            fn += '.py'

        self.filename = fn
        self.fname = os.path.splitext(str(fn))[0].split("/")[-1]
        return self.fileSave()

    def closeEvent(self, e):
        if self.maybeSave():
            e.accept()
        else:
            e.ignore()

        ### ask to save
    def maybeSave(self):
        if not self.isModified():
            return True

        if self.filename.startswith(':/'):
            return True

        ret = QMessageBox.question(self, "Message",
                "<h4><p>The document was modified.</p>\n" \
                "<p>Do you want to save changes?</p></h4>",
                QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel)

        if ret == QMessageBox.Yes:
            if self.filename == "":
                self.fileSaveAs()
                return False
            else:
                self.fileSave()
                return True

        if ret == QMessageBox.Cancel:
            return False

        return True

    def findText(self):
        ft = self.findfield.text()
        if self.editor.find(ft):
            return
        else:
            self.editor.moveCursor(1)
            if self.editor.find(ft):
                self.editor.moveCursor(QTextCursor.Start,
                                       QTextCursor.MoveAnchor)

    def handleQuit(self):
        print("Goodbye ...")
        app.quit()

    def set_numbers_visible(self, value=True):
        self.numbers.setVisible(False)

    def match_left(self, block, character, start, found):
        map = {'{': '}', '(': ')', '[': ']'}

        while block.isValid():
            data = block.userData()
            if data is not None:
                braces = data.braces
                N = len(braces)

                for k in range(start, N):
                    if braces[k].character == character:
                        found += 1

                    if braces[k].character == map[character]:
                        if not found:
                            return braces[k].position + block.position()
                        else:
                            found -= 1

                block = block.next()
                start = 0

    def match_right(self, block, character, start, found):
        map = {'}': '{', ')': '(', ']': '['}

        while block.isValid():
            data = block.userData()

            if data is not None:
                braces = data.braces

                if start is None:
                    start = len(braces)
                for k in range(start - 1, -1, -1):
                    if braces[k].character == character:
                        found += 1
                    if braces[k].character == map[character]:
                        if found == 0:
                            return braces[k].position + block.position()
                        else:
                            found -= 1
            block = block.previous()
            start = None
#    '''

        cursor = self.editor.textCursor()
        block = cursor.block()
        data = block.userData()
        previous, next = None, None

        if data is not None:
            position = cursor.position()
            block_position = cursor.block().position()
            braces = data.braces
            N = len(braces)

            for k in range(0, N):
                if braces[k].position == position - block_position or braces[
                        k].position == position - block_position - 1:
                    previous = braces[k].position + block_position
                    if braces[k].character in ['{', '(', '[']:
                        next = self.match_left(block, braces[k].character,
                                               k + 1, 0)
                    elif braces[k].character in ['}', ')', ']']:
                        next = self.match_right(block, braces[k].character, k,
                                                0)
                    if next is None:
                        next = -1

        if next is not None and next > 0:
            if next == 0 and next >= 0:
                format = QTextCharFormat()

            cursor.setPosition(previous)
            cursor.movePosition(QTextCursor.NextCharacter,
                                QTextCursor.KeepAnchor)

            format.setBackground(QColor('white'))
            self.left_selected_bracket.format = format
            self.left_selected_bracket.cursor = cursor

            cursor.setPosition(next)
            cursor.movePosition(QTextCursor.NextCharacter,
                                QTextCursor.KeepAnchor)

            format.setBackground(QColor('white'))
            self.right_selected_bracket.format = format
            self.right_selected_bracket.cursor = cursor


#            '''

    def paintEvent(self, event):
        highlighted_line = QTextEdit.ExtraSelection()
        highlighted_line.format.setBackground(lineHighlightColor)
        highlighted_line.format.setProperty(QTextFormat.FullWidthSelection,
                                            QVariant(True))
        highlighted_line.cursor = self.editor.textCursor()
        highlighted_line.cursor.clearSelection()
        self.editor.setExtraSelections([
            highlighted_line, self.left_selected_bracket,
            self.right_selected_bracket
        ])

    def document(self):
        return self.editor.document

    def isModified(self):
        return self.editor.document().isModified()

    def setModified(self, modified):
        self.editor.document().setModified(modified)

    def setLineWrapMode(self, mode):
        self.editor.setLineWrapMode(mode)

    def clear(self):
        self.editor.clear()

    def setPlainText(self, *args, **kwargs):
        self.editor.setPlainText(*args, **kwargs)

    def setDocumentTitle(self, *args, **kwargs):
        self.editor.setDocumentTitle(*args, **kwargs)

    def set_number_bar_visible(self, value):
        self.numbers.setVisible(value)

    def replaceAll(self):
        print("replacing all")
        oldtext = self.editor.document().toPlainText()
        newtext = oldtext.replace(self.findfield.text(),
                                  self.replacefield.text())
        self.editor.setPlainText(newtext)
        self.setModified(True)

    def replaceOne(self):
        print("replacing all")
        oldtext = self.editor.document().toPlainText()
        newtext = oldtext.replace(self.findfield.text(),
                                  self.replacefield.text(), 1)
        self.editor.setPlainText(newtext)
        self.setModified(True)

    def setCurrentFile(self, fileName):
        self.curFile = fileName
        if self.curFile:
            self.setWindowTitle("%s - Recent Files" %
                                self.strippedName(self.curFile))
        else:
            self.setWindowTitle("Recent Files")

        settings = QSettings('Axel Schneider', 'PTEdit')
        files = settings.value('recentFileList')

        try:
            files.remove(fileName)
        except ValueError:
            pass

        files.insert(0, fileName)
        del files[self.MaxRecentFiles:]

        settings.setValue('recentFileList', files)

        for widget in QApplication.topLevelWidgets():
            if isinstance(widget, myEditor):
                widget.updateRecentFileActions()

    def updateRecentFileActions(self):
        mytext = ""
        settings = QSettings('Axel Schneider', 'PTEdit')
        files = settings.value('recentFileList')
        files = files if files else []
        numRecentFiles = min(len(files), self.MaxRecentFiles)

        for i in range(numRecentFiles):
            text = "&%d %s" % (i + 1, self.strippedName(files[i]))
            self.recentFileActs[i].setText(text)
            self.recentFileActs[i].setData(files[i])
            self.recentFileActs[i].setVisible(True)

        for j in range(numRecentFiles, self.MaxRecentFiles):
            self.recentFileActs[j].setVisible(False)

        self.separatorAct.setVisible((numRecentFiles > 0))

    def clearRecentFileList(self, fileName):
        self.rmenu.clear()

    def strippedName(self, fullFileName):
        return QFileInfo(fullFileName).fileName()
class MasternodeWizard(QDialog, MessageBoxMixin, BaseWizard):

    accept_signal = pyqtSignal()

    def __init__(self, config, app, manager, parent):
        BaseWizard.__init__(self, config, None, None)
        QDialog.__init__(self, None)
        self.app = app
        self.gui = parent
        self.manager = manager
        self.setMinimumSize(600, 400)
        self.accept_signal.connect(self.accept)
        self.setWindowTitle('Electrum-AUDAX  -  ' + _('Masternode Wizard'))

        self.mn = MasternodeAnnounce()

        self.alias_e = None
        self.address_e = None
        self.privkey_e = None
        self.valid_utxo_list = None

        self.title = QLabel()
        self.main_widget = QWidget()
        self.back_button = QPushButton(_("Back"), self)
        self.back_button.setText(
            _('Back') if self.can_go_back() else _('Cancel'))
        self.next_button = QPushButton(_("Next"), self)
        self.next_button.setDefault(True)
        self.logo = QLabel()
        self.icon_filename = None
        self.loop = QEventLoop()
        self.rejected.connect(lambda: self.loop.exit(0))
        self.back_button.clicked.connect(lambda: self.loop.exit(1))
        self.next_button.clicked.connect(lambda: self.loop.exit(2))

        outer_vbox = QVBoxLayout(self)
        inner_vbox = QVBoxLayout()
        inner_vbox.addWidget(self.title)
        inner_vbox.addWidget(self.main_widget)
        inner_vbox.addStretch(1)
        # inner_vbox.addWidget(self.please_wait)
        inner_vbox.addStretch(1)
        scroll_widget = QWidget()
        scroll_widget.setLayout(inner_vbox)
        scroll = QScrollArea()
        scroll.setWidget(scroll_widget)
        scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        scroll.setWidgetResizable(True)
        icon_vbox = QVBoxLayout()
        icon_vbox.addWidget(self.logo)
        icon_vbox.addStretch(1)
        hbox = QHBoxLayout()
        hbox.addLayout(icon_vbox)
        hbox.addSpacing(5)
        hbox.addWidget(scroll)
        hbox.setStretchFactor(scroll, 1)
        outer_vbox.addLayout(hbox)
        outer_vbox.addLayout(Buttons(self.back_button, self.next_button))
        self.set_icon('electrum.png')
        self.show()
        self.raise_()
        self.refresh_gui()  # Need for QT on MacOSX.  Lame.

    def set_icon(self, filename):
        prior_filename, self.icon_filename = self.icon_filename, filename
        self.logo.setPixmap(
            QPixmap(icon_path(filename)).scaledToWidth(
                60, mode=Qt.SmoothTransformation))
        return prior_filename

    def set_layout(self, layout, title=None, next_enabled=True):
        self.title.setText("<b>%s</b>" % title if title else "")
        self.title.setVisible(bool(title))
        # Get rid of any prior layout by assigning it to a temporary widget
        prior_layout = self.main_widget.layout()
        if prior_layout:
            QWidget().setLayout(prior_layout)
        self.main_widget.setLayout(layout)
        self.back_button.setEnabled(True)
        self.next_button.setEnabled(next_enabled)
        if next_enabled:
            self.next_button.setFocus()
        self.main_widget.setVisible(True)

    def exec_layout(self,
                    layout,
                    title=None,
                    raise_on_cancel=True,
                    next_enabled=True):
        self.set_layout(layout, title, next_enabled)
        result = self.loop.exec_()
        if not result and raise_on_cancel:
            raise UserCancelled
        if result == 1:
            raise GoBack from None
        self.title.setVisible(False)
        self.back_button.setEnabled(False)
        self.next_button.setEnabled(False)
        self.main_widget.setVisible(False)
        self.please_wait.setVisible(True)
        self.refresh_gui()
        return result

    def refresh_gui(self):
        # For some reason, to refresh the GUI this needs to be called twice
        self.app.processEvents()
        self.app.processEvents()

    def run(self):
        vbox = QVBoxLayout()

        self.alias_e = QLineEdit()
        self.alias_e.setPlaceholderText(_('Choose a name for this masternode'))
        self.address_e = QLineEdit()
        self.address_e.setPlaceholderText(
            _('Address of your masternode (format: ip:port)'))
        self.privkey_e = QLineEdit()
        self.privkey_e.setPlaceholderText(
            _('Enter your masternode private key or generate one'))
        self.privkey_e_action = self.privkey_e.addAction(
            read_QIcon('key.png'), QLineEdit.TrailingPosition)
        self.privkey_e_action.triggered.connect(self.create_private_key)

        form = QFormLayout()
        form.setContentsMargins(0, 0, 0, 0)
        form.addRow(_('Alias:'), self.alias_e)
        form.addRow(_('IP Address:'), self.address_e)
        form.addRow(_('Masternode Private Key:'), self.privkey_e)

        vbox.addLayout(form)

        self.set_layout(vbox,
                        title=_('Electrum-AUDAX - ' +
                                _('Masternode Configuration')))

        while True:
            result = self.loop.exec_()
            if result != 2:  # 2 = next
                return

            if not self.alias_e.text():
                self.show_error(_("Choose a name for this masternode"))
                self.alias_e.setFocus()
                continue

            # TODO: Alias already exists

            if not self.address_e.text():
                self.show_error(_("Address of your masternode"))
                self.address_e.setFocus()
                continue

            # Check if maternode address is valid
            try:
                addr = NetworkAddress(self.address_e.text())
            except:
                self.show_error(_("Invalid network address"))
                self.address_e.setFocus()
                continue

            # check private key
            if not self.privkey_e.text():
                self.show_error(_("Enter your masternode private key"))
                self.privkey_e.setFocus()
                continue

            try:
                deserialize_privkey('p2pkh:' + self.privkey_e.text())
            except:
                self.show_error(_("Invalid private key"))
                self.privkey_e.setFocus()
                continue

            self.mn.alias = self.alias_e.text()
            self.mn.addr = addr
            self.mn.private_key = self.privkey_e.text()

            txin_type, privkey, compressed = deserialize_privkey(
                'p2pkh:' + self.mn.private_key)
            self.mn.masternode_pubkey = ecc.ECPrivkey(
                privkey).get_public_key_hex(compressed=compressed)

            self.choose_utxo()
            break

        return True

    def choose_utxo(self):
        vbox = QVBoxLayout()

        form = QFormLayout()
        form.setContentsMargins(0, 0, 0, 0)

        title = QLabel(
            _('Choose a collateral payment for your masternode. A valid collateral payment is exactly 2500 AUDAX.'
              ))
        title.setWordWrap(True)
        form.addRow(title)

        self.valid_utxo_list = MasternodeOutputsWidget(self)
        form.addRow(self.valid_utxo_list)

        vbox.addLayout(form)

        self.valid_utxo_list.update()
        self.set_layout(vbox,
                        title=_('Electrum-AUDAX - ' + _('Choose collateral')))

        while True:
            result = self.loop.exec_()
            if result != 2:  # 2 = next
                return

            idx = self.valid_utxo_list.currentIndex()
            item = self.valid_utxo_list.model().itemFromIndex(
                idx.sibling(idx.row(), self.valid_utxo_list.Columns.TXID))

            if not item:
                continue

            txid = item.text().split(':')

            self.mn.vin = {'prevout_hash': txid[0], 'prevout_n': int(txid[1])}

            self.add_masternode()
            break
        return True

    def add_masternode(self):
        self.manager.add_masternode(self.mn)
        self.manager.wallet.network.trigger_callback('masternodes')

    def terminate(self):
        self.accept_signal.emit()

    def create_private_key(self):
        private_key = serialize_privkey(os.urandom(32), False, 'p2pkh', False)
        self.privkey_e.setText(private_key.split(':')[1])
class WebBrowser(QMainWindow):
    def __init__(self):
        super().__init__()

        # Create lists that will keep track of the new windows, 
        # tabs and urls
        self.window_list = []
        self.list_of_web_pages = []
        self.list_of_urls = []

        self.initializeUI()

    def initializeUI(self):
        self.setMinimumSize(300, 200)
        self.setWindowTitle("12.6 – Web Browser")
        self.setWindowIcon(QIcon(os.path.join('images', 'pyqt_logo.png')))

        self.positionMainWindow() 

        self.createMenu()
        self.createToolbar()
        self.createTabs()

        self.show()

    def createMenu(self):
        """
        Set up the menu bar.
        """
        new_window_act = QAction('New Window', self)
        new_window_act.setShortcut('Ctrl+N')
        new_window_act.triggered.connect(self.openNewWindow)

        new_tab_act = QAction('New Tab', self)
        new_tab_act.setShortcut('Ctrl+T')
        new_tab_act.triggered.connect(self.openNewTab)

        quit_act = QAction("Quit Browser", self)
        quit_act.setShortcut('Ctrl+Q')
        quit_act.triggered.connect(self.close)

        # Create the menu bar
        menu_bar = self.menuBar()
        menu_bar.setNativeMenuBar(False)

        # Create file menu and add actions
        file_menu = menu_bar.addMenu('File')
        file_menu.addAction(new_window_act)
        file_menu.addAction(new_tab_act)
        file_menu.addSeparator()
        file_menu.addAction(quit_act)

        self.status_bar = QStatusBar()
        self.setStatusBar(self.status_bar)

    def createToolbar(self):
        """
        Set up the navigation toolbar.
        """
        tool_bar = QToolBar("Address Bar")
        tool_bar.setIconSize(QSize(30, 30))
        self.addToolBar(tool_bar)
        
        # Create toolbar actions
        back_page_button = QAction(QIcon(os.path.join('icons', 'back.png')), "Back", self)
        back_page_button.triggered.connect(self.backPageButton)

        forward_page_button = QAction(QIcon(os.path.join('icons', 'forward.png')), "Forward", self)
        forward_page_button.triggered.connect(self.forwardPageButton)

        refresh_button = QAction(QIcon(os.path.join('icons', 'refresh.png')), "Refresh", self)
        refresh_button.triggered.connect(self.refreshButton)

        home_button = QAction(QIcon(os.path.join('icons', 'home.png')), "Home", self)
        home_button.triggered.connect(self.homeButton)

        stop_button = QAction(QIcon(os.path.join('icons', 'stop.png')), "Stop", self)
        stop_button.triggered.connect(self.stopButton)

        # Set up the address bar
        self.address_line = QLineEdit()
        # addAction() is used here to merely display the icon in the line edit. 
        self.address_line.addAction(QIcon('icons/search.png'), QLineEdit.LeadingPosition)
        self.address_line.setPlaceholderText("Enter website address")
        self.address_line.returnPressed.connect(self.searchForUrl)

        tool_bar.addAction(home_button)
        tool_bar.addAction(back_page_button)
        tool_bar.addAction(forward_page_button)
        tool_bar.addAction(refresh_button)
        tool_bar.addWidget(self.address_line)
        tool_bar.addAction(stop_button)

    def createTabs(self):
        """
        Create the QTabWidget object and the different pages. 
        Handle when a tab is closed. 
        """
        self.tab_bar = QTabWidget()
        self.tab_bar.setTabsClosable(True) # Add close buttons to tabs
        self.tab_bar.setTabBarAutoHide(True) # Hides tab bar when less than 2 tabs
        self.tab_bar.tabCloseRequested.connect(self.closeTab)

        # Create tab 
        self.main_tab = QWidget()
        self.tab_bar.addTab(self.main_tab, "New Tab")

        # Call method that sets up each page
        self.setupTab(self.main_tab)

        self.setCentralWidget(self.tab_bar)

    def setupWebView(self):
        """
        Create the QWebEngineView object that is used to view 
        web docs. Set up the main page, and handle web_view signals.
        """
        web_view = QWebEngineView()
        web_view.setUrl(QUrl("https://google.com"))

        # Create page loading progress bar that is displayed in 
        # the status bar.
        self.page_load_pb = QProgressBar()
        self.page_load_label = QLabel()
        web_view.loadProgress.connect(self.updateProgressBar)

        # Display url in address bar
        web_view.urlChanged.connect(self.updateUrl)

        ok = web_view.loadFinished.connect(self.updateTabTitle)
        if ok:
            # Web page loaded
            return web_view
        else:
            print("The request timed out.")        

    def setupTab(self, tab):
        """
        Create individual tabs and widgets. Add the tab's url and 
        web view to the appropriate list. 
        Update the address bar if the user switches tabs.
        """
        # Create the web view that will be displayed on the page.
        self.web_page = self.setupWebView()

        tab_v_box = QVBoxLayout()
        # Sets the left, top, right, and bottom margins to use around the layout.
        tab_v_box.setContentsMargins(0,0,0,0)
        tab_v_box.addWidget(self.web_page)

        # Append new web_page and url to the appropriate lists
        self.list_of_web_pages.append(self.web_page)
        self.list_of_urls.append(self.address_line)
        self.tab_bar.setCurrentWidget(self.web_page)

        # If user switches pages, update the url in the address to 
        # reflect the current page. 
        self.tab_bar.currentChanged.connect(self.updateUrl)

        tab.setLayout(tab_v_box)

    def openNewWindow(self):
        """
        Create new instance of the WebBrowser class. 
        """
        new_window = WebBrowser()
        new_window.show()
        self.window_list.append(new_window)

    def openNewTab(self):
        """
        Create new tabs. 
        """
        new_tab = QWidget()
        self.tab_bar.addTab(new_tab, "New Tab")
        self.setupTab(new_tab)

        # Update the tab_bar index to keep track of the new tab.
        # Load the url for the new page.
        tab_index = self.tab_bar.currentIndex()
        self.tab_bar.setCurrentIndex(tab_index + 1)
        self.list_of_web_pages[self.tab_bar.currentIndex()].load(QUrl("https://google.com"))

    def updateProgressBar(self, progress):
        """
        Update progress bar in status bar.
        This provides feedback to the user that page is still loading.
        """
        if progress < 100:
            self.page_load_pb.setVisible(progress)
            self.page_load_pb.setValue(progress)
            self.page_load_label.setVisible(progress)
            self.page_load_label.setText("Loading Page... ({}/100)".format(str(progress)))
            self.status_bar.addWidget(self.page_load_pb)
            self.status_bar.addWidget(self.page_load_label)
        else:
            self.status_bar.removeWidget(self.page_load_pb)
            self.status_bar.removeWidget(self.page_load_label)

    def updateTabTitle(self):
        """
        Update the title of the tab to reflect the website.
        """
        tab_index = self.tab_bar.currentIndex()
        title = self.list_of_web_pages[self.tab_bar.currentIndex()].page().title()
        self.tab_bar.setTabText(tab_index, title)

    def updateUrl(self):
        """
        Update the url in the address to reflect the current page being displayed.
        """
        url = self.list_of_web_pages[self.tab_bar.currentIndex()].page().url()
        formatted_url = QUrl(url).toString()
        self.list_of_urls[self.tab_bar.currentIndex()].setText(formatted_url)

    def searchForUrl(self):
        """
        Make a request to load a url.
        """
        url_text = self.list_of_urls[self.tab_bar.currentIndex()].text()

        # Append http to url
        url = QUrl(url_text)
        if url.scheme() == "":
            url.setScheme("http")

        # Request url
        if url.isValid():
            self.list_of_web_pages[self.tab_bar.currentIndex()].page().load(url)
        else:
            url.clear()

    def backPageButton(self):
        tab_index = self.tab_bar.currentIndex()
        self.list_of_web_pages[tab_index].back()

    def forwardPageButton(self):
        tab_index = self.tab_bar.currentIndex()
        self.list_of_web_pages[tab_index].forward()

    def refreshButton(self):
        tab_index = self.tab_bar.currentIndex()
        self.list_of_web_pages[tab_index].reload()

    def homeButton(self):
        tab_index = self.tab_bar.currentIndex()
        self.list_of_web_pages[tab_index].setUrl(QUrl("https://google.com"))

    def stopButton(self):
        tab_index = self.tab_bar.currentIndex()
        self.list_of_web_pages[tab_index].stop()

    def closeTab(self, tab_index):
        """
        This signal is emitted when the close button on a tab is clicked. 
        The index is the index of the tab that should be removed.
        """
        self.list_of_web_pages.pop(tab_index)
        self.list_of_urls.pop(tab_index)

        self.tab_bar.removeTab(tab_index)

    def positionMainWindow(self):
        """
        Use QDesktopWidget class to access information about your screen  
        and use it to position the application window when starting a new application.
        """
        desktop = QDesktopWidget().screenGeometry() 
        screen_width = desktop.width() 
        screen_height = desktop.height() 
        self.setGeometry(0, 0, screen_width, screen_height)
Beispiel #19
0
    def setupUI(self):
        hbox = QHBoxLayout(self)
        hbox.setContentsMargins(22, 12, 22, 12)
        splitter = QSplitter(Qt.Vertical)
        splitter.setStyleSheet(
            "QSplitter::handle{border-image: url(icons/split_line.png)}")
        splitter.setHandleWidth(17)

        hbox.addWidget(splitter)

        left = QWidget(splitter)
        vbox = QVBoxLayout(left)
        vbox.setSpacing(0)
        vbox.setContentsMargins(0, 0, 0, 4)

        buttonsContainer1 = QWidget()
        vbox.addWidget(buttonsContainer1)
        hbox2 = QHBoxLayout(buttonsContainer1)
        hbox2.setContentsMargins(2, 3, 2, 10)

        comboWhere = QComboBox()
        comboWhere.setStyleSheet(
            "QComboBox {width:160px;min-width:20px;height:28px;border:1px solid #c7c7c7;font-size:14px;selection-background-color:#f4f4f4;}"
            "QComboBox QAbstractItemView {background:#ffffff;color:#333333;}"
            "QComboBox::drop-down{width: 21px;border-left: 0px solid #333333;}"
            "QComboBox::down-arrow:hover {image: url(icons/ComboBox_hover.png);}"
            "QComboBox::down-arrow {image: url(icons/ComboBox_default.png);}")
        comboWhere.currentIndexChanged.connect(
            self.handleComboWhereIndexChanged)
        hbox2.addWidget(comboWhere)
        self.comboWhere = comboWhere

        comboLang = QComboBox()
        comboLang.setStyleSheet(
            "QComboBox {width:160px;min-width:20px;height:28px;border:1px solid #c7c7c7;font-size:14px;selection-background-color:#f4f4f4;}"
            "QComboBox QAbstractItemView {background:#ffffff;color:#333333;}"
            "QComboBox::drop-down{width: 21px;border-left: 0px solid #333333;}"
            "QComboBox::down-arrow:hover {image: url(icons/ComboBox_hover.png);}"
            "QComboBox::down-arrow {image: url(icons/ComboBox_default.png);}")
        comboLang.currentIndexChanged.connect(
            self.handleComboLanguageIndexChanged)
        hbox2.addWidget(comboLang)
        self.comboLang = comboLang

        #addStretch
        hbox2.addStretch()

        btnInstallFont = QPushButton()
        btnInstallFont.setEnabled(True)
        btnInstallFont.clicked.connect(self.installFonts)
        btnInstallFont.setStyleSheet(
            "QPushButton{border-image: url(icons/install_default.png) 0 0 0 0;border:none;color:rgb(255, 255, 255);font-size:14px;}"
            "QPushButton:hover{border-image: url(icons/install_hover.png) 0 0 0 0;border:none;color:rgb(255, 255, 255);}"
            "QPushButton:checked{border-image: url(icons/install_click.png) 0 0 0 0;border:none;color:rgb(255, 255, 255);}"
        )
        btnInstallFont.setFixedSize(100, 30)
        hbox2.addWidget(btnInstallFont)
        self.btnInstallFont = btnInstallFont

        btnUninstallFont = QPushButton()
        btnUninstallFont.setEnabled(False)
        btnUninstallFont.clicked.connect(self.uninstallFonts)
        btnUninstallFont.setStyleSheet(
            "QPushButton{border-image: url(icons/uninstall_default.png);font-size:14px;}"
            "QPushButton:disabled{border-image: url(icons/uninstall_forbid.png) 0 0 0 0;border:none;color:#c1c1c1;font-size:14px;}"
            "QPushButton:hover{border-image: url(icons/uninstall_hover.png) 0 0 0 0;border:none;color:rgb(51, 51, 51);}"
            "QPushButton:checked{border-image: url(icons/uninstall_click.png) 0 0 0 0;border:none;color:rgb(51, 51, 51);}"
        )
        btnUninstallFont.setFixedSize(100, 30)
        hbox2.addWidget(btnUninstallFont)
        self.btnUninstallFont = btnUninstallFont

        buttonsContainer4 = QWidget()
        vbox.addWidget(buttonsContainer4)
        hbox4 = QHBoxLayout(buttonsContainer4)
        hbox4.setContentsMargins(0, 0, 0, 6)
        hbox4.setSpacing(3)

        #add checkBox
        checkCheckALL = QCheckBox()
        checkCheckALL.setChecked(False)
        checkCheckALL.setStyleSheet(
            "QCheckBox::indicator {width: 20px; height: 20px;}"
            "QCheckBox::indicator:unchecked {image:url(icons/CheckBox_uncheck_default.png);}"
            "QCheckBox::indicator:unchecked:hover {image:url(icons/CheckBox_uncheck_hover.png);}"
            "QCheckBox::indicator:checked:hover {image:url(icons/CheckBox_checked_hover.png);}"
            "QCheckBox::indicator:checked {image:url(icons/CheckBox_checked_default.png);}"
        )
        checkCheckALL.stateChanged.connect(self.CheckboxChange)
        checkCheckALL.stateChanged.connect(self.apply)
        hbox4.addWidget(checkCheckALL)
        self.checkCheckALL = checkCheckALL

        #add Label
        textLabel = QLabel()
        hbox4.addWidget(textLabel)
        self.textLabel = textLabel

        textLabel3 = QLabel()
        hbox4.addWidget(textLabel3)
        self.textLabel3 = textLabel3

        textLabel4 = QLabel()
        hbox4.addWidget(textLabel4)
        self.textLabel4 = textLabel4

        btnExpandAll = QPushButton()
        btnExpandAll.setStyleSheet(
            "QPushButton{border-image: url(icons/ExpandAll_default.png) 0 0 0 0;border:none;color:rgb(51, 51, 51);}"
            "QPushButton:hover{border-image: url(icons/ExpandAll_hover.png) 0 0 0 0;border:none;color:rgb(51, 51, 51);}"
            "QPushButton:checked{border-image: url(icons/ExpandAll_click.png) 0 0 0 0;border:none;color:rgb(51, 51, 51);}"
        )
        btnExpandAll.setFixedSize(87, 26)
        btnExpandAll.clicked.connect(self.expandORcollapse)

        self.btnExpandAll = btnExpandAll
        hbox4.addWidget(btnExpandAll)

        #addStretch
        hbox4.addStretch()

        tree = QTreeWidget()
        tree.setColumnCount(3)
        tree.setColumnWidth(0, 250)
        tree.setColumnWidth(1, 250)
        tree.setColumnWidth(2, 300)
        tree.setStyleSheet(
            "QTreeWidget {border:1px solid #c7c7c7;}"
            "QTreeWidget QHeaderView::section{padding-left:6px;height:24px;background-color:#f8f8f8;border:1px solid #dddddd;border-bottom: 0px;border-top: 0px;}"
            "QTreeView::branch:has-children:!has-siblings:closed,\
                            QTreeView::branch:closed:has-children:has-siblings{border-image: none; image: url(icons/treeArrow_right.png);}\
                            QTreeView::branch:open:has-children:!has-siblings,\
                            QTreeView::branch:open:has-children:has-siblings{border-image: none; image: url(icons/treeArrow_bottom.png);}\
                            QTreeWidget::indicator:checked {image: url(icons/CheckBox_checked_default.png);}\
                            QTreeWidget::indicator:checked:hover {image: url(icons/CheckBox_checked_hover.png);}\
                            QTreeWidget::indicator:unchecked {image: url(icons/CheckBox_uncheck_default.png);}\
                            QTreeWidget::indicator:unchecked:hover {image: url(icons/CheckBox_uncheck_hover.png);}"
            "QTreeView QScrollBar:vertical {border:1px solid #c7c7c7;border-left: 0px;background-color:#f1f1f1;padding-top:15px;padding-bottom:15px;}"
            "QTreeView QScrollBar::handle:vertical {background-color:#c7c7c7;min-height:30px;}"
            "QTreeView QScrollBar::handle:vertical:hover {background-color:#a6a6a6;}"
            "QTreeView QScrollBar::add-line:vertical {border-image: url(icons/scorllAdd_default.png);}"
            "QTreeView QScrollBar::add-line:vertical:hover {border-image: url(icons/scorllAdd_hover.png);}"
            "QTreeView QScrollBar::sub-line:vertical:hover {border-image: url(icons/scorllSub_hover.png);}"
            "QTreeView QScrollBar::sub-line:vertical {border-image: url(icons/scorllSub_default.png);}"
        )
        tree.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        tree.itemChanged.connect(self.handleTreeItemChanged)
        vbox.addWidget(tree)
        self.tree = tree

        editSearch = QLineEdit("")
        editSearch.setFixedSize(210, 30)
        editAction = QAction(editSearch)
        editSearch.addAction(editAction, QLineEdit.TrailingPosition)
        editAction.setIcon(QIcon("icons/search.png"))
        editSearch.textChanged.connect(self.handleEditSearchTextChanged)
        editAction.triggered.connect(self.loopSearch)
        editSearch.setStyleSheet("QLineEdit {border:1px solid #c7c7c7;}")
        self.editSearch = editSearch
        hbox4.addWidget(editSearch)

        right = QWidget()
        splitter.addWidget(right)
        #        splitter.setSizes([200, 200])
        splitter.setStretchFactor(0, 45)
        splitter.setStretchFactor(1, 55)

        vbox2 = QVBoxLayout(right)
        vbox2.setSpacing(0)
        vbox2.setContentsMargins(0, 4, 0, 10)

        buttonsContainer2 = QWidget()
        vbox2.addWidget(buttonsContainer2)
        hbox3 = QHBoxLayout(buttonsContainer2)
        hbox3.setContentsMargins(0, 0, 0, 5)
        hbox3.setSpacing(7)

        #add Label
        textLabel2 = QLabel()
        hbox3.addWidget(textLabel2)
        self.textLabel2 = textLabel2

        spinBox = QSpinBox()
        spinBox.setRange(5, 60)
        spinBox.setValue(14)
        spinBox.setSingleStep(1)
        spinBox.setFixedSize(150, 26)
        spinBox.setStyleSheet(
            "QSpinBox {padding-right:23px;border: 1px solid #c7c7c7;}"
            "QSpinBox::down-button{subcontrol-origin: padding;subcontrol-origin:border;subcontrol-position:right;image: url(icons/reduce_default.png);position:relative;right:23px;}"
            "QSpinBox::down-button:hover{image: url(icons/reduce_click.png);}"
            "QSpinBox::up-button{subcontrol-origin:border;subcontrol-position:right;image: url(icons/add_default.png);position:relative;right:2px;}"
            "QSpinBox::up-button:hover{image: url(icons/add_click.png);}")

        spinBox.valueChanged.connect(self.handleFontSizeChanged)
        hbox3.addWidget(spinBox)
        self.spinBox = spinBox

        lineEdit = QLineEdit()
        lineEdit.setStyleSheet(
            "QLineEdit {border:1px solid #c7c7c7;height:24px;}")
        hbox3.addWidget(lineEdit)
        self.lineEdit = lineEdit

        scroll = QScrollArea()
        #scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        #scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        scroll.setWidgetResizable(True)
        scroll.setStyleSheet(
            "QScrollArea {border:1px solid #c7c7c7;}"
            "QScrollArea QScrollBar {border:1px solid #c7c7c7;border-left: 0px;}"
            "QScrollArea QScrollBar:vertical {background-color:#f1f1f1;padding-top:15px;padding-bottom:15px;}"
            "QScrollArea QScrollBar::handle:vertical {background-color:#c7c7c7;min-height:30px;}"
            "QScrollArea QScrollBar::handle:vertical:hover {background-color:#a6a6a6;}"
            "QScrollArea QScrollBar::add-line:vertical {border-image: url(icons/scorllAdd_default.png);}"
            "QScrollArea QScrollBar::add-line:vertical:hover {border-image: url(icons/scorllAdd_hover.png);}"
            "QScrollArea QScrollBar::sub-line:vertical:hover {border-image: url(icons/scorllSub_hover.png);}"
            "QScrollArea QScrollBar::sub-line:vertical {border-image: url(icons/scorllSub_default.png);}"
        )
        vbox2.addWidget(scroll)

        displayer = FontDisplayer()
        scroll.setWidget(displayer)
        self.displayer = displayer
Beispiel #20
0
class InitialPage(QWizardPage):

    def __init__(self):
        super().__init__()
        vbox = QVBoxLayout(self)
        frame = QFrame(self)
        vbox.addStretch(1)
        frame.setFrameShape(QFrame.StyledPanel)
        vbox.addWidget(frame)
        # Fields
        fields_box = QGridLayout(frame)
        # Project name
        fields_box.addWidget(QLabel(translations.TR_WIZARD_PROJECT_NAME), 0, 0)
        self._line_project_name = QLineEdit("untitled")
        self.registerField("name*", self._line_project_name)
        fields_box.addWidget(self._line_project_name, 0, 1)
        # Project location
        fields_box.addWidget(
            QLabel(translations.TR_WIZARD_PROJECT_LOCATION), 1, 0)
        self._line_location = QLineEdit()
        self._line_location.setReadOnly(True)
        self._line_location.setText(utils.get_home_dir())
        self.registerField("path", self._line_location)
        choose_dir_act = self._line_location.addAction(
            self.style().standardIcon(
                self.style().SP_DirIcon), QLineEdit.TrailingPosition)
        fields_box.addWidget(self._line_location, 1, 1)
        # Project description
        fields_box.addWidget(QLabel(translations.TR_PROJECT_DESCRIPTION), 2, 0)
        self._txt_desciption = QPlainTextEdit()
        fields_box.addWidget(self._txt_desciption, 2, 1)
        self.registerField("description", self._txt_desciption)
        # Project license
        fields_box.addWidget(QLabel(translations.TR_PROJECT_LICENSE), 3, 0)
        combo_license = QComboBox()
        combo_license.addItems(LICENSES)
        combo_license.setCurrentIndex(12)
        fields_box.addWidget(combo_license, 3, 1)
        self.registerField("license", combo_license, property="currentText")
        # Project interpreter
        fields_box.addWidget(
            QLabel(translations.TR_WIZARD_PROJECT_INTERPRETER), 4, 0)
        combo_interpreter = QComboBox()
        combo_interpreter.addItems(utils.get_python())
        combo_interpreter.setCurrentText(sys.executable)
        fields_box.addWidget(combo_interpreter, 4, 1)
        self.registerField("interpreter", combo_interpreter)
        # Connections
        self._line_project_name.textChanged.connect(self._on_text_changed)
        choose_dir_act.triggered.connect(self._choose_dir)

    def _choose_dir(self):
        dirname = QFileDialog.getExistingDirectory(
            self, translations.TR_WIZARD_CHOOSE_DIR, utils.get_home_dir())
        if dirname:
            self._line_location.setText(dirname)

    @property
    def location(self):
        return self._line_location.text()

    @property
    def project_name(self):
        return self._line_project_name.text()

    def _on_text_changed(self):
        ok = self.validate()
        if not ok:
            self._line_project_name.setStyleSheet("background-color: red")
        else:
            self._line_project_name.setStyleSheet("background-color: none;")

    def validate(self):
        ok = True
        project_path = os.path.join(self.location, self.project_name)
        if file_manager.folder_exists(project_path):
            ok = False
        return ok

    def isComplete(self):
        val = super().isComplete()
        return val and self.validate()
Beispiel #21
0
class ParameterTab(QWidget):

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

        #  Building widget tab 2.

        # Button for selecting download location.
        self.browse_btn = QPushButton('Browse')

        self.save_profile_btn = QPushButton('Save Profile')
        self.save_profile_btn.resize(self.save_profile_btn.sizeHint())

        self.download_label = QLabel('Download to:')

        self.favlabel = QLabel('Favorites:')
        self.optlabel = QLabel('All settings:')

        # LineEdit for download location.
        self.download_lineedit = QLineEdit()
        self.download_lineedit.setReadOnly(True)
        self.download_lineedit.setFocusPolicy(Qt.NoFocus)

        if settings.is_activate('Download location'):
            self.download_lineedit.setText('')
            self.download_lineedit.setToolTip(settings.get_active_setting('Download location'))
        else:
            self.download_lineedit.setText('DL')
            self.download_lineedit.setToolTip('Default download location.')
        self.download_lineedit.setContextMenuPolicy(Qt.ActionsContextMenu)

        # Sets up the parameter tree.
        self.options = ParameterTree(options, self)
        self.favorites = ParameterTree(favorites, self)
        self.favorites.favorite = True

        # Can only be toggled in settings manually
        if settings.user_options['show_collapse_arrows']:
            self.options.setRootIsDecorated(True)
            self.favorites.setRootIsDecorated(True)
        else:
            self.options.setRootIsDecorated(False)
            self.favorites.setRootIsDecorated(False)

        self.open_folder_action = QAction('Open location', parent=self.download_lineedit)
        self.copy_action = QAction('Copy', parent=self.download_lineedit)

        self.download_lineedit.addAction(self.open_folder_action)
        self.download_lineedit.addAction(self.copy_action)

        # Layout tab 2.

        self.QH = QHBoxLayout()

        # Adds widgets to the horizontal layout. label, lineedit and button.
        self.QH.addWidget(self.download_label)
        self.QH.addWidget(self.download_lineedit)
        self.QH.addWidget(self.browse_btn)
        self.QH.addWidget(self.save_profile_btn)

        self.QV = QVBoxLayout()
        self.QV.addLayout(self.QH, stretch=0)

        self.fav_frame = QFrame()
        self.opt_frame2 = QFrame()

        self.opt_frame2.setFrameShape(QFrame.HLine)
        self.fav_frame.setFrameShape(QFrame.HLine)

        self.fav_frame.setLineWidth(2)
        self.opt_frame2.setLineWidth(2)

        self.fav_frame.setObjectName('line')
        self.opt_frame2.setObjectName('line')

        self.fav_layout = QVBoxLayout()
        self.opt_layout = QVBoxLayout()

        self.fav_layout.setSizeConstraint(QVBoxLayout.SetMinimumSize)
        self.fav_layout.addWidget(self.favlabel, stretch=0)
        self.fav_layout.addWidget(self.fav_frame, stretch=0)
        self.fav_layout.addWidget(self.favorites, stretch=1, alignment=Qt.AlignTop)

        self.opt_layout.addWidget(self.optlabel, stretch=0)
        self.opt_layout.addWidget(self.opt_frame2, stretch=0)
        self.opt_layout.addWidget(self.options, stretch=1, alignment=Qt.AlignTop)

        self.parameter_layout = QHBoxLayout()
        self.parameter_layout.addLayout(self.fav_layout)
        self.parameter_layout.addLayout(self.opt_layout)

        self.QV.addLayout(self.parameter_layout)

        self.setLayout(self.QV)

        self.download_option = self.find_download_widget()

    def enable_favorites(self, enable):
        if not enable:
            self.favorites.hide()
            self.fav_frame.hide()
            self.favlabel.hide()
        else:
            self.favorites.show()
            self.fav_frame.show()
            self.favlabel.show()

    def find_download_widget(self):
        """ Finds the download widget. """
        # TODO: Refactor to check the settings file/object, not the parameterTrees.
        for item in self.favorites.topLevelItems():
            if item.data(0, DATA_SLOT) == 'Download location':
                self.download_option = item
                return item
        for item in self.options.topLevelItems():
            if item.data(0, DATA_SLOT) == 'Download location':
                self.download_option = item
                return item
        raise SettingsError('No download item found in settings.')
Beispiel #22
0
class InitWindow(QWidget):
    sigOpenProject = pyqtSignal(object)
    sigExit = pyqtSignal()

    log = logging.getLogger(__name__)

    WIDTH = 600
    HEIGHT = 400

    def __init__(self,
                 recent_projects: List[Path] = None,
                 is_updated: bool = False):
        flags = Qt.WindowFlags()
        flags |= Qt.FramelessWindowHint
        super().__init__(flags=flags)

        self.setAttribute(Qt.WA_DeleteOnClose)
        self.setWindowTitle('GIWAXS analysis')
        self.setWindowIcon(Icon('window_icon'))
        self.project_name: str = 'untitled'
        self.project_path: Path = Path(
            '~/GIWAXS projects').expanduser().resolve() / self.project_name

        self.__init_ui(recent_projects, is_updated)
        self.setFixedWidth(self.WIDTH)
        self.setFixedHeight(self.HEIGHT)
        center_widget(self)
        self.show()

    def __init_ui(self,
                  recent_projects: List[Path] or None,
                  is_updated: bool = False):
        layout = QGridLayout(self)
        layout.setContentsMargins(40, 20, 40, 40)
        self.file_line = QLineEdit(str(self.project_path), self)
        self.file_line.textEdited.connect(self._on_text_editing)

        browse_action = self.file_line.addAction(Icon('folder'),
                                                 QLineEdit.LeadingPosition)

        browse_action.triggered.connect(self._new_project_dialog)
        self.create_button = QPushButton(
            f'Create project "{self.project_name}"', self)
        self.create_button.clicked.connect(self._create)

        if is_updated:
            title = f'GIWAXS analysis. Updated to the latest version {__version__}!'
        else:
            title = f'GIWAXS analysis (version {__version__})'

        layout.addWidget(Label(title, self, 11, True),
                         0,
                         0,
                         1,
                         3,
                         alignment=Qt.AlignHCenter)
        layout.addWidget(Label('New project', self, 9.5), 1, 0, 1, 3)
        layout.addWidget(self.file_line, 2, 0, 1, 2)
        layout.addWidget(self.create_button, 2, 2)

        if recent_projects:
            layout.addWidget(self._init_recent_projects_area(recent_projects),
                             3, 0, 1, 3)

        layout.addLayout(self._init_exit_button(), 4 if recent_projects else 3,
                         0, 1, 3)

    def _init_exit_button(self):
        e_layout = QVBoxLayout()
        exit_button = QPushButton('Exit')
        exit_button.clicked.connect(self.sigExit)
        e_layout.addWidget(QLabel(''))
        e_layout.addWidget(exit_button)
        return e_layout

    def _init_recent_projects_area(self, recent_projects):
        q_scroll_area = QScrollArea(self)
        q_scroll_area.setWidgetResizable(True)
        q_scroll_area.setGeometry(0, 0, self.WIDTH, self.HEIGHT // 2)

        projects_list_widget = QWidget(self)
        projects_list_widget.setSizePolicy(QSizePolicy.Expanding,
                                           QSizePolicy.Expanding)

        scroll_layout = QVBoxLayout(projects_list_widget)
        scroll_layout.addWidget(QLabel('', self))
        scroll_layout.addWidget(Label('Recent projects', self, 9.5))
        for path in recent_projects:
            btn = QPushButton(path.name)
            btn.clicked.connect(lambda *x, p=path: self.sigOpenProject.emit(p))
            scroll_layout.addWidget(btn)
        q_scroll_area.setWidget(projects_list_widget)

        return q_scroll_area

    @pyqtSlot(str, name='onTextEditing')
    def _on_text_editing(self, path: str):
        path = Path(path)
        folder, name = path.parent, path.name
        if not folder.is_dir():
            folder = self.project_path.parent
        self.project_name = name
        self.project_path = folder / name
        self.create_button.setText(f'Create project "{self.project_name}"')

    @pyqtSlot(name='NewProjectDialog')
    def _new_project_dialog(self):
        folder = QFileDialog.getExistingDirectory(
            self,
            'New project folder',
            options=QFileDialog.ShowDirsOnly | QFileDialog.DontUseNativeDialog)
        if not folder:
            return
        folder = Path(folder).resolve()
        if folder.is_dir():
            self.project_path = folder / self.project_name
            self.file_line.setText(str(self.project_path))
        else:
            color_animation(self.file_line)
            show_error('Invalid folder. Please, select existing folder',
                       error_title='Wrong path')

    def _create(self):
        try:
            self.project_path.mkdir(parents=True, exist_ok=True)
            self.sigOpenProject.emit(self.project_path.resolve())
        # except FileExistsError:
        #     show_error(f'The folder {str(self.project_path.resolve())} already exists', error_title='Folder exists')
        #     color_animation(self.file_line)
        except PermissionError:
            folder = get_folder_filepath(
                self,
                'Permission denied, please, create a project folder manually',
                directory=str(Path('~').expanduser().resolve()))
            if folder and folder.is_dir():
                self.sigOpenProject.emit(folder.resolve())
Beispiel #23
0
class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        translator = QTranslator()
        print(QLocale.system().name())
        translator.load('qt_' + QLocale.system().name(),
                        QLibraryInfo.location(QLibraryInfo.TranslationsPath))
        app.installTranslator(translator)

        self.setStyleSheet(myStyleSheet(self))
        self.MaxRecentFiles = 5
        self.windowList = []
        self.recentFileActs = []
        self.curFile = ''
        self.setAcceptDrops(True)
        self.settings = QSettings("QTextEdit", "QTextEdit")
        self.myeditor = QTextEdit()
        assert (self.locale().language() == QLocale.German)
        self.myeditor.setAcceptRichText(False)
        self.myeditor.setUndoRedoEnabled(True)
        self.myeditor.setStyleSheet(myStyleSheet(self))
        self.myeditor.setContextMenuPolicy(Qt.CustomContextMenu)
        self.myeditor.customContextMenuRequested.connect(
            self.contextMenuRequested)

        self.createActions()
        self.createToolBars()
        self.createMenus()
        self.createStatusBar()

        self.setWindowIcon(QIcon.fromTheme("gnome-documents"))

        self.readSettings()
        self.myeditor.document().contentsChanged.connect(
            self.documentWasModified)
        self.setCurrentFile('')
        self.setCentralWidget(self.myeditor)
        self.myeditor.setFocus()

    def closeEvent(self, event):
        if self.maybeSave():
            self.writeSettings()
            event.accept()
        else:
            event.ignore()

    def newFile(self):
        if self.maybeSave():
            self.myeditor.clear()
            self.setCurrentFile('')

    def open(self):
        if self.maybeSave():
            fileName, _ = QFileDialog.getOpenFileName(
                self, "Datei öffnen",
                QDir.homePath() + "/Dokumente",
                "Text Dateien (*.txt *.csv *.sh *.py) ;; alle Dateien (*.*)")
            if fileName:
                self.loadFile(fileName)
            else:
                self.statusBar().showMessage("abgebrochen", 3000)

    def save(self):
        if not self.myeditor.toPlainText() == "":
            if self.myeditor.document().isModified():
                if self.curFile:
                    return self.saveFile(self.curFile)
                    self.setCurrentFile(fileName)
                else:
                    return self.saveAs()
            else:
                self.statusBar().showMessage(
                    "Datei '" + self.curFile + "' bereits gespeichert", 3000)
        else:
            self.statusBar().showMessage("kein Text")

    def saveAs(self):
        if not self.myeditor.toPlainText() == "":
            if self.curFile:
                fileName, _ = QFileDialog.getSaveFileName(
                    self, "Speichern als...", self.curFile,
                    "Text Dateien (*.txt)")
            else:
                fileName, _ = QFileDialog.getSaveFileName(
                    self, "Speichern als...",
                    QDir.homePath() + "/Dokumente/Unbenannt.txt",
                    "Text Dateien (*.txt)")
            if fileName:
                return self.saveFile(fileName)

            return False
        else:
            self.statusBar().showMessage("kein Text")

    def contextMenuRequested(self, point):
        cmenu = QMenu()
        cmenu = self.myeditor.createStandardContextMenu()
        if not self.myeditor.textCursor().selectedText() == "":
            cmenu.addSeparator()
            cmenu.addAction(QIcon.fromTheme("edit-find-and-replace"),
                            "alle Übereinstimmungen ersetzen",
                            self.replaceThis)
        cmenu.exec_(self.myeditor.mapToGlobal(point))

    def replaceThis(self):
        if not self.myeditor.textCursor().selectedText() == "":
            rtext = self.myeditor.textCursor().selectedText()
            dlg = QInputDialog(self, Qt.Dialog)
            dlg.setOkButtonText("Replace")
            text = dlg.getText(self, "Ersetzen",
                               "ersetze '" + rtext + "' durch:",
                               QLineEdit.Normal, "")
            oldtext = self.myeditor.document().toPlainText()
            if not (text[0] == ""):
                newtext = oldtext.replace(rtext, text[0])
                self.myeditor.setPlainText(newtext)
                self.myeditor.document().setModified(True)

    def about(self):
        link = "<p><a title='Axel Schneider' href='http://goodoldsongs.jimdo.com' target='_blank'>Axel Schneider</a></p>"
        title = "über QTextEdit"
        message = (
            "<span style='text-shadow: #2e3436 2px 2px 2px; color: #6169e1; font-size: 24pt;font-weight: bold;'><strong>QTextEdit 1.2</strong></span></p><br><br>created by<h2 >"
            + link + "</h2> with PyQt5"
            "<br><br>Copyright © 2018 The Qt Company Ltd and other contributors."
            "<br>Qt and the Qt logo are trademarks of The Qt Company Ltd.")
        msg = QMessageBox(QMessageBox.Information, title, message,
                          QMessageBox.NoButton, self,
                          Qt.Dialog | Qt.NoDropShadowWindowHint).show()

    def documentWasModified(self):
        self.setWindowModified(self.myeditor.document().isModified())

    def createActions(self):
        self.newAct = QAction(QIcon.fromTheme('document-new'),
                              "&Neu",
                              self,
                              shortcut=QKeySequence.New,
                              statusTip="neue Datei erstellen",
                              triggered=self.newFile)

        self.openAct = QAction(QIcon.fromTheme('document-open'),
                               "Öffnen.",
                               self,
                               shortcut=QKeySequence.Open,
                               statusTip="Datei öffnen",
                               triggered=self.open)

        self.saveAct = QAction(QIcon.fromTheme('document-save'),
                               "Speichern",
                               self,
                               shortcut=QKeySequence.Save,
                               statusTip="Dokument speichern",
                               triggered=self.save)

        self.saveAsAct = QAction(
            QIcon.fromTheme('document-save-as'),
            "Speichern als...",
            self,
            shortcut=QKeySequence.SaveAs,
            statusTip="Dokument unter neuem Namen speichern",
            triggered=self.saveAs)

        self.exitAct = QAction(QIcon.fromTheme('application-exit'),
                               "Beenden",
                               self,
                               shortcut="Ctrl+Q",
                               statusTip="Programm beenden",
                               triggered=self.close)

        self.cutAct = QAction(QIcon.fromTheme('edit-cut'),
                              "Ausschneiden",
                              self,
                              shortcut=QKeySequence.Cut,
                              statusTip="Ausschneiden",
                              triggered=self.myeditor.cut)

        self.copyAct = QAction(QIcon.fromTheme('edit-copy'),
                               "Kopieren",
                               self,
                               shortcut=QKeySequence.Copy,
                               statusTip="Kopieren",
                               triggered=self.myeditor.copy)

        self.pasteAct = QAction(QIcon.fromTheme('edit-paste'),
                                "Einfügen",
                                self,
                                shortcut=QKeySequence.Paste,
                                statusTip="Einfügen",
                                triggered=self.myeditor.paste)

        self.undoAct = QAction(QIcon.fromTheme('edit-undo'),
                               "Rückgängig",
                               self,
                               shortcut=QKeySequence.Undo,
                               statusTip="Rückgängig",
                               triggered=self.myeditor.undo)

        self.redoAct = QAction(QIcon.fromTheme('edit-redo'),
                               "Wiederholen",
                               self,
                               shortcut=QKeySequence.Redo,
                               statusTip="Wiederholen",
                               triggered=self.myeditor.redo)

        self.aboutAct = QAction(QIcon.fromTheme('help-about'),
                                "Info",
                                self,
                                statusTip="über QTextEdit",
                                triggered=self.about)

        self.aboutQtAct = QAction(QIcon.fromTheme('help-about'),
                                  "über Qt",
                                  self,
                                  statusTip="über Qt",
                                  triggered=QApplication.instance().aboutQt)

        self.repAllAct = QPushButton("alles ersetzen")
        self.repAllAct.setIcon(QIcon.fromTheme("edit-find-and-replace"))
        self.repAllAct.setStatusTip("alles ersetzen")
        self.repAllAct.clicked.connect(self.replaceAll)

        self.cutAct.setEnabled(False)
        self.copyAct.setEnabled(False)
        self.myeditor.copyAvailable.connect(self.cutAct.setEnabled)
        self.myeditor.copyAvailable.connect(self.copyAct.setEnabled)
        self.undoAct.setEnabled(False)
        self.redoAct.setEnabled(False)
        self.myeditor.undoAvailable.connect(self.undoAct.setEnabled)
        self.myeditor.redoAvailable.connect(self.redoAct.setEnabled)

        ### print preview
        self.printPreviewAct = QAction("Druckvorschau",
                                       self,
                                       shortcut=QKeySequence.Print,
                                       statusTip="Druckvorschau",
                                       triggered=self.handlePrintPreview)
        self.printPreviewAct.setIcon(QIcon.fromTheme("document-print-preview"))
        ### print
        self.printAct = QAction("Drucken",
                                self,
                                shortcut=QKeySequence.Print,
                                statusTip="Dokument drucken",
                                triggered=self.handlePrint)
        self.printAct.setIcon(QIcon.fromTheme("document-print"))

        for i in range(self.MaxRecentFiles):
            self.recentFileActs.append(
                QAction(self, visible=False, triggered=self.openRecentFile))

    def findText(self):
        word = self.findfield.text()
        if self.myeditor.find(word):
            self.statusBar().showMessage("'" + word + "' gefunden", 2000)
        else:
            self.myeditor.moveCursor(QTextCursor.Start)
            if self.myeditor.find(word):
                return
            else:
                self.statusBar().showMessage("nichts gefunden", 3000)

    def replaceAll(self):
        oldtext = self.findfield.text()
        newtext = self.replacefield.text()
        if not oldtext == "":
            h = self.myeditor.toHtml().replace(oldtext, newtext)
            self.myeditor.setText(h)
            self.setModified(True)
            self.statusBar().showMessage("alles ersetzt", 3000)
        else:
            self.statusBar().showMessage("nichts zu ersetzen", 3000)

    def replaceOne(self):
        oldtext = self.findfield.text()
        newtext = self.replacefield.text()
        if not oldtext == "":
            h = self.myeditor.toHtml().replace(oldtext, newtext, 1)
            self.myeditor.setText(h)
            self.setModified(True)
            self.statusBar().showMessage("1 ersetzt", 3000)
        else:
            self.statusBar().showMessage("nichts zu ersetzen", 3000)

    def openRecentFile(self):
        action = self.sender()
        if action:
            if (self.maybeSave()):
                self.loadFile(action.data())

    def createMenus(self):
        self.fileMenu = self.menuBar().addMenu("&Datei")
        self.separatorAct = self.fileMenu.addSeparator()
        self.fileMenu.addAction(self.newAct)
        self.fileMenu.addAction(self.openAct)
        self.fileMenu.addAction(self.saveAct)
        self.fileMenu.addAction(self.saveAsAct)
        self.fileMenu.addSeparator()
        for i in range(self.MaxRecentFiles):
            self.fileMenu.addAction(self.recentFileActs[i])
        self.updateRecentFileActions()
        self.fileMenu.addSeparator()
        self.clearRecentAct = QAction("Liste löschen",
                                      self,
                                      triggered=self.clearRecentFiles)
        self.clearRecentAct.setIcon(QIcon.fromTheme("edit-clear"))
        self.fileMenu.addAction(self.clearRecentAct)
        self.fileMenu.addSeparator()
        self.fileMenu.addAction(self.exitAct)

        self.editMenu = self.menuBar().addMenu("&Bearbeiten")
        self.editMenu.addAction(self.undoAct)
        self.editMenu.addAction(self.redoAct)
        self.editMenu.addSeparator()
        self.editMenu.addAction(self.cutAct)
        self.editMenu.addAction(self.copyAct)
        self.editMenu.addAction(self.pasteAct)

        self.menuBar().addSeparator()

        self.helpMenu = self.menuBar().addMenu("&Hilfe")
        self.helpMenu.addAction(self.aboutAct)

    def createToolBars(self):
        self.fileToolBar = self.addToolBar("Datei")
        self.fileToolBar.setIconSize(QSize(16, 16))
        self.fileToolBar.addAction(self.newAct)
        self.fileToolBar.addAction(self.openAct)
        self.fileToolBar.addAction(self.saveAct)
        self.fileToolBar.addAction(self.saveAsAct)
        self.fileToolBar.addSeparator()
        self.fileToolBar.addAction(self.printPreviewAct)
        self.fileToolBar.addAction(self.printAct)
        self.fileToolBar.setStyleSheet("QToolBar { border: 0px }")
        self.fileToolBar.setMovable(False)
        self.setContextMenuPolicy(Qt.NoContextMenu)

        self.editToolBar = self.addToolBar("Bearbeiten")
        self.editToolBar.setIconSize(QSize(16, 16))
        self.editToolBar.addAction(self.undoAct)
        self.editToolBar.addAction(self.redoAct)
        self.editToolBar.addSeparator()
        self.editToolBar.addAction(self.cutAct)
        self.editToolBar.addAction(self.copyAct)
        self.editToolBar.addAction(self.pasteAct)
        self.editToolBar.setMovable(False)
        self.editToolBar.setStyleSheet("QToolBar { border: 0px }")

        ### find / replace toolbar
        self.addToolBarBreak()
        self.findToolBar = self.addToolBar("Suchen")
        self.findToolBar.setIconSize(QSize(16, 16))
        self.findfield = QLineEdit()
        self.findfield.addAction(QIcon.fromTheme("edit-find"), 0)
        self.findfield.setClearButtonEnabled(True)
        self.findfield.setFixedWidth(200)
        self.findfield.setPlaceholderText("suchen")
        self.findfield.setStatusTip("drücke RETURN zum suchen")
        self.findfield.setText("")
        self.findfield.returnPressed.connect(self.findText)
        self.findToolBar.addWidget(self.findfield)
        self.replacefield = QLineEdit()
        self.replacefield.addAction(QIcon.fromTheme("edit-find-replace"), 0)
        self.replacefield.setClearButtonEnabled(True)
        self.replacefield.setFixedWidth(200)
        self.replacefield.setPlaceholderText("ersetzen durch")
        self.replacefield.setStatusTip(
            "drücke RETURN um das erste zu ersetzen")
        self.replacefield.returnPressed.connect(self.replaceOne)
        self.findToolBar.addSeparator()
        self.findToolBar.addWidget(self.replacefield)
        self.findToolBar.addSeparator()
        self.findToolBar.addWidget(self.repAllAct)
        self.findToolBar.setMovable(False)
        self.findToolBar.setStyleSheet("QToolBar { border: 0px }")

    def createStatusBar(self):
        self.statusBar().setStyleSheet(myStyleSheet(self))
        self.statusBar().showMessage("Willkommen")
        self.DigitalClock = DigitalClock()
        self.DigitalClock.setStyleSheet(
            "QLCDNumber {padding: 2px, 2px 2px 2px; border: 0px solid #2e3436; color: #3465a4; background-color: transparent }"
        )
        self.statusBar().addPermanentWidget(self.DigitalClock)

    def readSettings(self):
        pos = self.settings.value("pos", QPoint(200, 200))
        size = self.settings.value("size", QSize(400, 400))
        self.resize(size)
        self.move(pos)

    def writeSettings(self):
        self.settings.setValue("pos", self.pos())
        self.settings.setValue("size", self.size())

    def maybeSave(self):
        if self.myeditor.document().isModified():
            ret = QMessageBox.warning(
                self,
                "QTextEdit Meldung",
                "Das Dokument wurde geändert.\nSollen die Änderungen gespeichert werden?",
                QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel,
                defaultButton=QMessageBox.Save)
            if ret == QMessageBox.Save:
                return self.save()
            if ret == QMessageBox.Cancel:
                return False
        return True

    def loadFile(self, fileName):
        file = QFile(fileName)
        if not file.open(QFile.ReadOnly | QFile.Text):
            QMessageBox.warning(
                self, "Meldung",
                "Cannot read file %s:\n%s." % (fileName, file.errorString()))
            return

        infile = QTextStream(file)
        QApplication.setOverrideCursor(Qt.WaitCursor)
        self.myeditor.setPlainText(infile.readAll())
        QApplication.restoreOverrideCursor()

        self.setCurrentFile(fileName)
        self.statusBar().showMessage("Datei '" + fileName + "' geladen", 3000)

    def saveFile(self, fileName):
        file = QFile(fileName)
        if not file.open(QFile.WriteOnly | QFile.Text):
            QMessageBox.warning(
                self, "Message",
                "Cannot write file %s:\n%s." % (fileName, file.errorString()))
            return False

        outfile = QTextStream(file)
        QApplication.setOverrideCursor(Qt.WaitCursor)
        outfile << self.myeditor.toPlainText()
        QApplication.restoreOverrideCursor()

        self.setCurrentFile(fileName)
        self.statusBar().showMessage("Datei '" + fileName + "' gespeichert",
                                     3000)
        return True

    def setCurrentFile(self, fileName):
        self.curFile = fileName
        self.myeditor.document().setModified(False)
        self.setWindowModified(False)

        if self.curFile:
            self.setWindowTitle(self.strippedName(self.curFile) + "[*]")
        else:
            self.setWindowTitle('Unbenannt.txt' + "[*]")

        files = self.settings.value('recentFileList', [])
        if not files == "":
            try:
                files.remove(fileName)
            except ValueError:
                pass

            if fileName:
                files.insert(0, fileName)
                del files[self.MaxRecentFiles:]

                self.settings.setValue('recentFileList', files)
                self.updateRecentFileActions()

    def updateRecentFileActions(self):
        mytext = ""
        files = self.settings.value('recentFileList', [])
        numRecentFiles = min(len(files), self.MaxRecentFiles)
        #        if not files == "":
        for i in range(numRecentFiles):
            text = "&%d %s" % (i + 1, self.strippedName(files[i]))
            self.recentFileActs[i].setText(text)
            self.recentFileActs[i].setData(files[i])
            self.recentFileActs[i].setVisible(True)
            self.recentFileActs[i].setIcon(QIcon.fromTheme("text-x-generic"))

        for j in range(numRecentFiles, self.MaxRecentFiles):
            self.recentFileActs[j].setVisible(False)

        self.separatorAct.setVisible((numRecentFiles > 0))

    def clearRecentFiles(self, fileName):
        self.settings.clear()
        self.updateRecentFileActions()

    def strippedName(self, fullFileName):
        return QFileInfo(fullFileName).fileName()

    def msgbox(self, message):
        QMessageBox.warning(self, "Message", message)

    def handlePrint(self):
        if self.myeditor.toPlainText() == "":
            self.statusBar().showMessage("kein Text zum Drucken")
            self.msgbox("kein Text zum Drucken")
        else:
            dialog = QtPrintSupport.QPrintDialog()
            if dialog.exec_() == QDialog.Accepted:
                self.handlePaintRequest(dialog.printer())
                self.statusBar().showMessage("Dokument gedruckt")

    def handlePrintPreview(self):
        if self.myeditor.toPlainText() == "":
            self.statusBar().showMessage("kein Text für Vorschau")
            self.msgbox("kein Text für Vorschau")
        else:
            dialog = QtPrintSupport.QPrintPreviewDialog()
            dialog.setGeometry(10, 0, self.width() - 60, self.height() - 60)
            dialog.paintRequested.connect(self.handlePaintRequest)
            dialog.exec_()
            self.statusBar().showMessage("Vorschau geschlossen")

    def handlePaintRequest(self, printer):
        printer.setDocName(self.curFile)
        document = self.myeditor.document()
        document.print_(printer)

    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls():
            event.accept()
        else:
            event.ignore()

    def dropEvent(self, event):
        f = str(event.mimeData().urls()[0].toLocalFile())
        self.loadFile(f)
Beispiel #24
0
class RenameDialog(QDialog):
    def __init__(self, parent: QWidget) -> None:
        super().__init__(parent)

        self._basename: str = ""

        self._build_gui()

    def _build_gui(self) -> None:
        self.resize(600, 100)
        self.setWindowTitle("RenameDialog")
        self.setWindowModality(Qt.WindowModal)

        # Widgets
        icon_label = QLabel()
        icon_label.setPixmap(
            QIcon.fromTheme("accessories-text-editor").pixmap(48))
        icon_label.setAlignment(Qt.AlignTop)

        self.label = QLabel("Rename ...")
        self.label.setTextInteractionFlags(Qt.TextSelectableByMouse)
        self.name_edit = QLineEdit(self)

        self.name_reload = self.name_edit.addAction(QIcon.fromTheme("reload"),
                                                    QLineEdit.TrailingPosition)
        self.name_reload.setShortcut("F5")
        self.name_reload.setToolTip("Reset the filename to it's original name")

        self.button_box = QDialogButtonBox(self)

        self.btn_rename = QPushButton(QIcon.fromTheme("document-save-as"),
                                      "Rename")
        self.button_box.addButton(self.btn_rename, QDialogButtonBox.AcceptRole)
        self.btn_cancel = self.button_box.addButton(QDialogButtonBox.Cancel)
        self.btn_rename.setDefault(True)

        # layout
        self.vbox = QVBoxLayout()

        self.vbox.addWidget(self.label)
        self.vbox.addWidget(self.name_edit)
        self.vbox.addStretch()
        self.vbox.addWidget(self.button_box)

        hbox = QHBoxLayout()
        hbox.addWidget(icon_label)
        hbox.addLayout(self.vbox)
        self.setLayout(hbox)

        # signals
        self.name_edit.returnPressed.connect(self.accept)
        self.btn_rename.clicked.connect(self._on_rename_clicked)
        self.btn_cancel.clicked.connect(self._on_cancel_clicked)
        self.name_reload.triggered.connect(self._on_name_reload)

    def _on_rename_clicked(self) -> None:
        self.accept()

    def _on_cancel_clicked(self) -> None:
        self.reject()

    def _on_name_reload(self) -> None:
        self.name_edit.setText(self._basename)
        root, ext = os.path.splitext(self._basename)
        self.name_edit.setSelection(0, len(root))

    def get_old_basename(self) -> str:
        return self._basename

    def get_new_basename(self) -> str:
        return cast(str, self.name_edit.text())

    def set_basename(self, basename: str) -> None:
        self._basename = basename

        self.setWindowTitle("Rename \"{}\"".format(basename))
        self.label.setText("Rename \"{}\" to:".format(basename))

        self.name_edit.setText(basename)
        root, ext = os.path.splitext(basename)
        self.name_edit.setSelection(0, len(root))
Beispiel #25
0
class GeneralConfiguration(QWidget):
    """General configuration class"""

    def __init__(self, parent):
        super().__init__()
        self._preferences = parent
        vbox = QVBoxLayout(self)

        # Groups
        group_box_start = QGroupBox(translations.TR_PREFERENCES_GENERAL_START)
        group_box_close = QGroupBox(translations.TR_PREFERENCES_GENERAL_CLOSE)
        group_box_workspace = QGroupBox(
            translations.TR_PREFERENCES_GENERAL_WORKSPACE)
        group_box_reset = QGroupBox(translations.TR_PREFERENCES_GENERAL_RESET)
        group_box_swap = QGroupBox(
            translations.TR_PREFERENCES_GENERAL_SWAPFILE)
        group_box_modification = QGroupBox(
            translations.TR_PREFERENCES_GENERAL_EXTERNALLY_MOD)

        # Group start
        box_start = QVBoxLayout(group_box_start)
        self._check_last_session = QCheckBox(
            translations.TR_PREFERENCES_GENERAL_LOAD_LAST_SESSION)
        self._check_notify_updates = QCheckBox(
            translations.TR_PREFERENCES_GENERAL_NOTIFY_UPDATES)
        box_start.addWidget(self._check_last_session)
        box_start.addWidget(self._check_notify_updates)
        # Group close
        box_close = QVBoxLayout(group_box_close)
        self._check_confirm_exit = QCheckBox(
            translations.TR_PREFERENCES_GENERAL_CONFIRM_EXIT)
        box_close.addWidget(self._check_confirm_exit)
        # Workspace and Project
        grid_workspace = QGridLayout(group_box_workspace)
        self._text_workspace = QLineEdit()
        choose_workspace_action = self._text_workspace.addAction(
            self.style().standardIcon(self.style().SP_DirIcon),
            QLineEdit.TrailingPosition)
        clear_workspace_action = self._text_workspace.addAction(
            self.style().standardIcon(self.style().SP_LineEditClearButton),
            QLineEdit.TrailingPosition)
        self._text_workspace.setReadOnly(True)
        grid_workspace.addWidget(
            QLabel(translations.TR_PREFERENCES_GENERAL_WORKSPACE), 0, 0)
        grid_workspace.addWidget(self._text_workspace, 0, 1)

        # Resetting prefences
        box_reset = QVBoxLayout(group_box_reset)
        btn_reset = QPushButton(
            translations.TR_PREFERENCES_GENERAL_RESET_PREFERENCES)
        box_reset.addWidget(btn_reset)

        # Swap File
        box_swap = QGridLayout(group_box_swap)
        box_swap.addWidget(QLabel(
            translations.TR_PREFERENCES_GENERAL_SWAPFILE_LBL), 0, 0)
        self._combo_swap_file = QComboBox()
        self._combo_swap_file.addItems([
            translations.TR_PREFERENCES_GENERAL_SWAPFILE_DISABLE,
            translations.TR_PREFERENCES_GENERAL_SWAPFILE_ENABLE
        ])
        self._combo_swap_file.currentIndexChanged.connect(
            self._change_swap_widgets_state)
        box_swap.addWidget(self._combo_swap_file, 0, 1)
        box_swap.addWidget(QLabel(
            translations.TR_PREFERENCES_GENERAL_SWAPFILE_SYNC_INTERVAL), 1, 0)
        self._spin_swap = QSpinBox()
        self._spin_swap.setSuffix("s")
        self._spin_swap.setRange(5, 600)
        self._spin_swap.setSingleStep(5)
        box_swap.addWidget(self._spin_swap, 1, 1)

        # Externally modification
        box_mod = QHBoxLayout(group_box_modification)
        box_mod.addWidget(
            QLabel(translations.TR_PREFERENCES_GENERAL_EXTERNALLY_MOD_LABEL))
        self._combo_mod = QComboBox()
        self._combo_mod.addItems(["Ask", "Reload", "Ignore"])
        box_mod.addWidget(self._combo_mod)

        # Add groups to main layout
        vbox.addWidget(group_box_start)
        vbox.addWidget(group_box_close)
        vbox.addWidget(group_box_workspace)
        vbox.addWidget(group_box_swap)
        vbox.addWidget(group_box_modification)
        vbox.addWidget(group_box_reset, alignment=Qt.AlignLeft)
        vbox.addSpacerItem(
            QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Expanding))

        # Settings
        qsettings = IDE.ninja_settings()
        qsettings.beginGroup("ide")
        self._check_last_session.setChecked(
            qsettings.value("loadFiles", defaultValue=True, type=bool))
        self._check_notify_updates.setChecked(
            qsettings.value("notifyUpdates", defaultValue=True, type=bool))
        qsettings.endGroup()
        self._combo_swap_file.setCurrentIndex(settings.SWAP_FILE)
        self._spin_swap.setValue(settings.SWAP_FILE_INTERVAL)
        self._text_workspace.setText(settings.WORKSPACE)
        self._combo_mod.setCurrentIndex(settings.RELOAD_FILE)
        self._check_confirm_exit.setChecked(settings.CONFIRM_EXIT)
        # Connections
        btn_reset.clicked.connect(self._reset_preferences)
        choose_workspace_action.triggered.connect(self._load_workspace)
        clear_workspace_action.triggered.connect(self._text_workspace.clear)
        self._preferences.savePreferences.connect(self.save)

    def _change_swap_widgets_state(self, index):
        if index == 0:
            self._spin_swap.setEnabled(False)
        else:
            self._spin_swap.setEnabled(True)

    def _reset_preferences(self):
        """Reset all preferences to default values"""

        result = QMessageBox.question(
            self,
            translations.TR_PREFERENCES_GENERAL_RESET_TITLE,
            translations.TR_PREFERENCES_GENERAL_RESET_BODY,
            buttons=QMessageBox.Yes | QMessageBox.No
        )
        if result == QMessageBox.Yes:
            qsettings = IDE.ninja_settings()
            qsettings.clear()
            self._preferences.close()

    def _load_workspace(self):
        """Ask the user for a Workspace path"""
        path = QFileDialog.getExistingDirectory(
            self, translations.TR_PREFERENCES_GENERAL_SELECT_WORKSPACE)
        self._text_workspace.setText(path)

    def save(self):
        """Save all preferences values"""

        qsettings = IDE.ninja_settings()
        qsettings.beginGroup("ide")

        settings.CONFIRM_EXIT = self._check_confirm_exit.isChecked()
        qsettings.setValue("confirmExit", settings.CONFIRM_EXIT)
        qsettings.setValue("loadFiles", self._check_last_session.isChecked())
        qsettings.setValue("notifyUpdates",
                           self._check_notify_updates.isChecked())
        settings.WORKSPACE = self._text_workspace.text()
        qsettings.setValue("workspace", settings.WORKSPACE)
        settings.RELOAD_FILE = self._combo_mod.currentIndex()
        qsettings.setValue("reloadSetting", settings.RELOAD_FILE)

        settings.SWAP_FILE = self._combo_swap_file.currentIndex()
        qsettings.setValue("swapFile", settings.SWAP_FILE)
        settings.SWAP_FILE_INTERVAL = self._spin_swap.value()
        qsettings.setValue("swapFileInterval", settings.SWAP_FILE_INTERVAL)

        qsettings.endGroup()
class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setGeometry(0, 0, 700, 400)
        self.setContentsMargins(6, 6, 6, 6)
        self.setStyleSheet(myStyleSheet(self))
        self.setWindowTitle("Radio Stations - searching with pyradios")
        self.genreList = genres.splitlines()
        self.findfield = QLineEdit()
        self.findfield.setFixedWidth(250)
        self.findfield.addAction(QIcon.fromTheme("edit-find"), 0)
        self.findfield.setPlaceholderText("type search term and press RETURN ")
        self.findfield.returnPressed.connect(self.findStations)
        self.findfield.setClearButtonEnabled(True)
        self.field = QPlainTextEdit()
        self.field.setContextMenuPolicy(Qt.CustomContextMenu)
        self.field.customContextMenuRequested.connect(
            self.contextMenuRequested)
        self.field.cursorPositionChanged.connect(self.selectLine)
        self.field.setWordWrapMode(QTextOption.NoWrap)
        ### volume slider
        self.volSlider = QSlider()
        self.volSlider.setFixedWidth(100)
        self.volSlider.setOrientation(Qt.Horizontal)
        self.volSlider.valueChanged.connect(self.setVolume)
        self.volSlider.setMinimum(0)
        self.volSlider.setMaximum(100)
        ### genre box
        self.combo = QComboBox()
        self.combo.currentIndexChanged.connect(self.comboSearch)
        self.combo.addItem("choose Genre")
        for m in self.genreList:
            self.combo.addItem(m)
        self.combo.addItem("Country")
        self.combo.setFixedWidth(150)
        ### toolbar ###
        self.tb = self.addToolBar("tools")
        self.tb.setContextMenuPolicy(Qt.PreventContextMenu)
        self.tb.setMovable(False)
        self.saveButton = QPushButton("Save as txt")
        self.saveButton.setIcon(QIcon.fromTheme("document-save"))
        self.saveButton.clicked.connect(self.saveStations)
        self.savePlaylistButton = QPushButton("Save as m3u")
        self.savePlaylistButton.setIcon(QIcon.fromTheme("document-save"))
        self.savePlaylistButton.clicked.connect(self.savePlaylist)
        self.setCentralWidget(self.field)
        self.tb.addWidget(self.findfield)
        self.tb.addWidget(self.saveButton)
        self.tb.addWidget(self.savePlaylistButton)
        self.tb.addSeparator()
        self.tb.addWidget(self.combo)
        ### player ###
        self.player = QMediaPlayer()
        self.player.metaDataChanged.connect(self.metaDataChanged)
        self.startButton = QPushButton("Play")
        self.startButton.setIcon(QIcon.fromTheme("media-playback-start"))
        self.startButton.clicked.connect(self.getURLtoPlay)
        self.stopButton = QPushButton("Stop")
        self.stopButton.setIcon(QIcon.fromTheme("media-playback-stop"))
        self.stopButton.clicked.connect(self.stopPlayer)
        self.statusBar().addPermanentWidget(self.volSlider)
        self.statusBar().addPermanentWidget(self.startButton)
        self.statusBar().addPermanentWidget(self.stopButton)
        ## actions
        self.getNameAction = QAction(QIcon.fromTheme("edit-copy"),
                                     "copy Station Name",
                                     self,
                                     triggered=self.getName)
        self.getUrlAction = QAction(QIcon.fromTheme("edit-copy"),
                                    "copy Station URL",
                                    self,
                                    triggered=self.getURL)
        self.getNameAndUrlAction = QAction(QIcon.fromTheme("edit-copy"),
                                           "copy Station Name,URL",
                                           self,
                                           triggered=self.getNameAndUrl)
        self.getURLtoPlayAction = QAction(
            QIcon.fromTheme("media-playback-start"),
            "play Station",
            self,
            shortcut="F6",
            triggered=self.getURLtoPlay)
        self.addAction(self.getURLtoPlayAction)
        self.stopPlayerAction = QAction(QIcon.fromTheme("media-playback-stop"),
                                        "stop playing",
                                        self,
                                        shortcut="F7",
                                        triggered=self.stopPlayer)
        self.addAction(self.stopPlayerAction)
        self.helpAction = QAction(QIcon.fromTheme("help-info"),
                                  "Help",
                                  self,
                                  shortcut="F1",
                                  triggered=self.showHelp)
        self.addAction(self.helpAction)

        self.getForWebAction = QAction(QIcon.fromTheme("browser"),
                                       "copy for WebPlayer",
                                       self,
                                       triggered=self.getForWeb)
        self.volSlider.setValue(60)
        self.statusBar().showMessage("Welcome", 0)

    def setVolume(self):
        self.player.setVolume(self.volSlider.value())

    def comboSearch(self):
        if self.combo.currentIndex() > 0:
            self.findfield.setText(self.combo.currentText())
            self.findStations()

    def getName(self):
        t = self.field.textCursor().selectedText().partition(",")[0]
        clip = QApplication.clipboard()
        clip.setText(t)

    def getURL(self):
        t = self.field.textCursor().selectedText().partition(",")[2]
        clip = QApplication.clipboard()
        clip.setText(t)

    def getNameAndUrl(self):
        t = self.field.textCursor().selectedText()
        clip = QApplication.clipboard()
        clip.setText(t)

    def getForWeb(self):
        t = self.field.textCursor().selectedText()
        name = t.partition(",")[0]
        url = t.partition(",")[2]
        result = f"<li><a class='chlist' href='{url}'>{name}</a></li>"
        clip = QApplication.clipboard()
        clip.setText(result)

    def selectLine(self):
        tc = self.field.textCursor()
        tc.select(QTextCursor.LineUnderCursor)
        tc.movePosition(QTextCursor.StartOfLine, QTextCursor.MoveAnchor)  ##,
        tc.movePosition(QTextCursor.EndOfBlock, QTextCursor.KeepAnchor)
        self.field.setTextCursor(tc)

    def showHelp(self):
        QMessageBox.information(
            self, "Information",
            "F6 -> play Station (from line where cursor is)\nF7 -> stop playing"
        )

    def stopPlayer(self):
        self.player.stop()
        self.statusBar().showMessage("Player stopped", 0)

    ### QPlainTextEdit contextMenu
    def contextMenuRequested(self, point):
        cmenu = QMenu()
        if not self.field.toPlainText() == "":
            cmenu.addAction(self.getNameAction)
            cmenu.addAction(self.getUrlAction)
            cmenu.addAction(self.getNameAndUrlAction)
            cmenu.addSeparator()
            cmenu.addAction(self.getURLtoPlayAction)
            cmenu.addAction(self.stopPlayerAction)
            cmenu.addSeparator()
            cmenu.addAction(self.helpAction)
            cmenu.addAction(self.getForWebAction)
        cmenu.exec_(self.field.mapToGlobal(point))

    def getURLtoPlay(self):
        url = ""
        tc = self.field.textCursor()
        rtext = tc.selectedText().partition(",")[2]
        stext = tc.selectedText().partition(",")[0]
        url = rtext
        print("stream url=", url)
        self.player.setMedia(QMediaContent(QUrl(url)))
        self.player.play()
        self.statusBar().showMessage("%s %s" % ("playing", stext), 0)

    def metaDataChanged(self):
        if self.player.isMetaDataAvailable():
            trackInfo = (self.player.metaData("Title"))
            trackInfo2 = (self.player.metaData("Comment"))
            if not trackInfo == None:
                self.statusBar().showMessage(trackInfo, 0)
                if not trackInfo2 == None:
                    self.statusBar().showMessage("%s %s" %
                                                 (trackInfo, trackInfo2))

    def findStations(self):
        self.field.setPlainText("")
        my_value = self.findfield.text()
        self.statusBar().showMessage("searching ...")
        base_url = "https://de1.api.radio-browser.info/xml/stations/byname/"
        url = f"{base_url}{my_value}"
        xml = requests.get(url).content.decode()
        if xml:
            root = ET.fromstring(xml)

            for child in root:
                ch_name = child.attrib["name"]
                ch_url = child.attrib["url"]
                self.field.appendPlainText(f"{ch_name},{ch_url}")
                self.copyToClipboard()

                tc = self.field.textCursor()
                tc.movePosition(QTextCursor.Start, QTextCursor.MoveAnchor)
                tc.select(QTextCursor.LineUnderCursor)
                tc.movePosition(QTextCursor.EndOfBlock, QTextCursor.KeepAnchor)
                self.field.setTextCursor(tc)

        else:
            self.statusBar().showMessage("nothing found", 0)

        self.field.verticalScrollBar().triggerAction(
            QScrollBar.SliderToMinimum)
        self.field.horizontalScrollBar().triggerAction(
            QScrollBar.SliderToMinimum)

    def saveStations(self):
        if not self.field.toPlainText() == "":
            path, _ = QFileDialog.getSaveFileName(
                None, "RadioStations",
                self.findfield.text() + ".txt", "Text Files (*.txt)")
            if path:
                s = self.field.toPlainText()
                with open(path, 'w') as f:
                    f.write(s)
                    f.close()
                    self.statusBar().showMessage("saved!", 0)

    def savePlaylist(self):
        if not self.field.toPlainText() == "":
            path, _ = QFileDialog.getSaveFileName(
                None, "RadioStations",
                self.findfield.text() + ".m3u", "Playlist Files (*.m3u)")
            if path:
                result = ""
                s = self.field.toPlainText()
                st = []
                for line in s.splitlines():
                    st.append(line)
                result += "#EXTM3U"
                result += '\n'
                for x in range(len(st)):
                    result += "#EXTINF:" + str(x) + "," + st[x].partition(
                        ",")[0]
                    result += '\n'
                    result += st[x].partition(",")[2]
                    result += '\n'
                with open(path, 'w') as f:
                    f.write(result)
                    f.close()
                    self.statusBar().showMessage("saved!", 0)

    def copyToClipboard(self):
        clip = QApplication.clipboard()
        if not self.field.toPlainText() == "":
            clip.setText(self.field.toPlainText())
Beispiel #27
0
class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.webfile = f"{QFileInfo.path(QFileInfo(app.arguments()[0]))}/myradio.html"
        print(self.webfile)
        self.setGeometry(0, 0, 700, 800)
        self.setMaximumWidth(700)
        self.setContentsMargins(6, 6, 6, 6)
        self.setStyleSheet(myStyleSheet(self))
        self.setWindowTitle("Radio Stations - searching with pyradios")
        self.genreList = genres.splitlines()
        self.findfield = QLineEdit()
        self.findfield.setFixedWidth(250)
        self.findfield.addAction(QIcon.fromTheme("edit-find"), 0)
        self.findfield.setPlaceholderText("type search term and press RETURN ")
        self.findfield.returnPressed.connect(self.findStations)
        self.findfield.setClearButtonEnabled(True)
        self.field = ""
        ### genre box
        self.combo = QComboBox()
        self.combo.currentIndexChanged.connect(self.comboSearch)
        self.combo.addItem("choose Genre")
        for m in self.genreList:
            self.combo.addItem(m)
        self.combo.addItem("Country")
        self.combo.setFixedWidth(150)
        ### toolbar ###
        self.tb = self.addToolBar("tools")
        self.tb.setContextMenuPolicy(Qt.PreventContextMenu)
        self.tb.setMovable(False)
        self.saveButton = QPushButton("Save as txt")
        self.saveButton.setIcon(QIcon.fromTheme("document-save"))
        self.saveButton.clicked.connect(self.saveStations)
        self.savePlaylistButton = QPushButton("Save as m3u")
        self.savePlaylistButton.setIcon(QIcon.fromTheme("document-save"))
        self.savePlaylistButton.clicked.connect(self.savePlaylist)
        self.tb.addWidget(self.findfield)
        self.tb.addWidget(self.saveButton)
        self.tb.addWidget(self.savePlaylistButton)
        self.tb.addSeparator()
        self.tb.addWidget(self.combo)

        self.statusBar().showMessage("Welcome", 0)
        self.view = QWebEngineView()
        if QFileInfo(self.webfile).exists:
            self.view.load(QUrl.fromLocalFile(self.webfile))
        self.setCentralWidget(self.view)

    def comboSearch(self):
        if self.combo.currentIndex() > 0:
            self.findfield.setText(self.combo.currentText())
            self.findStations()

    def findStations(self):
        html_content = html_top
        self.field = ""
        my_value = self.findfield.text()
        self.statusBar().showMessage("searching ...")
        base_url = "https://de1.api.radio-browser.info/xml/stations/byname/"
        url = f"{base_url}{my_value}"
        xml = requests.get(url).content.decode()
        if xml:
            root = ET.fromstring(xml)

            for child in root:
                ch_name = child.attrib["name"]
                ch_url = child.attrib["url"]
                self.field += (f"{ch_name},{ch_url}")
                self.field += '\n'


#        mysearch = self.findfield.text()
#        self.statusBar().showMessage("searching ...")
#        rb = RadioBrowser()
#        myparams = {'name': 'search', 'nameExact': 'false', 'bitrateMin': 64}
#
#        for key in myparams.keys():
#                if key == "name":
#                    myparams[key] = mysearch
#
#        r = rb.station_search(params=myparams)
#
#        n = ""
#        m = ""
#        for i in range(len(r)):
#            for key,value in r[i].items():
#                if str(key) == "name":
#                    n = value.replace(",", " ")
#                if str(key) == "url_resolved":
#                    m = value
#            if not n == "" and not m == "":
#                self.field += ("%s,%s" % (n, m.replace('\n', '')))
#                self.field += '\n'
#
        text = linesep.join([s for s in self.field.splitlines()
                             if s]).splitlines()

        if not len(text) == 0:
            self.statusBar().showMessage("found " + str(len(text)) + " '" +
                                         self.findfield.text() + "' Stations")
            for line in text:
                ch = line.split(",")
                if len(ch) > 1:
                    name = ch[0]
                    url = ch[1]
                    html_content += f"\t\t<li><a class='chlist' href='{url}'>{name}</a></li>"
            html_content += html_end
            with open(self.webfile, 'w') as f:
                f.write(html_content)
                f.close()

            self.view.load(QUrl.fromLocalFile(self.webfile))

        else:
            self.statusBar().showMessage("nothing found", 0)

    def saveStations(self):
        if not self.field == "":
            path, _ = QFileDialog.getSaveFileName(
                None, "RadioStations",
                self.findfield.text() + ".txt", "Text Files (*.txt)")
            if path:
                s = self.field
                with open(path, 'w') as f:
                    f.write(s)
                    f.close()
                    self.statusBar().showMessage("saved!", 0)

    def savePlaylist(self):
        if not self.field == "":
            path, _ = QFileDialog.getSaveFileName(
                None, "RadioStations",
                self.findfield.text() + ".m3u", "Playlist Files (*.m3u)")
            if path:
                result = ""
                s = self.field
                st = []
                for line in s.splitlines():
                    st.append(line)
                result += "#EXTM3U"
                result += '\n'
                for x in range(len(st)):
                    result += "#EXTINF:" + str(x) + "," + st[x].partition(
                        ",")[0]
                    result += '\n'
                    result += st[x].partition(",")[2]
                    result += '\n'
                with open(path, 'w') as f:
                    f.write(result)
                    f.close()
                    self.statusBar().showMessage("saved!", 0)
Beispiel #28
0
class View(QWidget):

    send_data           = pyqtSignal(object)
    baudrate_src_changed    = pyqtSignal(object)
    baudrate_pump_changed    = pyqtSignal(object)
    baudrate_temp_changed    = pyqtSignal(object)
    #eol_changed         = pyqtSignal(object)
    port_changed        = pyqtSignal(object)
    seedPulseChanged = pyqtSignal(object)
    seedFreValueChanged = pyqtSignal(object)
    seedPulseFreChanged = pyqtSignal(object)
    firstPumpChanged = pyqtSignal(object)
    secondPumpChanged = pyqtSignal(object)
    startSrcModel = pyqtSignal(object)
    startPumpModel = pyqtSignal(object)
    startTempModel = pyqtSignal(object)
    beginTime = pyqtSignal(object)
    emitUsername = pyqtSignal(object)

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


        self.queue      = Queue()
        self.end_cmd    = None
        self.autoscroll = True
        self.msg_sent   = False

        self.timer = QTimer()
        self.timer.timeout.connect(self.update_gui)
        self.timer.start(100)
        self.srcModelstarted = False
        self.pumpModelstarted = False
        self.tempModelstarted = False
        self.currentValueList =list()
        self.currentTimeList = list()
        self.buttonMinimumWidth = 100
        # self.topSeedCurrent = 700
        # self.topPumpCurrent = 1000
        self.canClosePort = True

        self.initSeedPulse = 0
        self.initSeedFre = 0
        self.init1stCurrent = 0
        self.init2stCurrent = 0
        self.initSeedCurrent =0
        # get the lastsave record
        self.last = LastLog()
        self.lastpick = self.last.loadLast()
        uslast = self.lastpick.get('user',False)
        print('uslast',uslast)
        if uslast is False:
            self.user = User()
        else:
            self.user = uslast
        #init down machine status
        self.__init__slaveStatus()
        self.__initUI()


    def __init__slaveStatus(self):
        self.isSeedOpen = False
        self.seedcurrentre = False
        self.seedpulsere = False
        self.seedfrequecere = False
        self.seedcurrent = 0
        self.seedpulse = 0
        self.seedfrequece = 0
        self.firstcurrent = 0
        self.secondcurrent = 0
        self.isFirstPumpOpen = False
        self.isSecondPumpOpen = False
        self.isLEDOpen = False


    def __initUI(self):
        '''main window box'''

        self.mainBox = QVBoxLayout(self)#使用垂直布局类
        self.showBox = QHBoxLayout()
        self.setWindowState(Qt.WindowMaximized)
###
#command area: push button, plain text edit and line edit
###
        cmd_btn = QPushButton('Send Command (ctrl+Q)')
        cmd_btn.setMinimumWidth(self.buttonMinimumWidth)
        cmd_btn.clicked.connect(self.emit_send_data)
        #import cmd strl+enter
        cmdEnterAction = QAction(self)
        cmdEnterAction.setShortcut('ctrl+Q')
        cmdEnterAction.setStatusTip(' press ctrl+Q to send command')
        cmdEnterAction.triggered.connect(self.emit_send_data)
        self.cmd_edit = QLineEdit()
        self.cmd_edit.addAction(cmdEnterAction)
        cmdBox = QVBoxLayout()


#message box
        self.editer = QPlainTextEdit()
        self.editer.setReadOnly(True)
# <<<<<<< HEAD
        self.editer.setMaximumSize(300,2000)
# =======
        cmdBox = QVBoxLayout()
        # cmdBox.addWidget(self.cmd_edit)
        # cmdBox.addWidget(cmd_btn)
        self.powerShow = PowerShow()
        cmdBox.addWidget(self.powerShow)
# >>>>>>> a45e80ec77a4a8729fa4205165faae001fd09cab
        cmdBox.addWidget(self.editer)
        # cmd_btn.setMaximumSize(300,400)
        # self.cmd_edit.setMaximumSize(300,100)

###
#paint area use matplotlib
###
        self.paintwidget = QWidget(self)
        self.painter = MyDynamicMplCanvas(self.paintwidget, width=5, height=4, dpi=100)
        # self.showBox.addLayout(self.powerShowUI())
        self.showBox.addLayout(cmdBox)
        self.showBox.addWidget(self.painter)
        self.toolBoxUI()
        self.mainBox.addWidget(self.toolBox)
        self.mainBox.addLayout(self.showBox)


        self.setLayout(self.mainBox)
        self.setWindowTitle("光子暗化平台软件")

    def toolBoxUI(self):
        '''use a tab widget to organize set area
        '''
###
#QTabWidget() layout
###
        gbox1 = QGroupBox()
        gbox1.setStyleSheet("QGroupBox{border:None;}")
        self.useBox = QHBoxLayout(gbox1)
        self.useBox.setGeometry(QRect( 0, 0, 300,100))
        gbox2 = QGroupBox()
        gbox2.setStyleSheet("QGroupBox{border:None;}")
        self.portUI = PortGBUI()
        self.portUI.setupUi(gbox2)
        # self.portUI.widget.setGeometry(QRect( 0, 0, 450,200))
        gbox3 = QGroupBox()
        gbox3.setStyleSheet("QGroupBox{border:None;}")
        self.pumpUI = PumpUI()
        self.pumpUI.setupUi(gbox3)
        self.pumpUI.groupBox.setTitle(' ')
        # self.pumpUI.widget.setGeometry(QRect( 0, 0, 400,200))
        gbox4 = QGroupBox()
        gbox4.setStyleSheet("QGroupBox{border:None;}")
        gbox5 = QGroupBox()
        gbox5.setStyleSheet("QGroupBox{border:None;}")
        #self.menuBox = QHBoxLayout()

        # self.setBox = QHBoxLayout(gbox2)
        self.pumpBox = QGridLayout(gbox3)
        self.powerRecordBox = QHBoxLayout(gbox4)
        self.toolBox = QTabWidget()
        # self.toolBox.setStyleSheet("QTabWidget.pane{background: transparent;}\
        #     ")
        self.toolBox.addTab(gbox1,'用户登录')
        self.toolBox.addTab(gbox2,'串口设置')
        self.toolBox.addTab(gbox3,'泵浦开关')
        self.toolBox.addTab(gbox4,'功率计')
        self.toolBox.addTab(gbox5,'帮助')
        # self.toolBox.
        self.toolBox.setTabEnabled(1,False)
        self.toolBox.setTabEnabled(2,False)
        self.toolBox.setTabEnabled(3,False)
        self.toolBox.setMaximumSize(10000,200)
        # self.toolBox.resize(1200,200)
        userbox = UserView()
        userbox.usersignal.connect(self.setUser)
        self.useBox.addWidget(userbox)
        # self.useBox.addStretch()
        self.powerRecord = PowerRecord()
        self.powerRecord.getNowFig(self.painter)
        self.powerRecord.timeStateSignal.connect(self.painter.getLogTimeState)
        self.powerRecord.logStateSignal.connect(self.painter.getStartLog)
        self.powerRecord.plotlist.connect(self.painter.XYaxitList)
        self.powerRecordBox.addWidget(self.powerRecord)
#
#port set
#
        menuItem = ['300 baud','1200 baud',
            '2400 baud','4800 baud','9600 baud',
            '19200 baud','38400 baud','57600 baud',
            '115200 baud','230400 baud','250000 baud']
        self.portUI.baundrateSource.addItems(menuItem)
        self.portUI.baundratePump.addItems(menuItem)
        # self.portUI.baundrateTemp.addItems(menuItem)
#source port set
        #source
        portItem = ['com1','com2','com3','com4',
            'com5','com6','com7','com8','com9',
            'com10','com11','com12','com13',
            'com14','com15','com16','com17',
            'com18','com19','com20']
        self.portUI.portSource.addItems(portItem)
        self.portUI.portPump.addItems(portItem)
        self.setPortButton = self.portUI.openportSource
        self.closePortButton = self.portUI.closeportSource
        self.baundrateMenu = self.portUI.baundrateSource
        self.portEdit = self.portUI.portSource
        self.baundrateMenu.currentIndexChanged.connect(self.emit_br_src_changed)
        baudindex = self.lastpick.get('srcBaud',False)
        if baudindex is not False :
            self.baundrateMenu.setCurrentIndex(baudindex)
        else:
            self.baundrateMenu.setCurrentIndex(4)
        portindex = self.lastpick.get('srcPort',False)
        if baudindex is not False :
            self.portEdit.setCurrentIndex(portindex)
        else:
            self.portEdit.setCurrentIndex(1)

        baudindex = self.lastpick.get('pumpBaud',False)
        if baudindex is not False :
            self.portUI.baundratePump.setCurrentIndex(baudindex)
        else:
            self.portUI.baundratePump.setCurrentIndex(4)
        portindex = self.lastpick.get('pumpPort',False)
        if baudindex is not False :
            self.portUI.portPump.setCurrentIndex(portindex)
        else:
            self.portUI.portPump.setCurrentIndex(2)

###
#pump set
###
        self.openSeedButton = self.pumpUI.sourceSet
        self.setSeedPulse = self.pumpUI.pulseSpin
        self.openSeedButton.clicked.connect(self.emitSeedPulseAndFre)
        self.setSeedPulse.setValue(self.initSeedPulse)
        self.setSeedFreValue = self.pumpUI.frequencySpin
        self.setSeedCurrent = self.pumpUI.currentSpin
        self.setSeedCurrent.setValue(self.initSeedCurrent)
        self.openAll = self.pumpUI.sourceOpen
        self.sendfirst = self.pumpUI.firstPumpSet
        self.sendfirst.clicked.connect(self.emitFirstPumpCurrent)
        self.sendsecond = self.pumpUI.secondPumpSet
        self.sendsecond.clicked.connect(self.emitSecondPumpCurrent)
        self.setFirstpump = self.pumpUI.firstpumpSpin
        self.setFirstpump.setValue(self.init1stCurrent)
        self.setSecondpump = self.pumpUI.secondpumpSpin
        self.setSecondpump.setValue(self.init2stCurrent)
        self.closeAll = self.pumpUI.sourceClose
        self.pumpUI.firstpumpSpin.setMaximum(1000)
        self.pumpUI.secondpumpSpin.setMaximum(10000)
        self.pumpUI.secondpumpSpin.setSingleStep(500)




    def enableClosePort(self):
        if self.setSeedPulse.text()[:-2] > self.initSeedPulse :
            self.canClosePort = False
        print(self.canClosePort)
        if self.setSeedFreValue.texttext()[:-3] > self.initSeedFre :
            self.canClosePort = False
        print(self.canClosePort)
        if self.setSeedCurrent.text()[:-2] > self.initSeedCurrent:
            self.canClosePort = False
        print(self.canClosePort)
        if self.setFirstpump.text()[:-2] > self.init1stCurrent :
            self.canClosePort = False
        print(self.canClosePort)
        if self.setSecondpump.text()[:-2] > self.init2stCurrent :
            self.canClosePort = False
        print(self.canClosePort)

    def seedSignalSet(self, seedcurrent, seedpulse, seedfrequece):
        self.seedcurrent = seedcurrent
        self.setSeedCurrent.setValue(self.seedcurrent)
        self.seedpulse = seedpulse
        self.setSeedPulse.setValue(self.seedpulse)
        self.seedfrequece = seedfrequece
        self.setSeedFreValue.setValue(self.seedfrequece)

    def firstCurrentSet(self,value):
        self.firstcurrent = value
        self.setFirstpump.setValue(self.firstcurrent)

    def secondCurrentSet(self,value):
        self.secondcurrent = value
        self.setSecondpump.setValue(self.secondcurrent)

#==============================================================================
# Get, set
#==============================================================================

    def setPowerShowList(self,lst):
        self.powerShow.powerList = lst
        self.powerShow.updateFigure()

    def set_queue(self, queue):
        self.queue = queue

    def set_end_cmd(self, end_cmd):
        self.end_cmd = end_cmd

    # def set_autoscroll(self, value):
    #     self.autoscroll = value

    def set_port(self, value):
        self.portEdit.clear()
        self.portEdit.insert(value)

    def getSrcPort(self):
        self.lastpick['srcPort'] = self.portEdit.currentIndex()
        return self.portEdit.currentText()

    def getSrcBaudrate(self):
        self.lastpick['srcBaud'] = self.baundrateMenu.currentIndex()
        return self.baundrateMenu.currentText()[:-5]

    def getPumpPort(self):
        self.lastpick['pumpPort'] = self.portUI.portPump.currentIndex()
        return self.portUI.portPump.currentText()

    def getPumpBaudrate(self):
        self.lastpick['pumpBaud'] = self.portUI.baundratePump.currentIndex()
        return self.portUI.baundratePump.currentText()[:-5]

    def get_cmd(self):
        return self.cmd_edit.text()


    def setCurrentValue(self, currentValue,timeValue):
        if currentValue is not None:
            self.currentValueList = currentValue
            self.currentTimeList = timeValue


    def Button2Plot(self):
        self.painter.update_figure()

    def closeEvent(self, event):
        self.last.saveLast(self.lastpick)
        self.end_cmd()
        QWidget.closeEvent(self, event)
        print('exit')

    def beginGui(self):
        self.update()

    def update_gui(self):
        self.process_incoming()
        self.update()

    def updataFigure(self,newtime,power):
        # self.setCurrentValue(currentValue, timeValue)
        self.painter.XYaxit(newtime,power)
        self.painter.update_figure()

        # print('update?')
        # self.update()

    def process_incoming(self):
        while self.queue.qsize():
            try:
                msg = self.queue.get(0)
                self.editer.appendPlainText(str(msg))
                #show to the textplain?
                #if self.autoscroll:
                self.editer.ensureCursorVisible()
                self.scroll_down()
            except Queue.empty:
                print('=== empty queue ===')

    def scroll_down(self):
        sb = self.editer.verticalScrollBar()
        sb.setValue(sb.maximum())


    def changePort(self):
        if not self.msg_sent:
            self.msg_sent = True
            self.emit_port_changed()
        else:
            self.msg_sent = False
            return None

#==============================================================================
# Signals
#==============================================================================

    def emit_send_data(self):
        self.send_data.emit(self.get_cmd())
        self.cmd_edit.clear()

    def emit_send_command(self,command):
        self.send_data.emit(command)
        self.cmd_edit.clear()

    def emit_br_src_changed(self, value):
        baudrate = self.baundrateMenu.itemText(value)[:-5]
        self.baudrate_src_changed.emit(baudrate)

    def emit_br_pump_changed(self, value):
        baudrate = self.baundrateMenu.itemText(value)[:-5]
        self.baudrate_pump_changed.emit(baudrate)

    # def emit_br_temp_changed(self, value):
    #     baudrate = self.baundrateMenu.itemText(value)[:-5]
    #     self.baudrate_temp_changed.emit(baudrate)

    def emit_port_changed(self):
        self.port_changed.emit(self.portEdit.text())
        self.portEdit.clear()

    def emitWriteSeedPulse(self):
        self.seedPulseChanged.emit(self.setSeedPulse.text()[:-2])

    def emitWriteSeedFre(self):
        self.seedFreValueChanged.emit(self.setSeedFreValue.text()[:-3])

    def emitFirstPumpCurrent(self):
        self.firstPumpChanged.emit(self.setFirstpump.text()[:-2])

    def emitSecondPumpCurrent(self):
        self.secondPumpChanged.emit(self.setSecondpump.text()[:-2])

    def emitSeedPulseAndFre(self):
        seedPulseAndFre = [self.setSeedPulse.text()[:-2],
            self.setSeedFreValue.text()[:-3],self.setSeedCurrent.text()[:-2]]
        # print(self.setSeedPulse.text()[:-2],
        #     self.setSeedFreValue.text()[:-2],self.setSeedCurrent.text()[:-2])
        self.seedPulseFreChanged.emit(seedPulseAndFre)

    def setUser(self,value):
        self.user = value
        if value.getName() is not False:
            self.toolBox.setTabEnabled(1,True)
            self.toolBox.setTabEnabled(2,True)
            self.toolBox.setTabEnabled(3,True)
            self.powerRecord.setUserID(self.user.getName())
            self.startSrcModel.emit(self.srcModelstarted)
            self.srcModelstarted = True
            self.startPumpModel.emit(self.pumpModelstarted)
            self.pumpModelstarted = True
            # self.startTempModel.emit(self.tempModelstarted)
            # self.tempModelstarted = True
            self.emitUsername.emit(self.user.getName())
            print('emit username:'******'NoneUser')
        print('use in view:',self.user.getName())

    def lastLogSave(self):
        self.last.saveLast(self.lastpick)
Beispiel #29
0
class SearchPanel(QWidget):
    searched = pyqtSignal(str, QWebEnginePage.FindFlag)

    def __init__(self, parent=None):
        """
        Args:
            parent:
        """
        super(SearchPanel, self).__init__(parent)
        self.setContentsMargins(0, 0, 0, 0)
        self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        fh = QFile(
            '/home/alexandr/PycharmProjects/Pocket/pocket_articles/css/searchpanel.qss'
        )
        # fh = QFile(':/css/searchpanel.qss')
        if fh.open(QIODevice.ReadOnly):
            self.setStyleSheet(fh.readAll().data().decode())
        # self.setStyleSheet(_QSS)

        hbox = QHBoxLayout(self)
        hbox.setContentsMargins(0, 0, 0, 0)

        icon_close = QIcon(
            QPixmap(':/images/window-close.png').scaledToWidth(16))
        icon_back = QIcon(':/images/back.png')
        icon_forward = QIcon(':/images/forward.png')

        self.nextBtn = QPushButton(icon_forward, 'Следующее')
        self.nextBtn.clicked.connect(self.search)
        self.nextBtn.setFixedHeight(20)

        self.prevBtn = QPushButton(icon_back, 'Предыдущее')
        self.prevBtn.clicked.connect(
            lambda: self.search(QWebEnginePage.FindBackward))
        self.prevBtn.setFixedHeight(20)

        self.caseSensitively = QCheckBox('Учитывать регистр')

        self.search_le = QLineEdit()
        self.search_le.addAction(QIcon(':/images/search-50.svg'),
                                 QLineEdit.LeadingPosition)
        self.search_le.setClearButtonEnabled(True)

        self.closeBtn = QPushButton(icon_close, '')
        self.closeBtn.clicked.connect(self.hide_widget)
        self.closeBtn.setFixedHeight(20)

        hbox.addStretch(1)
        hbox.addWidget(self.closeBtn)
        hbox.addWidget(self.search_le, 1)
        hbox.addWidget(self.prevBtn)
        hbox.addWidget(self.nextBtn)
        hbox.addWidget(self.caseSensitively)

        QShortcut(Qt.Key_Escape, self, self.hide_widget)
        QShortcut(Qt.Key_F3, self, self.search)
        QShortcut(QKeySequence.FindNext, self, self.search)
        QShortcut(QKeySequence.FindPrevious, self,
                  lambda: self.search(QWebEnginePage.FindBackward))
        QShortcut(QKeySequence(Qt.SHIFT + Qt.Key_F3), self,
                  lambda: self.search(QWebEnginePage.FindBackward))

        # ставим фокус на строку ввода
        self.setFocusProxy(self.search_le)

        self.search_le.returnPressed.connect(self.search)
        self.search_le.textChanged.connect(self.search)

    @pyqtSlot()
    def hide_widget(self):
        self.search_le.clear()
        self.hide()

    @pyqtSlot()
    def search(self, flag: QWebEnginePage.FindFlag = None):
        """
        Args:
            flag (QWebEnginePage.FindFlag):
        """
        if not flag:
            flag = QWebEnginePage.FindFlag()
        if self.caseSensitively.isChecked():
            flag |= QWebEnginePage.FindCaseSensitively
        self.searched.emit(self.search_le.text(), flag)

    def showEvent(self, a0: QShowEvent) -> None:
        """
        Args:
            a0 (QShowEvent):
        """
        super(SearchPanel, self).showEvent(a0)
        self.setFocus(Qt.ShortcutFocusReason)
Beispiel #30
0
class SideDock(QDockWidget):
    """
    Side Dock/Panel, named "Navy Base Overview", displays all important data of the user.
        This is the first coded QWidget of WGViewer (even before LoginForm).
    """
    sig_resized = pyqtSignal()
    sig_closed = pyqtSignal()

    def __init__(self, parent, realrun: bool):
        super(SideDock, self).__init__(parent)
        self.is_realrun = realrun

        _, self.user_screen_h = wgv_utils.get_user_resolution()
        self.qsettings = QSettings(wgv_data.get_qsettings_file(), QSettings.IniFormat)
        if self.qsettings.contains(QKEYS.EXP_AUTO) and self.qsettings.value(QKEYS.EXP_AUTO, type=bool):
            logger.debug("Auto expedition is on")
            self.is_exp_auto = True
        else:
            logger.debug("Auto expedition is off")
            self.is_exp_auto = False

        self.equipment_names = wgv_data.get_shipEquipmnt()
        self.ship_names = wgv_data.get_processed_userShipVo()

        # index 0 for daily, 1 for weekly, 2+ for tasks/events
        self.task_counter_desc_labels = []
        self.task_counter_labels = []
        self.task_counter_timers = []
        self.task_counters = []

        self.name_layout_widget = QWidget(self)
        self.name_layout = QHBoxLayout(self.name_layout_widget)
        self.name_label = QLabel(self.name_layout_widget)
        self.lvl_label = QLabel(self.name_layout_widget)
        self.ship_count_label = QLabel(self.name_layout_widget)
        self.equip_count_label = QLabel(self.name_layout_widget)
        self.collect_count_label = QLabel(self.name_layout_widget)

        self.sign_widget = QLineEdit(self)
        self.table_model = ResourceTableModel()
        self.table_view = QTableView(self)
        self.bath_list_view = BathListView()
        self.bath_list_view_widget = QWidget(self)
        self.bath_list_view_layout = QVBoxLayout(self.bath_list_view_widget)
        self.triple_list_view_widget = QWidget(self)
        self.triple_list_view = QHBoxLayout(self.triple_list_view_widget)
        self.build_list_view = BuildListView()
        self.dev_list_view = DevListView()
        self.exp_list_view = ExpListView(parent.main_tabs)
        self.task_list_view = TaskListView()
        self.task_panel_widget = QWidget(self)
        self.task_panel_view = QHBoxLayout(self.task_panel_widget)
        self.countdowns_layout_widget = QWidget(self)
        self.countdowns_layout = QVBoxLayout(self.countdowns_layout_widget)

        self.sig_resized.connect(self.update_geometry)
        self.sig_closed.connect(parent.on_dock_closed)

        self._init_ui()
        self.set_data()

    def set_data(self) -> None:
        d = wgv_data.get_api_initGame()
        self.on_received_lists(d)
        self.on_received_resource(d)
        self.on_received_name(d)
        self.on_received_tasks(d)

    def _init_ui(self) -> None:
        self.setFloating(False)
        self.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
        self.setMinimumWidth(int(0.4 * self.user_screen_h))
        self.setWindowTitle("Navy Base Overview")

        self._init_name_info()
        self._init_sign_info()
        self._init_resource_info()
        self._init_bath_info()
        self._init_triple_list()
        self._init_task_panel()

    def _init_name_info(self) -> None:
        self.name_layout.setContentsMargins(0, 0, 0, 0)

        self.name_layout.addWidget(self.name_label)
        self.name_layout.addWidget(self.lvl_label)
        self.name_layout.addWidget(self.ship_count_label)
        self.name_layout.addWidget(self.equip_count_label)
        self.name_layout.addWidget(self.collect_count_label)

    def _init_sign_info(self) -> None:
        icon_path = get_data_path('assets/icons/sign_16.png')
        self.sign_widget.addAction(QIcon(icon_path), QLineEdit.LeadingPosition)

    def _init_resource_info(self) -> None:
        self.table_view.setModel(self.table_model)
        x = 0.03 * self.user_screen_h
        self.table_view.setIconSize(QSize(x, x))
        self.table_view.verticalHeader().hide()
        self.table_view.horizontalHeader().hide()
        self.table_view.setShowGrid(False)
        self.table_view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.table_view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.table_view.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.table_view.setFocusPolicy(Qt.NoFocus)
        self.table_view.setSelectionMode(QAbstractItemView.NoSelection)
        self.table_view.horizontalScrollBar().setEnabled(False)
        self.table_view.verticalScrollBar().setEnabled(False)

    def _init_bath_info(self) -> None:
        self.bath_list_view_layout.setContentsMargins(0, 0, 0, 0)
        self.bath_list_view_layout.addWidget(self.bath_list_view)

    def _init_triple_list(self) -> None:
        self.triple_list_view.setContentsMargins(0, 0, 0, 0)
        self.triple_list_view.addWidget(self.build_list_view)
        self.triple_list_view.addWidget(self.dev_list_view)
        self.triple_list_view.addWidget(self.exp_list_view)

    def _init_task_panel(self) -> None:
        self.task_panel_view.setContentsMargins(0, 0, 0, 0)
        self._init_countdowns()
        self.task_panel_view.addWidget(self.task_list_view)
        self.task_panel_view.addWidget(self.countdowns_layout_widget)

    def _init_countdowns(self) -> None:
        # TODO? design problem now the most suitable count is 4, 5 would be max
        #   although MoeFantasy opens mostly 1 event at a time, rarely 2.
        self.countdowns_layout.setContentsMargins(0, 0, 0, 0)

        l1 = QLabel(self.countdowns_layout_widget)
        l1.setToolTip("Refreshing daily at 0300 UTC+8")  # Intel' server also use CN time
        l1.setText("Next daily:")
        l1.adjustSize()
        self.task_counter_desc_labels.append(l1)

        l2 = QLabel(self.countdowns_layout_widget)
        l2.setText("Next weekly:")
        l2.setToolTip("Refreshing weekly at 0400 UTC+8 or New Year")
        l2.adjustSize()
        self.task_counter_desc_labels.append(l2)

        self.task_counter_labels.append(QLabel(self.countdowns_layout_widget))
        self.task_counter_labels.append(QLabel(self.countdowns_layout_widget))

        self.countdowns_layout.addWidget(l1)
        self.countdowns_layout.addWidget(self.task_counter_labels[0])
        self.countdowns_layout.addWidget(l2)
        self.countdowns_layout.addWidget(self.task_counter_labels[1])

        _, _, d_counter, w_counter = get_tasks_countdowns()
        self.task_counters.append(d_counter)
        self.task_counters.append(w_counter)

        self._init_task_counters()

    # ================================
    # Getter / Setter
    # ================================

    def add_task_countdown(self, text: str, _time: int, idx: int) -> None:
        l1 = QLabel(self.countdowns_layout_widget)
        l1.setText(text)
        l1.adjustSize()
        self.task_counter_desc_labels.append(l1)
        self.countdowns_layout.addWidget(l1)

        l2 = QLabel(self.countdowns_layout_widget)
        self.task_counter_labels.append(l2)
        self.task_counters.append(_time)
        self.countdowns_layout.addWidget(l2)
        self.start_new_timer(self.task_counters, self.task_counter_labels, self.task_counter_timers, idx)

    def get_ship_name(self, _id):
        return self.ship_names[str(_id)]['Name']

    def get_equip_name(self, cid: int) -> str:
        return next((i for i in self.equipment_names if i['cid'] == cid), {'title': '?'})['title']

    @staticmethod
    def get_ship_type(_id: int) -> str:
        return wgv_utils.get_build_type(_id)

    @staticmethod
    def _remove_widget(parent, widget: [QLayout, QWidget]) -> None:
        logger.warning("Deleting widget")
        parent.removeWidget(widget)
        widget.deleteLater()
        widget = None
        return

    def get_exp_list_view(self) -> ExpListView:
        return self.exp_list_view

    # ================================
    # Timer Related
    # ================================

    def count_down(self, counters: list, labels: list, timers: list, idx: int) -> None:
        # TODO? refactor; each list view has its own countdown method?
        counters[idx] -= 1
        if counters[idx] > 0:
            pass
        else:
            if counters == self.task_counters:
                if idx < 2:
                    # refreshing daily/weekly timers
                    _, _, d, w = get_tasks_countdowns()
                    counters[0] = d
                    counters[1] = w
                else:
                    counters[idx] = 0
                    timers[idx].stop()
                    self._remove_widget(self.countdowns_layout, labels[idx])
                    self._remove_widget(self.countdowns_layout, self.task_counter_desc_labels[idx])
                    return
            elif counters == self.bath_list_view.get_counters():
                counters[idx] = 0
                timers[idx].stop()
                self.bath_list_view.update_item(idx, 0, "Repairing Dock Unused")
                self.bath_list_view.update_item(idx, 1, "--:--:--")
            elif counters == self.exp_list_view.get_counters():
                counters[idx] = 0
                timers[idx].stop()
                # To avoid "Idling" (uninitialized) issue
                labels[idx].setText(str(timedelta(seconds=counters[idx])))
                if self.is_realrun and self.is_exp_auto:
                    self.exp_list_view.auto_restart(idx)
                else:
                    # otherwise will cause problem
                    pass
            else:
                counters[idx] = 0
                timers[idx].stop()
        labels[idx].setText(str(timedelta(seconds=counters[idx])))

    def start_new_timer(self, counters: list, labels: list, timers: list, idx: int) -> None:
        """
        Creates a QTimer() object and auto connects to 1 sec count down.
        Then auto start
        """
        tr = QTimer()
        tr.setInterval(1000)
        tr.timeout.connect(lambda: self.count_down(counters, labels, timers, idx))
        if counters == self.task_counters:
            timers.append(tr)
        else:
            timers[idx] = tr
        tr.start()

    def _init_task_counters(self) -> None:
        self.start_new_timer(self.task_counters, self.task_counter_labels, self.task_counter_timers, 0)
        self.start_new_timer(self.task_counters, self.task_counter_labels, self.task_counter_timers, 1)

    def _process_timer_data(self, _data, view, func, item_id, counters, labels, timers) -> None:
        for i, v in enumerate(_data):
            if v["locked"] == 0:
                if "endTime" in v:
                    _left_time = _calc_left_time(v["endTime"])
                    counters[i] = _left_time
                    self.start_new_timer(counters, labels, timers, i)
                    val1 = func(v[item_id])
                    view.update_item(i, 0, val1)
                else:
                    view.update_item(i, 0, "Unused")
                    view.update_item(i, 1, "--:--:--")
            else:
                pass

    # ================================
    # Signals
    # ================================

    @pyqtSlot(dict)
    def on_received_resource(self, data: dict) -> None:
        if data is not None:
            def _get_item_by_id(item_id: int) -> int:
                return next((i for i in x if i["itemCid"] == item_id), {"num": 0})["num"]

            u = data["userVo"]
            x = data["packageVo"]
            self.table_model.update_fuel(u["oil"])
            self.table_model.update_ammo(u["ammo"])
            self.table_model.update_steel(u["steel"])
            self.table_model.update_bauxite(u["aluminium"])
            self.table_model.update_gold(u["gold"])
            self.table_model.update_repair(_get_item_by_id(541))
            self.table_model.update_build(_get_item_by_id(141))
            self.table_model.update_bp_construct(_get_item_by_id(241))
            self.table_model.update_bp_dev(_get_item_by_id(741))
            self.table_model.update_revive(_get_item_by_id(66641))
            self.table_model.update_DD(_get_item_by_id(10441))
            self.table_model.update_CA(_get_item_by_id(10341))
            self.table_model.update_BB(_get_item_by_id(10241))
            self.table_model.update_CV(_get_item_by_id(10141))
            self.table_model.update_SS(_get_item_by_id(10541))

            self.table_model.write_csv()

    @pyqtSlot(dict)
    def update_lvl_label(self, x: dict) -> None:
        # userLevelVo
        if x is not None:
            self.lvl_label.setText("Lv. " + str(x["level"]))
            lvl_tooltip = str(x["exp"]) + " / " + str(x["nextLevelExpNeed"])
            self.lvl_label.setToolTip(lvl_tooltip)

    @pyqtSlot(dict)
    def on_received_name(self, data: dict) -> None:
        if data is not None:
            x = data["userVo"]["detailInfo"]
            self.name_label.setText(x["username"])
            name_tooltip = "resource soft cap = " + str(data["userVo"]["resourcesTops"][0])
            self.name_label.setToolTip(name_tooltip)

            self.update_lvl_label(x)

            ship_icon = get_data_path('assets/icons/ship_16.png')
            ship_str = f"<html><img src='{ship_icon}'></html> " + str(x["shipNum"]) + " / " + str(x["shipNumTop"])
            self.ship_count_label.setText(ship_str)

            equip_icon = get_data_path('assets/icons/equip_16.png')
            equip_str = f"<html><img src='{equip_icon}'></html> " + str(x["equipmentNum"]) + " / " + str(x["equipmentNumTop"])
            self.equip_count_label.setText(equip_str)

            collect_icon = get_data_path('assets/icons/collect_16.png')
            collect_str = f"<html><img src='{collect_icon}'></html> " + str(len(data["unlockShip"])) + " / " + str(x["basicShipNum"])
            self.collect_count_label.setText(collect_str)

            self.sign_widget.setText(data["friendVo"]["sign"])

    def update_one_expedition(self, data: dict) -> None:
        # Input = pveExploreVo['levels'][_idx]
        _idx = int(data['fleetId'])-5
        _exp_counters = self.exp_list_view.get_counters()
        _exp_counters[_idx] = _calc_left_time(data["endTime"])
        self.start_new_timer(_exp_counters, self.exp_list_view.get_counter_labels(), self.exp_list_view.get_counter_timers(), _idx)
        n = "Fleet #" + data["fleetId"] + "   " + data["exploreId"].replace("000", "-")
        self.exp_list_view.update_item(_idx, 0, n)

    def cancel_one_expedition(self, fleet_idx: int) -> None:
        self.exp_list_view.update_item(fleet_idx, 0, EXP_LABEL_L)
        self.exp_list_view.update_item(fleet_idx, 1, EXP_LABEL_R)
        self.exp_list_view.get_counters()[fleet_idx] = 0
        self.exp_list_view.get_counter_timers()[fleet_idx].stop()

    def update_expeditions(self, data: dict) -> None:
        if data is not None:
            p = sorted(data["levels"], key=lambda x: int(x['fleetId']), reverse=False)
            for _, val in enumerate(p):
                self.update_one_expedition(val)

    @pyqtSlot(dict)
    def on_received_lists(self, data: dict) -> None:
        if data is not None:
            self._process_timer_data(data["repairDockVo"], self.bath_list_view, self.get_ship_name, "shipId",
                                     self.bath_list_view.get_counters(), self.bath_list_view.get_counter_labels(), self.bath_list_view.get_counter_timers())

            self._process_timer_data(data["dockVo"], self.build_list_view, self.get_ship_type, "shipType",
                                     self.build_list_view.get_counters(), self.build_list_view.get_counter_labels(), self.build_list_view.get_counter_timers())

            self._process_timer_data(data["equipmentDockVo"], self.dev_list_view, self.get_equip_name, "equipmentCid",
                                     self.dev_list_view.get_counters(), self.bath_list_view.get_counter_labels(), self.dev_list_view.get_counter_timers())

            self.update_expeditions(data["pveExploreVo"])

    @pyqtSlot(dict)
    def on_received_tasks(self, data: dict) -> None:
        if data is not None:
            t = data["taskVo"]
            for i in t:
                stat = str(i["condition"][0]["finishedAmount"]) + " / " + str(i["condition"][0]["totalAmount"])
                desc = wgv_utils.clear_desc(i["desc"])
                if '#' in desc:
                    # TODO: (lowest priority) how to find `#s10030711#n` ? looks like not the same ID in docks
                    desc = re.sub(r'\[[^]]*\]', i["title"], desc)
                else:
                    pass
                if i['end_time'] != "":
                    desc += "\nEvent End On: " + i['end_time']
                    lim_flag = True
                else:
                    lim_flag = False
                prefix = TASK_TYPE[i['type']]
                title = f"{prefix}\t{i['title']}"
                self.task_list_view.add_item(title, stat, desc, lim_flag)

            m = data["marketingData"]["activeList"]
            for i in m:
                self.add_task_countdown(i["title"], i["left_time"], len(self.task_counters))

    # ================================
    # Events
    # ================================

    def resizeEvent(self, event: QResizeEvent) -> None:
        # overriding resizeEvent() method
        self.sig_resized.emit()
        return super(SideDock, self).resizeEvent(event)

    def closeEvent(self, event: QCloseEvent) -> None:
        cb = QCheckBox('show on start-up')
        if self.qsettings.contains(QKEYS.UI_SIDEDOCK) is True:
            cb.setChecked(self.qsettings.value(QKEYS.UI_SIDEDOCK, type=bool) is True)
        else:
            pass
        box = QMessageBox(QMessageBox.Question, "INFO", "Do you want to close side dock?\n(Can re-open in View menu)",
                          QMessageBox.Yes | QMessageBox.No, self)

        box.setStyleSheet(wgv_utils.get_color_scheme())
        box.setDefaultButton(QMessageBox.No)
        box.setCheckBox(cb)

        if box.exec() == QMessageBox.Yes:
            event.accept()
            self.sig_closed.emit()
        else:
            event.ignore()
        self.qsettings.setValue(QKEYS.UI_SIDEDOCK, cb.isChecked())

    def update_geometry(self) -> None:
        y = int(0.03 * self.user_screen_h)
        h = int(0.05 * self.user_screen_h)
        gap = int(0.01 * self.user_screen_h)

        self.name_layout_widget.setGeometry(0, y, self.geometry().width(), h)
        self.sign_widget.setGeometry(0, y + h, self.geometry().width(), y)

        y = int(2 * y + h + gap)
        h = int(0.09 * self.user_screen_h)
        self.table_view.setGeometry(0, y, self.geometry().width(), h)
        for i in range(5):
            self.table_view.setColumnWidth(i, self.geometry().width() / 5)
        for i in range(3):
            self.table_view.setRowHeight(i, h / 3)

        y = y + h + gap
        self.bath_list_view_widget.setGeometry(0, y, self.geometry().width(), h)

        y = y + h + gap
        self.triple_list_view_widget.setGeometry(0, y, self.geometry().width(), h)

        y = y + h + gap
        h = int(0.19 * self.user_screen_h)
        self.task_panel_widget.setGeometry(0, y, self.geometry().width(), h)
Beispiel #31
0
class InitialPage(QWizardPage):
    def __init__(self):
        super().__init__()
        vbox = QVBoxLayout(self)
        frame = QFrame(self)
        vbox.addStretch(1)
        frame.setFrameShape(QFrame.StyledPanel)
        vbox.addWidget(frame)
        # Fields
        fields_box = QGridLayout(frame)
        # Project name
        fields_box.addWidget(QLabel(translations.TR_WIZARD_PROJECT_NAME), 0, 0)
        self._line_project_name = QLineEdit("untitled")
        self.registerField("name*", self._line_project_name)
        fields_box.addWidget(self._line_project_name, 0, 1)
        # Project location
        fields_box.addWidget(QLabel(translations.TR_WIZARD_PROJECT_LOCATION),
                             1, 0)
        self._line_location = QLineEdit()
        self._line_location.setReadOnly(True)
        self._line_location.setText(utils.get_home_dir())
        self.registerField("path", self._line_location)
        choose_dir_act = self._line_location.addAction(
            self.style().standardIcon(self.style().SP_DirIcon),
            QLineEdit.TrailingPosition)
        fields_box.addWidget(self._line_location, 1, 1)
        # Project description
        fields_box.addWidget(QLabel(translations.TR_PROJECT_DESCRIPTION), 2, 0)
        self._txt_desciption = QPlainTextEdit()
        fields_box.addWidget(self._txt_desciption, 2, 1)
        self.registerField("description", self._txt_desciption)
        # Project license
        fields_box.addWidget(QLabel(translations.TR_PROJECT_LICENSE), 3, 0)
        combo_license = QComboBox()
        combo_license.addItems(LICENSES)
        combo_license.setCurrentIndex(12)
        fields_box.addWidget(combo_license, 3, 1)
        self.registerField("license", combo_license, property="currentText")
        # Project interpreter
        fields_box.addWidget(
            QLabel(translations.TR_WIZARD_PROJECT_INTERPRETER), 4, 0)
        combo_interpreter = QComboBox()
        combo_interpreter.addItems(utils.get_python())
        combo_interpreter.setCurrentText(sys.executable)
        fields_box.addWidget(combo_interpreter, 4, 1)
        self.registerField("interpreter", combo_interpreter)
        # Connections
        self._line_project_name.textChanged.connect(self._on_text_changed)
        choose_dir_act.triggered.connect(self._choose_dir)

    def _choose_dir(self):
        dirname = QFileDialog.getExistingDirectory(
            self, translations.TR_WIZARD_CHOOSE_DIR, utils.get_home_dir())
        if dirname:
            self._line_location.setText(dirname)

    @property
    def location(self):
        return self._line_location.text()

    @property
    def project_name(self):
        return self._line_project_name.text()

    def _on_text_changed(self):
        ok = self.validate()
        if not ok:
            self._line_project_name.setStyleSheet("background-color: red")
        else:
            self._line_project_name.setStyleSheet("background-color: none;")

    def validate(self):
        ok = True
        project_path = os.path.join(self.location, self.project_name)
        if file_manager.folder_exists(project_path):
            ok = False
        return ok

    def isComplete(self):
        val = super().isComplete()
        return val and self.validate()
class MainWindow(CenterWindow):
    """
    Displays list with tasks assigned to current user in JIRA
    """
    def __init__(self, controller):
        super().__init__()
        self.setStyleSheet(QSS)
        self.controller = controller
        self.resize(1000, 600)
        self.setWindowTitle('JIRA Quick Reporter')
        self.setWindowIcon(QIcon(LOGO_PATH))
        self.center()
        self.current_item = None

        self.vbox = QVBoxLayout()

        self.save_btn_box = QHBoxLayout()
        self.filter_name_label = QLabel()
        self.filter_name_label.setObjectName('filter_name_label')
        self.filter_name_label.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.filter_name_label.setAlignment(Qt.AlignLeft)
        self.filter_edited_label = QLabel('-> edited')
        self.filter_edited_label.setObjectName('filter_edited_label')
        self.filter_edited_label.hide()
        self.filter_edited_label.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.save_filter_btn = QPushButton('Save as')
        self.save_filter_btn.setObjectName('save_filter_btn')
        self.save_filter_btn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.save_filter_btn.clicked.connect(self.controller.save_filter)

        self.overwrite_filter_button = QPushButton('Save')
        self.overwrite_filter_button.setToolTip('You need to edit filter query first')
        self.overwrite_filter_button.setObjectName('save_filter_btn')
        self.overwrite_filter_button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.overwrite_filter_button.clicked.connect(lambda: self.controller.save_filter(True))

        self.delete_filter_btn = QPushButton()
        self.delete_filter_btn.setObjectName('delete_filter_btn')
        self.delete_filter_btn.clicked.connect(self.delete_filter)
        self.delete_filter_btn.setIcon(QIcon(DELETE_FILTER_ICON))
        self.delete_filter_btn.setIconSize(
            QSize(
                self.delete_filter_btn.sizeHint().height(),
                self.delete_filter_btn.sizeHint().height()
            )
        )
        self.delete_filter_btn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.delete_filter_btn.setToolTip('Delete filter')

        self.save_btn_box.addWidget(self.filter_name_label, Qt.AlignLeft)
        self.save_btn_box.addWidget(self.filter_edited_label, Qt.AlignLeft)
        self.save_btn_box.addWidget(self.save_filter_btn, Qt.AlignLeft)
        self.save_btn_box.addWidget(self.overwrite_filter_button, Qt.AlignLeft)
        self.save_btn_box.addStretch()
        self.save_btn_box.addWidget(self.delete_filter_btn, Qt.AlignRight)

        self.create_filter_box = QHBoxLayout()
        self.query_field = QLineEdit()
        self.query_field.setObjectName('query_field')
        self.query_field.setPlaceholderText('You need to write a query here')
        self.action_help = QAction()
        self.action_help.setIcon(self.style().standardIcon(QStyle.SP_MessageBoxQuestion))
        self.help_filter_url = QUrl(FILTER_FIELD_HELP_URL)
        self.action_help.triggered.connect(self.filter_field_help)
        self.query_field.addAction(self.action_help, QLineEdit.TrailingPosition)
        self.query_field.installEventFilter(self)
        self.search_issues_button = QPushButton('Search')
        self.search_issues_button.setObjectName('search_issues_button')
        self.search_issues_button.clicked.connect(self.controller.search_issues_by_query)
        self.create_filter_box.addWidget(self.query_field)
        self.create_filter_box.addWidget(self.search_issues_button)

        self.list_box = QVBoxLayout()
        self.issue_list_widget = QListWidget()
        self.issue_list_widget.setObjectName('issue_list')
        self.label_info = QLabel('You have no issues.')
        self.label_info.setAlignment(Qt.AlignCenter)
        self.list_box.addWidget(self.issue_list_widget)
        self.list_box.addWidget(self.label_info)
        self.label_info.hide()

        self.vbox.addLayout(self.save_btn_box)
        self.vbox.addLayout(self.create_filter_box)
        self.vbox.addLayout(self.list_box)

        self.filters_frame = QFrame()
        self.filters_frame.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding)
        self.filters_frame.setFrameShape(QFrame.StyledPanel)
        self.filters_frame.setObjectName('filters_frame')
        self.filters_box = QVBoxLayout(self.filters_frame)
        self.filters_box_label = QLabel('Issues and filters')
        self.filters_box_label.setObjectName('filters_box_label')
        self.filters_box.addWidget(self.filters_box_label)
        self.filters_list = QListWidget()
        self.filters_list.installEventFilter(self)
        self.filters_list.itemClicked.connect(self.on_filter_selected)
        self.filters_list.setObjectName('filters_list')
        self.filters_list.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.filters_box.addWidget(self.filters_list)
        self.add_filter_button = QPushButton('+')
        self.add_filter_button.clicked.connect(self.add_filter_btn_click)
        self.add_filter_button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.filters_box.addWidget(self.add_filter_button, alignment=Qt.AlignRight)

        self.btn_box = QHBoxLayout()
        self.refresh_btn = QPushButton('Refresh')
        self.refresh_btn.clicked.connect(self.controller.refresh_issue_list)
        self.btn_box.addWidget(self.refresh_btn, alignment=Qt.AlignRight)
        self.vbox.addLayout(self.btn_box)

        self.toggle_frame_filters_btn = QPushButton('<')
        self.toggle_frame_filters_btn.clicked.connect(self.toggle_frame_filters)
        self.toggle_frame_filters_btn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.toggle_frame_filters_btn.setObjectName('toggle_filters_btn')

        self.main_box = QHBoxLayout()
        self.main_box.addWidget(self.filters_frame)
        self.main_box.addWidget(self.toggle_frame_filters_btn, alignment=Qt.AlignTop)
        self.main_box.addLayout(self.vbox)
        self.setLayout(self.main_box)

        self.tray_icon = QSystemTrayIcon(self)
        self.tray_icon.setIcon(QIcon(LOGO_PATH))

        self.tray_menu = QMenu()
        self.action_open = QAction('Open JQR', self)
        self.action_quit = QAction('Quit JQR', self)
        self.tray_menu.addAction(self.action_open)
        self.action_open.triggered.connect(self.show_jqr_from_tray)
        self.tray_menu.addAction(self.action_quit)
        self.action_quit.triggered.connect(self.controller.quit_app)
        self.tray_icon.setContextMenu(self.tray_menu)
        self.tray_icon.show()
        self.timer_log_work = QTimer()
        self.timer_log_work.timeout.connect(self.notification_to_log_work)
        self.timer_log_work.start(LOG_TIME)

        self.timer_refresh = QTimer()
        self.timer_refresh.timeout.connect(self.controller.auto_refresh_issue_list)

    def show_jqr_from_tray(self):
        self.hide()
        self.setWindowFlags(self.windowFlags() & ~Qt.WindowStaysOnTopHint)
        self.activateWindow()
        self.show()

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Return:
            self.controller.search_issues_by_query()

    def notification_to_log_work(self):
        QSound.play(RING_SOUND_PATH)
        self.tray_icon.showMessage(
            '1 hour had passed',
            'Don\'t forget to log your work!',
            msecs=2000
        )
        self.timer_log_work.start(LOG_TIME)

    def update_issues(self, update_list):
        for issue in update_list:
            item = self.issue_list_widget.findItems(
                issue['key'], Qt.MatchExactly
            )[0]
            item.setText(issue['key'])
            issue_widget = self.issue_list_widget.itemWidget(item)
            issue_widget.set_issue_key(issue['key'], issue['link'])
            issue_widget.set_issue_title(issue['title'])
            issue_widget.set_time(
                issue['estimated'],
                issue['logged'],
                issue['remaining']
            )
            issue_widget.set_workflow.clear()
            issue_widget.set_workflow.addItems(self.controller.get_possible_workflows(issue))
            issue_widget.set_workflow.setCurrentIndex(0)

            issue_widget.set_workflow.activated[str].disconnect()
            issue_widget.set_workflow.activated[str].connect(
                partial(
                    self.controller.change_workflow,
                    issue['workflow'],
                    issue['issue_obj'],
                )
            )

    def delete_issues(self, delete_list):
        for issue in delete_list:
            item = self.issue_list_widget.findItems(
                issue['key'], Qt.MatchExactly
            )[0]
            self.issue_list_widget.takeItem(
                self.issue_list_widget.row(item)
            )

    def insert_issues(self, new_issues_list):
        for issue in new_issues_list:
            issue_widget = QCustomWidget()
            issue_widget.set_issue_key(issue['key'], issue['link'])
            issue_widget.set_issue_title(issue['title'])
            issue_widget.set_time(
                issue['estimated'],
                issue['logged'],
                issue['remaining']
            )

            issue_widget.quick_log_btn.clicked.connect(
                partial(
                    self.controller.log_work_from_list,
                    issue['key']
                )
            )

            issue_widget.log_work_btn.clicked.connect(
                partial(
                    self.controller.open_time_log,
                    issue['key']
                )
            )

            issue_widget.open_pomodoro_btn.clicked.connect(
                partial(
                    self.controller.open_pomodoro_window,
                    issue['key'], issue['title']
                )
            )

            # add workflow statuses to dropdown
            possible_workflows = self.controller.get_possible_workflows(issue)

            issue_widget.set_workflow.addItems(possible_workflows)
            issue_widget.set_workflow.setCurrentIndex(0)
            issue_widget.set_workflow.activated[str].connect(
                partial(
                    self.controller.change_workflow,
                    issue['workflow'],
                    issue['issue_obj'],
                )
            )

            # add issue item to list
            issue_list_widget_item = QListWidgetItem()
            issue_list_widget_item.setText(issue['key'])
            issue_list_widget_item.setSizeHint(issue_widget.sizeHint())
            self.issue_list_widget.insertItem(issue['index'], issue_list_widget_item)
            self.issue_list_widget.setItemWidget(
                issue_list_widget_item, issue_widget
            )
        self.set_size_hint()

    def set_size_hint(self):
        self.issue_list_widget.setMinimumWidth(
            self.issue_list_widget.sizeHintForColumn(0) + 50
        )
        self.issue_list_widget.setMinimumHeight(
            self.issue_list_widget.sizeHintForRow(0) * 2
        )

    def show_filters(self, filters_dict):
        for index, key in enumerate(filters_dict):
            if key == SEARCH_ITEM_NAME:
                self.filters_list.insertItem(0, key)
            else:
                self.filters_list.addItem(key)
                self.filters_list.item(index).setToolTip(key)
        self.filters_list.item(0).setText(self.filters_list.item(0).text().capitalize())

        # add separator after first item
        separator = QFrame()
        separator.setFrameShape(QFrame.HLine)
        separator.setObjectName('separator')
        item_separator = QListWidgetItem()
        item_separator.setFlags(Qt.NoItemFlags)
        self.filters_list.insertItem(1, item_separator)
        self.filters_list.setItemWidget(item_separator, separator)

        self.filters_list.setCurrentItem(
            self.filters_list.findItems(
                MY_ISSUES_ITEM_NAME, Qt.MatchExactly
            )[0])

        self.filters_list.setSizeAdjustPolicy(QAbstractScrollArea.AdjustToContents)
        self.on_filter_selected(self.filters_list.currentItem())

    def filter_field_help(self):
        QDesktopServices.openUrl(self.help_filter_url)

    def on_filter_selected(self, item):
        if not item.text():
            return
        self.current_item = item
        if len(self.current_item.text()) > 50:
            set_text = '{}...'.format(self.current_item.text()[:50])
        else:
            set_text = self.current_item.text()
        self.issue_list_widget.scrollToTop()
        self.controller.search_issues_by_filter_name(item.text())
        self.filter_name_label.setText(set_text)
        self.filter_edited_label.hide()

        if self.filters_list.currentItem().text() == MY_ISSUES_ITEM_NAME:
            self.save_filter_btn.hide()
            self.overwrite_filter_button.hide()
            self.filter_edited_label.hide()
            self.delete_filter_btn.hide()

        elif self.filters_list.currentItem().text() == SEARCH_ITEM_NAME.capitalize():
            # activate save button
            self.overwrite_filter_button.hide()
            self.save_filter_btn.show()
            self.delete_filter_btn.hide()
        else:
            # activate overwrite button
            self.overwrite_filter_button.show()
            self.overwrite_filter_button.setEnabled(False)
            self.save_filter_btn.hide()
            self.delete_filter_btn.show()

    def toggle_frame_filters(self):
        if self.toggle_frame_filters_btn.text() == '<':
            self.toggle_frame_filters_btn.setText('>')
            self.filters_frame.hide()
        else:
            self.toggle_frame_filters_btn.setText('<')
            self.filters_frame.show()

    def add_filter_btn_click(self):
        self.overwrite_filter_button.hide()
        self.save_filter_btn.show()
        self.delete_filter_btn.hide()
        self.filter_edited_label.hide()
        self.filters_list.setCurrentItem(None)
        self.query_field.setText('')
        self.filter_name_label.setText('Add new filter')
        self.controller.current_issues.clear()
        self.show_no_issues()

    def eventFilter(self, obj, event):
        # if user started typing in filter field
        if obj is self.query_field and event.type() == QEvent.KeyRelease:
            if not self.filters_list.currentItem():
                return super().eventFilter(obj, event)
            current_filter_name = self.filters_list.currentItem().text().lower()
            # if current filter is not 'Search issues' or 'my open issues'
            if current_filter_name not in (SEARCH_ITEM_NAME, MY_ISSUES_ITEM_NAME):
                # if query of current filter has not changed
                if self.controller.filters_handler.get_filter_by_name(
                        current_filter_name
                ) != self.query_field.text():
                    # show that filter has been edited
                    self.filter_edited_label.show()
                    self.overwrite_filter_button.setEnabled(True)
                else:
                    self.filter_edited_label.hide()
                    self.overwrite_filter_button.setEnabled(False)
        return super().eventFilter(obj, event)

    def set_current_filter(self, filter_name):
        items = self.filters_list.findItems(
            filter_name, Qt.MatchExactly
        )
        self.filters_list.setCurrentItem(items[0])
        self.on_filter_selected(items[0])

    def add_filter(self, filter_name):
        self.filters_list.addItem(filter_name)
        self.set_current_filter(filter_name)

    def delete_filter(self):
        filter_name = self.filters_list.currentItem().text()
        reply = QMessageBox.question(
            self,
            'Delete filter',
            "Are you sure you want to delete "
            "'{}' filter?".format(filter_name),
            QMessageBox.Yes | QMessageBox.Cancel
        )
        if reply == QMessageBox.Yes:
            self.controller.filters_handler.delete_filter(filter_name)
            self.filters_list.takeItem(
                self.filters_list.currentRow()
            )
            self.filters_list.setCurrentItem(
                self.filters_list.findItems(
                    MY_ISSUES_ITEM_NAME, Qt.MatchExactly
                )[0])
            self.on_filter_selected(self.filters_list.currentItem())

    def show_no_issues(self, error_text=None):
        self.issue_list_widget.clear()
        self.issue_list_widget.hide()
        if error_text:
            self.label_info.setText(error_text)
        self.label_info.show()

    def set_workflow_current_state(self, issue_key):
        item = self.issue_list_widget.findItems(
            issue_key, Qt.MatchExactly
        )[0]
        custom_item = self.issue_list_widget.itemWidget(item)
        custom_item.set_workflow.setCurrentIndex(0)

    def wheelEvent(self, event):
        # top left corner coordinates of the issue list
        list_pos = self.issue_list_widget.pos()
        # check if cursor position is on the issue list
        if event.pos().x() >= list_pos.x() and event.pos().y() >= list_pos.y():
            if event.angleDelta().y() < 0:
                self.controller.refresh_issue_list(True)
                event.accept()

    def closeEvent(self, event):
        event.ignore()
        self.hide()
Beispiel #33
0
class PasswordDialog(QDialog):
    def __init__(self, parent=None, help_text='', show_stats=True):
        super(PasswordDialog, self).__init__(parent)
        self.setMinimumWidth(400)

        self.label = QLabel("Password:"******"Toggle visibility")
        self.action.triggered.connect(self.toggle_visibility)
        self.lineedit.addAction(self.action, QLineEdit.TrailingPosition)
        self.lineedit.returnPressed.connect(self.accept)

        layout = QGridLayout(self)
        layout.addWidget(self.label, 1, 1)
        layout.addWidget(self.lineedit, 2, 1)

        if show_stats:
            self.progressbar = QProgressBar()
            self.progressbar.setMaximum(4)
            self.progressbar.setTextVisible(False)
            self.progressbar.setFixedHeight(5)
            self.progressbar.setStyleSheet(
                'QProgressBar { background-color: transparent }'
                'QProgressBar::chunk { background-color: gray }'
            )

            self.rating_label = QLabel()
            self.rating_label.setAlignment(Qt.AlignRight)

            self.time_label = QLabel()
            self.time_label.setStyleSheet('color: gray')

            layout.addWidget(self.progressbar, 3, 1)
            layout.addWidget(self.time_label, 4, 1)
            layout.addWidget(self.rating_label, 4, 1)

            self.lineedit.textChanged.connect(self.update_stats)

            self.update_color('transparent')

        if help_text:
            gbox = QGroupBox()
            gbox_layout = QGridLayout()
            gbox_label = QLabel(help_text)
            gbox_label.setWordWrap(True)
            gbox_label.setAlignment(Qt.AlignCenter)
            gbox_label.setStyleSheet('color: gray')
            gbox_layout.addWidget(gbox_label)
            gbox.setLayout(gbox_layout)
            layout.addWidget(gbox, 5, 1)

        layout.addItem(QSpacerItem(0, 0, 0, QSizePolicy.Expanding), 6, 1)

    def update_color(self, color):
        self.rating_label.setStyleSheet(
            'QLabel {{ color: {} }}'.format(color))
        self.progressbar.setStyleSheet(
            'QProgressBar {{ background-color: transparent }}'
            'QProgressBar::chunk {{ background-color: {} }}'.format(color))

    def toggle_visibility(self):
        if self.lineedit.echoMode() == QLineEdit.Password:
            self.lineedit.setEchoMode(QLineEdit.Normal)
        else:
            self.lineedit.setEchoMode(QLineEdit.Password)

    def update_stats(self, text):  # noqa: max-complexity=11 XXX
        if not text:
            self.time_label.setText('')
            self.rating_label.setText('')
            self.progressbar.setValue(0)
            return
        res = zxcvbn(text)
        t = res['crack_times_display']['offline_slow_hashing_1e4_per_second']
        self.time_label.setText("Time to crack: {}".format(t))
        s = res['crack_times_seconds']['offline_slow_hashing_1e4_per_second']
        seconds = int(s)
        if seconds == 0:
            self.rating_label.setText("Very weak")
            self.update_color('lightgray')
            self.rating_label.setStyleSheet('QLabel { color: gray }')
            self.progressbar.setValue(1)
        elif seconds < 86400:  # 1 day
            self.rating_label.setText("Weak")
            self.update_color('red')
            self.progressbar.setValue(1)
        elif seconds < 2592000:  # 1 month
            self.rating_label.setText("Alright")
            self.update_color('orange')
            self.progressbar.setValue(2)
        elif seconds < 3153600000:  # 100 years
            self.rating_label.setText("Good")
            self.update_color('#9CC259')
            self.progressbar.setValue(3)
        else:  # > 100 years
            self.rating_label.setText("Excellent")
            self.update_color('#00B400')
            self.progressbar.setValue(4)
        warning = res['feedback']['warning']
        try:
            suggestion = "Suggestion: " + res['feedback']['suggestions'][0]
        except IndexError:
            suggestion = None
        if warning and suggestion:
            self.rating_label.setToolTip(warning + '\n\n' + suggestion)
        elif warning:
            self.rating_label.setToolTip(warning)
        elif suggestion:
            self.rating_label.setToolTip(suggestion)
        else:
            self.rating_label.setToolTip(None)

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Escape:
            self.reject()

    @staticmethod
    def get_password(parent=None, label=None, help_text='', show_stats=True):
        dialog = PasswordDialog(parent, help_text, show_stats)
        if label:
            dialog.label.setText(label)
        result = dialog.exec_()
        return (dialog.lineedit.text(), result)
class MyWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MyWindow, self).__init__()
        self.setObjectName("MediathekQuery")
        self.root = QFileInfo(__file__).absolutePath()
        self.setAttribute(Qt.WA_DeleteOnClose)
        self.settings = QSettings('Axel Schneider', self.objectName())
        self.viewer = QTableWidget()
        
        
        self.horizontalHeader = self.viewer.horizontalHeader()
        
        icon = self.root + "/icon.png"
        
        self.titleList = []
        self.topicList = []
        self.urlList = []
        self.urlKleinList = []
        self.beschreibungList = []
        self.idList = []
        self.chList = []
        self.lengthList = []
        self.results = ""
        
        self.myurl = ""
        self.fname = ""
        self.viewer.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.viewer.SelectionMode(QAbstractItemView.SingleSelection)
        self.viewer.setSortingEnabled(False)
        self.viewer.verticalHeader().setStretchLastSection(False)
        self.viewer.horizontalHeader().setStretchLastSection(True)

        self.viewer.setColumnCount(7)
        self.viewer.setColumnWidth(0, 48)
        self.viewer.setColumnWidth(1, 130)
        self.viewer.setColumnWidth(2, 160)
        self.viewer.setColumnWidth(3, 60)
        self.viewer.hideColumn(4)
        self.viewer.hideColumn(5)
        self.viewer.setHorizontalHeaderLabels(["Sender", "Thema", "Titel", "Länge", "HD", "SD", "Beschreibung"])

        self.viewer.verticalHeader().setVisible(True)
        self.viewer.horizontalHeader().setVisible(True)
        self.setStyleSheet(stylesheet(self))        
        self.viewer.selectionModel().selectionChanged.connect(self.getCellText)
        
        self.layout = QGridLayout()
        self.layout.addWidget(self.viewer,0, 0, 1, 7)

        self.findfield = QLineEdit()
        self.fAction = QAction(QIcon.fromTheme("edit-clear"), "", triggered = self.findfieldAction)
        self.findfield.addAction(self.fAction, 1)
        self.findfield.returnPressed.connect(self.myQuery)
        self.findfield.setFixedWidth(200)
        self.findfield.setPlaceholderText("suchen ...")
        self.findfield.setToolTip("ENTER to find")
        self.layout.addWidget(self.findfield,1, 0)
        
        self.chCombo = QComboBox()
        self.chCombo.setFixedWidth(80)
        self.chCombo.addItems(['ARD', 'ZDF', 'MDR', 'PHOENIX', 'RBB', 'BR', 'HR', 'SR', \
                               'SWR', 'NDR', 'DW', 'WDR', 'ARTE', '3SAT', 'KIKA', 'ORF', 'SRF'])
        self.chCombo.addItem("alle")
        self.chCombo.setToolTip("Sender wählen")
        self.chCombo.currentIndexChanged.connect(self.myQuery)
        self.layout.addWidget(self.chCombo,1, 1)
        
        self.btnPlay = QPushButton("Play")
        self.btnPlay.setFixedWidth(80)
        self.btnPlay.setIcon(QIcon.fromTheme("media-playback-start"))
        self.layout.addWidget(self.btnPlay,1, 2)
        self.btnPlay.clicked.connect(self.playVideo)
        
        self.btnDownload = QPushButton("Download")
        self.btnDownload.setFixedWidth(100)
        self.btnDownload.setIcon(QIcon.fromTheme("download"))
        self.layout.addWidget(self.btnDownload,1, 3)
        self.btnDownload.clicked.connect(self.downloadVideo)
        
        self.chBox = QPushButton("SD")
        self.chBox.setToolTip("umschalten HD / SD")
        self.chBox.setStyleSheet("background: #729fcf;")
        self.chBox.setFixedWidth(44)
        self.chBox.clicked.connect(self.toggleQuality)
        self.layout.addWidget(self.chBox,1, 4)
        
        self.lbl = QLabel("Info")
        self.layout.addWidget(self.lbl,1, 5)

        self.chkbox = QCheckBox("nach Filmlänge sortieren")
        self.layout.addWidget(self.chkbox,1, 6)
        self.chkbox.setCheckState(0)
        self.chkbox.setToolTip("Standard-Sortierung ist nach Erscheinungsdatum")
        self.chkbox.stateChanged.connect(self.myQuery)
        
        self.myWidget = QWidget()
        self.myWidget.setLayout(self.layout)

        self.msg("Ready")
        self.setCentralWidget(self.myWidget)
        self.setWindowIcon(QIcon(icon))
        self.setGeometry(20,20,600,450)
        self.setWindowTitle("Mediathek Suche")
        self.readSettings()
        self.msg("Ready")
        self.findfield.setFocus()
        self.player = MediathekPlayer.VideoPlayer('')
        self.player.hide()
        wildcards = "Wildcards:    + Titel    # Thema    * Beschreibung\n '<xx Suchbegriff' kleiner als xx Minuten    '>xx Suchbegriff' grösser als xx Minuten "
        help_label = QLabel(wildcards)
        help_label.setToolTip("ohne Wildcard werden alle Felder durchsucht")
        help_label.setStyleSheet("font-size: 8pt; color: #1a2334;")
        self.statusBar().addPermanentWidget(help_label)
        self.statusBar().showMessage("Ready")
        
    def toggleQuality(self):
        if self.chBox.text() == "SD":
            self.chBox.setText("HD")
            self.chBox.setStyleSheet("background: #8ae234;")
            self.getCellText()
        else:
            self.chBox.setText("SD")
            self.chBox.setStyleSheet("background: #729fcf;")
            self.getCellText()
        
    def myQuery(self):
        if not self.findfield.text() == "":
            self.viewer.setRowCount(0)
            self.viewer.clearContents()
            self.titleList = []
            self.topicList = []
            self.urlList = []
            self.urlKleinList = []
            self.beschreibungList = []
            self.idList = []
            self.chList = []
            self.lengthList = []

            channels = [self.chCombo.currentText()]
            if channels == ["alle"]:
                channels = ["ard", "zdf", "mdr", "phoenix", "rbb", "br", "hr", "sr", "swr", "ndr",\
                            "dw", "wdr", "arte", "3sat", "kika", "orf", "srf"]
            print("suche",  self.findfield.text(), "in", ','.join(channels).upper())
            
            if self.findfield.text().startswith("*"):
                ### nur Beschreibung
                for ch in channels:
                    r = self.makeQueryBeschreibung(ch, self.findfield.text()[1:])
            elif self.findfield.text().startswith("#"):
                ### nur Thema
                for ch in channels:
                    r = self.makeQueryTopic(ch, self.findfield.text()[1:])
            elif self.findfield.text().startswith("+"):
                ### nur Titel
                for ch in channels:
                    r = self.makeQueryTitle(ch, self.findfield.text()[1:])
            elif self.findfield.text().startswith(">"):
                ### Zeit grösser
                for ch in channels:
                    r = self.makeQueryBigger(ch, self.findfield.text())
            elif self.findfield.text().startswith("<"):
                ### Zeit kleiner
                for ch in channels:
                    r = self.makeQuerySmaller(ch, self.findfield.text())
            else:
                ### alle Felder
                for ch in channels:
                    r = self.makeQuery(ch, self.findfield.text())

            for b in range(len(self.titleList)):
                self.idList.append(str(b))
            self.viewer.setSortingEnabled(False)   
            for x in range(len(self.titleList)):
                self.viewer.insertRow(x)
                self.viewer.setItem(x, 0, QTableWidgetItem(self.chList[x]))
                self.viewer.setItem(x, 1, QTableWidgetItem(self.topicList[x]))
                self.viewer.setItem(x, 2, QTableWidgetItem(self.titleList[x]))
                self.viewer.setItem(x, 3, QTableWidgetItem(self.lengthList[x]))
                self.viewer.setItem(x, 4, QTableWidgetItem(self.urlList[x]))
                self.viewer.setItem(x, 5, QTableWidgetItem(self.urlKleinList[x]))
                self.viewer.setItem(x, 6, QTableWidgetItem(self.beschreibungList[x]))
            for x in range(len(self.titleList)):
                self.viewer.resizeRowToContents(x)

        
    def makeQuery(self, channel, myquery):
        headers = {
            'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:10.0) Gecko/20100101 Firefox/10.0',
            'Accept': '*/*',
            'Accept-Language': 'de-DE,en;q=0.5',
            'Content-Type': 'text/plain;charset=UTF-8',
            'Connection': 'keep-alive',
        }
        if self.chkbox.checkState() == 2:
            data = {"future":"true", "size":"500", "sortBy":"duration", "sortOrder":"desc", \
                    "queries":[{"fields":["title", "topic", "description"],
                    "query":"" + myquery + ""},{"fields":["channel"],
                    "query":"" + channel + ""}]}
        else:
            data = {"future":"true", "size":"500", "sortBy":"timestamp", "sortOrder":"asc", \
                    "queries":[{"fields":["title", "topic", "description"],
                    "query":"" + myquery + ""},{"fields":["channel"],
                    "query":"" + channel + ""}]}            
        
        response = requests.post('https://mediathekviewweb.de/api/query', headers=headers, json=data)
        response_json = response.json()
        count = int(response_json['result']['queryInfo']['resultCount'])
        for x in range(count):
            topic = response_json['result']['results'][x]['topic']
            title = response_json['result']['results'][x]['title']
            url = response_json['result']['results'][x]['url_video']
            url_klein = response_json['result']['results'][x]['url_video_low']
            beschreibung = response_json['result']['results'][x]['description']
            l = response_json['result']['results'][x]['duration']
            if not l == "":
                length = time.strftime('%H:%M:%S', time.gmtime(l))
                self.lengthList.append(length)
            else:
                self.lengthList.append("")
            ch = response_json['result']['results'][x]['channel']
            if not ch == "":
                self.chList.append(ch)
            else:
                self.chList.append("")
            if not title == "":    
                self.titleList.append(title)
            else:
                self.titleList.append("")
            if not topic == "":
                self.topicList.append(topic)
            else:
                self.topicList.append("")
            if not url == "":
                self.urlList.append(url)
            else:
                self.urlList.append("")
            if not url_klein == "":
                self.urlKleinList.append(url_klein)
            else:
                self.urlKleinList.append("")
            if not beschreibung == "":
                self.beschreibungList.append(beschreibung)
            else:
                self.beschreibungList.append("")
            
        print(count, "Beiträge gefunden")
        self.lbl.setText(f"{count} Beiträge gefunden")
        
    def makeQueryBeschreibung(self, channel, myquery):
        headers = {
            'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:10.0) Gecko/20100101 Firefox/10.0',
            'Accept': '*/*',
            'Accept-Language': 'de-DE,en;q=0.5',
            'Content-Type': 'text/plain;charset=UTF-8',
            'Connection': 'keep-alive',
        }
        
        data = {"future":"true", "size":"500", "sortBy":"timestamp", "sortOrder":"desc", \
                "queries":[{"fields":["description"],
                "query":"" + myquery + ""},{"fields":["channel"],
                "query":"" + channel + ""}]}
        
        response = requests.post('https://mediathekviewweb.de/api/query', headers=headers, json=data)
        response_json = response.json()
        count = int(response_json['result']['queryInfo']['resultCount'])
        for x in range(count):
            topic = response_json['result']['results'][x]['topic']
            title = response_json['result']['results'][x]['title']
            url = response_json['result']['results'][x]['url_video']
            url_klein = response_json['result']['results'][x]['url_video_low']
            beschreibung = response_json['result']['results'][x]['description']
            l = response_json['result']['results'][x]['duration']
            if not l == "":
                length = time.strftime('%H:%M:%S', time.gmtime(l))
                self.lengthList.append(length)
            else:
                self.lengthList.append("")
            ch = response_json['result']['results'][x]['channel']
            if not ch == "":
                self.chList.append(ch)
            else:
                self.chList.append("")
            if not title == "":    
                self.titleList.append(title)
            else:
                self.titleList.append("")
            if not topic == "":
                self.topicList.append(topic)
            else:
                self.topicList.append("")
            if not url == "":
                self.urlList.append(url)
            else:
                self.urlList.append("")
            if not url_klein == "":
                self.urlKleinList.append(url_klein)
            else:
                self.urlKleinList.append("")
            if not beschreibung == "":
                self.beschreibungList.append(beschreibung)
            else:
                self.beschreibungList.append("")
            
        print(count, "Beiträge gefunden")
        self.lbl.setText(f"{count} Beiträge gefunden")
        
    def makeQueryTopic(self, channel, myquery):
        headers = {
            'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:10.0) Gecko/20100101 Firefox/10.0',
            'Accept': '*/*',
            'Accept-Language': 'de-DE,en;q=0.5',
            'Content-Type': 'text/plain;charset=UTF-8',
            'Connection': 'keep-alive',
        }
        
        data = {"future":"true", "size":"500", "sortBy":"timestamp", "sortOrder":"desc", \
                "queries":[{"fields":["topic"],
                "query":"" + myquery + ""},{"fields":["channel"],
                "query":"" + channel + ""}]}
        
        response = requests.post('https://mediathekviewweb.de/api/query', headers=headers, json=data)
        response_json = response.json()
        count = int(response_json['result']['queryInfo']['resultCount'])
        for x in range(count):
            topic = response_json['result']['results'][x]['topic']
            title = response_json['result']['results'][x]['title']
            url = response_json['result']['results'][x]['url_video']
            url_klein = response_json['result']['results'][x]['url_video_low']
            beschreibung = response_json['result']['results'][x]['description']
            l = response_json['result']['results'][x]['duration']
            if not l == "":
                length = time.strftime('%H:%M:%S', time.gmtime(l))
                self.lengthList.append(length)
            else:
                self.lengthList.append("")
            ch = response_json['result']['results'][x]['channel']
            if not ch == "":
                self.chList.append(ch)
            else:
                self.chList.append("")
            if not title == "":    
                self.titleList.append(title)
            else:
                self.titleList.append("")
            if not topic == "":
                self.topicList.append(topic)
            else:
                self.topicList.append("")
            if not url == "":
                self.urlList.append(url)
            else:
                self.urlList.append("")
            if not url_klein == "":
                self.urlKleinList.append(url_klein)
            else:
                self.urlKleinList.append("")
            if not beschreibung == "":
                self.beschreibungList.append(beschreibung)
            else:
                self.beschreibungList.append("")
            
        print(count, "Beiträge gefunden")
        self.lbl.setText(f"{count} Beiträge gefunden")
        
    def makeQueryTitle(self, channel, myquery):
        headers = {
            'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:10.0) Gecko/20100101 Firefox/10.0',
            'Accept': '*/*',
            'Accept-Language': 'de-DE,en;q=0.5',
            'Content-Type': 'text/plain;charset=UTF-8',
            'Connection': 'keep-alive',
        }
        
        data = {"future":"true", "size":"500", "sortBy":"timestamp", "sortOrder":"desc", \
                "queries":[{"fields":["title"],
                "query":"" + myquery + ""},{"fields":["channel"],
                "query":"" + channel + ""}]}
        
        response = requests.post('https://mediathekviewweb.de/api/query', headers=headers, json=data)
        response_json = response.json()
        count = int(response_json['result']['queryInfo']['resultCount'])
        for x in range(count):
            topic = response_json['result']['results'][x]['topic']
            title = response_json['result']['results'][x]['title']
            url = response_json['result']['results'][x]['url_video']
            url_klein = response_json['result']['results'][x]['url_video_low']
            beschreibung = response_json['result']['results'][x]['description']
            l = response_json['result']['results'][x]['duration']
            if not l == "":
                length = time.strftime('%H:%M:%S', time.gmtime(l))
                self.lengthList.append(length)
            else:
                self.lengthList.append("")
            ch = response_json['result']['results'][x]['channel']
            if not ch == "":
                self.chList.append(ch)
            else:
                self.chList.append("")
            if not title == "":    
                self.titleList.append(title)
            else:
                self.titleList.append("")
            if not topic == "":
                self.topicList.append(topic)
            else:
                self.topicList.append("")
            if not url == "":
                self.urlList.append(url)
            else:
                self.urlList.append("")
            if not url_klein == "":
                self.urlKleinList.append(url_klein)
            else:
                self.urlKleinList.append("")
            if not beschreibung == "":
                self.beschreibungList.append(beschreibung)
            else:
                self.beschreibungList.append("")
            
        print(count, "Beiträge gefunden")
        self.lbl.setText(f"{count} Beiträge gefunden")
        
#######################################################################
    def makeQueryBigger(self, channel, myquery):
        headers = {
            'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:10.0) Gecko/20100101 Firefox/10.0',
            'Accept': '*/*',
            'Accept-Language': 'de-DE,en;q=0.5',
            'Content-Type': 'text/plain;charset=UTF-8',
            'Connection': 'keep-alive',
        }
        if self.chkbox.checkState() == 2:
            data = {"future":"true", "size":"500", "sortBy":"duration", "sortOrder":"desc", \
                    "queries":[{"fields":["duration"],
                    "query":"" + myquery[1:].partition(" ")[2] + ""},{"fields":["channel"],
                    "query":"" + channel + ""}]}
        else:
            data = {"future":"true", "size":"500", "sortBy":"timestamp", "sortOrder":"asc", \
                    "queries":[{"fields":["title", "topic", "description"],
                    "query":"" + myquery[1:].partition(" ")[2] + ""},{"fields":["channel"],
                    "query":"" + channel + ""}]}            
        
        response = requests.post('https://mediathekviewweb.de/api/query', headers=headers, json=data)
        response_json = response.json()
        count = int(response_json['result']['queryInfo']['resultCount'])
        for x in range(count):
            topic = response_json['result']['results'][x]['topic']
            title = response_json['result']['results'][x]['title']
            url = response_json['result']['results'][x]['url_video']
            url_klein = response_json['result']['results'][x]['url_video_low']
            beschreibung = response_json['result']['results'][x]['description']
            l = response_json['result']['results'][x]['duration']
            if not l == "":
                length = time.strftime('%H:%M:%S', time.gmtime(l))
                mydur = myquery[1:].partition(" ")[0]
                hour = time.strftime('%H', time.gmtime(l))
                minute = time.strftime('%M', time.gmtime(l))
                dur = int(hour) * 60 + int(minute)
                if dur > int(mydur) - 1:
                    self.lengthList.append(length)
                    ch = response_json['result']['results'][x]['channel']
                    if not ch == "":
                        self.chList.append(ch)
                    else:
                        self.chList.append("")
                    if not title == "":    
                        self.titleList.append(title)
                    else:
                        self.titleList.append("")
                    if not topic == "":
                        self.topicList.append(topic)
                    else:
                        self.topicList.append("")
                    if not url == "":
                        self.urlList.append(url)
                    else:
                        self.urlList.append("")
                    if not url_klein == "":
                        self.urlKleinList.append(url_klein)
                    else:
                        self.urlKleinList.append("")
                    if not beschreibung == "":
                        self.beschreibungList.append(beschreibung)
                    else:
                        self.beschreibungList.append("")
            
        print(count, "Beiträge gefunden")
        self.lbl.setText(f"{count} Beiträge gefunden")
#######################################################################
    def makeQuerySmaller(self, channel, myquery):
        headers = {
            'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:10.0) Gecko/20100101 Firefox/10.0',
            'Accept': '*/*',
            'Accept-Language': 'de-DE,en;q=0.5',
            'Content-Type': 'text/plain;charset=UTF-8',
            'Connection': 'keep-alive',
        }
        if self.chkbox.checkState() == 2:
            data = {"future":"true", "size":"500", "sortBy":"duration", "sortOrder":"desc", \
                    "queries":[{"fields":["duration"],
                    "query":"" + myquery[1:].partition(" ")[2] + ""},{"fields":["channel"],
                    "query":"" + channel + ""}]}
        else:
            data = {"future":"true", "size":"500", "sortBy":"timestamp", "sortOrder":"asc", \
                    "queries":[{"fields":["title", "topic", "description"],
                    "query":"" + myquery[1:].partition(" ")[2] + ""},{"fields":["channel"],
                    "query":"" + channel + ""}]}            
        
        response = requests.post('https://mediathekviewweb.de/api/query', headers=headers, json=data)
        response_json = response.json()
        count = int(response_json['result']['queryInfo']['resultCount'])
        for x in range(count):
            topic = response_json['result']['results'][x]['topic']
            title = response_json['result']['results'][x]['title']
            url = response_json['result']['results'][x]['url_video']
            url_klein = response_json['result']['results'][x]['url_video_low']
            beschreibung = response_json['result']['results'][x]['description']
            l = response_json['result']['results'][x]['duration']
            if not l == "":
                length = time.strftime('%H:%M:%S', time.gmtime(l))
                mydur = myquery[1:].partition(" ")[0]
                hour = time.strftime('%H', time.gmtime(l))
                minute = time.strftime('%M', time.gmtime(l))
                dur = int(hour) * 60 + int(minute)
                if dur < int(mydur):
                    self.lengthList.append(length)
                    ch = response_json['result']['results'][x]['channel']
                    if not ch == "":
                        self.chList.append(ch)
                    else:
                        self.chList.append("")
                    if not title == "":    
                        self.titleList.append(title)
                    else:
                        self.titleList.append("")
                    if not topic == "":
                        self.topicList.append(topic)
                    else:
                        self.topicList.append("")
                    if not url == "":
                        self.urlList.append(url)
                    else:
                        self.urlList.append("")
                    if not url_klein == "":
                        self.urlKleinList.append(url_klein)
                    else:
                        self.urlKleinList.append("")
                    if not beschreibung == "":
                        self.beschreibungList.append(beschreibung)
                    else:
                        self.beschreibungList.append("")
            
        print(count, "Beiträge gefunden")
        self.lbl.setText(f"{count} Beiträge gefunden")
#######################################################################

    def findfieldAction(self):
        self.findfield.setText("")
        
    def downloadVideo(self):
        if not self.url == "":
            self.downloader = Downloader.Downloader()
            self.downloader.setWindowTitle("Downloader")
            self.downloader.url = self.url
            item = self.viewer.selectedIndexes()[2]
            if not item == "":
                filename = str(item.data())
            self.downloader.fname = filename + self.url[-4:]
            self.downloader.fname = self.downloader.fname.replace(' (', '_').replace(') ', '_')\
            .replace(')', '_').replace('/', '_')
            if '_.' in self.downloader.fname:
                self.downloader.fname = self.downloader.fname.replace('_.', '.')
            self.downloader.lbl.setText("speichern als: " + self.downloader.homepath + self.downloader.fname)
            self.downloader.move(self.x() + 2, self.y() + 28)
            self.downloader.show()
        else:
            print("keine URL")
            self.msg("keine URL")
        
        
    def getCellText(self):
        if self.viewer.selectionModel().hasSelection():
            row = self.selectedRow()
            if not self.chBox.text() == "SD":
                item = self.urlList[row]
            else:
                item = self.urlKleinList[row]
            if not item == "":
                name = item
                self.url = str(item)
                QApplication.clipboard().setText(self.url)
                print(self.url)
            infotext = f"{self.chList[row]}: {self.topicList[row]} - {self.titleList[row]} \
                        ({self.chBox.text()}) Dauer: {self.lengthList[row]}"
            self.msg(infotext)
            self.fname = str(self.viewer.selectedIndexes()[1].data())

        
    def playVideo(self):
        if self.viewer.selectionModel().hasSelection():
            row = self.selectedRow()
            if not self.chBox.text() == "SD":
                item = item = self.urlList[row]
                print("play HD")
            else:
                item = self.urlKleinList[row]
                print("play SD")
            if not item == "":
                self.url = item
                if not self.url == "":
                    print("url =", self.url)
                    self.player.show()
                    self.player.playMyURL(self.url)
                else:
                    print("keine URL vorhanden")
                    self.msg("keine URL vorhanden")
            else:
                print("keine URL vorhanden")
        else:
            print("keine URL vorhanden")

    def selectedRow(self):
        if self.viewer.selectionModel().hasSelection():
            row =  self.viewer.selectionModel().selectedIndexes()[0].row()
            return int(row)           

    def closeEvent(self, e):
        self.writeSettings()
        self.player.close()
        e.accept()

    def readSettings(self):
        print("lese Fensterposition")
        if self.settings.contains('geometry'):
            self.setGeometry(self.settings.value('geometry'))

    def writeSettings(self):
        print("Fensterposition gespeichert")
        self.settings.setValue('geometry', self.geometry())

    def msg(self, message):
        self.statusBar().showMessage(message, 0)