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()
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)