Example #1
0
class AreasBrowserDialog(BaseDialog):
    def __init__(self, parent, area_name, areas):
        super().__init__(parent, _("Select the area you mean"), _("&Select"),
                         _("&Close"))
        self._areas = list(areas.items())
        for id, (parent_name, data) in self._areas:
            self._areas_list.addItem(
                _("{area_name}, {parent_name}").format(
                    area_name=area_name, parent_name=parent_name))
        self._areas_list.setCurrentRow(0)

    def create_ui(self):
        areas_label = QLabel(_("Areas"))
        self.layout.addWidget(areas_label, 0, 0)
        self._areas_list = QListWidget(self)
        areas_label.setBuddy(self._areas_list)
        self._areas_list.currentRowChanged.connect(self.on_areas_list_listbox)
        self.layout.addWidget(self._areas_list, 1, 0)
        props_label = QLabel(_("Area properties"))
        self.layout.addWidget(props_label, 0, 1)
        self._area_props = QListWidget()
        props_label.setBuddy(self._area_props)
        self.layout.addWidget(self._area_props, 1, 1)

    def on_areas_list_listbox(self, index):
        self._area_props.clear()
        for key, value in self._areas[index][1][1].items():
            self._area_props.addItem(f"{underscored_to_words(key)}: {value}")
        self._area_props.addItem(
            _("Area id: {}").format(self._areas[index][0]))

    @property
    def selected_area_id(self):
        return self._areas[self._areas_list.currentRow()][0]
Example #2
0
class SignalGrouper(QDialog):
    def __init__(self, chartData, parent=None):
        QDialog.__init__(self, parent)
        self.chartData = chartData
        self._create()

    def _create(self):
        self.mLayout = QVBoxLayout(self)
        
        self.gSelector = QListWidget()
        groups = self.chartData.getDataGroups()
        self.gSelector.addItems(groups)
        self.gSelector.currentTextChanged.connect(self._updateGroupList)
        self.chartData.dataGroupAdded.connect(self.gSelector.addItem)
        self.chartData.dataGroupAdded.connect(self.gSelector.addItem)
        self.mLayout.addWidget(self.gSelector)

        self.sSelector = QListWidget()
        self.mLayout.addWidget(self.sSelector)

        groupBtn = QPushButton('Create group from selected')
        groupBtn.clicked.connect(self.createNewGroup)
        self.mLayout.addWidget(groupBtn)
        

    def _updateGroupList(self):
        newGroup = self.gSelector.currentItem().text()
        sStruct = self.chartData[newGroup].getColStructure()
        self.sSelector.clear()
        for ws in sStruct:
            firstChannel = sStruct[ws][0]
            isOneSignal = self.chartData[newGroup][firstChannel][ws][0]
            if isOneSignal:
                item = QListWidgetItem(ws, self.sSelector)
                item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
                item.setCheckState(Qt.Unchecked)

    def createNewGroup(self):
        checkList = []
        for i in range(self.sSelector.count()):
            sItem = self.sSelector.item(i)
            if sItem.checkState() == Qt.Checked:
                checkList.append(sItem.text())
        if len(checkList) > 0:
            groupName, result = QInputDialog().getText(self, 'Input', 'Enter group name:')
            if result:
                ws = self.gSelector.currentItem().text()
                sStruct = self.chartData[ws].getColStructure(checkList)
                sKeys = list(sStruct.keys())
                for s in range(len(sKeys)):
                    if sStruct[sKeys[s]] != sStruct[sKeys[s-1]]:
                        print('Signals have diffrent channel sets')
                        return
                self.chartData.appendSignalGroup(ws, groupName, sStruct[sKeys[0]], checkList)
            else:
                return
        else:
            return
