예제 #1
0
class LogDialog(QDialog):
    def __init__(self, parent, rpt_file_path):
        self.rpt_file_path = rpt_file_path

        QDialog.__init__(self, parent)

        self.setWindowTitle('Log: ' + self.rpt_file_path)

        main_lay = QVBoxLayout(self)

        self.txt_log = QPlainTextEdit(self)
        self.txt_log.setMinimumWidth(500)
        self.txt_log.setMinimumHeight(300)
        main_lay.addWidget(self.txt_log)

        self.btn_close = QPushButton('Close')
        self.btn_close.clicked.connect(self.close_dialog)
        main_lay.addWidget(self.btn_close)

        self.fill_txt()

    def close_dialog(self):
        self.close()

    def fill_txt(self):
        with codecs.open(self.rpt_file_path, 'r', encoding='UTF-8') as inp_f:
            lines = inp_f.read().splitlines()

        for line in lines:
            self.txt_log.appendPlainText(line.replace('\b', ''))

        # Scroll up
        self.txt_log.moveCursor(QTextCursor.Start)
        self.txt_log.ensureCursorVisible()
예제 #2
0
class WidgetEditList(OWTextableBaseWidget):
    """Textable widget for modifing the lexical content of the list
    """

    #----------------------------------------------------------------------
    # Widget's metadata...

    name = "Edit Lexical List"
    description = "Edit words contained in lists (lexical fields)"
    icon = "icons/lexical_hunter.svg"

    #----------------------------------------------------------------------
    # Channel definitions...

    inputs = [("Word segmentation", Segmentation, "inputData")]
    outputs = [("Segmentation with annotations", Segmentation)]

    #----------------------------------------------------------------------
    # Layout parameters...

    want_main_area = True

    #----------------------------------------------------------------------
    # Settings...

    settingsHandler = VersionedSettingsHandler(
        version=__version__.rsplit(".", 1)[0])

    textFieldContent = settings.Setting(u''.encode('utf-8'))
    encoding = settings.Setting(u'utf-8')
    selectedFields = []
    listTitle = ""
    listWord = ""

    titleList = settings.Setting([])
    baseLocation = settings.Setting('.')

    def __init__(self, caller):
        """Widget creator."""

        super().__init__()
        # Variable to communicate with the base widjet by calling
        # self.creator.vriable_name

        self.caller = caller
        # Other attributes...
        self.inputSeg = None
        self.outputSeg = None

        # Next two instructions are helpers from TextableUtils. Corresponding
        # interface elements are declared here and actually drawn below (at
        # their position in the UI)...
        self.infoBox = InfoBox(widget=self.controlArea)
        # Temporary dictionary so that the user can cancel changes
        self.tempDict = defaultDict.copy()

        # User interface...

        # CONTROL AREA #
        # Options box for the structure
        titleListBox = gui.widgetBox(
            widget=self.controlArea,
            box="Lists",
            orientation="horizontal",
        )
        # SAVE AREA
        # (After the control one but need to be first for the savechange button)
        SaveBox = gui.widgetBox(
            widget=self.controlArea,
            box=None,
            orientation="horizontal",
        )
        self.SaveChanges = gui.button(
            widget=SaveBox,
            master=self,
            label="Save changes",
            callback=self.saveChanges,
            width=130,
        )
        self.CancelChanges = gui.button(
            widget=SaveBox,
            master=self,
            label="Cancel",
            callback=self.closeWindow,
            width=130,
        )
        # END OF SAVE AREA

        # List of Lexical list that the user can select
        self.titleLabelsList = gui.listBox(
            widget=titleListBox,
            master=self,
            value="selectedFields",  # setting (list)
            labels="titleList",  # setting (list)
            tooltip=
            "The list of lexical list that you want to use for annotation",
            callback=self.updateGUI,
        )
        self.titleLabelsList.setMinimumHeight(300)
        self.titleLabelsList.setMinimumWidth(150)
        self.titleLabelsList.setSelectionMode(1)

        # a box for vertical align of the button
        controlBox = gui.widgetBox(
            widget=titleListBox,
            box=None,
            orientation="vertical",
        )
        # Actions on list
        self.EditList = gui.button(
            widget=controlBox,
            master=self,
            label="Edit",
            callback=self.setEditContent,
            width=130,
            autoDefault=False,
        )
        self.ImportList = gui.button(
            widget=controlBox,
            master=self,
            label="Import",
            callback=self.importLexic,
            width=130,
            autoDefault=False,
        )
        self.ExportList = gui.button(
            widget=controlBox,
            master=self,
            label="Export All",
            callback=self.exportAllLexics,
            width=130,
        )
        self.ExportSelectedList = gui.button(
            widget=controlBox,
            master=self,
            label="Export Selected",
            callback=self.exportOneLexic,
            width=130,
        )
        self.NewList = gui.button(
            widget=controlBox,
            master=self,
            label="New",
            callback=self.newLexicalField,
            width=130,
        )
        self.ClearList = gui.button(
            widget=controlBox,
            master=self,
            label="Clear all",
            callback=self.clearList,
            width=130,
        )
        self.RemoveSelectedList = gui.button(
            widget=controlBox,
            master=self,
            label="Remove Selected",
            callback=self.deleteSelectedList,
            width=130,
        )

        # MAIN AREA (edit list) #
        # structure ...
        listEditBox = gui.widgetBox(
            widget=self.mainArea,
            box="Edit",
            orientation="vertical",
        )

        listEditBox.setMinimumWidth(300)
        # Edit the titile of the list
        self.titleEdit = gui.lineEdit(
            widget=listEditBox,
            master=self,
            value="listTitle",
            label="List name",
            orientation="vertical",
        )

        # Editable text Field. Each line gonna be a enter of
        # the lexical list selected
        self.ContentLabel = gui.label(
            widget=listEditBox,
            master=self,
            label="List content",
        )
        self.editor = QPlainTextEdit()
        listEditBox.layout().addWidget(self.editor)
        self.editor.setMinimumHeight(300)

        buttonEditBox = gui.widgetBox(widget=listEditBox,
                                      box=None,
                                      orientation="horizontal")

        # For saving the chang on the list edit
        self.CommitList = gui.button(
            widget=buttonEditBox,
            master=self,
            label="Commit",
            callback=self.saveEdit,
            width=100,
        )

        self.CancelList = gui.button(widget=buttonEditBox,
                                     master=self,
                                     label="Cancel list changes",
                                     callback=self.cancelListChanges,
                                     width=100)

        gui.rubber(self.controlArea)

        self.setTitleList()
        self.updateGUI()

        # Now Info box and Send button must be drawn...
        self.infoBox.draw()

        # Set the window as modal
        self.exec()

    def setEditContent(self):
        """Sets the lexical field informations when the user wants to edit it"""
        # Getting selected list title
        self.listTitle = list(self.titleList)[self.selectedFields[0]]
        # Converting words list to string
        self.editContent = '\n'.join(self.tempDict[self.listTitle])
        # Setting editor content with words list (converted to string)
        self.editor.setPlainText(self.editContent)
        # Getting old title (to delete it later if the users wants to)
        self.oldTitle = self.listTitle

        self.updateGUI()

    def setTitleList(self):
        """Displays the lexical fields titles in the edit widget view"""
        self.titleList = sorted(self.tempDict.keys())

    def clearList(self):
        """Clears the list of lexical fields"""
        confBox = QMessageBox(
            QMessageBox.Question, "Textable",
            "Do you really want to delete all the lexical lists?",
            QMessageBox.Yes | QMessageBox.No)

        # Getting the answer of the user
        result = confBox.exec_()
        if result == QMessageBox.Yes:
            # Reset textfields values
            self.titleEdit.setText("")
            self.editor.setPlainText("")
            # Deleting all lexical fields
            self.tempDict.clear()
            self.setTitleList()
        else:
            pass

    def deleteSelectedList(self):
        """Deletes selected lexical field"""
        confBox = QMessageBox(QMessageBox.Question, "Textable",
                              "Do you really want to delete this list?",
                              QMessageBox.Yes | QMessageBox.No)

        # Getting the answer of the user
        result = confBox.exec_()
        if result == QMessageBox.Yes:
            # Getting selected list title
            self.listToDelete = list(self.titleList)[self.selectedFields[0]]
            # Reset textfields values
            self.titleEdit.setText("")
            self.editor.setPlainText("")
            # Deleting selected list
            self.tempDict.pop(self.listToDelete, None)
            self.titleList = sorted(self.tempDict.keys())
        else:
            pass

    def newLexicalField(self):
        """Sets a new entry in the lexical fields dictionnary"""
        newDict = "New lexical field"
        i = 1
        while newDict in self.tempDict.keys():
            newDict = "New lexical field %i" % i
            i += 1

        self.tempDict[newDict] = ""
        self.setTitleList()

    def saveEdit(self):
        """Saves the modifications made by the user on the list"""
        # Getting textfields values
        self.val = self.editor.toPlainText()
        self.newTitle = self.titleEdit.text()

        # Reset textfields values
        self.titleEdit.setText("")
        self.editor.setPlainText("")

        wordList = self.val.split("\n")

        self.tempDict[self.newTitle] = wordList
        # Deleting old key and value
        if self.newTitle != self.oldTitle:
            del self.tempDict[self.oldTitle]

        self.titleList = sorted(self.tempDict.keys())

        self.updateGUI()

    def cancelListChanges(self):
        # Reset textfields values
        self.titleEdit.setText("")
        self.editor.setPlainText("")
        self.updateGUI()

    def saveChanges(self):
        """Saves changes made by the user"""
        defaultDict.clear()
        defaultDict.update(self.tempDict)
        self.hide()
        self.caller.setTitleList()

    def closeWindow(self):
        """Cancels changes made by the user"""
        self.hide()

    def importLexic(self):
        """Lets the user import a lexical field from a text file"""

        # Opening a file browser
        filePath = QFileDialog.getOpenFileName(self,
                                               u'Import lexical field file',
                                               self.baseLocation,
                                               u'Text files (*)')
        if not filePath:
            return
        self.file = os.path.normpath(filePath)
        self.baseLocation = os.path.dirname(filePath)
        # Gets txt file name and substracts .txt extension
        fileName = os.path.join(self.baseLocation, self.file)

        # Cutting the path to get the name
        if platform.system() == "Windows":
            listLexicName = fileName.split('\\')

        else:
            listLexicName = fileName.split('/')

        # Getting file name
        lexicName = listLexicName[-1]
        lexicName = re.sub('\.txt$', '', lexicName)

        # Trying to open the files and store their content in a dictionnary
        # then store all of theses in a list
        try:
            fileHandle = open(fileName, encoding='utf-8')
            content = fileHandle.readlines()
            # Deleting spaces
            self.tempDict[lexicName] = [re.sub(r'\s', "", i) for i in content]
            fileHandle.close()
            self.setTitleList()
        except IOError:
            QMessageBox.warning(None, 'Textable', "Couldn't open file.",
                                QMessageBox.Ok)
            return

    def exportOneLexic(self):
        """Lets the user export the selected list to a text file"""
        # Opening file browser
        filePath = QFileDialog.getSaveFileName(
            self,
            u'Export Selected Lexical List',
            self.baseLocation,
        )

        # Setting content to save
        exportTitle = list(self.titleList)[self.selectedFields[0]]
        exportContent = self.tempDict[exportTitle]

        # Saving lexic content
        if filePath:
            outputFile = open(
                filePath,
                encoding='utf8',
                mode='w+',
                errors='xmlcharrefreplace',
            )

            outputFile.write('\n'.join(exportContent))
            outputFile.close()
            QMessageBox.information(None, 'Textable',
                                    'Lexical file correctly exported',
                                    QMessageBox.Ok)

    def exportAllLexics(self):
        """Lets the user export all the lexics"""
        # Opening file browser
        filePath = QFileDialog.getExistingDirectory(self,
                                                    u'Export Selected List',
                                                    self.baseLocation)

        if filePath:
            for name in self.tempDict:
                exportName = name.replace(" ", "_")
                if platform.system() == "Windows":
                    fullName = r"{}\{}.txt".format(filePath, exportName)
                else:
                    fullName = r"{}/{}.txt".format(filePath, exportName)

                outputFile = open(
                    fullName,
                    encoding='utf8',
                    mode='w+',
                    errors='xmlcharrefreplace',
                )
                outputFile.write('\n'.join(self.tempDict[name]))
                outputFile.close()
            QMessageBox.information(None, 'Textable',
                                    'Lexical files correctly exported',
                                    QMessageBox.Ok)

    def inputData(self, newInput):
        """Process incoming data."""
        pass

    def updateGUI(self):
        if self.titleEdit.text() != "":
            # Disabled elements
            self.SaveChanges.setDisabled(True)
            self.CancelChanges.setDisabled(True)
            self.EditList.setDisabled(True)
            self.ImportList.setDisabled(True)
            self.ExportList.setDisabled(True)
            self.ExportSelectedList.setDisabled(True)
            self.NewList.setDisabled(True)
            self.ClearList.setDisabled(True)
            self.RemoveSelectedList.setDisabled(True)

            # Enabled elements
            self.CommitList.setDisabled(False)
            self.CancelList.setDisabled(False)
            self.editor.setDisabled(False)
            self.titleEdit.setDisabled(False)

        if self.titleEdit.text() == "":
            # Enabled elements
            self.SaveChanges.setDisabled(False)
            self.CancelChanges.setDisabled(False)
            self.EditList.setDisabled(False)
            self.ImportList.setDisabled(False)
            self.ExportList.setDisabled(False)
            self.ExportSelectedList.setDisabled(False)
            self.NewList.setDisabled(False)
            self.ClearList.setDisabled(False)
            self.RemoveSelectedList.setDisabled(False)

            # Disabled elements
            self.CommitList.setDisabled(True)
            self.CancelList.setDisabled(True)
            self.editor.setDisabled(True)
            self.titleEdit.setDisabled(True)

        if not self.selectedFields:
            # Disabled elements if a list isn't selected
            self.RemoveSelectedList.setDisabled(True)
            self.ExportSelectedList.setDisabled(True)
            self.EditList.setDisabled(True)

    # The following method needs to be copied verbatim in
    # every Textable widget that sends a segmentation...
    def setCaption(self, title):
        if 'captionTitle' in dir(self):
            changed = title != self.captionTitle
            super().setCaption(title)
            if changed:
                self.sendButton.settingsChanged()
        else:
            super().setCaption(title)