Example #3
0
class DWidget(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        hlayout = QHBoxLayout()

        ##################################################### Left
        self.menu_level = 0
        self.item_list = QListWidget()
        self.fill_main_item_list()
        #self.item_list.setMinimumWidth(256)
        self.item_list.setMaximumWidth(300)
        self.item_list.setSizePolicy(QSizePolicy.Expanding,
                                     QSizePolicy.Expanding)
        self.item_list.setSizePolicy(QSizePolicy.Preferred,
                                     QSizePolicy.Preferred)
        self.item_list.itemClicked[QListWidgetItem].connect(self.item_clicked)

        ##################################################### Right
        b = QTabWidget()
        b.addTab(QWidget(), "Primera")
        b.addTab(QWidget(), "Segunda")
        b.setMinimumWidth(768)
        #b.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        b.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)

        hlayout.addWidget(self.item_list)
        hlayout.addWidget(b)
        self.setLayout(hlayout)

    @Slot()
    def item_clicked(self, item):
        self.menu_level += 1
        item_text = item.text()

        if self.menu_level < 2:
            self.item_list.clear()

            item = QListWidgetItem("< Back")
            item.setSizeHint(QSize(item.sizeHint().width(), 50))
            self.item_list.addItem(item)

            for i in range(10):
                item = QListWidgetItem("Sub menu {} ({})".format(i, item_text))
                item.setSizeHint(QSize(item.sizeHint().width(), 50))
                self.item_list.addItem(item)
        elif "Back" in item_text:
            self.item_list.clear()
            self.menu_level = 0
            self.fill_main_item_list()

    def fill_main_item_list(self):
        for i in range(10):
            item = QListWidgetItem("Menu {}".format(i))
            item.setSizeHint(QSize(item.sizeHint().width(), 50))
            self.item_list.addItem(item)
Example #4
0
class ServerGUI(QMainWindow):
    server = None

    def __init__(self):
        super().__init__()
        self.setWindowTitle("Stopped")

        self.start_button = QPushButton("Start")
        self.clients_list = QListWidget()
        self.start_button.clicked.connect(self.start_server)

        # Setting layout
        self.layout = QVBoxLayout()
        self.layout.addWidget(self.start_button)
        self.layout.addWidget(QLabel("Clients:"))
        self.layout.addWidget(self.clients_list)
        widget = QWidget()
        widget.setLayout(self.layout)
        self.setCentralWidget(widget)
        self.setIcon()

    def setIcon(self):
        appIcon = QIcon("icons/server.png")
        self.setWindowIcon(appIcon)

    def stop_server(self):
        self.server.stop_server()
        self.server = None
        self.start_button.clicked.connect(self.start_server)
        self.start_button.setText("Start")
        self.setWindowTitle("Stopped")

    def start_server(self):
        ip, port = "0.0.0.0", random.randint(8000, 8999)
        if self.server is None:
            self.server = Server(ip, port, server_gui=self)
        self.server.start_server()
        self.start_button.setText("Stop")
        self.start_button.clicked.connect(self.stop_server)
        self.setWindowTitle(f"{ip}:{port}")

    def update_client_list(self, clients):
        self.clients_list.clear()

        for client in clients:
            self.clients_list.addItem(f"{client.username}:{client.socket_id}")
Example #5
0
class ppDiscoverWidget(QWidget, Discovery):
    DeviceChanged = Signal(ppDevice)

    def __init__(self):
        QWidget.__init__(self)
        Discovery.__init__(self, DeviceID.BEBOP_FAMILY)

        self.button = QPushButton("Refresh Devices")
        self.lst = QListWidget(self)

        self.layout = QVBoxLayout()
        self.layout.addWidget(self.lst)
        self.layout.addWidget(self.button)
        self.setLayout(self.layout)
        self.button.clicked.connect(self.discover)
        self.lst.currentItemChanged.connect(self.on_item_changed)
        self.setFixedWidth(140)

    def add_service(self, zeroconf, type, name):
        """ Internal function for zeroconf.ServiceBrowser. """
        info = super().add_service(zeroconf, type, name)
        #        self.devices.append(info)
        item = ppDevice(info)
        self.lst.addItem(item)
        # item2=ppDevice(info)
        # self.lst.addItem(item2)
        print('[' + item.name + '-' + item.ip + ']')
        item.connect()
        item.start_stream()

    def discover(self, wd=2):
        print("searching devices...")
        self.lst.clear()
        #self.devices = []
        super().start()
        super().wait_for_change(2)
        super().stop()
        print("OK")

    def on_item_changed(self, curr, prev):
        print("switch on " + curr.name)
        self.DeviceChanged.emit(curr)

    @property
    def curentDevice(self):
        return self.lst.currentItem()
Example #6
0
class AutocompleteWidget(QDialog):

    WIDTH = 300
    HEIGHT = 120

    def __init__(self, suggestions: list):
        super(AutocompleteWidget, self).__init__()
        self.widget = QListWidget()
        self.widget.setStyleSheet("background-color: #232323;")
        self.setWindowFlags(Qt.FramelessWindowHint | Qt.Window)
        self.vbox = QVBoxLayout()
        self.label = QLabel("")
        self.vbox.addWidget(self.widget, 10)
        self.vbox.addWidget(self.label, 1)
        self.setLayout(self.vbox)
        self.updateSuggestionList(suggestions)
        self.result = None

    def updateSuggestionList(self, suggestions):
        self.widget.clear()
        if suggestions:
            for keyword in suggestions:
                self.widget.addItem(AutoCompleteListWidgetItem(keyword))
            self.label.setText("Number of suggestions: {}.".format(
                len(suggestions)))
        else:
            self.label.setText("No available suggestions.")
        self.setSize()

    def setSize(self):
        self.setFixedSize(self.minimumSizeHint())
        self.setFixedHeight(AutocompleteWidget.HEIGHT)
        self.setFixedWidth(AutocompleteWidget.WIDTH)

    def keyPressEvent(self, e):
        if e.key() == Qt.Key_Escape:
            self.close()
        if e.key() == Qt.Key_Return:
            selectedItems = self.widget.selectedItems()
            if len(selectedItems) > 0:
                self.result = selectedItems[0]
            self.close()
        if e.key() == Qt.Key_Backspace:
            self.close()
        if e.key() == Qt.Key_Left:
            self.parent().setFocus()
Example #7
0
class SimpleTodoPlus(QWidget):
    def __init__(self):
        QWidget.__init__(self)

        self.todo_list_widget = QListWidget(self)
        self.todo_list_widget.itemChanged.connect(self.onItemChanged)

        self.add_todo_btn = QPushButton("Add Todo", self)
        self.add_todo_btn.clicked.connect(self.add_todo_btn_clicked)

        self.remove_todo_btn = QPushButton("Remove Todo", self)
        self.remove_todo_btn.clicked.connect(self.remove_todo_btn_clicked)

        self.clear_todo_btn = QPushButton("Clear Todo", self)
        self.clear_todo_btn.clicked.connect(self.clear_todo_btn_clicked)

        vbox_layout = QVBoxLayout(self)
        vbox_layout.addWidget(self.todo_list_widget)

        hbox_layout = QHBoxLayout()
        hbox_layout.addWidget(self.add_todo_btn)
        hbox_layout.addWidget(self.remove_todo_btn)
        hbox_layout.addWidget(self.clear_todo_btn)

        vbox_layout.addLayout(hbox_layout)

    def add_todo_btn_clicked(self):
        item = QListWidgetItem(f"Todo {self.todo_list_widget.count() + 1}")
        item.setFlags(item.flags() | Qt.ItemIsUserCheckable
                      | Qt.ItemIsEditable)
        item.setCheckState(Qt.Unchecked)
        self.todo_list_widget.addItem(item)
        self.todo_list_widget.edit(self.todo_list_widget.indexFromItem(item))

    def remove_todo_btn_clicked(self):
        if self.todo_list_widget.count():
            self.todo_list_widget.takeItem(self.todo_list_widget.currentRow())

    def clear_todo_btn_clicked(self):
        self.todo_list_widget.clear()

    def onItemChanged(self, item):
        font = item.font()
        font.setStrikeOut(item.checkState() == Qt.Checked)
        item.setFont(font)
Example #8
0
File: gui.py Project: mei-li/german
class MyWidget(QWidget):
    def __init__(self):
        QWidget.__init__(self)


        self.search = QLineEdit()

        self.results = QListWidget()

        self.layout = QVBoxLayout()
        self.layout.addWidget(self.search)
        self.layout.addWidget(self.results)
        self.setLayout(self.layout)

        self.search.returnPressed.connect(self.search_word)

    @Slot()
    def search_word(self):
        self.results.clear()
        for word in find_similar_ending_words(self.search.text()):
            self.results.addItem(word)
    def populate_list_with_track_info(track: MKVTrack,
                                      list_widget: QListWidget):
        """
        Populate the listwidget with the selected track's information
        :param self:
        :param track:
        :param list_widget:
        :return:
        """

        track_name = "N/A"
        if track.track_name is not None:
            track_name = track.track_name

        list_widget.clear()
        list_widget.addItem(" File Path: " + track.file_path)
        list_widget.addItem(" Track ID: " + str(track.track_id))
        list_widget.addItem(" Track Name: " + track_name)
        list_widget.addItem(" Track Type: " + track._track_type)
        list_widget.addItem(" Track Codec: " + track._track_codec)
        list_widget.addItem(" Language: " + track.language)
        list_widget.addItem(" Default Track: " + str(track.default_track))
        list_widget.addItem(" Forced Track: " + str(track.forced_track))
Example #10
0
    def clear(self) -> None:
        QListWidget.clear(self)

        # 防止异步加载时,信息错乱
        QtTask().CancelTasks(self.GetName())
Example #11
0
class ProjectSwitcher(QDialog):
    def __init__(self, configurationManager: ConfigurationManager,
                 projectComboBox):
        super(ProjectSwitcher, self).__init__()
        self.setWindowFlags(Qt.FramelessWindowHint | Qt.Window)
        self.configurationManager = configurationManager
        self.projectComboBox = projectComboBox
        self.latestProjectIndex = -1
        self.setStyleSheet("background-color: #232323; color: white;")
        self.projectList = QListWidget()
        self.vbox = QVBoxLayout()
        self.pathLabel = QLabel()
        self.pathLabel.setStyleSheet("font-size: 10px; color: grey;")
        self.vbox.addWidget(QLabel("<center>Project switcher</center>"), 1)
        self.vbox.addWidget(self.projectList, 10)
        self.vbox.addWidget(self.pathLabel, 1)
        self.setLayout(self.vbox)

    def showSwitcher(self):
        self.latestProjectIndex = self.getCurrentProjectIndex()
        self.updateProjectList()
        self.updateProjectListCurrentItem(self.latestProjectIndex)
        self.setFixedSize(self.sizeHint())
        self.setFixedWidth(500)
        self.show()

    def getCurrentProjectIndex(self):
        for i in range(len(self.configurationManager.allProjects)):
            if self.configurationManager.allProjects[i].proxy.getProjectPath(
            ) == self.configurationManager.currentProject.proxy.getProjectPath(
            ):
                return i
        return -1  # should never execute

    def updateProjectList(self):
        self.projectList.clear()
        for project in self.configurationManager.allProjects:
            self.projectList.addItem(ProjectSwitcherListItem(project.proxy))

    def updateProjectListCurrentItem(self, index):
        self.projectList.setCurrentRow(index)
        projectProxy = self.projectList.currentItem().projectProxy
        self.pathLabel.setText(projectProxy.getProjectPath())

    def hideSwitcher(self):
        if self.latestProjectIndex >= -1:
            self.projectComboBox.setCurrentText(
                self.projectList.currentItem().projectProxy.path)
        self.hide()

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Tab or event.key(
        ) == Qt.Key_Down or event.key() == Qt.Key_E:
            self.latestProjectIndex = (self.latestProjectIndex + 1) % len(
                self.configurationManager.allProjects)
        elif event.key() == Qt.Key_Up or event.key() == Qt.Key_Backtab:
            self.latestProjectIndex -= 1
            if self.latestProjectIndex < 0:
                self.latestProjectIndex = len(
                    self.configurationManager.allProjects) - 1
        self.updateProjectListCurrentItem(self.latestProjectIndex)

    def keyReleaseEvent(self, event):
        if event.key() == Qt.Key_Backtab:
            return
        if event.modifiers() != Qt.ControlModifier:
            if self.latestProjectIndex != -1:
                self.projectComboBox.setCurrentText(
                    self.projectList.currentItem().projectProxy.path)
            self.latestProjectIndex = -1
            self.hideSwitcher()

    def focusOutEvent(self, event):
        super(ProjectSwitcher, self).focusOutEvent(event)
        self.hide()
Example #12
0
class DatasheetView(QMainWindow):

    def __init__(self, pdfPath=None, pageNumber=1):
        
        super().__init__()

        # initialize data files
        # self.fileStore = path.join(path.curdir, "/files")
        # mkdir(self.fileStore)
        self.svgFiles = []


        # window dimensions
        self.top = 300
        self.left = 800
        self.width = 860
        self.height = 980

        self.setGeometry(self.left, self.top, self.width, self.height)
        
        # window title
        self.setWindowTitle("Hello")


        # sets up main layout -- splitters
        self.initUILayout()  
        self.initUIToolbar()

        self.populatePDF(pdfPath, pageNumber)

        self.show()


    def initUILayout(self):

        # set left-side, Dynamic View
        self.dynamicViewDisplay = QLabel()

        self.vBoxA = QVBoxLayout()
        self.vBoxA.addWidget(self.dynamicViewDisplay)
        
        self.groupA = QGroupBox()
        self.groupA.setTitle("Dynamic Veiw")
        self.groupA.setLayout(self.vBoxA)
        
        # set left-side, Static View
        self.staticViewDisplay = QLabel()
        
        self.vBoxB = QVBoxLayout()
        self.vBoxB.addWidget(self.staticViewDisplay)

        self.groupB = QGroupBox()
        self.groupB.setTitle("Static View")
        self.groupB.setLayout(self.vBoxB)


        # add Dynamic and Static Views to resizeable left-side Splitter
        self.altViewSplit = QSplitter(Qt.Vertical)
        self.altViewSplit.addWidget(self.groupA)
        self.altViewSplit.addWidget(self.groupB)
        


        # set up Tools View section
        self.toolsTabView = QTabWidget()
        self.toolsTabView.setTabsClosable(True)
        self.toolsTabView.setMovable(True)
        self.toolsTabView.setDocumentMode(True)

        # self.toolsTabView.setTabBarAutoHide(True)

        # add attribute for storing page notes
        self.notesDB = []
        self.notesDisplay = QListWidget(self)
        self.notesDisplay.setMaximumHeight(200)

        # add ToC to Tools View
        self.ToCListView = QListWidget()
        self.toolsTabView.addTab(self.ToCListView, "Table of Contents")

        # add notes list to tools view
        self.toolsTabView.addTab(self.notesDisplay, "Notes")

        # add tools view to the left-side splitter
        self.altViewSplit.addWidget(self.toolsTabView)




        # set right-side view -- SVG Viewer
        self.mainDisplay = QSvgWidget()

        
        self.vBoxMain = QVBoxLayout()
        self.vBoxMain.addWidget(self.mainDisplay)

        self.notesArea = QLineEdit()
        self.notesArea.setPlaceholderText("Add a note about this page...")
        self.notesArea.returnPressed.connect(self.onAddNote)
        
        self.vBoxMain.addWidget(self.notesArea)

        self.mainViewGroup = QGroupBox()
        self.mainViewGroup.setTitle("Main View")
        self.mainViewGroup.setLayout(self.vBoxMain)


        # join both sides together
        self.leftRightSplit = QSplitter(Qt.Horizontal)
        self.leftRightSplit.addWidget(self.altViewSplit)
        self.leftRightSplit.addWidget(self.mainViewGroup)        


        self.setCentralWidget(self.leftRightSplit)







    def initUIToolbar(self):

        mainMenu = self.menuBar() # get the menu bar already in use by this QMainWindow class
        
        fileMenu = mainMenu.addMenu("File")
        editMenu = mainMenu.addMenu("Edit")
        LayoutMenu = mainMenu.addMenu("Layout")
        AboutMenu = mainMenu.addMenu("About")

        saveAction = fileMenu.addAction("Save")
        quitAction = fileMenu.addAction("Exit Bettersheets")
        quitAction.triggered.connect(self.quitApp)
        copyAction = editMenu.addAction("Copy")
        resetAction = LayoutMenu.addAction("Reset Default Layout")

        # mainMenu.setNativeMenuBar(True)
        # mainMenu.show()

        self. toolBar = self.addToolBar("Tools")
        self.toolBar.addAction(saveAction)
        self.toolBar.addAction(copyAction)
        



    def contextMenuEvent(self, event):
        # return super().contextMenuEvent(event)
        contextMenu = QMenu()
        
        selectAction = contextMenu.addAction("Select Area")
        extractAction = contextMenu.addAction("Extract Content")
        openAction = contextMenu.addAction("Open PDF")
        closeAction = contextMenu.addAction("Close PDF")
        quitAction = contextMenu.addAction("Quit")

        triggered_action = contextMenu.exec_(self.mapToGlobal(event.pos()))

        if triggered_action == quitAction:
            self.quitApp()

    def quitApp(self):
        self.close()


    def onAddNote(self):
        print("note added")

        text = self.notesArea.text()

        if text:
            self.notesDB.append(text)
            self.notesDisplay.clear()
            self.notesDisplay.addItems(self.notesDB)
            self.notesArea.clear()

    def populatePDF(self, pdfPath, pageNumber):

        if pdfPath:
            self.document = PDFContext(pdfPath, pageNumber)
            
            ToC = self.document.getToC()
            ToC_headings_list = [x[1] for x in ToC]
            self.ToCListView.clear()
            self.ToCListView.addItems(ToC_headings_list)

            # display page in main view
            self.document.openPDF(pdfPath, pageNumber)
            self.SVGString = self.document.getRender(self.document.currentPageNumber)

            # set filename of current PDF
            self.pdfName = path.split(pdfPath)[1].split('.')[0]

            # write current page to .svg file
            file_loc = self._writeSVGToFile_(self.pdfName, pageNumber, self.SVGString)

            # open the file we just wrote to
            self.mainDisplay.load(file_loc)
            

    @staticmethod
    def _writeSVGToFile_(pdfName: str, pageNumber: int, svg_string: str) -> str:
        """
        return the full file path we just wrote
        """
        
        file_loc = f"./src/main/files/{pdfName}-page-{pageNumber}.svg"

        with open(file_loc , 'w') as f:  
            f.write(svg_string)

        print("File_loc: ", file_loc)
        return file_loc
Example #13
0
class PersonaUI(QWidget):
    """
    Widget for Persona creation view.

    :param MainFrame mainframe: application mainframe
    :param QWidget op: parent widget
    """
    def __init__(self, mainframe, op):
        QWidget.__init__(self)
        self.mainframe = mainframe
        self.op = op

        self.grid = QGridLayout()
        self.setLayout(self.grid)

        self.listP = None
        self.listLS = None
        self.listEL1 = None
        self.listEL2 = None

        self.nameT = None
        self.levelT = None
        self.textT = None
        self.strT = None
        self.magT = None
        self.endT = None
        self.agiT = None
        self.luckT = None

        self.createFrame = None
        self.buttonFrame = None
        self.bfgrid = None
        # Actual create frame variables.
        self.cfgrid = None
        self.lsdic = None
        self.slashO = None
        self.strikeO = None
        self.pierceO = None
        self.fireO = None
        self.iceO = None
        self.windO = None
        self.elecO = None
        self.darkO = None
        self.lightO = None
        self.arcO = None
        self.iSpellOs = None
        self.lsSpellO = None
        self.lslevel = None


        self.initUI(True)

    def initUI(self, infoDump):
        """
        Initializes the basic UI showing the list of Personas.
        Does a lot of stuff.

        :param dict infoDump: not sure lol
        """
        self.mainframe.setWindowTitle("Persona Creator")

        if not infoDump:
            self.createFrameDraw()

        self.initButtonFrame(infoDump)

        self.listP = QListWidget(self)
        self.grid.addWidget(self.listP, 0, 3, 2, 1)
        temp = json_reader.readPerNames()
        self.listP.addItems(temp)

    def initButtonFrame(self, infoDump):
        """
        Initializes the buttonframes that are present in all Persona creator views.

        :param dict infoDump: not sure lol
        """
        self.buttonFrame = QWidget(self)
        self.bfgrid = QGridLayout()
        self.buttonFrame.setLayout(self.bfgrid)

        self.grid.addWidget(self.buttonFrame, 3, 0, 1, 4)


        new = QPushButton(self.buttonFrame, text="New")
        new.clicked.connect(self.new)
        self.bfgrid.addWidget(new, 4, 0)

        back = QPushButton(self.buttonFrame, text="Back")
        back.clicked.connect(self.back)
        self.bfgrid.addWidget(back, 4, 4)

        remove = QPushButton(self.buttonFrame, text="Remove")
        remove.clicked.connect(self.remove)
        self.bfgrid.addWidget(remove, 4, 3)

        edit = QPushButton(self.buttonFrame, text="Edit")
        edit.clicked.connect(self.edit)
        self.bfgrid.addWidget(edit, 4, 2)

        if not infoDump:
            save = QPushButton(self.buttonFrame, text="Save")
            save.clicked.connect(self.save)
            self.bfgrid.addWidget(save, 4, 1)


    def createFrameDraw(self):
        """
        Initializes the GUI of the actual creation frame view.
        Does a LOT of stuff.
        """
        self.createFrame = QWidget(self)
        self.cfgrid = QGridLayout()
        self.createFrame.setLayout(self.cfgrid)
        self.grid.addWidget(self.createFrame, 0, 0, 2, 2)

        self.lsdic = {}

        nameL = QLabel(self.createFrame, text="Name:")
        self.cfgrid.addWidget(nameL, 0, 0)
        self.nameT = QLineEdit(self.createFrame)
        self.nameT.setFixedSize(100, 20)
        self.cfgrid.addWidget(self.nameT, 0, 1)

        strL = QLabel(self.createFrame, text="Str")
        self.cfgrid.addWidget(strL, 0, 2)
        self.strT = QLineEdit(self.createFrame)
        self.strT.setFixedSize(20, 20)
        self.cfgrid.addWidget(self.strT, 0, 3)
        magL = QLabel(self.createFrame, text="Mag")
        self.cfgrid.addWidget(magL, 1, 2)
        self.magT = QLineEdit(self.createFrame)
        self.magT.setFixedSize(20, 20)
        self.cfgrid.addWidget(self.magT, 1, 3)
        endL = QLabel(self.createFrame, text="End")
        self.cfgrid.addWidget(endL, 2, 2)
        self.endT = QLineEdit(self.createFrame)
        self.endT.setFixedSize(20, 20)
        self.cfgrid.addWidget(self.endT, 2, 3)
        agiL = QLabel(self.createFrame, text="Agi")
        self.cfgrid.addWidget(agiL, 3, 2)
        self.agiT = QLineEdit(self.createFrame)
        self.agiT.setFixedSize(20, 20)
        self.cfgrid.addWidget(self.agiT, 3, 3)
        luckL = QLabel(self.createFrame, text="Luck")
        self.cfgrid.addWidget(luckL, 4, 2)
        self.luckT = QLineEdit(self.createFrame)
        self.luckT.setFixedSize(20, 20)
        self.cfgrid.addWidget(self.luckT, 4, 3)

        resList = json_reader.data_list("resistances")
        resL = QLabel(self.createFrame, text="Resistance:")
        self.cfgrid.addWidget(resL, 0, 5)
        slashL = QLabel(self.createFrame, text="Slash")
        self.cfgrid.addWidget(slashL, 1, 5)
        self.slashO = QComboBox(self.createFrame)
        self.slashO.addItems(resList)
        self.slashO.setCurrentIndex(1)
        self.cfgrid.addWidget(self.slashO, 1, 6)
        strikeL = QLabel(self.createFrame, text="Strike")
        self.cfgrid.addWidget(strikeL, 2, 5)
        self.strikeO = QComboBox(self.createFrame)
        self.strikeO.addItems(resList)
        self.strikeO.setCurrentIndex(1)
        self.cfgrid.addWidget(self.strikeO, 2, 6)
        pierceL = QLabel(self.createFrame, text="Pierce")
        self.cfgrid.addWidget(pierceL, 3, 5)
        self.pierceO = QComboBox(self.createFrame)
        self.pierceO.addItems(resList)
        self.pierceO.setCurrentIndex(1)
        self.cfgrid.addWidget(self.pierceO, 3, 6)
        fireL = QLabel(self.createFrame, text="Fire")
        self.cfgrid.addWidget(fireL, 4, 5)
        self.fireO = QComboBox(self.createFrame)
        self.fireO.addItems(resList)
        self.fireO.setCurrentIndex(1)
        self.cfgrid.addWidget(self.fireO, 4, 6)
        iceL = QLabel(self.createFrame, text="Ice")
        self.cfgrid.addWidget(iceL, 5, 5)
        self.iceO = QComboBox(self.createFrame)
        self.iceO.addItems(resList)
        self.iceO.setCurrentIndex(1)
        self.cfgrid.addWidget(self.iceO, 5, 6)
        elecL = QLabel(self.createFrame, text="Elec")
        self.cfgrid.addWidget(elecL, 6, 5)
        self.elecO = QComboBox(self.createFrame)
        self.elecO.addItems(resList)
        self.elecO.setCurrentIndex(1)
        self.cfgrid.addWidget(self.elecO, 6, 6)
        windL = QLabel(self.createFrame, text="Wind")
        self.cfgrid.addWidget(windL, 7, 5)
        self.windO = QComboBox(self.createFrame)
        self.windO.addItems(resList)
        self.windO.setCurrentIndex(1)
        self.cfgrid.addWidget(self.windO, 7, 6)
        lightL = QLabel(self.createFrame, text="Light")
        self.cfgrid.addWidget(lightL, 8, 5)
        self.lightO = QComboBox(self.createFrame)
        self.lightO.addItems(resList)
        self.lightO.setCurrentIndex(1)
        self.cfgrid.addWidget(self.lightO, 8, 6)
        darkL = QLabel(self.createFrame, text="Dark")
        self.cfgrid.addWidget(darkL, 9, 5)
        self.darkO = QComboBox(self.createFrame)
        self.darkO.addItems(resList)
        self.darkO.setCurrentIndex(1)
        self.cfgrid.addWidget(self.darkO, 9, 6)

        spellList = json_reader.data_list("spells")
        self.listLS = QListWidget(self.createFrame)
        self.listLS.setFixedSize(200, 300)
        self.cfgrid.addWidget(self.listLS, 3, 7, 8, 2)

        newLS = QPushButton(self.createFrame, text="+")
        newLS.clicked.connect(self.addLS)
        self.cfgrid.addWidget(newLS, 2, 7)
        delLS = QPushButton(self.createFrame, text="DEL")
        delLS.clicked.connect(self.delLS)
        self.cfgrid.addWidget(delLS, 2, 8)

        lsl = QLabel(self.createFrame, text="Learned Spells:")
        self.cfgrid.addWidget(lsl, 0, 7, 1, 2)

        arcanaL = QLabel(self.createFrame, text="Arcana:")
        self.cfgrid.addWidget(arcanaL, 1, 0)
        arc_list = json_reader.data_list("arcanas")
        self.arcO = QComboBox(self.createFrame)
        self.arcO.addItems(arc_list)
        self.arcO.setCurrentIndex(0)
        self.cfgrid.addWidget(self.arcO, 1, 1)

        levelL = QLabel(self.createFrame, text="Level:")
        self.cfgrid.addWidget(levelL, 2, 0)
        self.levelT = QLineEdit(self.createFrame)
        self.levelT.setFixedSize(20, 20)
        self.cfgrid.addWidget(self.levelT, 2, 1)

        heritageL = QLabel(self.createFrame, text="Inherits:")
        self.cfgrid.addWidget(heritageL, 3, 0, 1, 2)

        elements = json_reader.data_list("elements")
        elements.append("Support")
        self.listEL1 = QComboBox(self.createFrame)
        self.listEL1.addItems(elements)
        self.cfgrid.addWidget(self.listEL1, 4, 0)
        self.listEL2 = QComboBox(self.createFrame)
        self.listEL2.addItems(elements)
        self.cfgrid.addWidget(self.listEL2, 4, 1)

        iSpellL = QLabel(self.createFrame, text="Initial Spells:")
        self.cfgrid.addWidget(iSpellL, 5, 0, 1, 2)
        self.iSpellOs = []
        for i in range(6, 9):
            temp = QComboBox(self.createFrame)
            temp.addItems(spellList)
            temp2 = QComboBox(self.createFrame)
            temp2.addItems(spellList)
            self.cfgrid.addWidget(temp, i, 0, 1, 2)
            self.cfgrid.addWidget(temp2, i, 2, 1, 2)
            self.iSpellOs.extend([temp, temp2])

        textL = QLabel(self.createFrame, text="Info:")
        self.cfgrid.addWidget(textL, 10, 0)
        self.textT = QTextEdit(self.createFrame)
        self.textT.setFixedSize(300, 100)
        self.cfgrid.addWidget(self.textT, 10, 1, 1, 5)

        self.lslevel = QLineEdit(self.createFrame)
        self.lslevel.setFixedSize(40, 20)
        self.lsSpellO = QComboBox(self.createFrame)
        self.lsSpellO.addItems(spellList)

        self.cfgrid.addWidget(self.lsSpellO, 1, 7)
        self.cfgrid.addWidget(self.lslevel, 1, 8)

    def addLS(self):
        """
        Add a learned spell to the list, based on what was entered.
        """
        print("Adding learned spell")
        chosenSpell = self.lsSpellO.currentText()
        if (int)(self.lslevel.text()) <= (int)(self.levelT.text()):
            popup("You cannot add a spell at an earlier level than the Persona's base level", "Critical")
            return
        if chosenSpell != "":
            print("Ok")
            self.lsdic[chosenSpell] = self.lslevel.text()
            self.listLS.addItem(chosenSpell + " at level " + self.lslevel.text())
            self.lslevel.setText("")
            self.lsSpellO.setCurrentIndex(0)
            return
        popup("You must choose a spell", "Critical")

    def delLS(self):
        """
        Remove the selected learned spell from the list
        """
        print("Deleting learned spell")
        key = ""
        i = 0
        while len(self.listLS.currentItem().text()) > i:
            if self.listLS.currentItem().text()[i] == " " and \
               self.listLS.currentItem().text()[i+1] == "a" and \
               self.listLS.currentItem().text()[i+2] == "t":  # TODO EWWWWWW
                break
            key += self.listLS.currentItem().text()[i]
            i = i + 1
        print(key)
        print(self.lsdic.pop(key))
        self.listLS.takeItem(self.listLS.currentRow())


    def loadPer(self, name):
        """
        Load a certain Persona from file.

        :param str name: name of Persona to load
        """
        data = json_reader.readOne(name, 'pers')
        self.nameT.setText(data["name"])
        self.textT.setText(data["desc"])
        self.strT.setText(data["stats"][0])
        self.magT.setText(data["stats"][1])
        self.endT.setText(data["stats"][2])
        self.agiT.setText(data["stats"][3])
        self.luckT.setText(data["stats"][4])
        self.levelT.setText(data["level"])

        self.arcO.setCurrentIndex(
            [self.arcO.itemText(i) for i in range(self.arcO.count())].index(data["arcana"])
        )

        self.listEL1.setCurrentIndex(
            [self.listEL1.itemText(i) for i in range(self.listEL1.count())].index(data["heritage"][0])
        )
        self.listEL2.setCurrentIndex(
            [self.listEL2.itemText(i) for i in range(self.listEL2.count())].index(data["heritage"][1])
        )

        self.slashO.setCurrentIndex(
            [self.slashO.itemText(i) for i in range(self.slashO.count())].index(data["resistance"][0])
        )
        self.strikeO.setCurrentIndex(
            [self.strikeO.itemText(i) for i in range(self.strikeO.count())].index(data["resistance"][1])
        )
        self.pierceO.setCurrentIndex(
            [self.pierceO.itemText(i) for i in range(self.pierceO.count())].index(data["resistance"][2])
        )
        self.fireO.setCurrentIndex(
            [self.fireO.itemText(i) for i in range(self.fireO.count())].index(data["resistance"][3])
        )
        self.iceO.setCurrentIndex(
            [self.iceO.itemText(i) for i in range(self.iceO.count())].index(data["resistance"][4])
        )
        self.elecO.setCurrentIndex(
            [self.elecO.itemText(i) for i in range(self.elecO.count())].index(data["resistance"][5])
        )
        self.windO.setCurrentIndex(
            [self.windO.itemText(i) for i in range(self.windO.count())].index(data["resistance"][6])
        )
        self.lightO.setCurrentIndex(
            [self.lightO.itemText(i) for i in range(self.lightO.count())].index(data["resistance"][7])
        )
        self.darkO.setCurrentIndex(
            [self.darkO.itemText(i) for i in range(self.darkO.count())].index(data["resistance"][8])
        )

        i = 0
        for combobox in self.iSpellOs:
            combobox.setCurrentIndex(
                [combobox.itemText(j) for j in range(combobox.count()-1)].index(data["spellDeck"][i])
            )
            i += 1

        self.lsdic = data["spellLearn"]
        self.listLS.clear()
        for spell, level in self.lsdic.items():
            self.listLS.addItem(spell + " at level " + level)

        print("Loaded " + data["name"])

    def edit(self):
        """
        Switch to edit view, also loads the selected Persona.
        """
        try:
            if self.listP.currentItem().text() != "":
                if self.createFrame and not popup("Override any unsaved changes?", "Warning"):
                    return
                self.loadPer(self.listP.currentItem().text())
        except AttributeError:  # To initialize createFrame UI before load
            if self.listP.currentItem().text() != "":
                temp = self.listP.currentItem().text()
                self.buttonFrame.close()
                self.initUI(False)
                self.loadPer(temp)
            else:
                return
        self.createFrame.show()
        self.mainframe.center()
        print("Changed to edit frame")

    def save(self):
        """
        Validate all info and save to file on disk.
        """
        if os.path.exists(json_reader.buildPath("data/pers/"+self.nameT.text()+".json")):
            if not popup("Override existing Persona "+self.nameT.text()+"?", "Question"):
                return
        print("Saving")
        spellDeck = []
        for combobox in self.iSpellOs:
            spellDeck.append(combobox.currentText())
        stats = [self.strT.text(), self.magT.text(), self.endT.text(), self.agiT.text(), self.luckT.text()]
        res = [self.slashO.currentText(), self.strikeO.currentText(), self.pierceO.currentText(),
               self.fireO.currentText(), self.iceO.currentText(), self.elecO.currentText(),
               self.windO.currentText(), self.lightO.currentText(), self.darkO.currentText()]
        try:
            (int)(self.levelT.text())
            (int)(self.strT.text())
            (int)(self.magT.text())
            (int)(self.endT.text())
            (int)(self.agiT.text())
            (int)(self.luckT.text())
        except ValueError:
            popup("There is a number entry that isn't valid.\nEntries requiring numbers are:\nLEVEL\nSTR"
                  "\nMAG\nEND\nAGI\nLUCK", "Critical")
            print("Not Saved")
            return
        if not (self.nameT.text() and not self.nameT.text().isspace()):
            popup("No name entered for your Persona. Name is a required field.", "Critical")
            print("No Name, not saved")
            return
        toWrite = Persona(
            self.nameT.text(),
            self.arcO.currentText(),
            self.levelT.text(),
            self.textT.toPlainText(),
            spellDeck,
            self.lsdic,
            stats,
            res,
            [self.listEL1.currentText(), self.listEL2.currentText()]
        )
        json_reader.writeOne(toWrite, 'pers')
        temp = self.nameT.text()
        if (temp not in [self.listP.item(i).text() for i in range(self.listP.count())]):
            self.listP.addItem(temp)
        self.loadPer(temp)
        print("Saved Persona")

    def remove(self):
        """
        Remove a created Persona from the list and delete the file on disk.
        """
        if self.listP.currentItem().text() == "":
            return
        if not popup(
                "Are you certain you want to completely remove this Persona?\n(Cannot be undone)", "Warning"
            ):
            return
        print("Removing Persona " + self.listP.currentItem().text())
        json_reader.deletePer(self.listP.currentItem().text())
        self.listP.takeItem(
            [self.listP.item(i).text() for i in range(self.listP.count())].index(
                self.listP.currentItem().text())
        )

    def new(self):
        """
        Open an empty Persona edit view.
        """
        if self.createFrame and not popup("Override any unsaved changes?", "Warning"):
            return
        if self.createFrame:
            self.createFrame.close()
        self.buttonFrame.close()
        self.initUI(False)
        self.createFrame.show()
        self.mainframe.center()
        print("Created")

    def back(self):
        """
        Return to the parent widget.
        """
        print("Returned to main screen")
        self.mainframe.changeState(self.op)
Example #14
0
class BrowserWin(QWidget):
    def __init__(self, *args, **kwargs):

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

        # parent Maya window
        self.setParent(mainWindow)
        self.setWindowFlags(Qt.Window)
        # Window settings
        self.setWindowTitle('AC_AssetBrowser')

        # Build window
        self.mainLayout = QVBoxLayout()
        self.btnLayout = QHBoxLayout()
        self.radioLayout = QHBoxLayout()

        # radio buttons load import
        self.radioLabel = QLabel("Action: ")
        self.importRadioBtn = QRadioButton("Import File")
        self.openRadioBtn = QRadioButton("Open File")
        self.saveRadioBtn = QRadioButton("Save File")

        # Find asset directories to load from and populate the drop down
        self.fileType = QComboBox()
        self.__populate_list(self.fileType)
        self.curr_cat = self.fileType.currentText()

        # list of assets in self.list
        self.fileList = QListWidget()
        self.fileList.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.__populate_list(self.fileList,
                             directory=os.path.join(DIRECTORY, self.curr_cat))

        self.fileName = QLineEdit()

        self.loadBtn = QPushButton("Load Asset")
        self.publishBtn = QPushButton("Publish")
        self.closeBtn = QPushButton("Close")

        # Add widgets to layouts
        self.radioLayout.addWidget(self.radioLabel)
        self.radioLayout.addWidget(self.importRadioBtn)
        self.radioLayout.addWidget(self.openRadioBtn)
        self.radioLayout.addWidget(self.saveRadioBtn)

        self.mainLayout.addLayout(self.radioLayout)

        self.mainLayout.addWidget(self.fileType)
        self.mainLayout.addWidget(self.fileList)
        self.mainLayout.addWidget(self.fileName)

        self.btnLayout.addWidget(self.loadBtn)
        self.btnLayout.addWidget(self.publishBtn)
        self.btnLayout.addWidget(self.closeBtn)

        self.mainLayout.addLayout(self.btnLayout)
        self.setLayout(self.mainLayout)

        # Set state of widgets
        self.importRadioBtn.toggle()
        self.fileName.setPlaceholderText("file_name")
        self.fileName.setEnabled(False)
        self.publishBtn.setEnabled(False)

        # Signals
        self.fileType.currentIndexChanged.connect(self.selectionChanged)
        self.loadBtn.clicked.connect(self.loadBtnCmd)
        self.publishBtn.clicked.connect(self.publishBtnCmd)
        self.closeBtn.clicked.connect(self.closeBtnCmd)
        self.importRadioBtn.toggled.connect(self.onImportToggled)
        self.openRadioBtn.toggled.connect(self.onOpenToggled)
        self.saveRadioBtn.toggled.connect(self.onSaveToggled)

    def __populate_list(self, destination, directory=DIRECTORY):
        _dirs = os.listdir(directory)
        _items = [_dir for _dir in _dirs]

        return destination.addItems(_items)

    def selectionChanged(self):
        self.curr_cat = self.fileType.currentText()
        self.fileList.clear()
        self.__populate_list(self.fileList,
                             directory=os.path.join(DIRECTORY, self.curr_cat))

    def loadBtnCmd(self):
        if self.importRadioBtn.isChecked():
            selected_files = self.fileList.selectedItems()
            for _file in selected_files:
                asset_file = os.path.join(DIRECTORY, self.curr_cat,
                                          _file.text())
                cmds.file(asset_file, i=True)
        elif self.openRadioBtn.isChecked():
            selected_file = self.fileList.currentItem()
            asset_file = os.path.join(DIRECTORY, self.curr_cat,
                                      selected_file.text())
            cmds.file(asset_file, o=True, force=True)
        else:
            print("Did you mean to publish this asset?")

    def publishBtnCmd(self):
        if self.saveRadioBtn.isChecked() and self.fileName.text() is not None:
            path_to_save = os.path.join(DIRECTORY, self.curr_cat,
                                        self.fileName.text())
            cmds.file(rn="{}.ma".format(path_to_save))
            cmds.file(save=True)
            self.fileList.clear()
            self.__populate_list(self.fileList,
                                 directory=os.path.join(
                                     DIRECTORY, self.curr_cat))

    def closeBtnCmd(self):
        self.close()

    def onSaveToggled(self):
        items = self.fileList.selectedItems()
        for item in items:
            item.setSelected(False)
        self.fileName.setEnabled(not self.fileName.isEnabled())
        self.publishBtn.setEnabled(not self.publishBtn.isEnabled())

    def onImportToggled(self):
        if self.importRadioBtn.isChecked():
            self.fileList.setSelectionMode(QAbstractItemView.ExtendedSelection)

    def onOpenToggled(self):
        if self.openRadioBtn.isChecked():
            items = self.fileList.selectedItems()
            items.pop()
            for item in items:
                item.setSelected(False)
            self.fileList.setSelectionMode(QAbstractItemView.SingleSelection)
Example #15
0
class SelectPackages_Dialog(QDialog):
    def __init__(self, parent, packages):
        super(SelectPackages_Dialog, self).__init__(parent)

        self.file_paths = []
        self.required_packages = packages

        self.setLayout(QVBoxLayout())

        self.layout().addWidget(QLabel('You need to select the locations of the following required node packages'))

        # package lists
        required_packages_list_widget = QListWidget()
        for p in packages:
            package_item = QListWidgetItem()
            package_item.setText(p)
            required_packages_list_widget.addItem(package_item)
        
        
        selected_items_widget = QWidget()
        selected_items_widget.setLayout(QVBoxLayout())
        self.selected_packages_list_widget = QListWidget()
        selected_items_widget.layout().addWidget(self.selected_packages_list_widget)

        auto_import_button = QPushButton('auto import')
        auto_import_button.clicked.connect(self.auto_import_button_clicked)
        selected_items_widget.layout().addWidget(auto_import_button)

        add_package_button = QPushButton('add')
        add_package_button.clicked.connect(self.add_package_button_clicked)
        selected_items_widget.layout().addWidget(add_package_button)

        clear_package_list_button = QPushButton('clear')
        clear_package_list_button.clicked.connect(self.clear_selected_packages_list)
        selected_items_widget.layout().addWidget(clear_package_list_button)

        finished_button = QPushButton('OK')
        finished_button.clicked.connect(self.finished_button_clicked)
        selected_items_widget.layout().addWidget(finished_button)

        packages_lists_widget = QWidget()
        packages_lists_widget.setLayout(QHBoxLayout())
        packages_lists_widget.layout().addWidget(required_packages_list_widget)
        packages_lists_widget.layout().addWidget(selected_items_widget)

        self.layout().addWidget(packages_lists_widget)

        self.setWindowTitle('select required packages')
        


    def auto_import_button_clicked(self):
        packages_dir = '../packages'
        folders_list = [x[0] for x in os.walk(packages_dir)]
        required_files = self.required_packages.copy()

        for folder in folders_list:
            for r_f in required_files:
                if r_f+'.pypac' in os.listdir(packages_dir+'/'+folder):
                    self.file_paths.append(packages_dir+'/'+folder+'/'+r_f+'.pypac')
                    break
            self.rebuild_selected_packages_list_widget()

        if len(self.file_paths) == len(self.required_packages):
            self.finished()


    def add_package_button_clicked(self):
        file_names = QFileDialog.getOpenFileNames(self, 'select package files', '../packages', 'PyScript Package(*.pypac)')[0]
        
        for file_name in file_names:
            try:
                f = open(file_name)
                f.close()
                self.file_paths.append(file_name)
            except FileNotFoundError:
                GlobalStorage.debug('couldn\'t open file')
        
        self.rebuild_selected_packages_list_widget()
    
    
    def rebuild_selected_packages_list_widget(self):
        # remove all items
        self.selected_packages_list_widget.clear()

        for f in self.file_paths:
            file_item = QListWidgetItem()
            file_item.setText(f)
            self.selected_packages_list_widget.addItem(file_item)


    def clear_selected_packages_list(self):
        self.file_paths.clear()
        self.rebuild_selected_packages_list_widget()


    def finished_button_clicked(self):
        # TODO analyse for potentially wrong packages

        self.finished()


    def finished(self):
        self.accept()
class Order(QWidget):
    def __init__(self):
        super(Order, self).__init__()
        self.game_on = False
        self.required_bosses = [
            'Asylum Demon', 'Bell Gargoyle', 'Quelaag', 'Iron Golem',
            'ornstein & smough', 'Ceaseless Discharge', 'Sif', '4 Kings',
            'Bed Of Chaos', 'Seath', 'Pinwheel', 'Nito', 'Gwyn'
        ]
        self.order_list = QListWidget()
        self.order_list.setDragDropMode(QAbstractItemView.InternalMove)
        self.capra_box = QCheckBox("Capra Demon")
        self.capra_box.toggled.connect(
            lambda: self.add_to_list(self.capra_box))
        self.centipede_box = QCheckBox("Centipede Demon")
        self.centipede_box.toggled.connect(
            lambda: self.add_to_list(self.centipede_box))
        self.priscilla_box = QCheckBox("Priscilla")
        self.priscilla_box.toggled.connect(
            lambda: self.add_to_list(self.priscilla_box))
        self.gwyndolin_box = QCheckBox("Gwyndolin")
        self.gwyndolin_box.toggled.connect(
            lambda: self.add_to_list(self.gwyndolin_box))
        self.firesage_box = QCheckBox("Demon Firesage")
        self.firesage_box.toggled.connect(
            lambda: self.add_to_list(self.firesage_box))
        self.gaping_box = QCheckBox("Gaping Dragon")
        self.gaping_box.toggled.connect(
            lambda: self.add_to_list(self.gaping_box))
        self.butterfly_box = QCheckBox("Moonlight Butterfly")
        self.butterfly_box.toggled.connect(
            lambda: self.add_to_list(self.butterfly_box))

        self.start_button = QPushButton("Start New Game")
        self.start_button.clicked.connect(self.start_game)
        self.selected_bosses = []
        for i in self.required_bosses:
            self.order_list.addItem(i)
            self.selected_bosses.append(i)
        self.layout = QGridLayout()
        self.layout.addWidget(self.capra_box, 0, 0)
        self.layout.addWidget(self.centipede_box, 0, 1)
        self.layout.addWidget(self.priscilla_box, 1, 0)
        self.layout.addWidget(self.gwyndolin_box, 1, 1)
        self.layout.addWidget(self.firesage_box, 2, 0)
        self.layout.addWidget(self.gaping_box, 2, 1)
        self.layout.addWidget(self.butterfly_box, 3, 0)
        self.layout.addWidget(self.order_list, 4, 0, 1, 2)
        self.setLayout(self.layout)

    def start_game(self):
        self.game_on = True

    def add_to_list(self, item):
        if item.checkState():
            self.order_list.addItem(item.text())
            self.selected_bosses.append(item.text())
        else:
            self.order_list.clear()
            del self.selected_bosses[self.selected_bosses.index(item.text())]
            for i in self.selected_bosses:
                self.order_list.addItem(i)
Example #17
0
class MyWindow(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.setWindowTitle(
            'Graphical utility for destroying, zeroing, and deleting files')

        self.label_donate = QLabel(
            'Copyright (c) 2021, Aleksandr Suvorov | Donate: 4048 0250 0089 5923'
        )
        self.label_donate.setAlignment(Qt.AlignCenter)

        self.label_logo = QLabel(f'Smart Cleaner<sup> {VERSION}</sup>')
        self.label_logo.setAlignment(Qt.AlignCenter)
        self.label_logo.setStyleSheet('font-size: 48px;')

        self.label_files = QLabel('Files')
        self.label_files.setStyleSheet("color: rgb(84, 180, 40);")

        self.label_dirs = QLabel('Folders')
        self.label_dirs.setStyleSheet("color: rgb(177, 98, 42);")

        self.label_errors = QLabel('Errors')
        self.label_errors.setStyleSheet("color: rgb(255, 68, 44);")

        self.lcd_files = QLCDNumber()
        self.lcd_files.setSegmentStyle(QLCDNumber.Flat)
        self.lcd_files.setStyleSheet("color: rgb(84, 180, 40);")
        self.lcd_dirs = QLCDNumber()
        self.lcd_dirs.setSegmentStyle(QLCDNumber.Flat)
        self.lcd_dirs.setStyleSheet("color: rgb(177, 98, 42);")
        self.lcd_errors = QLCDNumber()
        self.lcd_errors.setSegmentStyle(QLCDNumber.Flat)
        self.lcd_errors.setMinimumHeight(30)
        self.lcd_errors.setStyleSheet("color: rgb(255, 68, 44);")
        self.lcd_files.setDigitCount(15)
        self.lcd_dirs.setDigitCount(15)
        self.lcd_errors.setDigitCount(15)

        self.h_box1 = QHBoxLayout()
        self.h_box1.addWidget(self.label_dirs)
        self.h_box1.addWidget(self.label_files)
        self.h_box1.addWidget(self.label_errors)

        self.h_box2 = QHBoxLayout()
        self.h_box2.addWidget(self.lcd_dirs)
        self.h_box2.addWidget(self.lcd_files)
        self.h_box2.addWidget(self.lcd_errors)

        self.label_cons = QLabel('Information console:')

        self.text_browser = QTextBrowser()
        self.text_browser.setText(
            f'Smart Cleaner v{VERSION} \nUtility for overwriting, zeroing, and deleting files\n'
            f'https://github.com/mysmarthub')

        self.btn_console_clear = QPushButton('Reset')
        self.btn_donate = QPushButton('Donate | Visa: 4048 0250 0089 5923')
        self.btn_donate.setToolTip(
            'We will be grateful for any financial support.\nThis will help the program '
            'develop and remain free.\nThanks!')
        self.btn_exit = QPushButton('Exit')

        self.h_box3 = QHBoxLayout()
        self.h_box3.addWidget(self.btn_donate)
        self.h_box3.addStretch(1)
        self.h_box3.addWidget(self.btn_console_clear)

        self.chb_del_dirs = QCheckBox('Delete folders')
        self.chb_del_dirs.setChecked(True)

        self.label_shred = QLabel('Rewrite:')

        self.spin_box = QSpinBox()
        self.spin_box.setMinimum(1)
        self.spin_box.setMaximum(1000)
        self.spin_box.setValue(30)

        self.h_box4 = QHBoxLayout()
        self.h_box4.addWidget(self.chb_del_dirs)
        self.h_box4.addWidget(self.label_shred)
        self.h_box4.addWidget(self.spin_box)
        self.h_box4.addStretch(1)

        self.list_widget = QListWidget()
        self.list_widget.setSelectionMode(QAbstractItemView.ExtendedSelection)

        self.btn_add_folder = QPushButton('+ Folder')
        self.btn_add_files = QPushButton('+ Files')
        self.btn_remove_item = QPushButton('- Remove')
        self.btn_zero_files = QPushButton('Zeroing')
        self.btn_shred_files = QPushButton('Erasing')
        self.btn_del_files = QPushButton('Delete')

        self.h_box5 = QHBoxLayout()
        self.h_box5.addWidget(self.btn_add_folder)
        self.h_box5.addWidget(self.btn_add_files)
        self.h_box5.addWidget(self.btn_remove_item)
        self.h_box5.addStretch(1)
        self.h_box5.addWidget(self.btn_shred_files)
        self.h_box5.addWidget(self.btn_zero_files)
        self.h_box5.addWidget(self.btn_del_files)
        self.h_box5.addWidget(self.btn_exit)

        self.v_box = QVBoxLayout()
        self.v_box.addWidget(self.label_logo)
        self.v_box.addLayout(self.h_box1)
        self.v_box.addLayout(self.h_box2)
        self.v_box.addWidget(self.label_cons)
        self.v_box.addWidget(self.text_browser)
        self.v_box.addLayout(self.h_box3)
        self.v_box.addLayout(self.h_box4)
        self.v_box.addWidget(self.list_widget)
        self.v_box.addLayout(self.h_box5)
        self.v_box.addWidget(self.label_donate)

        self.setLayout(self.v_box)

        self.smart_cleaner = SmartCleaner()

        self.btn_donate.clicked.connect(
            lambda: webbrowser.open('https://yoomoney.ru/to/4100115206129186'))
        self.btn_console_clear.clicked.connect(self.clear_console)
        self.btn_add_folder.clicked.connect(self.add_dir)
        self.btn_add_files.clicked.connect(self.add_files)
        self.btn_remove_item.clicked.connect(self.remove_items)
        self.btn_shred_files.clicked.connect(self.shred_start)
        self.btn_zero_files.clicked.connect(self.zeroing_start)
        self.btn_del_files.clicked.connect(self.delete_start)
        self.btn_exit.clicked.connect(self.close)
        self.smart_cleaner.signal.connect(self.update_information)
        self.smart_cleaner.started.connect(self.at_start)
        self.smart_cleaner.finished.connect(self.at_finish)

    def clear_console(self):
        self.lcd_dirs.display(0)
        self.lcd_files.display(0)
        self.lcd_errors.display(0)
        self.text_browser.setText(
            f'Smart Cleaner v{VERSION} \nUtility for overwriting, zeroing, and deleting files\n'
            f'https://github.com/mysmarthub')

    def add_dir(self) -> None:
        path = QFileDialog.getExistingDirectory(self,
                                                'Select the folder to add: ')
        self._add_path(path)

    def add_files(self) -> None:
        path_tuple = QFileDialog.getOpenFileNames(self,
                                                  'Select files to add: ')
        for path in path_tuple[0]:
            self._add_path(path)

    def add_item(self, item: str) -> None:
        self.list_widget.addItem(item)

    def remove_items(self) -> None:
        for SelectedItem in self.list_widget.selectedItems():
            self.list_widget.takeItem(self.list_widget.row(SelectedItem))
            self.smart_cleaner.path_data.del_path(SelectedItem.text())
            self.text_browser.append(
                f'{SelectedItem.text()}\nThe path was successfully deleted!!!')

    def _add_path(self, path: str) -> None:
        if path:
            if self.smart_cleaner.path_data.add_path(path):
                self.add_item(path)
                self.text_browser.append(
                    f'{path}\nThe path was added successfully!')
            else:
                self.text_browser.append(
                    f'Error when adding or the path was added earlier!!!')

    def shred_start(self):
        self.start(method='shred')

    def zeroing_start(self):
        self.start(method='zero')

    def delete_start(self):
        self.start(method='del')

    def start(self, method='shred'):
        if not self.smart_cleaner.path_data.is_any_data:
            self.show_msg('Warning!', 'There is no data for mashing!!!')
        else:
            reply = QMessageBox.question(
                self, 'Warning!', 'The data will be destroyed, are you sure?',
                QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
            if reply == QMessageBox.Yes:
                if method == 'zero':
                    self.text_browser.append('Files are reset to zero.')
                elif method == 'shred':
                    self.text_browser.append('File mashing is started.')
                elif method == 'del':
                    self.text_browser.append('File deletion started.')
                self.smart_cleaner.work_method = method
                self.smart_cleaner.shreds = self.spin_box.value()
                self.smart_cleaner.delete_a_folder = self.chb_del_dirs.isChecked(
                )
                self.smart_cleaner.start()

    def update_information(self, s: str) -> None:
        self.text_browser.append(s)
        self.update_lcd()

    def update_lcd(self) -> None:
        self.lcd_dirs.display(str(self.smart_cleaner.cleaner.count_del_dirs))
        self.lcd_files.display(str(self.smart_cleaner.cleaner.count_del_files))
        self.lcd_errors.display(str(self.smart_cleaner.num_errors))

    def at_start(self):
        self.from_disable(True)

    def at_finish(self) -> None:
        if self.smart_cleaner.work_method != 'zero':
            self.list_widget.clear()
        self.update_lcd()
        self.from_disable(False)
        self.finish_msg()

    def finish_msg(self) -> None:
        if self.smart_cleaner.work_method == 'zero':
            msg = ('Reset', 'Reset files: ')
            count = self.smart_cleaner.cleaner.count_zero_files
        elif self.smart_cleaner.work_method == 'shred':
            msg = ('Mashing', 'Passageways: ')
            count = self.smart_cleaner.cleaner.count_del_files
        else:
            msg = ('Delete', 'Deleted files: ')
            count = self.smart_cleaner.cleaner.count_del_files
        self.show_msg(
            'Warning!', f'{msg[0]} completed successfully!!!\n'
            f' {msg[1]} {count}\n '
            f'Deleted folders: {self.smart_cleaner.cleaner.count_del_dirs}\n '
            f'Errors: {self.smart_cleaner.num_errors}')

    def from_disable(self, status: bool) -> None:
        self.btn_zero_files.setDisabled(status)
        self.btn_remove_item.setDisabled(status)
        self.btn_add_folder.setDisabled(status)
        self.btn_shred_files.setDisabled(status)
        self.btn_console_clear.setDisabled(status)
        self.btn_add_files.setDisabled(status)
        self.btn_del_files.setDisabled(status)
        self.chb_del_dirs.setDisabled(status)
        self.spin_box.setDisabled(status)
        self.list_widget.setDisabled(status)

    def show_msg(self,
                 title: str = 'Warning!',
                 msg: str = 'Message...') -> None:
        QMessageBox.about(self, title, msg)

    def closeEvent(self, event) -> None:
        reply = QMessageBox.question(
            self, 'Exit', 'Are you sure you want to terminate the program?',
            QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
        if reply == QMessageBox.Yes:
            self.hide()
            self.smart_cleaner.wait(3000)
            event.accept()
        else:
            event.ignore()
Example #18
0
class MatchStatWindow(QDialog):
    def __init__(self, parent=None):
        super(MatchStatWindow, self).__init__(parent)
        self.setModal(True)
        self.setWindowTitle("Mérkőzés választása")
        self.resize(740, 600)
        self.layout = QVBoxLayout()
        self.setLayout(self.layout)

        self.merkozesek = QListWidget()
        self.merkozesek.setFixedHeight(200)
        self.merkozesek.setFixedWidth(730)
        self.merkozesek.itemDoubleClicked.connect(self.stat_game)
        self.layout.addWidget(self.merkozesek)
        self.szumma = MatchSumWidget(self)
        self.layout.addWidget(self.szumma)
        self.history = QWidget()
        self.history.setFixedWidth(690)
        self.history_layout = QGridLayout()
        self.history.setLayout(self.history_layout)
        scroll = QScrollArea()
        scroll.setWidget(self.history)
        scroll.setWidgetResizable(True)
        self.layout.addWidget(scroll)

        self.match_valasztas()

    def match_valasztas(self):
        matches = QSqlRelationalTableModel(db=db)
        matches.setTable("match_settings")
        matches.setSort(8, Qt.DescendingOrder)
        matches.select()
        self.merkozesek.clear()
        for i in  range(matches.rowCount()):
            self.merkozesek.addItem(str(matches.record(i).value(1)) + "\t" +
                                    str(matches.record(i).value(2)) + "\t" +
                                    str(int(matches.record(i).value(3)) + matches.record(i).value(6)) + "\t" +
                                    str(int(matches.record(i).value(3)) + matches.record(i).value(7)) + "\t" +
                                    str(matches.record(i).value(4)) + "\t" +
                                    str(matches.record(i).value(5)) + "\t" +
                                    str(matches.record(i).value(8))[:16] + "\t" +
                                    str(matches.record(i).value(0))
            )

    def stat_game(self):
        # Az átvett adatok:
        para = self.merkozesek.currentItem().text().rsplit("\t")
        # Összegyűjtjük egy listába a szükséges infókat
        self.get_adatok(para)
        self.szumma.change_data(self.adatok)
        for x in reversed(range(self.history_layout.count())):
            self.history_layout.itemAt(x).widget().deleteLater()
        # kiszedjük az adott meccs összes set és leg esetére a dobásokat
        sor = 0
        for s in range(1, self.adatok[8] + 1):
            # s: a set-ek száma
            if self.adatok[8] != 1:
                self.history_layout.addWidget(QLabel("Set: " + str(s)), sor, 0, 1, 2)
                sor += 1
            for l in range(1, self.adatok[7][s-1] + 1):
                sl1_model = QSqlQueryModel()
                p1_data_list = []
                p1_data_list.append(self.adatok[4])   # start_score1
                sl1_query = QSqlQuery(f"select * from dobas where match_id ={self.adatok[6]} and set_id={s} and leg_id={l} and player_id='{self.adatok[0]}'", db=db)
                sl1_model.setQuery(sl1_query)
                for i in range(sl1_model.rowCount()):
                    # Itt a model már tartalmazza a p1 összes dobását az adott leg-ben.
                    p1_data_row = []
                    p1_data_row.append(sl1_model.record(i).value(1))
                    p1_data_row.append(sl1_model.record(i).value(2))
                    p1_data_list.append(p1_data_row)
                self.history_layout.addWidget(PlayerLegWidget(self, p1_data_list), sor, 0, Qt.AlignTop)

                sl2_model = QSqlQueryModel()
                p2_data_list = []
                p2_data_list.append(self.adatok[5])  # start_score2
                sl2_query = QSqlQuery(f"select * from dobas where match_id ={self.adatok[6]} and set_id={s} and leg_id={l} and player_id='{self.adatok[2]}'", db=db)
                sl2_model.setQuery(sl2_query)
                for j in range(sl2_model.rowCount()):
                    p2_data_row = []
                    p2_data_row.append(sl2_model.record(j).value(1))
                    p2_data_row.append(sl2_model.record(j).value(2))
                    p2_data_list.append(p2_data_row)
                self.history_layout.addWidget(PlayerLegWidget(self, p2_data_list), sor, 1, Qt.AlignTop)
                sor += 1

    def get_adatok(self, para):
        print(para)
        # self.adatok[0]  : p1_id
        # self.adatok[1]  : name1
        # self.adatok[2]  : p2_id
        # self.adatok[3]  : name2
        # self.adatok[4]  : start_score1
        # self.adatok[5]  : start_score2
        # self.adatok[6]  : match
        # self.adatok[7]  : legs
        # self.adatok[8]  : sets
        # self.adatok[9]  : dátum

        self.adatok = []
        name1_id = int(para[0])
        self.adatok.append(name1_id)
        query_name1 = QSqlQuery(f"select player_name from players where player_id={name1_id}", db=db)
        query_name1.exec_()
        while query_name1.next():
            name1 = query_name1.value(0)
        self.adatok.append(name1)
        name2_id = int(para[1])
        self.adatok.append(name2_id)
        query_name2 = QSqlQuery(f"select player_name from players where player_id={name2_id}", db=db)
        query_name2.exec_()
        while query_name2.next():
            name2 = query_name2.value(0)
        self.adatok.append(name2)

        start_score1 = int(para[2])
        start_score2 = int(para[3])
        match = int(para[7])
        setek = int(para[5])
        self.adatok.append(start_score1)
        self.adatok.append(start_score2)
        self.adatok.append(match)
        # Kell a max set-number, ezt beállítani a sets változóba
        # Ciklussal minden set-ben megnézni a max leg-numbert, és ezeket append-elni a legs[]-hez
        # Végül leg, set sorrendben append-elni az adatokhoz
        legs = []
        sets = 0
        query2 = QSqlQuery(
            f"select max(set_id) as max_set from matches where match_id={match}", db=db)
        query2.exec_()
        while query2.next():
            sets = int(query2.value(0))

        for i in range(1, sets + 1):
            query = QSqlQuery(f"select max(leg_id) as max_leg from matches where match_id={match} and set_id={i}", db=db)
            query.exec_()
            while query.next():
                legs.append(int(query.value(0)))
                # sets.append(int(query.value(1)))

        self.adatok.append(legs)
        self.adatok.append(sets)

        datum = para[6][:16]
        self.adatok.append(datum)
        print(self.adatok)
Example #19
0
class LevelSelector(QDialog):
    def __init__(self, parent):
        super(LevelSelector, self).__init__(parent)

        self.setWindowTitle("Level Selector")
        self.setModal(True)

        self.selected_world = 1
        self.selected_level = 1
        self.object_set = 0
        self.object_data_offset = 0x0
        self.enemy_data_offset = 0x0

        self.world_label = QLabel(parent=self, text="World")
        self.world_list = QListWidget(parent=self)
        self.world_list.addItems(WORLD_ITEMS)

        self.world_list.itemDoubleClicked.connect(self.on_ok)
        self.world_list.itemSelectionChanged.connect(self.on_world_click)

        self.level_label = QLabel(parent=self, text="Level")
        self.level_list = QListWidget(parent=self)

        self.level_list.itemDoubleClicked.connect(self.on_ok)
        self.level_list.itemSelectionChanged.connect(self.on_level_click)

        self.enemy_data_label = QLabel(parent=self, text="Enemy Data")
        self.enemy_data_spinner = Spinner(parent=self)

        self.object_data_label = QLabel(parent=self, text="Object Data")
        self.object_data_spinner = Spinner(self)

        self.object_set_label = QLabel(parent=self, text="Object Set")
        self.object_set_dropdown = QComboBox(self)
        self.object_set_dropdown.addItems(OBJECT_SET_ITEMS)

        self.button_ok = QPushButton("Ok", self)
        self.button_ok.clicked.connect(self.on_ok)
        self.button_cancel = QPushButton("Cancel", self)
        self.button_cancel.clicked.connect(self.close)

        self.window_layout = QGridLayout(self)

        self.window_layout.addWidget(self.world_label, 0, 0)
        self.window_layout.addWidget(self.level_label, 0, 1)

        self.window_layout.addWidget(self.world_list, 1, 0)
        self.window_layout.addWidget(self.level_list, 1, 1)

        self.window_layout.addWidget(self.enemy_data_label, 2, 0)
        self.window_layout.addWidget(self.object_data_label, 2, 1)
        self.window_layout.addWidget(self.enemy_data_spinner, 3, 0)
        self.window_layout.addWidget(self.object_data_spinner, 3, 1)

        self.window_layout.addWidget(self.object_set_label, 4, 0)
        self.window_layout.addWidget(self.object_set_dropdown, 4, 1)

        self.window_layout.addWidget(self.button_ok, 5, 0)
        self.window_layout.addWidget(self.button_cancel, 5, 1)

        self.setLayout(self.window_layout)

        self.world_list.setCurrentRow(1)  # select Level 1-1
        self.on_world_click()

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

    def on_world_click(self):
        index = self.world_list.currentRow()

        assert index >= 0

        self.level_list.clear()

        # skip first meaningless item
        for level in Level.offsets[1:]:
            if level.game_world == index:
                if level.name:
                    self.level_list.addItem(level.name)

        if self.level_list.count():
            self.level_list.setCurrentRow(0)

            self.on_level_click()

    def on_level_click(self):
        index = self.level_list.currentRow()

        assert index >= 0

        self.selected_world = self.world_list.currentRow()
        self.selected_level = index + 1

        level_is_overworld = self.selected_world == OVERWORLD_MAPS_INDEX

        if level_is_overworld:
            level_array_offset = self.selected_level
        else:
            level_array_offset = Level.world_indexes[self.selected_world] + self.selected_level

        object_data_for_lvl = Level.offsets[level_array_offset].rom_level_offset

        if not level_is_overworld:
            object_data_for_lvl -= Level.HEADER_LENGTH

        self.object_data_spinner.setValue(object_data_for_lvl)

        if not level_is_overworld:
            enemy_data_for_lvl = Level.offsets[level_array_offset].enemy_offset
        else:
            enemy_data_for_lvl = 0

        if enemy_data_for_lvl > 0:
            # data in look up table is off by one, since workshop ignores the first byte
            enemy_data_for_lvl -= 1

        self.enemy_data_spinner.setValue(enemy_data_for_lvl)
        self.enemy_data_spinner.setEnabled(not level_is_overworld)

        # if self.selected_world >= WORLD_1_INDEX:
        object_set_index = Level.offsets[level_array_offset].real_obj_set
        self.object_set_dropdown.setCurrentIndex(object_set_index)

        self.button_ok.setDisabled(self.selected_world == 0)

    def on_ok(self, _):
        if self.selected_world == 0:
            return

        self.object_set = self.object_set_dropdown.currentIndex()
        self.object_data_offset = self.object_data_spinner.value()
        # skip the first byte, because it seems useless
        self.enemy_data_offset = self.enemy_data_spinner.value() + 1

        self.accept()

    def closeEvent(self, _close_event: QCloseEvent):
        self.reject()
Example #20
0
class TimerWindow(QWidget):

    elapsed_time = 0
    thread_running = False
    #api_token = 'fea20970f5bb1b75c96dfa8985fd15b2a3c0f8a8d3261381d0176a05475781ee88d9f7252511e5e085b99e1cee37efa86f7364b7ed5203bccd2c2fd9b76057fe'
    apa = IdleTime()
    workingthread = None
    systray = None
    db = Database()
    api_token = db.readDatabase()['userdata']['api_token']

    def __init__(self):
        super().__init__()
        self.title = 'Timey'
        self.left = 10
        self.top = 10
        self.width = 440
        self.height = 680
        self.initUI()
        self.NetworkSetup()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setWindowIcon(QIcon(Config.icon))
        self.setGeometry(self.left, self.top, self.width, self.height)

        layout = QGridLayout()
        self.setLayout(layout)
        layout.setColumnStretch(1, 4)
        layout.setColumnStretch(2, 4)

        style = """
            background-color: white;
            border-bottom: 1px solid #fff123;
            """

        self.setStyleSheet(style)
        self.labeltimer = QLabel('00:00:00', self)
        self.labeltimer.setAlignment(Qt.AlignCenter)
        self.labeltimer.setStyleSheet("""QLabel {
    font: medium Ubuntu;
    font-size: 32px;
    color: #006325;
    border-width:1px;
} """)

        fa5_icon = qta.icon('fa5s.play')
        #fa5_button = QtGui.QPushButton(fa5_icon, 'Font Awesome! (regular)')
        self.button = QPushButton(fa5_icon, "Start")
        self.button.clicked.connect(self.clickStart)
        self.button.setStyleSheet("""QPushButton {
    #background-color: #f06325;
    #color: white;
    #font-color: white;

    #min-width:  70px;
    #max-width:  70px;
    #min-height: 70px;
    #max-height: 70px;

    #border-radius: 35px;
    #border-width: 1px;
    border-color: #ae32a0;
    border-style: solid;
}
QPushButton:hover {
    background-color: #328930;
}
QPushButton:pressed {
    background-color: black;
    color: black;
    border-width:10px;
}
""")

        #self.label4 = QLabel('Working: ', self)
        #self.label4.setAlignment(Qt.AlignCenter)
        self.label3 = QLabel('None', self)
        self.label3.setAlignment(Qt.AlignCenter)

        self.test = QListWidget(self)
        self.test.addItem("item4")
        self.test.itemSelectionChanged.connect(self.selectItem)

        self.addtask = QLineEdit(self)
        #fa5_plusicon = qta.icon('fa5s.plus')
        self.addtaskbutton = QPushButton(qta.icon('fa5s.plus'), "Add")
        self.addtaskbutton.clicked.connect(self._click_additem)

        self.deltaskbutton = QPushButton(qta.icon('fa5s.minus'), "Del")
        self.deltaskbutton.clicked.connect(self._click_deltask)

        self.tasks = QListWidget(self)
        self.tasks.addItem("No tasks")

        layout.addWidget(self.labeltimer, 0, 0)
        layout.addWidget(self.button, 0, 1)
        #layout.addWidget(self.label4,1,0)
        layout.addWidget(self.label3, 1, 0)
        layout.addWidget(self.test, 2, 0)
        layout.addWidget(self.addtask, 3, 0)
        layout.addWidget(self.addtaskbutton, 3, 1)
        layout.addWidget(self.deltaskbutton, 3, 2)
        layout.addWidget(self.tasks, 4, 0)

        self.show()
        print("init end")

    def _update_timer(self):
        if self.thread_running == True:
            self.thread_running = False
            return 0
        while True:
            #self.elapsed_time = time.time()
            self.thread_running = True
            ''' this is little weired.. but works for now '''
            if self.apa.thread_exit == True or self.thread_exit == True:
                data = api.activity_current(self.api_token)
                print(data)
                if not data.get('error'):
                    api.activity_stop(self.api_token, data['id'])
                self.button.setText('Start')
                self.workingthread.exit()
                self.thread_running = False
                break
            self.elapsed_time += 1
            self.labeltimer.setText(self._online_time(self.elapsed_time))
            time.sleep(1)

    def _click_additem(self):
        print("oh oh oh oh")
        print(self.addtask.text())
        text = self.addtask.text()
        project_id = None

        if len(text) > 0:
            print("This seems acceptable")
            for _x in self.test.selectedItems():
                project_id = _x.data(Qt.UserRole)
            print(project_id)

            if project_id == None:
                QMessageBox.information(self, 'PyQt5 message',
                                        "Please select a a project first",
                                        QMessageBox.Ok)
            else:
                api.task_add(self.api_token, project_id, text)
                self.selectItem()
        else:
            QMessageBox.information(self, 'PyQt5 message',
                                    "Please enter a taskname first!",
                                    QMessageBox.Ok)
            print("please enter a name of the task you want to add first")

    def _click_deltask(self):
        print("Ooopsie")

        task_id = None
        for _x in self.tasks.selectedItems():
            task_id = _x.data(Qt.UserRole)

        print(task_id)

        if task_id is not None:
            api.task_delete(self.api_token, task_id)
            self.selectItem()
        else:
            QMessageBox.information(self, 'PyQt5 message',
                                    "unable to delete task, no such task_id",
                                    QMessageBox.Ok)

    def clickStart(self):
        logging.debug("click start/stop button")
        print(self.button.text())
        #self.test.clear()
        data = {}
        ''' user click start timer '''
        if self.button.text() == 'Start':
            project_id = None
            task_id = None
            for _x in self.test.selectedItems():
                project_id = _x.data(Qt.UserRole)

            for _x in self.tasks.selectedItems():
                task_id = _x.data(Qt.UserRole)

            if project_id == None:
                msgBox = QMessageBox()
                msgBox.setIcon(QMessageBox.Information)
                msgBox.setText("Please select a project first")
                msgBox.setWindowTitle("Select project")
                msgBox.setStandardButtons(QMessageBox.Ok)
                msgBox.exec()
                print("Please select one of your project first")
                return 0
            else:
                data = api.activity_start(self.api_token, project_id, task_id)
            ''' this need to be fix '''
            try:
                if data.get('error'):
                    errorBox = DialogBox()
                    returnValue = errorBox.MsgBox(
                        data.get('error') +
                        "Do you want to stop current activity?", "error")

                    if returnValue == QMessageBox.Ok:
                        data = api.activity_current(self.api_token)
                        print(data)
                        api.activity_stop(self.api_token, data['id'])
                        print("Time to do something weired!")

                    return 0  #do we need this?

                    #print(data.get('error'))
                elif data:
                    #apa = IdleTime()
                    self.apa.thread_exit = False
                    print(self.workingthread)
                    self.workingthread = QThread()
                    self.workingthread.started.connect(self.apa.thread_handle)
                    #self.apa.moveToThread(self.workingthread)
                    self.workingthread.start()

                    self.thread_exit = False
                    t = threading.Thread(target=self._update_timer)
                    t.start()
                    self.systray.StartWorking.setText("Stop Working")
                    self.button.setText('Stop')
                    fa5s_icon = qta.icon('fa5s.stop')
                    self.button.setIcon(fa5s_icon)
                    self.test.setDisabled(True)
                    return 1
            except AttributeError:
                ''' if we reach this stage we either got an invalid API response (no error field) or our internet connection isnt working '''
                #errorBox = DialogBox()
                #errorBox.MsgBox("No internet connection or invalid API response", "error")
                QMessageBox.information(
                    self, 'error',
                    "No internet connection or invalid API response",
                    QMessageBox.Ok)

        else:
            ''' stop activity if its running '''
            data = api.activity_current(self.api_token)
            print(data)
            api.activity_stop(self.api_token, data['id'])
            self.thread_exit = True
            self.apa.thread_exit = True
            self.systray.StartWorking.setText("Start Working")
            self.button.setText('Start')
            fa5s_icon = qta.icon('fa5s.play')
            self.button.setIcon(fa5s_icon)
            self.test.setDisabled(False)
        print("end of clickstart")

    def selectItem(self):
        for _x in self.test.selectedItems():
            self.label3.setText(_x.text())
            print(_x.text())
            print(_x.data(Qt.UserRole))
        try:
            data = api.task_get(self.api_token, _x.data(Qt.UserRole))
        except ApiException:
            data = self.db.searchTask(_x.data(Qt.UserRole))
        self.tasks.clear()
        print(data)
        for _x in data:
            item = QListWidgetItem(_x["name"], self.tasks)
            item.setData(Qt.UserRole, _x["task_id"])

        #print(self.test.text())

    def NetworkSetup(self):
        self.test.clear()
        data_p2 = None
        data_p = None
        try:
            data_p = api.get_projects(self.api_token)
        except ApiException:
            data_p = self.db.readDatabase()["projects"]

        #print("data_p:")
        #print(data_p)
        #print("data_p2")
        #print(data_p2)

        l = []
        print(data_p)
        for _x in data_p:
            print("loop")
            print(_x)
            #self.test.addItem(_x["name"])
            item = QListWidgetItem(_x["name"], self.test)
            item.setData(Qt.UserRole, _x["id"])
            #l = []
            try:
                lol = api.task_get(self.api_token, _x["id"])
                print(lol)
                for _x in lol:
                    #if len(lol) > 0:
                    l.append(_x)
            except ApiException:
                pass
            #print(lol)
        print(l)
        if len(l) > 0:
            self.db.saveTasks(l)

        end_date = datetime.utcnow().isoformat()
        start_date = datetime.utcnow().replace(hour=0,
                                               minute=0,
                                               second=0,
                                               microsecond=0).isoformat()
        try:
            data = api.get_activity(self.api_token, start_date, end_date)
        except ApiException:
            data = [{"duration": 20}, {"duration": 400}, {"duration": 300}]

        print(data)
        for _x in data:
            #self.db.save_activity()
            self.elapsed_time += _x['duration']
        ''' Set timer '''
        self.labeltimer.setText(self._online_time(self.elapsed_time))

        if len(data) > 0:
            self.db.save_activity(data)

        try:
            whoami = api.whoami(self.api_token)
            self.db.saveUser(whoami["username"], whoami["api_token"],
                             whoami['api_expire'])
            self.db.saveProjects(data_p)
        except (ApiException, TypeError):
            pass
        #self.db.saveTasks

    def _online_time(self, data):
        hour = 0
        minute = 0
        second = 0
        hour = int(data / 60 / 60)
        data = data - (hour * 3600)
        minute = int(data / 60)
        data = data - (minute * 60)
        second = int(data)

        if hour < 10:
            hour = "0" + str(hour)
        if minute < 10:
            minute = "0" + str(minute)
        if second < 10:
            second = "0" + str(second)

        time_string = str(hour) + ":" + str(minute) + ":" + str(second)

        return time_string

    def closeEvent(self, event):
        data = api.activity_current(self.api_token)
        print(data)
        try:
            if data.get('error'):
                msg = "are you sure you want to quit?"
            elif data.get('id'):
                msg = "Are you sure you want to quit? if you quit the app we will stop the timetracker."
        except:
            msg = "Are you sure you want to quit"
            #pass

        errorBox = DialogBox()
        returnValue = errorBox.MsgBox(msg, "error")

        if returnValue == QMessageBox.Ok:
            #if data.get('id'):
            try:
                api.activity_stop(self.api_token, data['id'])
            except (TypeError, KeyError):
                pass
            self.thread_exit = True
            self.apa.thread_exit = True
            time.sleep(2)
            event.accept()
        else:
            event.ignore()
        print("close event")
Example #21
0
class SelectPackages_Dialog(QDialog):
    def __init__(self, parent, packages):
        super(SelectPackages_Dialog, self).__init__(parent)

        self.file_paths = []
        self.required_packages = packages

        self.setLayout(QVBoxLayout())

        self.layout().addWidget(
            QLabel(
                'You need to select the locations of the following required node packages'
            ))

        # package lists
        required_packages_list_widget = QListWidget()
        for p in packages:
            package_item = QListWidgetItem()
            package_item.setText(p)
            required_packages_list_widget.addItem(package_item)

        selected_items_widget = QWidget()
        selected_items_widget.setLayout(QVBoxLayout())
        self.selected_packages_list_widget = QListWidget()
        selected_items_widget.layout().addWidget(
            self.selected_packages_list_widget)

        auto_import_button = QPushButton('auto import')
        auto_import_button.setFocus()
        auto_import_button.clicked.connect(self.auto_import_button_clicked)
        selected_items_widget.layout().addWidget(auto_import_button)

        add_package_button = QPushButton('add')
        add_package_button.clicked.connect(self.add_package_button_clicked)
        selected_items_widget.layout().addWidget(add_package_button)

        clear_package_list_button = QPushButton('clear')
        clear_package_list_button.clicked.connect(
            self.clear_selected_packages_list)
        selected_items_widget.layout().addWidget(clear_package_list_button)

        finished_button = QPushButton('OK')
        finished_button.clicked.connect(self.finished_button_clicked)
        selected_items_widget.layout().addWidget(finished_button)

        packages_lists_widget = QWidget()
        packages_lists_widget.setLayout(QHBoxLayout())
        packages_lists_widget.layout().addWidget(required_packages_list_widget)
        packages_lists_widget.layout().addWidget(selected_items_widget)

        self.layout().addWidget(packages_lists_widget)

        self.setWindowTitle('select required packages')

    def auto_import_button_clicked(self):
        packages_dir = '../packages'
        folders_list = [
            x[0] for x in os.walk(packages_dir) if os.path.basename(
                os.path.normpath(x[0])) in self.required_packages
        ]

        required_files = self.required_packages.copy()

        for folder in folders_list:
            for r_f in required_files:
                if r_f + '.rpc' in os.listdir(packages_dir + '/' + folder):
                    self.file_paths.append(
                        os.path.normpath(packages_dir + '/' + folder + '/' +
                                         r_f + '.rpc'))
                    break
            self.rebuild_selected_packages_list_widget()

        self.clean_packages_list()

        if self.all_required_packages_selected():
            self.finished()

    def add_package_button_clicked(self):
        file_names = \
            QFileDialog.getOpenFileNames(self, 'select package files', '../packages', 'Ryven Package(*.rpc)')[0]

        for file_name in file_names:
            try:
                f = open(file_name)
                f.close()
                self.file_paths.append(file_name)
            except FileNotFoundError:
                Debugger.debug('couldn\'t open file')

        self.rebuild_selected_packages_list_widget()

    def rebuild_selected_packages_list_widget(self):
        # remove all items
        self.selected_packages_list_widget.clear()

        for f in self.file_paths:
            file_item = QListWidgetItem()
            file_item.setText(f)
            self.selected_packages_list_widget.addItem(file_item)

    def clear_selected_packages_list(self):
        self.file_paths.clear()
        self.rebuild_selected_packages_list_widget()

    def finished_button_clicked(self):
        self.clean_packages_list()
        if self.all_required_packages_selected():
            self.finished()

    def clean_packages_list(self):
        """remove duplicates from self.file_paths"""

        files_dict = {}

        for p in self.file_paths:
            filename = os.path.splitext(os.path.basename(p))[0]
            files_dict[filename] = p

        self.file_paths = list(files_dict.values())

        self.rebuild_selected_packages_list_widget()

    def all_required_packages_selected(self):
        files = [
            os.path.splitext(os.path.basename(path))[0]
            for path in self.file_paths
        ]

        # search for missing packages
        for p in self.required_packages:
            if p not in files:
                return False
        return True

    def finished(self):
        self.accept()
Example #22
0
class FileSystemWidget(QWidget, DirectoryObserver):
    """
    Widget for listing directory contents and download files from the RDP client.
    """

    # fileDownloadRequested(file, targetPath, dialog)
    fileDownloadRequested = Signal(File, str, FileDownloadDialog)

    def __init__(self, root: Directory, parent: QObject = None):
        """
        :param root: root of all directories. Directories in root will be displayed with drive icons.
        :param parent: parent object.
        """

        super().__init__(parent)
        self.root = root
        self.breadcrumbLabel = QLabel()

        self.titleLabel = QLabel()
        self.titleLabel.setStyleSheet("font-weight: bold")

        self.titleSeparator: QFrame = QFrame()
        self.titleSeparator.setFrameShape(QFrame.HLine)

        self.listWidget = QListWidget()
        self.listWidget.setSortingEnabled(True)
        self.listWidget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.listWidget.customContextMenuRequested.connect(self.onCustomContextMenu)

        self.verticalLayout = QVBoxLayout()
        self.verticalLayout.addWidget(self.breadcrumbLabel)
        self.verticalLayout.addWidget(self.listWidget)

        self.setLayout(self.verticalLayout)
        self.listWidget.itemDoubleClicked.connect(self.onItemDoubleClicked)

        self.currentPath: Path = Path("/")
        self.currentDirectory: Directory = root
        self.listCurrentDirectory()

        self.currentDirectory.addObserver(self)

    def setWindowTitle(self, title: str):
        """
        Set the window title. When the title is not blank, a title label and a separator is displayed.
        :param title: the new title.
        """

        previousTitle = self.windowTitle()

        super().setWindowTitle(title)

        self.titleLabel.setText(title)

        if previousTitle == "" and title != "":
            self.verticalLayout.insertWidget(0, self.titleLabel)
            self.verticalLayout.insertWidget(1, self.titleSeparator)
        elif title == "" and previousTitle != "":
            self.verticalLayout.removeWidget(self.titleLabel)
            self.verticalLayout.removeWidget(self.titleSeparator)

            # noinspection PyTypeChecker
            self.titleLabel.setParent(None)

            # noinspection PyTypeChecker
            self.titleSeparator.setParent(None)

    def onItemDoubleClicked(self, item: FileSystemItem):
        """
        Handle double-clicks on items in the list. When the item is a directory, the current path changes and the
        contents of the directory are listed. Files are ignored.
        :param item: the item that was clicked.
        """

        if not item.isDirectory() and not item.isDrive():
            return

        if item.text() == "..":
            self.currentPath = self.currentPath.parent
        else:
            self.currentPath = self.currentPath / item.text()

        self.listCurrentDirectory()

    def listCurrentDirectory(self):
        """
        Refresh the list widget with the current directory's contents.
        """

        node = self.root

        for part in self.currentPath.parts[1 :]:
            node = next(d for d in node.directories if d.name == part)

        self.listWidget.clear()
        self.breadcrumbLabel.setText(f"Location: {str(self.currentPath)}")

        if node != self.root:
            self.listWidget.addItem(FileSystemItem("..", FileSystemItemType.Directory))

        for directory in node.directories:
            self.listWidget.addItem(FileSystemItem(directory.name, directory.type))

        for file in node.files:
            self.listWidget.addItem(FileSystemItem(file.name, file.type))

        if node is not self.currentDirectory:
            self.currentDirectory.removeObserver(self)
            node.addObserver(self)
            self.currentDirectory = node
            node.list()

    def onDirectoryChanged(self):
        """
        Refresh the directory view when the directory has changed.
        """

        self.listCurrentDirectory()

    def currentItemText(self) -> str:
        try:
            return self.listWidget.selectedItems()[0].text()
        except IndexError:
            return ""

    def selectedFile(self) -> Optional[File]:
        text = self.currentItemText()

        if text == "":
            return None

        if text == "..":
            return self.currentDirectory.parent

        for sequence in [self.currentDirectory.files, self.currentDirectory.directories]:
            for file in sequence:
                if text == file.name:
                    return file

        return None

    def canDownloadSelectedItem(self) -> bool:
        return self.selectedFile().type == FileSystemItemType.File

    def onCustomContextMenu(self, localPosition: QPoint):
        """
        Show a custom context menu with a "Download file" action when a file is right-clicked.
        :param localPosition: position where the user clicked.
        """
        selectedFile = self.selectedFile()

        if selectedFile is None:
            return

        globalPosition = self.listWidget.mapToGlobal(localPosition)

        downloadAction = QAction("Download file")
        downloadAction.setEnabled(selectedFile.type in [FileSystemItemType.File])
        downloadAction.triggered.connect(self.downloadFile)

        itemMenu = QMenu()
        itemMenu.addAction(downloadAction)

        itemMenu.exec_(globalPosition)

    def downloadFile(self):
        file = self.selectedFile()

        if file.type != FileSystemItemType.File:
            return

        filePath = file.getFullPath()
        targetPath, _ = QFileDialog.getSaveFileName(self, f"Download file {filePath}", file.name)

        if targetPath != "":
            dialog = FileDownloadDialog(filePath, targetPath, self)
            dialog.show()

            self.fileDownloadRequested.emit(file, targetPath, dialog)
Example #23
0
class QtEpsInfo(QtWidgets.QWidget, Ui_EpsInfo):
    def __init__(self, owner):
        super(self.__class__, self).__init__()
        Ui_EpsInfo.__init__(self)
        self.setupUi(self)
        self.owner = weakref.ref(owner)

        self.epsListWidget = QListWidget()
        self.epsListWidget.setFlow(self.epsListWidget.LeftToRight)
        self.epsListWidget.setWrapping(True)
        self.epsListWidget.setFrameShape(self.epsListWidget.NoFrame)
        self.epsListWidget.setResizeMode(self.epsListWidget.Adjust)
        self.epsListWidget.itemClicked.connect(self.SelectEps)
        self.gridLayout_2.addWidget(self.epsListWidget, 1, 0)
        self.closeFlag = self.__class__.__name__
        self.bookId = ""
        self.loadingForm = QtLoading(self)
        self.setWindowTitle("章节列表")

        self.greed = QColor(18, 161, 130)
        self.blue = QColor(97, 154, 195)
        self.white = QColor(0, 0, 0, 0)

    def OpenEpsInfo(self, bookId):
        self.show()
        self.loadingForm.show()
        self.bookId = bookId
        self.epsListWidget.clear()
        if bookId not in BookMgr().books:
            self.owner().qtTask.AddHttpTask(lambda x: BookMgr().AddBookById(self.bookId, x), self.OpenBookInfoBack,
                                            cleanFlag=self.closeFlag)
        else:
            self.owner().qtTask.AddHttpTask(lambda x: BookMgr().AddBookEpsInfo(self.bookId, x), self.OpenEpsInfoBack,
                                            cleanFlag=self.closeFlag)

    def OpenBookInfoBack(self, msg):
        if msg == Status.Ok:
            self.owner().qtTask.AddHttpTask(lambda x: BookMgr().AddBookEpsInfo(self.bookId, x), self.OpenEpsInfoBack,
                                            cleanFlag=self.closeFlag)
        else:
            self.loadingForm.close()

    def OpenEpsInfoBack(self, msg):
        self.loadingForm.close()
        self.epsListWidget.clear()
        if msg == Status.Ok:
            self.UpdateEpsInfo()
        return

    def UpdateEpsInfo(self):
        self.epsListWidget.clear()
        info = BookMgr().books.get(self.bookId)
        if not info:
            return
        downloadEpsId = self.owner().downloadForm.GetDownloadEpsId(self.bookId)
        for index, epsInfo in enumerate(info.eps):
            label = QLabel(epsInfo.title)
            label.setContentsMargins(20, 10, 20, 10)
            item = QListWidgetItem(self.epsListWidget)
            item.setSizeHint(label.sizeHint())
            if index in downloadEpsId:
                item.setBackground(self.greed)
            else:
                item.setBackground(self.white)
            self.epsListWidget.setItemWidget(item, label)

    def SelectEps(self, item):
        if item.background().color() == self.greed:
            return
        elif item.background().color() == self.blue:
            item.setBackground(self.white)
        else:
            item.setBackground(self.blue)
        return

    def SelectAll(self):
        for i in range(self.epsListWidget.count()):
            item = self.epsListWidget.item(i)
            if item.background().color() == self.greed:
                continue
            item.setBackground(self.blue)
        return

    def CancleSelect(self):
        for i in range(self.epsListWidget.count()):
            item = self.epsListWidget.item(i)
            if item.background().color() == self.greed:
                continue
            item.setBackground(self.white)
        return

    def StartDownload(self):
        downloadIds = []
        for i in range(self.epsListWidget.count()):
            item = self.epsListWidget.item(i)
            if item.background().color() == self.blue:
                downloadIds.append(i)
        if not downloadIds:
            return
        self.owner().downloadForm.AddDownload(self.bookId, downloadIds)
        self.UpdateEpsInfo()
        return
Example #24
0
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('清单')
        self.setFixedSize(320, 480)

        # 布局
        layout = QVBoxLayout()

        # 清单视图
        self.items_view = QListWidget()
        self.items_view.setIconSize(QSize(14, 14))
        self.items_view.doubleClicked.connect(self.toggle_complete)
        layout.addWidget(self.items_view)

        # 按钮布局
        button_layout = QHBoxLayout()
        layout.addLayout(button_layout)

        # delete button
        self.delete_button = QPushButton('DELETE')
        self.delete_button.clicked.connect(self.delete)
        button_layout.addWidget(self.delete_button)

        # Complete button
        self.complete_button = QPushButton('COMPLETE')
        self.complete_button.clicked.connect(self.complete)
        button_layout.addWidget(self.complete_button)

        # add input
        self.add_input = QLineEdit()
        self.add_input.returnPressed.connect(self.add)
        layout.addWidget(self.add_input)

        # add button
        self.add_button = QPushButton('ADD')
        self.add_button.clicked.connect(self.add)
        layout.addWidget(self.add_button)

        # status bar
        self.setStatusBar(QStatusBar())

        container = QWidget()
        container.setLayout(layout)
        self.setCentralWidget(container)

        self.setStyleSheet("""
            QListWidget {
                border: 1px solid #999;
                font-size: 13px;
            }
            
            QListWidget::item {
                color: #000;
                height: 30px;
                border-bottom: 1px solid #dedede;
            }
            QListWidget::item:selected {
                background-color: #fff9dd;
            }
            
            QPushButton {
                height: 24px;
                background-color: #fddb3a;
                font-weight: 900;
            }
            
            QLineEdit {
                padding: 5px;
            }
        """)

        self.items = []
        self.load()
        self.list_items()

    @Slot()
    def add(self):
        name = self.add_input.text()
        if name:
            self.items_view.addItem(QListWidgetItem(name))
            self.add_input.setText('')
            self.items.append({'name': name, 'done': False})
            # self.save()
            db.save(name, False)

    @Slot()
    def delete(self):
        items = self.items_view.selectedItems()
        if items:
            self.items.pop(self.items_view.currentRow())
            db.delete(self.items_view.currentRow() + 1)
            self.items_view.clear()
            self.list_items()
            # self.save()

    @Slot()
    def complete(self):
        items = self.items_view.selectedItems()
        if items:
            item_data = self.items[self.items_view.currentRow()]
            if not item_data['done']:
                icon = QIcon('done.svg')
                items[0].setIcon(icon)
                item_data['done'] = True
                # self.save()
                db.update(True, self.items_view.currentRow() + 1)

    @Slot()
    def toggle_complete(self):
        items = self.items_view.selectedItems()
        if items:
            item_data = self.items[self.items_view.currentRow()]
            if not item_data['done']:
                icon = QIcon('done.svg')
                items[0].setIcon(icon)
                item_data['done'] = True
                db.update(True, self.items_view.currentRow() + 1)
            else:
                icon = QIcon('')
                items[0].setIcon(icon)
                item_data['done'] = False
                db.update(False, self.items_view.currentRow() + 1)
            # self.save()

    def list_items(self):
        for item in self.items:
            list_item = QListWidgetItem(item['name'])
            if item['done']:
                icon = QIcon('done.svg')
                list_item.setIcon(icon)
            self.items_view.addItem(list_item)

    def load(self):
        # with open('data.json', 'r') as f:
        #     self.items = json.load(f)
        self.items = db.select()

    def save(self):
        with open('data.json', 'w') as f:
            json.dump(self.items, f)
Example #25
0
class CreationContainer(QWidget):
    """
    Apparently just another level of parent class for social link display.
    Man I was stupid.
    Still am luigi2hands

    :param MainFrame mainframe: application mainframe
    :param QWidget op: parent widget
    :param int load: index to load maybe?
    """
    def __init__(self, mainframe, op, load):
        QWidget.__init__(self)
        self.mainframe = mainframe
        self.op = op
        self.op.cc = self
        self.load = load

        # View initializers...
        self.actions = None
        self.window = None

        self.initUI()
        self.op.grid.addWidget(self, 0, 0, 2, 10)

    def initUI(self):
        """
        Initialize the GUI.
        Does lots of stuff.
        """
        self.grid = QGridLayout()
        self.setLayout(self.grid)

        self.actions = self.op.link.getIDs()
        self.actions.append("New element")
        types = ["Info", "Speak", "Camera Change", "Movement"]

        self.save = QPushButton(self, text="Save")
        self.grid.addWidget(self.save, 3, 0)

        self.existing_connections = QListWidget(self)
        self.populateExistingConnections()
        self.grid.addWidget(self.existing_connections, 1, 5, 2, 1)

        self.next = QComboBox(self)
        self.next.addItems(self.actions)
        self.next.setMaximumWidth(150)
        if self.load != 0:
            self.next.setCurrentIndex(self.op.i)
        self.grid.addWidget(self.next, 3, 2)

        self.window = None

        self.actOM = QComboBox(self)
        self.actOM.addItems(types)
        self.actOM.activated.connect(self.changeFrame)
        self.grid.addWidget(self.actOM, 0, 0, 1, 2)

        self.connect()
        self.next.setCurrentIndex(self.next.count() - 1)

        self.backB = QPushButton(self, text="Back to List Menu")
        self.backB.clicked.connect(self.back)
        self.grid.addWidget(self.backB, 3, 4)

        self.lead = QLabel(self, text="Leads to:")
        self.lead.setAlignment(Qt.AlignRight)
        self.grid.addWidget(self.lead, 3, 1)

        self.connectB = QPushButton(self, text="Connect")
        self.connectB.clicked.connect(self.lightConnect)
        self.grid.addWidget(self.connectB, 3, 3)

        self.follow_path = QPushButton(self, text="Enter linked element")
        self.follow_path.clicked.connect(self.follow)
        self.grid.addWidget(self.follow_path, 0, 6, 2, 1)

        self.rmvRel = QPushButton(self, text="Remove this connection")
        self.rmvRel.clicked.connect(self.removeRelation)
        self.grid.addWidget(self.rmvRel, 1, 6, 2, 1)

        self.conLab = QLabel(self, text="This action connects to:")
        self.grid.addWidget(self.conLab, 0, 5)

    def removeRelation(self):
        """
        Remove a relation, which will also delete the uniquely dependant subtree.
        """
        if not self.existing_connections.currentItem() or \
           not popup("Are you sure you want to remove this relation? Any elements with a unique dependancy "
                     "on this relation will also be deleted.\nIt is highly recommended you take a look at "
                     "the graphical view of the tree in order to see the potential effects of the deletion.",
                     "Warning"):
            return
        self.op.link.delRelation(
            self.op.i,
            self.actions.index(self.existing_connections.currentItem().text()))
        self.populateExistingConnections()
        self.updateElementList()
        self.op.linkstored.save()

    def populateExistingConnections(self):
        """
        Display all the existing connections of the current node.
        """
        self.existing_connections.clear()
        for relation in self.op.link.getRelations(self.op.i):
            self.existing_connections.addItem(
                self.op.link.getOneID(self.op.link.getItem(relation)))

    def back(self):
        """
        Return to the higher-level cutscene container view...
        """
        if not popup("Return to list main menu?\n(Lose any unsaved changes)",
                     "Warning"):
            return
        self.close()
        self.op.cc = None
        self.op.viewF(False)

    def follow(self):
        """
        Move on to the edit view of the selected relationship.
        """
        if not self.existing_connections.currentItem() or \
           self.existing_connections.currentItem().text() == "":
            return
        self.next.setCurrentIndex([
            self.next.itemText(i) for i in range(self.next.count())
        ].index(self.existing_connections.currentItem().text()))
        self.op.i = self.actions.index(self.next.currentText())
        self.connect()
        self.next.setCurrentIndex(self.next.count() - 1)

    def lightConnect(self):
        """
        Create a relationship between the current action and another.
        """
        if not self.checkCached():
            popup("Please save this action before linking it to a new one",
                  "Information")
            return
        if self.next.currentText() == "New element":
            self.op.link.addRelation(self.op.i, self.op.link.size())
            print("Linked to index " + str(self.op.link.size()))
            self.op.i = self.op.link.size()
            self.load = 0
            self.changeFrame(0)
            self.updateElementList()
        else:
            self.op.link.addRelation(
                self.op.i, self.actions.index(self.next.currentText()))
            print("Linked to index " +
                  str(self.actions.index(self.next.currentText())))
        self.populateExistingConnections()

    def connect(self):
        """
        Create a relationship between the current action and another, and enter the edit view of the
        relationship.

        :raises Exception: if the requested new action's type can't be processed (should never happen)
        """
        print(self.next.currentText())
        if self.next.currentText() == "New element":
            self.load = 0
            self.changeFrame(0)
        else:
            if isinstance(
                    self.op.link.getItem(
                        self.actions.index(self.next.currentText())), Info):
                self.actOM.setCurrentIndex(0)
            elif isinstance(
                    self.op.link.getItem(
                        self.actions.index(self.next.currentText())), Speak):
                self.actOM.setCurrentIndex(1)
            elif isinstance(
                    self.op.link.getItem(
                        self.actions.index(self.next.currentText())), Camera):
                self.actOM.setCurrentIndex(2)
            elif isinstance(
                    self.op.link.getItem(
                        self.actions.index(self.next.currentText())),
                    Movement):
                self.actOM.setCurrentIndex(3)
            else:
                raise Exception("Not a type!")
            self.load = self.op.link.getItem(
                self.actions.index(self.next.currentText()))
            self.changeFrame(0)

    def checkCached(self):
        """
        Check if the current element has been saved before.

        :returns: if the element has been saved
        :rtype: bool
        """
        print(len(self.op.link.items) - 1)
        print(self.op.i)
        if self.op.link.getItem(self.op.i) == []:
            return False
        return True

    def updateElementList(self):
        """
        Update the relationships list, I think.
        """
        self.next.clear()
        self.actions = self.op.link.getIDs()
        self.actions.append("New element")
        self.next.addItems(self.actions)
        self.next.setCurrentIndex(len(self.actions) - 1)

    def changeFrame(self, _):
        """
        Change view to edit a certain type of action.

        :param objct _: unused, but required by caller
        """
        print("Changed to " + self.actOM.currentText())
        try:
            self.window.close()
        except AttributeError:
            pass  # No window open
        if self.actOM.currentText() == "Speak":
            self.window = SpeakFrame(self, self.load)
        elif self.actOM.currentText() == "Camera Change":
            self.window = CameraFrame(self, self.load)
        elif self.actOM.currentText() == "Movement":
            self.window = MoveFrame(self, self.load)
        else:  # self.actOM.currentText() == "Info":
            self.window = InfoFrame(self, self.load)
        try:
            self.save.clicked.disconnect()
        except:  #pylint: disable=bare-except
            pass
        self.save.clicked.connect(self.window.save)
        self.populateExistingConnections()
        self.updateElementList()
Example #26
0
class Widget(QWidget):

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

        # Data for plotting and marker data storage
        self.data = {}
        self.slice_index = {
            'ind1': 0, 
            'ind2': 0
            }
        self.marker_id = 0
        self.marker_ind = []
        self.marker_setpoint = {
            'Marker1': 0, 
            'Marker2': 0, 
            }

        # Error message dialog widget
        self.error_popup = QErrorMessage()
        self.error_popup.setWindowTitle('Snap file error')

        # Left (List of Checkboxes)
        self.list_widget = QListWidget()
        #Resize width and height
        self.list_widget.setSizePolicy(QSizePolicy.Preferred, 
                                       QSizePolicy.Preferred)
        self.list_widget.setMinimumWidth(200)
        self.list_widget.setMaximumWidth(400)
        # self.list_widget.setMinimumHeight(300)
        self.list_widget.setMaximumHeight(500)

        # Signal groupbox
        self.signal_groupbox = QGroupBox('Available Signals')
        self.signal_groupbox.setMinimumWidth(200)
        self.signal_groupbox.setMaximumWidth(350)
        self.signal_groupbox.setMinimumHeight(100)
        self.sig_group_layout = QVBoxLayout()
        self.signal_groupbox.setLayout(self.sig_group_layout)
        # Statistics groupbox
        self.stats_groupbox = QGroupBox('Statistics')
        self.stats_groupbox.setMinimumWidth(200)
        self.stats_groupbox.setMaximumWidth(350)
        self.stats_groupbox.setMinimumHeight(240)
        self.stats_group_layout = QFormLayout()

        # Label initiation
        # Marker Time 1
        self.mark_one_time_label = QLabel('Marker1_time: ')
        self.mark_one_time_value = QLabel()
        # Marker Time 2
        self.mark_two_time_label = QLabel('Marker2_time: ')
        self.mark_two_time_value = QLabel()
        # On/Off labels for 0/1 signals counter
        self.on_off_label = QLabel('On/Off: ')
        self.on_off_value = QLabel()
        # Mean value
        self.mean_label = QLabel('Mean: ')
        self.mean_value = QLabel()
        # Standard deviation
        self.std_label = QLabel('Sigma(STD): ')
        self.std_value = QLabel()
        # Minimal value
        self.min_label = QLabel('Min: ')
        self.min_value = QLabel()
        # Maximual value
        self.max_label = QLabel('Max: ')
        self.max_value = QLabel()
        # Max - Min value
        self.val_diff_label = QLabel('Max-Min: ')
        self.val_diff_value = QLabel()
        # Time difference (X-axis)
        self.time_diff_label = QLabel('Time_diff: ')
        self.time_diff_value = QLabel('')

        # Row addition of labels
        self.stats_group_layout.addRow(self.mark_one_time_label, 
                                       self.mark_one_time_value)
        self.stats_group_layout.addRow(self.mark_two_time_label,
                                       self.mark_two_time_value)
        self.stats_group_layout.addRow(self.time_diff_label, 
                                       self.time_diff_value)
        self.stats_group_layout.addRow(self.on_off_label, self.on_off_value)
        self.stats_group_layout.addRow(self.mean_label, self.mean_value)
        self.stats_group_layout.addRow(self.std_label, self.std_value)
        self.stats_group_layout.addRow(self.min_label, self.min_value)
        self.stats_group_layout.addRow(self.max_label, self.max_value)
        self.stats_group_layout.addRow(self.val_diff_label, 
                                       self.val_diff_value)
        self.stats_groupbox.setLayout(self.stats_group_layout)

        # Set markers section of the application (bottom left)
        self.marker_grid = QGridLayout()
        self.marker_one_notice = QLabel()
        self.marker_two_notice = QLabel()
        self.set_marker_one_label = QLabel('Set Marker1:')
        self.set_marker_two_label = QLabel('Set Marker2:')
        self.set_marker_one_value = QLineEdit()
        self.set_marker_one_value.setMaximumWidth(100)
        self.set_marker_two_value = QLineEdit()
        self.set_marker_two_value.setMaximumWidth(100)

        self.marker_grid.addWidget(self.set_marker_one_label)
        self.marker_grid.addWidget(self.set_marker_one_value)
        self.marker_grid.addWidget(self.marker_one_notice)
        self.marker_grid.addWidget(self.set_marker_two_label)
        self.marker_grid.addWidget(self.set_marker_two_value)
        self.marker_grid.addWidget(self.marker_two_notice)
                                        
        # Leftside app layout
        self.v_layout = QVBoxLayout()
        self.v_layout.addWidget(self.list_widget)
        self.v_layout.addWidget(self.signal_groupbox)
        self.v_layout.addWidget(self.stats_groupbox)
        self.v_layout.addLayout(self.marker_grid)

        # Matplotlib figure
        self.fig = Figure(figsize=(5, 3))
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setSizePolicy(QSizePolicy.Expanding, 
                                  QSizePolicy.Expanding)
        self.ax = self.canvas.figure.subplots()
        self.ax.grid()
        self.ax.set_xlabel('Time[s]')
        self.fig.suptitle('Parameter Plot')
      
        # QWidget Layout
        self.h_layout = QHBoxLayout()
        self.h_layout.addLayout(self.v_layout)
        self.h_layout.addWidget(self.canvas)

        # Set the layout to the QWidget
        self.setLayout(self.h_layout)

        # ListWidget and plot connections
        self.list_widget.itemChanged.connect(self.item_changed)
        self.click_event = self.fig.canvas.mpl_connect('button_press_event',
                                                       self.on_click)
        self.set_marker_one_value.returnPressed.connect(
                                                lambda: self.add_marker('one'))
        self.set_marker_two_value.returnPressed.connect(
                                                lambda: self.add_marker('two'))
        
    # Add radio button when signal is checked for plotting
    def add_radio_button(self, name):
        self.rad_btn = QRadioButton(name)
        self.rad_btn.toggled.connect(self.calculate_signal_stats)
        self.sig_group_layout.addWidget(self.rad_btn)

    # Remove radio button when signal is unchecked for plotting
    def remove_radio_button(self, name):
        for item in self.signal_groupbox.children():
            try:
                if item.text() == name:
                    item.setParent(None)
            except AttributeError:
                pass
    
    # Remove all radiobuttons on new data load
    def clear_signals(self):
        count = 0
        for item in self.signal_groupbox.children():
            if count == 0:
                count = 1
                continue 
            else:
                item.setParent(None)  
    # Check state of all radiobuttons, if none is checked remove stats values
    def check_signals(self):
        count = 0
        num_of_check = 0
        for item in self.signal_groupbox.children():
            if count == 0:
                count = 1
                continue 
            else:
                if item.isChecked():
                    num_of_check += 1
        # If no radiobuttons are checked, remove stats
        if num_of_check == 0:
            self.mean_value.setText('') 
            self.std_value.setText('') 
            self.max_value.setText('') 
            self.min_value.setText('') 
            self.val_diff_value.setText('') 
            self.on_off_value.setText('')               

    # Item additon of listWidget
    def fill_list(self, list_items):
        self.list_widget.clear()

        for column in list_items:
            item = QListWidgetItem(column)
            item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable)
            item.setCheckState(Qt.Unchecked)
            self.list_widget.addItem(item)

        self.show()
    
    # If new data is loaded, replace the old one
    def replace_data(self, temp):
        if not temp == self.data:
            self.data = temp
            self.clear_signals()

    @Slot()
    # Item state changed in listWidget event handler
    def item_changed(self, item):
        if item.checkState() == Qt.Unchecked:
           self.remove_plot(item.text())
           self.remove_radio_button(item.text())
           self.check_signals()
        else:
            self.add_plot(self.data['Time'], 
                          self.data[item.text()], item.text())
            self.add_radio_button(item.text())
                
    # Method for plotting data
    def add_plot(self, x_data, y_data, name):
        self.ax.plot(x_data, y_data, label=name, picker=3)
        self.ax.grid(True)
        self.ax.relim()
        self.ax.set_xlabel('Time[s]')
        self.ax.autoscale_view()
        self.ax.legend(loc='upper right')
        self.canvas.draw()

    # Method for marker addition via QLineEdit
    def add_marker(self, label):
        # Check if any signal is plotted
        sig_count = 0
        for i in range(self.list_widget.count()):
            if self.list_widget.item(i).checkState() == Qt.Checked:
                sig_count += 1

        if sig_count == 0:
            self.marker_one_notice.setText('No active signal!')
            self.marker_two_notice.setText('No active signal!')
            return
        try:
            max_time = self.data['Time'][-1]
            min_time = self.data['Time'][0]
        except KeyError:
            self.marker_one_notice.setText('Signal data not loaded!')
            self.marker_two_notice.setText('Signal data not loaded!')
        if label == 'one':
            try:
                mark1_value = float(self.set_marker_one_value.text())
                if mark1_value < max_time and mark1_value > min_time:
                    if self.marker_id == 0:
                        self.marker_id += 1
                        label_id = self.marker_id
                    elif self.marker_id == 1:
                        self.marker_id += 1
                        label_id = self.marker_id
                        self.remove_marker('first')
                    else:
                        self.remove_marker('first')
                        label_id = 1

                    self.marker_one_notice.setText('')
                    self.marker_setpoint['Marker1'] = mark1_value
                    self.mark_one_time_value.setText(
                                            self.set_marker_one_value.text())
                    self.calculate_marker_stats()
                    self.calculate_signal_stats()
                    
                    # Draw the marker
                    L =  self.ax.axvline(
                                    x=float(self.set_marker_one_value.text()), 
                                    linestyle='dashed', 
                                    color='red', 
                                    label='_Marker' + str(label_id))
                    self.fig.canvas.draw()
                else:
                    self.marker_one_notice.setText('Marker1 out of bounds')
            except ValueError:
                self.marker_one_notice.setText('Non-Valid value entered!')
        else:
            try:
                mark2_value = float(self.set_marker_two_value.text()) 
                if mark2_value < max_time and mark2_value > min_time:
                    if self.marker_id == 1:
                        self.marker_id += 1
                        label_id = self.marker_id
                    elif self.marker_id == 2:
                        label_id = 2
                        self.remove_marker('second')
                    else:
                        self.marker_two_notice.setText('Marker1 not placed')
                    self.marker_two_notice.setText('')
                    self.marker_setpoint['Marker2'] = mark2_value
                    self.mark_two_time_value.setText(
                                            self.set_marker_two_value.text())
                    self.calculate_marker_stats()
                    self.calculate_signal_stats()
                    # Draw the marker
                    L =  self.ax.axvline(
                                    x=float(self.set_marker_two_value.text()), 
                                    linestyle='dashed', 
                                    color='red', 
                                    label='_Marker' + str(label_id))
                    self.fig.canvas.draw()
                else:
                    self.marker_two_notice.setText('Marker2 out of bounds')
            except:
                self.marker_two_notice.setText('Non-Valid value entered!')
    
    # Marker removal method
    def remove_marker(self, label):
        for item in self.ax.lines:
            if 'Marker' in item.get_label():
                self.marker_ind.append(item)

        # If there are two markers remove them from plot and adjust marker
        # time labels
        if label == 'both':
            self.marker_ind[0].remove()
            self.marker_ind[1].remove()
            self.marker_ind = []
            self.marker_setpoint['Marker1'] = 0
            self.marker_setpoint['Marker2'] = 0
            self.mark_one_time_value.setText('')
            self.mark_two_time_value.setText('')
            self.time_diff_value.setText('')
            self.marker_id = 0
        # Remove only marker1
        elif label == 'first':
            self.marker_ind[0].remove()
            self.marker_ind = []
            self.marker_setpoint['Marker1'] = 0
            self.mark_one_time_value.setText('')
            self.marker_id -= 1
        elif label == 'second':
            self.marker_ind[1].remove()
            self.marker_ind = []
            self.marker_setpoint['Marker2'] = 0
            self.mark_two_time_value.setText('')
            self.marker_id -= 1

        self.ax.set_xlabel('Time[s]')
        self.canvas.draw()
    
    # Method for plot removal
    def remove_plot(self, name):
        cnt = 0
        for item in self.ax.lines:
            if item.get_label() == name:
                self.ax.lines[cnt].remove()
            cnt += 1
        self.ax.relim()
        self.ax.autoscale_view()
        self.ax.legend(loc='upper right')
        self.ax.set_xlabel('Time[s]')
        self.canvas.draw()

        # Check if all elements are unticked
        counter = 0
        for i in range(self.list_widget.count()):
            if self.list_widget.item(i).checkState() == Qt.Checked:
                counter +=1
        if counter == 0:
            self.remove_marker('both')
            
    # On click event for plot, only two markers can be active at the time
    def on_click(self, event):
        try:
            # Catch left click event
            if event.button == 1:
                x = event.xdata
                if self.marker_id < 2:
                    if self.marker_id == 0:
                        self.marker_setpoint['Marker1'] = round(x)
                        self.mark_one_time_value.setText(
                                            str(self.marker_setpoint['Marker1']))
                        self.calculate_marker_stats()
                        self.calculate_signal_stats()
                    else:
                        self.marker_setpoint['Marker2'] = round(x)
                        self.mark_two_time_value.setText(
                                            str(self.marker_setpoint['Marker2']))
                        self.calculate_marker_stats()
                        self.calculate_signal_stats()
                    self.marker_id += 1
                    L =  self.ax.axvline(x=x, 
                                        linestyle='dashed', 
                                        color='red', 
                                        label='_Marker' + str(self.marker_id))
                    self.fig.canvas.draw()
            # Catch right click event
            elif event.button == 3:
                self.remove_marker('both')
        except TypeError:
            pass
    # Marker analysis method
    def calculate_marker_stats(self):
        if self.marker_setpoint['Marker2'] == 0:
            diff = self.data['Time'][-1] - self.marker_setpoint['Marker1']
            self.time_diff_value.setText(str(diff))
        else:
            diff = self.marker_setpoint['Marker2'] -  \
                   self.marker_setpoint['Marker1']
            
            self.time_diff_value.setText(convert_seconds(diff))
    # Signal analysis method
    def calculate_signal_stats(self):
        self.check_signals()
        selected_signal = ''
        signal_data = []
        num_off, num_on = 0, 0
        for item in self.signal_groupbox.children():
            try:
                if item.isChecked():
                    # Signal extraction block
                    selected_signal = item.text()
                    # If only one marker, Marker1 is placed on graph
                    if self.marker_setpoint['Marker2'] == 0 and self.marker_setpoint['Marker1'] != 0:
                        for i in range(len(self.data['Time'])):
                            if self.data['Time'][i] > self.marker_setpoint['Marker1']:
                                self.slice_index['ind1'] = i
                                break
                        signal_data = np.asarray(
                        self.data[selected_signal][self.slice_index['ind1']:], 
                                    dtype=np.float32)
                    # Both markers, Marker1 and Marker2 are present on graph
                    elif self.marker_setpoint['Marker1'] != 0 and self.marker_setpoint['Marker2'] != 0:
                        for i in range(len(self.data['Time'])):
                            if self.data['Time'][i] > self.marker_setpoint['Marker1']:
                                self.slice_index['ind1'] = i
                                break
                        for i in range(len(self.data['Time'])):
                            if self.data['Time'][len(self.data['Time']) - i - 1] < self.marker_setpoint['Marker2']:
                                self.slice_index['ind2'] = len(self.data['Time']) - i
                                break
                        signal_data = np.asarray(
                        self.data[selected_signal][self.slice_index['ind1']:self.slice_index['ind2'] - 1], 
                                                    dtype=np.float32)
                        
                    # No markers present, whole signal stats are showed
                    else:
                        signal_data = np.asarray(self.data[selected_signal], 
                                                    dtype=np.float32)
                    try:
                        # Signal mean calculation
                        self.mean_value.setText(str(np.mean(signal_data)))
                        # Standard deviation
                        self.std_value.setText(str(np.std(signal_data)))
                        # Maximum value
                        self.max_value.setText(str(np.max(signal_data)))
                        # Minimum value
                        self.min_value.setText(str(np.min(signal_data)))
                        # Max - Min
                        self.val_diff_value.setText(str(np.max(signal_data) - 
                                                    (np.min(signal_data))))
                        if np.max(signal_data) == 1.0:
                            for i in range(len(signal_data)):
                                if i != len(signal_data) - 1:
                                    temp = signal_data[i] - signal_data[i+1]
                                    if temp == 1:
                                        num_off += 1
                                    elif temp == -1:
                                        num_on += 1
                            self.on_off_value.setText(str(num_on) + 
                                                    '\\' + str(num_off))
                    except ValueError:
                        err_line1 = 'Missing data, result is empty array!'
                        err_line2 = '\n Please check snap file.' 
                        self.error_popup.showMessage(err_line1 + err_line2)
            except AttributeError:
                pass
class SelectPlayersWindow(QDialog):
    def __init__(self, parent=None):
        super(SelectPlayersWindow, self).__init__(parent)
        self.parent = parent
        self.setModal(True)
        self.setWindowTitle("Torna résztvevők")
        self.resize(520, 600)
        self.layout = QVBoxLayout()
        self.setLayout(self.layout)
        self.read_config()

        self.create_torna_selection()

        self.nevek_layout = QHBoxLayout()
        self.layout.addLayout(self.nevek_layout)
        self.show_saved_players()
        self.show_torna_players()

        self.gomb_nev_layout = QVBoxLayout()
        self.nevek_layout.addLayout(self.gomb_nev_layout)
        self.show_current_players()

        self.buttonbox = QDialogButtonBox(QDialogButtonBox.Ok
                                          | QDialogButtonBox.Cancel)
        self.buttonbox.clicked.connect(self.buttonbox_click)
        self.layout.addWidget(self.buttonbox)

    def create_torna_selection(self):
        self.tournaments = QComboBox()
        self.tournaments.setModelColumn(0)
        self.tournaments.currentIndexChanged.connect(self.torna_valasztas)
        self.layout.addWidget(self.tournaments)
        self.load_torna()

    def load_torna(self):
        torna = QSqlQueryModel()
        query = QSqlQuery("select * from torna_settings where aktiv=2")
        torna.setQuery(query)
        if torna.record(0).value(0):
            for i in range(torna.rowCount()):
                self.tournaments.addItem(
                    torna.record(i).value(1),
                    torna.record(i).value(0))  # a value(0) a torna_id
        else:
            print("Nincs aktív torna")

    def show_saved_players(self):
        self.saved_players = QListWidget()
        self.saved_players.setFixedHeight(500)
        self.saved_players.setFixedWidth(150)
        self.saved_players.setSortingEnabled(True)
        self.saved_players.itemDoubleClicked.connect(self.add_resztvevo)
        self.load_saved_players()
        self.nevek_layout.addWidget(self.saved_players)

    def show_torna_players(self):
        self.torna_players = QListWidget()
        self.torna_players.setFixedHeight(500)
        self.torna_players.setFixedWidth(150)
        self.torna_players.setSortingEnabled(True)
        self.torna_players.itemDoubleClicked.connect(self.add_resztvevo)
        self.load_torna_players()
        self.nevek_layout.addWidget(self.torna_players)

    def load_saved_players(self):
        players = QSqlQueryModel()
        players_query = QSqlQuery("select * from players where aktiv=1")
        players.setQuery(players_query)
        self.saved_players.clear()
        for i in range(players.rowCount()):
            item = QListWidgetItem(players.record(i).value(1))
            item.setData(Qt.UserRole, players.record(i).value(0))
            self.saved_players.addItem(item)

    def load_torna_players(self):
        players = QSqlQueryModel()
        players_query = QSqlQuery(
            "select * from torna_resztvevok where 1 group by player_id, player_name"
        )
        players.setQuery(players_query)
        self.torna_players.clear()
        for i in range(players.rowCount()):
            item = QListWidgetItem(players.record(i).value(1))
            item.setData(Qt.UserRole, players.record(i).value(0))
            self.torna_players.addItem(item)

    def add_resztvevo(self, item):
        new_item = QListWidgetItem(item)
        new_item.setData(Qt.UserRole, item.data(Qt.UserRole))
        self.current_players.addItem(new_item)
        query = QSqlQuery(
            f"insert into torna_resztvevok (player_id, player_name, torna_id) values ({new_item.data(Qt.UserRole)}, '{new_item.text()}', {self.torna_id})"
        )
        query.exec_()

    def show_current_players(self):
        query = QSqlQuery("select max(player_id) from torna_resztvevok")
        query.exec_()
        while query.next():
            self.first_new_id = int(query.value(0)) + 1
        print(self.first_new_id)
        self.add_new = QPushButton("Új")
        self.add_new.clicked.connect(self.uj_ember)
        self.current_players = QListWidget()
        self.current_players.setFixedHeight(470)
        self.current_players.setFixedWidth(150)
        self.current_players.setSortingEnabled(True)
        self.gomb_nev_layout.addWidget(self.add_new)
        self.current_players.itemDoubleClicked.connect(self.remove_resztvevo)
        self.gomb_nev_layout.addWidget(self.current_players)

    def uj_ember(self):
        ujember, ok = QInputDialog.getText(
            self, "Új versenyző",
            '<html style="font-size: 15px;">Írd be a versenyző nevét!</html>')
        if ok and len(ujember):
            item = QListWidgetItem(ujember)
            item.setData(Qt.UserRole, self.first_new_id)
            self.current_players.addItem(item)
            self.first_new_id += 1

            query = QSqlQuery(
                f"insert into torna_resztvevok (player_id, player_name, torna_id) values ({item.data(Qt.UserRole)}, '{item.text()}', {self.torna_id})"
            )
            query.exec_()

    def remove_resztvevo(self, item):
        self.current_players.takeItem(
            self.current_players.row(self.current_players.selectedItems()[0]))
        # print(item.data(Qt.UserRole), item.text())
        query = QSqlQuery(
            f"delete from torna_resztvevok where player_id={item.data(Qt.UserRole)} and torna_id={self.torna_id}"
        )
        query.exec_()

    def torna_valasztas(self, i):
        self.torna_id = self.tournaments.itemData(i)
        players = QSqlQueryModel()
        players_query = QSqlQuery(
            f"select * from torna_resztvevok where torna_id={self.torna_id}")
        players.setQuery(players_query)
        self.current_players.clear()
        for i in range(players.rowCount()):
            item = QListWidgetItem(players.record(i).value(1))
            item.setData(Qt.UserRole, players.record(i).value(0))
            self.current_players.addItem(item)

    def buttonbox_click(self, b):
        if b.text() == "OK":
            self.accept()
        elif b.text() == "Cancel":
            self.reject()

    def accept(self):
        # for i in range(self.current_players.count()):
        #     item = self.current_players.item(i)
        #     print(self.torna_id, item.data(Qt.UserRole), item.text()) # itt vannak a beszúrandó adatok
        super().accept()
        # INSERT INTO `torna_resztvevok` (`player_id`, `player_name`, `torna_id`)
        # VALUES ('1111', 'teszt_user2', '8892') ON DUPLICATE KEY UPDATE player_name='teszt_user2';
    def read_config(self):
        if os.path.exists('config.ini'):
            # Van config.ini, ki kell értékelni
            config.read('config.ini')
            self.station_id = config['DEFAULT'].get('station id')
            self.secret = config['DEFAULT'].get('secret key')
            # todo módosítani kell a torna_match táblát, hogy tartalmazza a tabla mellett a hozzá tartozó secret-et is
        else:
            # Nincs config.ini, alapértékekkel inicializálni
            msg = QMessageBox(self)
            msg.setStyleSheet("fonz-size: 20px")
            msg.setWindowTitle("Hiányzó beállítás file!")
            msg.setText(
                '<html style="font-size: 14px; color: red">Nem tudtam beolvasni a konfigurációt!<br></html>'
                +
                '<html style="font-size: 16px">Kérem módosítsa a beállításokat!</html>'
            )
            msg.exec_()
            sys.exit(1)
Example #28
0
class DatasheetView(QMainWindow):
    def __init__(self, pdfPath=None, openPages=[1]):

        super().__init__()

        if pdfPath:
            self.myPdfContext = PDFContext(pdfPath, openPages)

        # store diretory for debugging purposes
        self.svgDirectory = self.myPdfContext.directory

        # window dimensions
        self.top = 300
        self.left = 800
        self.width = 860
        self.height = 980

        self.setGeometry(self.left, self.top, self.width, self.height)

        # window title
        self.setWindowTitle("BetterSheets")

        # sets up main layout -- splitters
        self.initUILayout()
        self.initUIToolbar()
        self.initToC()

        # self.initPdfViewer()  # must be called after initUI to ensure PDFContext object exists
        self.show()

        print(self.mainDisplay.getVisibleChild())

    def initUILayout(self):

        # set left-side, Dynamic View
        self.dynamicViewDisplay = QLabel()

        self.vBoxA = QVBoxLayout()
        self.vBoxA.addWidget(self.dynamicViewDisplay)

        self.groupA = QGroupBox()
        self.groupA.setTitle("Dynamic Veiw")
        self.groupA.setLayout(self.vBoxA)

        # set left-side, Static View
        self.staticViewDisplay = QLabel()

        self.vBoxB = QVBoxLayout()
        self.vBoxB.addWidget(self.staticViewDisplay)

        self.groupB = QGroupBox()
        self.groupB.setTitle("Static View")
        self.groupB.setLayout(self.vBoxB)

        # add Dynamic and Static Views to resizeable left-side Splitter
        self.altViewSplit = QSplitter(Qt.Vertical)
        self.altViewSplit.addWidget(self.groupA)
        self.altViewSplit.addWidget(self.groupB)

        # set up Tools View section
        self.toolsTabView = QTabWidget()
        self.toolsTabView.setTabsClosable(True)
        self.toolsTabView.setMovable(True)
        self.toolsTabView.setDocumentMode(True)
        # self.toolsTabView.setTabBarAutoHide(True)

        # add attribute for storing page notes
        self.notesDB = []
        self.notesDisplay = QListWidget(self)
        self.notesDisplay.setMaximumHeight(200)

        # add ToC to Tools View
        self.ToCListView = QListWidget()
        self.toolsTabView.addTab(self.ToCListView, "Table of Contents")

        # add notes list to tools view
        self.toolsTabView.addTab(self.notesDisplay, "Notes")

        # add tools view to the left-side splitter
        self.altViewSplit.addWidget(self.toolsTabView)

        # set up main viewport
        self.mainDisplay = QDatasheetPageDisplayWidget(self.myPdfContext)
        self.mainDisplay.renderPages(1, 4)

        self.mainScroller = QScrollArea(self)
        self.mainScroller.setWidget(self.mainDisplay)
        self.mainScroller.setWidgetResizable(True)
        self.mainScroller.setBackgroundRole(QtGui.QPalette.Dark)
        self.mainScroller.setFixedHeight(800)

        print(self.mainScroller.viewport().childrenRect())

        # set up document tools

        self.hBoxDocTools = QHBoxLayout()

        self.searchLabel = QLabel("Search: ")
        self.searchBox = QLineEdit()
        self.searchBox.setPlaceholderText("Search")

        # self.

        self.vBoxMain = QVBoxLayout()
        self.vBoxMain.addWidget(self.mainScroller)

        self.notesArea = QLineEdit()
        self.notesArea.setPlaceholderText("Add a note about this page...")
        self.notesArea.returnPressed.connect(self.onAddNote)

        self.vBoxMain.addWidget(self.notesArea)

        self.mainViewGroup = QGroupBox()
        self.mainViewGroup.setTitle("Main View")
        self.mainViewGroup.setLayout(self.vBoxMain)

        # join both sides together
        self.leftRightSplit = QSplitter(Qt.Horizontal)
        self.leftRightSplit.addWidget(self.altViewSplit)
        self.leftRightSplit.addWidget(self.mainViewGroup)

        self.setCentralWidget(self.leftRightSplit)

    def initUIToolbar(self):

        mainMenu = self.menuBar(
        )  # get the menu bar already in use by this QMainWindow subclass

        fileMenu = mainMenu.addMenu("File")
        editMenu = mainMenu.addMenu("Edit")
        LayoutMenu = mainMenu.addMenu("Layout")
        AboutMenu = mainMenu.addMenu("About")

        saveAction = fileMenu.addAction("Save")
        quitAction = fileMenu.addAction("Exit Bettersheets")
        quitAction.triggered.connect(self.quitApp)
        copyAction = editMenu.addAction("Copy")
        resetAction = LayoutMenu.addAction("Reset Default Layout")

        self.toolBar = self.addToolBar("Tools")
        self.toolBar.addAction(saveAction)
        self.toolBar.addAction(copyAction)

    def contextMenuEvent(self, event):
        # return super().contextMenuEvent(event)
        contextMenu = QMenu()

        selectAction = contextMenu.addAction("Select Area")
        extractAction = contextMenu.addAction("Extract Content")
        openAction = contextMenu.addAction("Open PDF")
        closeAction = contextMenu.addAction("Close PDF")
        quitAction = contextMenu.addAction("Quit")

        triggered_action = contextMenu.exec_(self.mapToGlobal(event.pos()))

        if triggered_action == quitAction:
            self.quitApp()

    def quitApp(self):
        self.close()

    def onAddNote(self):
        print("note added")

        text = self.notesArea.text()

        if text:
            self.notesDB.append(text)
            self.notesDisplay.clear()
            self.notesDisplay.addItems(self.notesDB)
            self.notesArea.clear()

    def initPdfViewer(self, openPages: int):
        pass

    def initToC(self):

        # get table of contents
        ToC = self.myPdfContext.getToC()
        ToC_headings_list = [x[1] for x in ToC]

        self.ToCListView.clear()
        self.ToCListView.addItems(ToC_headings_list)
class QtBookInfo(QtWidgets.QWidget, Ui_BookInfo):
    def __init__(self, owner):
        super(self.__class__, self).__init__()
        Ui_BookInfo.__init__(self)
        self.setupUi(self)
        self.owner = weakref.ref(owner)
        self.loadingForm = QtLoading(self)
        self.bookId = ""
        self.url = ""
        self.path = ""
        self.bookName = ""
        self.lastEpsId = -1

        self.msgForm = QtBubbleLabel(self)
        self.picture.installEventFilter(self)
        self.title.setGeometry(QRect(328, 240, 329, 27 * 4))
        self.title.setWordWrap(True)
        self.title.setAlignment(Qt.AlignTop)
        self.title.setContextMenuPolicy(Qt.CustomContextMenu)
        self.title.customContextMenuRequested.connect(self.CopyTitle)

        # self.autor.setContextMenuPolicy(Qt.CustomContextMenu)
        # self.autor.customContextMenuRequested.connect(self.OpenAutor)

        layouy = self.horizontalLayout_4
        self.autorList = QtCategoryList(self)
        layouy.addWidget(QLabel("作者:"))
        layouy.addWidget(self.autorList)
        self.autorList.itemClicked.connect(self.ClickTagsItem)

        self.description.setContextMenuPolicy(Qt.CustomContextMenu)
        self.description.customContextMenuRequested.connect(
            self.CopyDescription)

        self.description.setGeometry(QRect(328, 240, 329, 27 * 4))
        self.description.setWordWrap(True)
        self.description.setAlignment(Qt.AlignTop)

        # self.categories.setGeometry(QRect(328, 240, 329, 27 * 4))
        # self.categories.setWordWrap(True)
        # self.categories.setAlignment(Qt.AlignTop)

        layouy = self.horizontalLayout_6
        self.categoriesList = QtCategoryList(self)
        layouy.addWidget(QLabel("分类:"))
        layouy.addWidget(self.categoriesList)
        self.categoriesList.itemClicked.connect(self.ClickCategoriesItem)

        # self.tags.setGeometry(QRect(328, 240, 329, 27 * 4))
        # self.tags.setWordWrap(True)
        # self.tags.setAlignment(Qt.AlignTop)

        layouy = self.horizontalLayout_7
        self.tagsList = QtCategoryList(self)
        layouy.addWidget(QLabel("Tags:"))
        layouy.addWidget(self.tagsList)
        self.tagsList.itemClicked.connect(self.ClickTagsItem)

        self.epsListWidget = QListWidget(self)
        self.epsListWidget.setFlow(self.epsListWidget.LeftToRight)
        self.epsListWidget.setWrapping(True)
        self.epsListWidget.setFrameShape(self.epsListWidget.NoFrame)
        self.epsListWidget.setResizeMode(self.epsListWidget.Adjust)

        self.epsLayout.addWidget(self.epsListWidget)

        self.listWidget = QtBookList(self, self.__class__.__name__)
        self.listWidget.InitUser(self.LoadNextPage)
        self.listWidget.doubleClicked.connect(self.OpenCommentInfo)

        self.childrenListWidget = QtBookList(None, self.__class__.__name__)
        self.childrenListWidget.InitUser(self.LoadChildrenNextPage)

        self.childrenWidget = QtWidgets.QWidget()
        layout = QHBoxLayout(self.childrenWidget)

        label = QLabel()
        label.setMinimumWidth(100)
        layout.addWidget(label)
        layout3 = QVBoxLayout()

        layout2 = QHBoxLayout()
        self.commentLine2 = QLineEdit()
        self.commentButton2 = QPushButton("回复")
        self.commentButton2.clicked.connect(self.SendCommentChildren)
        layout2.addWidget(self.commentLine2)
        layout2.addWidget(self.commentButton2)
        layout3.addLayout(layout2)
        layout3.addWidget(self.childrenListWidget)
        layout.addLayout(layout3)

        self.commentLayout.addWidget(self.listWidget)
        layout = QHBoxLayout()
        self.commentLine = QLineEdit()
        layout.addWidget(self.commentLine)
        self.commentButton = QPushButton("发送评论")
        layout.addWidget(self.commentButton)
        self.commentLayout.addLayout(layout, 1, 0)
        self.commentButton.clicked.connect(self.SendComment)

        # self.stackedWidget.addWidget(self.qtReadImg)
        self.epsListWidget.clicked.connect(self.OpenReadImg)

        self.closeFlag = self.__class__.__name__ + "-close"  # 切换book时,取消加载

    def closeEvent(self, a0: QtGui.QCloseEvent) -> None:
        if self.stackedWidget.currentIndex() == 1:
            self.stackedWidget.setCurrentIndex(0)
            self.owner().qtReadImg.AddHistory()
            self.LoadHistory()
            a0.ignore()
        else:
            a0.accept()

    def CopyTitle(self):
        clipboard = QApplication.clipboard()
        clipboard.setText(self.title.text())
        self.msgForm.ShowMsg("复制标题")
        return

    # def OpenAutor(self):
    #     text = self.autor.text()
    #     self.owner().userForm.listWidget.setCurrentRow(0)
    #     self.owner().searchForm.searchEdit.setText(text)
    #     self.owner().searchForm.Search()
    #     return

    def Clear(self):
        self.stackedWidget.setCurrentIndex(0)
        self.owner().qtTask.CancelTasks(self.closeFlag)
        self.epsListWidget.clear()
        self.ClearCommnetList()

    def CopyDescription(self):
        clipboard = QApplication.clipboard()
        clipboard.setText(self.description.text())
        self.msgForm.ShowMsg("复制描述")
        return

    def OpenBook(self, bookId):
        self.bookId = bookId
        self.setWindowTitle(self.bookId)
        # if self.bookId in self.owner().downloadForm.downloadDict:
        #     self.download.setEnabled(False)
        # else:
        #     self.download.setEnabled(True)

        self.Clear()
        self.show()
        self.loadingForm.show()
        self.owner().qtTask.AddHttpTask(
            lambda x: BookMgr().AddBookById(bookId, x), self.OpenBookBack)

    def close(self):
        super(self.__class__, self).close()

    def OpenBookBack(self, msg):
        self.loadingForm.close()
        self.listWidget.UpdatePage(1, 1)
        self.childrenListWidget.UpdatePage(1, 1)
        self.childrenListWidget.UpdateState()
        self.listWidget.UpdateState()
        self.categoriesList.clear()
        self.tagsList.clear()
        self.autorList.clear()
        info = BookMgr().books.get(self.bookId)
        if msg == Status.Ok and info:
            # self.autor.setText(info.author)
            self.autorList.AddItem(info.author)
            self.title.setText(info.title)
            self.bookName = info.title
            self.description.setText(info.description)
            self.isFinished.setText("完本" if info.finished else "未完本")
            for name in info.categories:
                self.categoriesList.AddItem(name)
            # self.categories.setText(','.join(info.categories))
            # self.tags.setText(','.join(info.tags))
            for name in info.tags:
                self.tagsList.AddItem(name)
            self.likes.setText(str(info.totalLikes))
            self.views.setText(str(info.totalViews))

            if info.isFavourite:
                self.favorites.setEnabled(False)
            else:
                self.favorites.setEnabled(True)
            self.picture.setText("图片加载中...")
            fileServer = info.thumb.get("fileServer")
            path = info.thumb.get("path")
            name = info.thumb.get("originalName")
            self.url = fileServer
            self.path = path
            timeArray, day = ToolUtil.GetDateStr(info.updated_at)
            self.updateTick.setText(str(day) + "天前更新")
            if config.IsLoadingPicture:

                self.owner().qtTask.AddDownloadTask(
                    fileServer,
                    path,
                    completeCallBack=self.UpdatePicture,
                    cleanFlag=self.closeFlag)
            self.owner().qtTask.AddHttpTask(lambda x: Server().Send(
                req.GetComments(self.bookId), bakParam=x),
                                            self.GetCommnetBack,
                                            cleanFlag=self.closeFlag)

            self.owner().qtTask.AddHttpTask(
                lambda x: BookMgr().AddBookEpsInfo(self.bookId, x),
                self.GetEpsBack,
                cleanFlag=self.closeFlag)
            self.startRead.setEnabled(False)
        else:
            # QtWidgets.QMessageBox.information(self, '加载失败', msg, QtWidgets.QMessageBox.Yes)
            self.msgForm.ShowError(msg)
            self.hide()
        return

    def UpdatePicture(self, data, status):
        if status == Status.Ok:
            pic = QtGui.QPixmap()
            pic.loadFromData(data)
            pic.scaled(self.picture.size(), QtCore.Qt.KeepAspectRatio)
            self.picture.setPixmap(pic)
            # self.picture.setScaledContents(True)
            self.update()
        else:
            self.picture.setText("图片加载失败")
        return

    # 加载评论
    def GetCommnetBack(self, data):
        try:
            self.loadingForm.close()
            self.listWidget.UpdateState()
            msg = json.loads(data)
            if msg.get("code") == 200:
                comments = msg.get("data", {}).get("comments", {})
                topComments = msg.get("data", {}).get("topComments", [])
                page = int(comments.get("page", 1))
                pages = int(comments.get("pages", 1))
                limit = int(comments.get("limit", 1))
                self.listWidget.UpdatePage(page, pages)
                total = comments.get("total", 0)
                self.tabWidget.setTabText(1, "评论({})".format(str(total)))
                if page == 1:
                    for index, info in enumerate(topComments):
                        floor = "置顶"
                        content = info.get("content")
                        name = info.get("_user", {}).get("name")
                        avatar = info.get("_user", {}).get("avatar", {})
                        createdTime = info.get("created_at")
                        commentsCount = info.get("commentsCount")
                        commnetId = info.get('_id')
                        likesCount = info.get("likesCount")
                        self.listWidget.AddUserItem(commnetId, commentsCount,
                                                    likesCount, content, name,
                                                    createdTime, floor,
                                                    avatar.get("fileServer"),
                                                    avatar.get("path"),
                                                    avatar.get("originalName"))

                for index, info in enumerate(comments.get("docs")):
                    floor = total - ((page - 1) * limit + index)
                    content = info.get("content")
                    name = info.get("_user", {}).get("name")
                    avatar = info.get("_user", {}).get("avatar", {})
                    createdTime = info.get("created_at")
                    commentsCount = info.get("commentsCount")
                    commnetId = info.get('_id')
                    likesCount = info.get("likesCount")
                    self.listWidget.AddUserItem(commnetId, commentsCount,
                                                likesCount, content, name,
                                                createdTime, floor,
                                                avatar.get("fileServer"),
                                                avatar.get("path"),
                                                avatar.get("originalName"))
            return
        except Exception as es:
            Log.Error(es)

    def GetEpsBack(self, st):
        if st == Status.Ok:
            self.UpdateEpsData()
            self.lastEpsId = -1
            self.LoadHistory()
            return
        return

    def UpdateEpsData(self):
        self.epsListWidget.clear()
        info = BookMgr().books.get(self.bookId)
        if not info:
            return
        self.startRead.setEnabled(True)
        downloadIds = self.owner().downloadForm.GetDownloadCompleteEpsId(
            self.bookId)
        for index, epsInfo in enumerate(info.eps):
            label = QLabel(epsInfo.title)
            label.setContentsMargins(20, 10, 20, 10)
            item = QListWidgetItem(self.epsListWidget)
            if index in downloadIds:
                item.setBackground(QColor(18, 161, 130))
            else:
                item.setBackground(QColor(0, 0, 0, 0))
            item.setSizeHint(label.sizeHint())
            self.epsListWidget.setItemWidget(item, label)
        self.tabWidget.setTabText(0, "章节({})".format(str(len(info.eps))))
        return

    def AddDownload(self):
        self.owner().epsInfoForm.OpenEpsInfo(self.bookId)
        # if self.owner().downloadForm.AddDownload(self.bookId):
        #     QtBubbleLabel.ShowMsgEx(self, "添加下载成功")
        # else:
        #     QtBubbleLabel.ShowMsgEx(self, "已在下载列表")
        # self.download.setEnabled(False)

    def AddFavority(self):
        User().AddAndDelFavorites(self.bookId)
        QtBubbleLabel.ShowMsgEx(self, "添加收藏成功")
        self.favorites.setEnabled(False)

    def LoadNextPage(self):
        self.loadingForm.show()
        self.owner().qtTask.AddHttpTask(lambda x: Server(
        ).Send(req.GetComments(self.bookId, self.listWidget.page + 1),
               bakParam=x),
                                        self.GetCommnetBack,
                                        cleanFlag=self.closeFlag)
        return

    def OpenReadImg(self, modelIndex):
        index = modelIndex.row()
        self.OpenReadIndex(index)

    def OpenReadIndex(self, index):
        item = self.epsListWidget.item(index)
        if not item:
            return
        widget = self.epsListWidget.itemWidget(item)
        if not widget:
            return
        name = widget.text()
        self.hide()
        self.owner().qtReadImg.OpenPage(self.bookId, index, name)
        # self.stackedWidget.setCurrentIndex(1)

    def StartRead(self):
        if self.lastEpsId >= 0:
            self.OpenReadIndex(self.lastEpsId)
        else:
            self.OpenReadIndex(0)
        return

    def LoadHistory(self):
        info = self.owner().historyForm.GetHistory(self.bookId)
        if not info:
            self.startRead.setText("观看第{}章".format(str(1)))
            return
        if self.lastEpsId == info.epsId:
            self.startRead.setText("观看第{}章".format(str(self.lastEpsId + 1)))
            return

        if self.lastEpsId >= 0:
            item = self.epsListWidget.item(self.lastEpsId)
            if item:
                downloadIds = self.owner(
                ).downloadForm.GetDownloadCompleteEpsId(self.bookId)
                if self.lastEpsId in downloadIds:
                    item.setBackground(QColor(18, 161, 130))
                else:
                    item.setBackground(QColor(0, 0, 0, 0))

        item = self.epsListWidget.item(info.epsId)
        if not item:
            return
        item.setBackground(QColor(238, 162, 164))
        self.epsListWidget.update()
        self.lastEpsId = info.epsId
        self.startRead.setText("观看第{}章".format(str(self.lastEpsId + 1)))

    def ClickCategoriesItem(self, item):
        text = item.text()
        self.owner().userForm.listWidget.setCurrentRow(1)
        self.owner().searchForm.searchEdit.setText("")
        self.owner().searchForm.OpenSearchCategories(text)
        return

    def ClickTagsItem(self, item):
        text = item.text()
        self.owner().userForm.listWidget.setCurrentRow(1)
        self.owner().searchForm.searchEdit.setText(text)
        self.owner().searchForm.Search()
        return

    def SendComment(self):
        data = self.commentLine.text()
        if not data:
            return
        self.commentLine.setText("")
        self.loadingForm.show()
        self.owner().qtTask.AddHttpTask(lambda x: Server().Send(
            req.SendComment(self.bookId, data), bakParam=x),
                                        callBack=self.SendCommentBack)

    def SendCommentBack(self, msg):
        try:
            data = json.loads(msg)
            if data.get("code") == 200:
                self.ClearCommnetList()
                self.owner().qtTask.AddHttpTask(lambda x: Server().Send(
                    req.GetComments(self.bookId), bakParam=x),
                                                self.GetCommnetBack,
                                                cleanFlag=self.closeFlag)
            else:
                self.loadingForm.close()
                QtBubbleLabel.ShowErrorEx(self, data.get("message", "错误"))
            self.commentLine.setText("")
        except Exception as es:
            self.loadingForm.close()
            Log.Error(es)

    def OpenCommentInfo(self, modelIndex):
        index = modelIndex.row()
        item = self.listWidget.item(index)
        if not item:
            return
        widget = self.listWidget.itemWidget(item)
        if not widget:
            return

        self.childrenListWidget.clear()
        self.childrenListWidget.UpdatePage(1, 1)
        self.childrenListWidget.UpdateState()
        if self.childrenListWidget.parentId == index:
            # self.childrenWidget.hide()
            self.childrenWidget.setParent(None)
            widget.gridLayout.removeWidget(self.childrenWidget)
            self.childrenListWidget.parentId = -1
            item.setSizeHint(widget.sizeHint())
            return
        if self.childrenListWidget.parentId >= 0:
            item2 = self.listWidget.item(self.childrenListWidget.parentId)
            widget2 = self.listWidget.itemWidget(item2)
            self.childrenWidget.setParent(None)
            widget2.gridLayout.removeWidget(self.childrenWidget)
            self.childrenListWidget.parentId = -1
            item2.setSizeHint(widget2.sizeHint())

        self.loadingForm.show()
        self.owner().qtTask.AddHttpTask(lambda x: Server().Send(
            req.GetCommentsChildrenReq(widget.id), bakParam=x),
                                        self.LoadCommentInfoBack,
                                        backParam=index,
                                        cleanFlag=self.closeFlag)

    def LoadCommentInfoBack(self, msg, index):
        try:
            self.loadingForm.close()
            item = self.listWidget.item(index)
            if not item:
                return
            widget = self.listWidget.itemWidget(item)
            if not widget:
                return
            self.childrenListWidget.UpdateState()
            data = json.loads(msg)
            self.childrenListWidget.parentId = index
            widget.gridLayout.addWidget(self.childrenWidget, 1, 0, 1, 1)
            if data.get("code") == 200:
                comments = data.get("data", {}).get("comments", {})
                page = int(comments.get("page", 1))
                total = int(comments.get("total", 1))
                pages = int(comments.get("pages", 1))
                limit = int(comments.get("limit", 1))
                self.childrenListWidget.UpdatePage(page, pages)
                for index, info in enumerate(comments.get("docs")):
                    floor = total - ((page - 1) * limit + index)
                    content = info.get("content")
                    name = info.get("_user", {}).get("name")
                    avatar = info.get("_user", {}).get("avatar", {})
                    createdTime = info.get("created_at")
                    commentsCount = info.get("commentsCount")
                    likesCount = info.get("likesCount")
                    commnetId = info.get('_id')
                    self.childrenListWidget.AddUserItem(
                        commnetId, commentsCount, likesCount, content, name,
                        createdTime, floor, avatar.get("fileServer"),
                        avatar.get("path"), avatar.get("originalName"))

                pass
            self.listWidget.scrollToItem(
                item, self.listWidget.ScrollHint.PositionAtTop)
            size = self.listWidget.size()
            item.setSizeHint(size)
        except Exception as es:
            Log.Error(es)

    def SendCommentChildren(self):
        data = self.commentLine2.text()
        if not data:
            return
        index = self.childrenListWidget.parentId
        item = self.listWidget.item(index)
        if not item:
            return
        widget = self.listWidget.itemWidget(item)
        if not widget:
            return
        self.commentLine2.setText("")
        commentId = widget.id
        self.loadingForm.show()
        self.childrenListWidget.clear()
        self.owner().qtTask.AddHttpTask(lambda x: Server().Send(
            req.SendCommentChildrenReq(commentId, data), bakParam=x),
                                        callBack=self.SendCommentChildrenBack,
                                        backParam=index)

    def SendCommentChildrenBack(self, msg, index):
        try:
            item = self.listWidget.item(index)
            if not item:
                self.loadingForm.close()
                return
            widget = self.listWidget.itemWidget(item)
            if not widget:
                self.loadingForm.close()
                return

            data = json.loads(msg)
            if data.get("code") == 200:
                self.owner().qtTask.AddHttpTask(lambda x: Server().Send(
                    req.GetCommentsChildrenReq(widget.id), bakParam=x),
                                                self.LoadCommentInfoBack,
                                                backParam=index,
                                                cleanFlag=self.closeFlag)
            else:
                self.loadingForm.close()
                QtBubbleLabel.ShowErrorEx(self, data.get("message", "错误"))
            self.commentLine.setText("")
        except Exception as es:
            self.loadingForm.close()
            Log.Error(es)

    def LoadChildrenNextPage(self):
        index = self.childrenListWidget.parentId
        item = self.listWidget.item(index)
        if not item:
            return
        widget = self.listWidget.itemWidget(item)
        if not widget:
            return
        self.loadingForm.show()
        self.owner().qtTask.AddHttpTask(
            lambda x: Server().Send(req.GetCommentsChildrenReq(
                widget.id, self.childrenListWidget.page + 1),
                                    bakParam=x),
            self.LoadCommentInfoBack,
            backParam=index,
            cleanFlag=self.closeFlag)
        return

    def ClearCommnetList(self):
        if self.childrenListWidget.parentId >= 0:
            item2 = self.listWidget.item(self.childrenListWidget.parentId)
            widget2 = self.listWidget.itemWidget(item2)
            self.childrenWidget.setParent(None)
            widget2.gridLayout.removeWidget(self.childrenWidget)
            self.childrenListWidget.parentId = -1
            item2.setSizeHint(widget2.sizeHint())
        self.childrenListWidget.clear()
        self.listWidget.clear()

    def eventFilter(self, obj, event):
        if event.type() == QEvent.MouseButtonPress:
            if event.button() == Qt.LeftButton:
                if obj.pixmap() and not obj.text():
                    QtImgMgr().ShowImg(obj.pixmap())
                return True
            else:
                return False
        else:
            return super(self.__class__, self).eventFilter(obj, event)
class Randomizer(QWidget):
    """A game randomizer for selecting a random game to play
       from the user's collection. User can select which
       platforms to choose from.
       gamesData: Raw table data in list of dictionaries"""
    def __init__(self, gamesData: list, platformsData: list, genresData: list):
        super(Randomizer, self).__init__()

        self._consoleItems = platformsData
        self._genreItems = genresData
        self._gamesData = gamesData
        self._games = []  # For holding the games to randomize
        self._gameCount = 0
        self._coverdir = path.join("data", "images", "covers")

        self.consoleLabel = QLabel("Platforms")
        self.consoleList = QListWidget()
        self.consoleList.addItems(self._consoleItems)
        self.consoleList.setSelectionMode(QAbstractItemView.MultiSelection)
        self.consoleList.setMaximumWidth(350)
        self.consoleList.itemClicked.connect(self._updateGameCount)

        self.genreLabel = QLabel("Genres")
        self.genreMatchExclusiveCB = QCheckBox("Match exclusive")
        self.genreMatchExclusiveCB.setToolTip(
            "Only match games which exclusively contain the selected genres.")
        self.genreMatchExclusiveCB.setChecked(False)
        self.genreMatchExclusiveCB.stateChanged.connect(self._updateGameCount)
        self.genreList = QListWidget()
        self.genreList.addItems(self._genreItems)
        self.genreList.setSelectionMode(QAbstractItemView.MultiSelection)
        self.genreList.setMaximumWidth(350)
        self.genreList.itemClicked.connect(self._updateGameCount)

        self.btnAll = QPushButton("Select All")
        self.btnAll.setMaximumSize(self.btnAll.sizeHint())
        self.btnAll.clicked.connect(self.consoleList.selectAll)
        self.btnAll.clicked.connect(self.genreList.selectAll)
        self.btnAll.clicked.connect(self._updateGameCount)
        self.btnNone = QPushButton("Select None")
        self.btnNone.setMaximumSize(self.btnNone.sizeHint())
        self.btnNone.clicked.connect(self.consoleList.clearSelection)
        self.btnNone.clicked.connect(self.genreList.clearSelection)
        self.btnNone.clicked.connect(self._updateGameCount)
        self._btnRnd = QPushButton("Randomize")
        self._btnRnd.setMaximumSize(self._btnRnd.sizeHint())
        self._btnRnd.clicked.connect(self._randomize)

        self._lblFont = QFont()
        self._lblFont.setPointSize(14)
        self._lblFont.setBold(True)
        self._lblPlay = QLabel()
        self._lblPlay.setAlignment(Qt.AlignCenter)
        self._lblPlay.setFont(self._lblFont)
        self._lblTitle = QLabel()
        self._lblTitle.setAlignment(Qt.AlignCenter)
        self._lblTitle.setFont(self._lblFont)
        self._lblTitle.setWordWrap(True)

        # Cover image
        self._cover = QLabel()
        self._cover.setVisible(False)
        self._cover.setAlignment(Qt.AlignCenter)
        p = QPixmap(path.join(self._coverdir, "none.png"))
        w = self._cover.width()
        h = self._cover.height()
        self._cover.setPixmap(
            p.scaled(w, h, Qt.KeepAspectRatio, Qt.SmoothTransformation))

        self._hboxButtons = QHBoxLayout()
        self._vboxLists = QVBoxLayout()
        self._vboxConsoles = QVBoxLayout()
        self._hboxGenres = QHBoxLayout()
        self._vboxGenres = QVBoxLayout()
        self._vboxResult = QVBoxLayout()
        self._grid = QGridLayout()
        self._hboxButtons.addWidget(self.btnAll, 0)
        self._hboxButtons.addWidget(self.btnNone, 0)
        self._hboxButtons.addWidget(self._btnRnd, 0)
        self._vboxConsoles.addWidget(self.consoleLabel, 0)
        self._vboxConsoles.addWidget(self.consoleList, 1)
        self._hboxGenres.addWidget(self.genreLabel, 0)
        self._hboxGenres.addWidget(self.genreMatchExclusiveCB, 0)
        self._vboxGenres.addWidget(self.genreList, 1)
        self._vboxLists.addSpacing(10)
        self._vboxLists.addLayout(self._vboxConsoles, 1)
        self._vboxLists.addSpacing(10)
        self._vboxLists.addLayout(self._hboxGenres, 0)
        self._vboxLists.addLayout(self._vboxGenres, 1)
        self._vboxResult.addStretch(3)
        self._vboxResult.addWidget(self._lblPlay, 0)
        self._vboxResult.addWidget(self._lblTitle, 0)
        self._vboxResult.addSpacing(50)
        self._vboxResult.addWidget(self._cover, 0)
        self._vboxResult.addStretch(3)
        self._grid.setMargin(0)
        self._grid.setSpacing(0)
        self._grid.addLayout(self._vboxLists, 0, 0)
        self._grid.addLayout(self._hboxButtons, 1, 0)
        self._grid.addLayout(self._vboxResult, 0, 1, 1, -1)

        self.widget = QWidget()
        self.widget.setLayout(self._grid)

    def _getSelectedItems(self) -> tuple:
        return [x.text() for x in self.consoleList.selectedItems()
                ], [x.text() for x in self.genreList.selectedItems()]

    def _randomize(self):
        platforms, genres = self._getSelectedItems()

        if len(self._games) > 0 and (len(platforms) > 0 or len(genres) > 0):
            choice = randint(0, len(self._games) - 1)
            self._lblPlay.setText("You will play:")
            self._lblTitle.setText(
                f"{self._games[choice]['name']}" if len(platforms) == 1 else
                f"{self._games[choice]['name']} [{self._games[choice]['platform']}]"
            )
            # Cover image
            cover = str(self._games[choice]['id']) + ".jpg"
            if path.exists(path.join(self._coverdir, cover)):
                # Update cover image if the game has one
                pixmap = path.join(self._coverdir, cover)
                self._cover.setVisible(True)
            else:
                pixmap = path.join(self._coverdir, "none.png")
                self._cover.setVisible(False)
            p = QPixmap(pixmap)
            w = self._cover.width()
            h = self._cover.height()
            self._cover.setPixmap(
                p.scaled(w, h, Qt.KeepAspectRatio, Qt.SmoothTransformation))
        elif len(self._games) == 0 and (len(platforms) > 0 or len(genres) > 0):
            self._lblPlay.setText("")
            self._lblTitle.setText("No games found with those criteria.")
            self._cover.setVisible(False)
        else:
            self._lblPlay.setText("")
            self._lblTitle.setText("Select at least one console or genre...")
            self._cover.setVisible(False)

    def _updateGameCount(self):
        platforms, genres = self._getSelectedItems()
        self._gameCount = 0
        self._games = []

        if len(platforms) > 0 or len(genres) > 0:
            for row in self._gamesData:
                if len(platforms) > 0 and len(genres) > 0:
                    if row["platform"] in platforms:
                        if self.genreMatchExclusiveCB.isChecked():
                            count = 0
                            for genre in row["genre"].split(", "):
                                if genre in genres:
                                    count += 1
                                else:  # Not exclusive
                                    count = 0
                                    break
                            if count == len(genres):
                                self._gameCount += 1
                                self._games.append(row)
                        else:
                            for genre in row["genre"].split(", "):
                                if genre in genres:
                                    self._gameCount += 1
                                    self._games.append(row)
                                    break  # We only need to match with one genre
                elif len(platforms) > 0 and len(genres) == 0:
                    if row["platform"] in platforms:
                        self._gameCount += 1
                        self._games.append(row)
                elif len(platforms) == 0 and len(genres) > 0:
                    if self.genreMatchExclusiveCB.isChecked():
                        count = 0
                        for genre in row["genre"].split(", "):
                            if genre in genres:
                                count += 1
                            else:  # Not exclusive
                                count = 0
                                break
                        if count == len(genres):
                            self._gameCount += 1
                            self._games.append(row)
                    else:
                        for genre in row["genre"].split(", "):
                            if genre in genres:
                                self._gameCount += 1
                                self._games.append(row)
                                break  # We only need to match with one genre

    def gameCount(self) -> int:
        return self._gameCount

    def updateLists(self, gamesData: list, platformsData: list,
                    genresData: list):
        self._gamesData = gamesData
        self._consoleItems = platformsData
        self._genreItems = genresData
        self.consoleList.clear()
        self.genreList.clear()

        self.consoleList.addItems(self._consoleItems)
        self.genreList.addItems(self._genreItems)