def getFileData(self, path: str): """ This retrieves the data from the file at the specified path. :param path: The path to read data from :return: Returns a string of the read in data """ # open the file with read only privileges logging.debug(path) file = open(path, 'r') # check if the file was opened if file.closed: logging.info("Could Not Open File - %s", path) return None # read all data then close file with file: try: data = file.read() except (ValueError, OSError) as e: corrupted_file = DialogBuilder(self.app, "File Corrupted", "Could not open the selected file.", "") button_box = QDialogButtonBox(QDialogButtonBox.Ok) corrupted_file.addButtonBox(button_box) corrupted_file.exec() logging.exception(e) logging.error("File could not be opened!") return None file.close() try: if self.encryptor is not None: data = self.encryptor.decrypt(data.encode()).decode() logging.debug("File was encrypted. Decrypting") except OSError: logging.info("File wasn't encrypted. Proceeding as normal") return data
def showCalendar(self): """ Shows a calendar with current date :return: CalendarWidget() """ logging.debug("Showing calendar") header = self.app.layout_props.getDefaultHeaderColorLight() select = self.app.layout_props.getDefaultSelectColor() calendar = CalendarWidget(header, select) setting_hint = "hints/showCalendarReminderHint" should_show_hint = not self.settings.contains( setting_hint) or self.settings.value(setting_hint) is True logging.info("%s: %s", setting_hint, str(should_show_hint)) if should_show_hint: hint = DialogBuilder(calendar, "Setting Reminders", "Hint: Select a date to create a Reminder!") hint.addButtonBox(QDialogButtonBox(QDialogButtonBox.Ok)) hint.exec() self.settings.setValue(setting_hint, not should_show_hint) def onCalendarReminder(): """ Creates a calendar reminder """ date: QDate = calendar.selectedDate() logging.info(date.toString("MM-dd-yyyy")) self.app.reminders.showDialog(calendar, False, date) calendar.selectionChanged.connect(onCalendarReminder) dialog = DialogBuilder() dialog.addWidget(calendar) dialog.layout().setContentsMargins(0, 0, 0, 0) dialog.setMinimumWidth(int(dialog.width() / 1.2)) dialog.setMinimumHeight(int(dialog.height() / 1.2)) dialog.exec()
def onSummaryAction(app, document): """ This spawns the prompt for the user to get the word embeddings needed for the doc summarizer :param app: Reference to the application :param document: Reference to the document :return: Returns summarized text if dictionaries are found """ # The action that gets called when the user selects a button on the prompt def onDialogButtonClicked(button): """ Handler for button click in dialog """ dependencyDialogHandler(app, button, document) # if summarizer has not been created create it if document.summarizer is None: logging.info( "Summarizer NOT initialized. Prompting user for dependency download." ) # prompt the user to select or Download the word word_embeddings download_dialog = DialogBuilder( app, "Dictionaries", "Would you like to download required dictionaries?", "If you have already downloaded them previously " "click open to select the location on disk.") button_box = QDialogButtonBox(QDialogButtonBox.Cancel | QDialogButtonBox.Open | QDialogButtonBox.Yes) download_dialog.addButtonBox(button_box) button_box.clicked.connect(onDialogButtonClicked) download_dialog.exec() return None # if there is already an instance of the summarizer logging.info("Summarizer is already initialized!") return document.summarizer.summarize(document.toPlainText())
def ensureDirectory(app, path: str): """ This will ensure that the directory we are saving the embedding files into exists. :param app: reference to the application :param path: path to the directory :return: Returns true on success and false otherwise """ # if the path doesnt exist make the directory if not os.path.exists(path): try: os.mkdir(path) logging.info("Created WordEmbeddings directory") return True except OSError as e: logging.exception(e) logging.error("Failed to create directory") return False # if it does exist prompt the user to clear the directory else: logging.info("Download path directory already exists!") # create the dialog to warn the user the dir will be cleared clear_dialog = DialogBuilder( app, "Download directory WordEmbeddings already exists...", "Would you like to clear the contents and proceed?", "Cancel will stop the download.") button_box = QDialogButtonBox(QDialogButtonBox.Cancel | QDialogButtonBox.Yes) clear_dialog.addButtonBox(button_box) # clear the directory if selected by the user if clear_dialog.exec(): logging.info("User chose to remove all contents") files = glob.glob(os.path.abspath(os.path.join(path, '*'))) for f in files: try: os.remove(f) logging.debug("Removed: %s", f) except OSError as e: dialog_fail = DialogBuilder( app, "Removing contents failed\nPermission denied") dialog_fail.show() logging.exception(e) logging.error("Error occured removing directory contents") return False return True logging.info("User chose not to clear directory. Exiting download") return False
def checkCurrentFileTime(self, document): """ this will check the times of the current file to see if its outdated. If it is up to date save it. If it is not up to date prompt the user if they want to update to the most recent changes or keep their current changes. :param document: reference to the document :return: returns true if the user wants to keep their changes, false otherwise """ if self.file_opened_time is not None and self.file_opened_time < os.path.getmtime( self.current_document.absoluteFilePath()): # if the file has been modified since the document was opened logging.warning("opened: %s, modified: %s", str(self.file_opened_time), str(os.path.getmtime(self.current_document.absoluteFilePath()))) # prompt the user if they want to keep their changes file_not_up_to_date_dialog = DialogBuilder(self.app, "File not up to date", "File not up to date", "The file has been " "externally " "modified. Would you " "like to keep your " "changes?") button_box = QDialogButtonBox(QDialogButtonBox.No | QDialogButtonBox.Yes) file_not_up_to_date_dialog.addButtonBox(button_box) if file_not_up_to_date_dialog.exec(): # if they want to keep their changes return true logging.debug("User chose to keep their changes") return True # if they want to update to the most recent changes on disk return false logging.debug("User chose to update to file saved on disk") data = self.getFileData(self.current_document.absoluteFilePath()) self.writeFileData(self.current_document.absoluteFilePath(), data) self.openDocument(document, self.current_document.absoluteFilePath(), False) self.file_opened_time = os.path.getatime(self.current_document.absoluteFilePath()) return False # return true if the file is up to date return True
def deleteReminder(key): """ Delete pop-up for reminder """ if key not in self.app.reminders.rem_list: logging.error("%s not in reminders list", key) fail() return title = self.app.reminders.rem_list[key]['title'] dialog = DialogBuilder(self.app, "Delete Reminder") dialog.setTitleText("Remove '" + title + "'?") dialog.setMsgText("This will permanently remove it from your reminders list.") dialog_but = QDialogButtonBox(QDialogButtonBox.Cancel | QDialogButtonBox.Yes) dialog.addButtonBox(dialog_but) if dialog.exec(): if not self.app.reminders.deleteReminder(key): logging.error("Could not remove reminder key %s", key) fail() else: logging.info("User chose to not delete the reminder")
def checkCurrentFileExists(self): """ this checks if the current file the user is working on exists. this returns a tuple of boolean values where the first value is if the file exists or if the user wants to keep the file. The second value in the tuple is if the file itself is missing. """ # check if the file exists if os.path.exists(self.current_document.absoluteFilePath()): # returns true that the file exists and false saying the file is not missing return True, False # if the file doesnt exist prompt the user to ask if they want to save it logging.warning("File not found") file_not_found_dialog = DialogBuilder(self.app, "File not found", "File not found", "The original file has been " "moved/deleted " "externally. Would you like " "to save a current " "copy of the file?") button_box = QDialogButtonBox(QDialogButtonBox.No | QDialogButtonBox.Yes) file_not_found_dialog.addButtonBox(button_box) # close the tab with the current name because we will create newtab if the user # wants to save the file and we dont want to keep it if the user does not want to save self.app.bar_open_tabs.forceCloseTab(self.current_document.absoluteFilePath()) if file_not_found_dialog.exec(): # if the user chose to save the document return true that the file will exist and # true that the file is in fact missing logging.info("User chose save the current document.") return True, True # if the user chose not to save the file return false that the file doesnt exist # and false that the file is missing logging.info("User chose NOT to save the file.") return False, False
def showDialog(self, block, show_calendar: bool = True, date: QDate = None): """ this will show the user a dialog of the the reminders :param block: Element to block by dialog :param show_calendar: Whether to include calendar or not :param date: Pre-defined date if calendar is not shown """ logging.info("showDialog: displays reminders dialog") # Set the default date format format_date_def: str = "yyyy-MM-dd" # ------------------------------# input_title = QLineEdit() input_title.setPlaceholderText("Title") # ------------------------------# # ------------------------------# # QPlain text edit allows text on multiple lines input_description = QPlainTextEdit() input_description.setMaximumHeight(120) def limitCharCount(): """ Limits the maximum number of characters allowed in description box """ # Limits the number of characters in input_description box text_content = input_description.toPlainText() length = len(text_content) max_length = 150 if length > max_length: logging.info("Description too long!") # Get the cursor and position cursor = input_description.textCursor() position = cursor.position() # Strip the text and set new_text = text_content[:max_length] input_description.setPlainText(new_text) # Restore cursor position cursor.setPosition(position - 1) input_description.setTextCursor(cursor) # Assign text limit listener input_description.textChanged.connect(limitCharCount) input_description.setPlaceholderText("Description") # ------------------------------# # ------------------------------# input_calendar = CalendarWidget() input_time = QTimeEdit() def updateTitle(): """ Updates title of the dialog box to selected date and time """ new_date: QDate = input_calendar.selectedDate() formatted_date = new_date.toString(format_date_def) new_time: QTime = input_time.time() formatted_time = new_time.toString("h:mm ap") new_title = formatted_date + " at " + formatted_time logging.debug("Update input_title %s", new_title) dialog.setTitleText(new_title) input_calendar.setFixedHeight(300) input_calendar.selectionChanged.connect(updateTitle) input_time.timeChanged.connect(updateTitle) # initial update of title with default values # ------------------------------# dialog = DialogBuilder(block, "Add reminder") dialog.addWidget(input_title) dialog.addWidget(input_description) # Determine whether to use calendar in dialog or not if show_calendar is True or date is None: dialog.addWidget(input_calendar) else: input_calendar.setSelectedDate(date) dialog.addWidget(input_time) updateTitle() button_box = QDialogButtonBox(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) dialog.addButtonBox(button_box) # Set size constrains for looks dialog.setFixedWidth(input_calendar.sizeHint().width()) dialog.setFixedHeight(dialog.sizeHint().height()) if dialog.exec(): if len(input_title.text()) != 0: if date is None: date = input_calendar.selectedDate() self.addReminder(date, input_time.text(), input_title.text(), input_description.toPlainText()) else: dialog_rem_error = DialogBuilder(block, "Error") dialog_rem_error.setTitleText( "This reminder does not have a title") dialog_rem_error.setMsgText("Reminder must contain a title.") dialog_buttons = QDialogButtonBox(QDialogButtonBox.Ok) dialog_rem_error.addButtonBox(dialog_buttons) # dialog_rem_error.show() if dialog_rem_error.exec(): self.showDialog(None, None, None) else: logging.info("Clicked cancel")
class EquationEditorWidget(QWidget): """ This is a widget is an interactive editor for the user to create and insert equations using latex """ def __init__(self, document): """ initializes the widgets :param document: reference to the the document :return: returns nothing """ logging.debug("") super().__init__() # initialize variables self.document = document self.url = "https://latex.codecogs.com/gif.latex?\\dpi{200}" self.pixmap = None self.equation = None self.equation_bar = None self.user_query = "" # create the QDialog and fill it in self.dialog = DialogBuilder(document) self.initUI() self.dialog.exec() def initUI(self): """ sets up the layout of the widget """ # creates the label to show what the user is working on self.equation = QLabel() self.dialog.addWidget(self.equation) # creates the qlineedit the user types into self.equation_bar = QLineEdit() self.dialog.addWidget(self.equation_bar) # widget to contain buttons widget = QWidget() hbox = QHBoxLayout(widget) # button to quit dialogs cancel = QPushButton("Cancel") cancel.clicked.connect(self.dialog.close) hbox.addWidget(cancel) # button to refresh the equation generate = QPushButton("Generate") generate.clicked.connect(self.onGenerate) hbox.addWidget(generate) # button to insert equation into the document insert = QPushButton("Insert") insert.clicked.connect(self.onInsert) hbox.addWidget(insert) self.dialog.addWidget(widget) def onGenerate(self): """ Generates the image from the users input. """ logging.info("User Generated Equation") if self.user_query != self.equation_bar.text(): self.user_query = self.equation_bar.text() # get the formatted equation from the web api req = requests.get(self.url + self.equation_bar.text()) # convert the image to a pixmap and display it to the user through the qlabel img = QImage() img.loadFromData(req.content) self.pixmap = QPixmap(img) self.equation.setPixmap(self.pixmap) def onInsert(self): """ When the user selects to insert the image. """ # generate the image if it has not been yet self.onGenerate() # if the pixmap is not none insert it to the document if self.pixmap is not None: logging.info("Inserted Equation") cursor = self.document.textCursor() # scale the pixmap and get its image font_size = self.document.currentCharFormat().fontPointSize() self.pixmap = self.pixmap.scaledToHeight(font_size + 35, Qt.SmoothTransformation) img = self.pixmap.toImage() # add the image to the document and close the prompt cursor.insertImage(img) self.dialog.close() else: logging.warning("No Pixmap Found")
def dependencyDialogHandler(app, button, document=None): """ This will handle the users choice for the Download prompt the user will select where they want to find/Download the files :param app: an application reference :param button: the button the user selected :param document: document reference :return: returns summary """ logging.debug("User selected %s", button.text()) # quit if the user selected cancel if button.text() == '&Cancel': return path_parent = QFileDialog.getExistingDirectory( app, "Select Folder To Download To", app.left_menu.model.rootPath(), QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks) if path_parent == "": logging.info("User Cancelled File Dialog") return path_child = os.path.abspath(os.path.join(path_parent, 'WordEmbeddings')) def files_exist(path1: str, path2: str): """ Checks if the files exist within any of the 2 directories """ if os.path.exists( os.path.abspath(os.path.join(path1, 'glove.6B.100d.vocab'))) and\ os.path.exists(os.path.abspath(os.path.join(path1, 'glove.6B.100d.npy'))): return path1 if os.path.exists( os.path.abspath(os.path.join(path2, 'glove.6B.100d.vocab'))) and \ os.path.exists(os.path.abspath(os.path.join(path2, 'glove.6B.100d.npy'))): return path2 return None existing_path = files_exist(path_parent, path_child) if existing_path is None: zip_file = 'glove.6B.100d.zip' # prompt the user that they need to download the dependency files if not os.path.exists( os.path.abspath(os.path.join(path_child, zip_file))): logging.warning("Missing Files and ZIP. To re-download") if button.text() == "Open": logging.error("Dictionaries not found in directory") download_dialog = DialogBuilder( app, "Error!", "Error - Dictionaries not found!", "Please select a different path" " or download them again.") button_box = QDialogButtonBox(QDialogButtonBox.Ok) download_dialog.addButtonBox(button_box) download_dialog.exec() return if not ensureDirectory(app, path_child): return should_download = True # create loading bar dialog and start the download thread progress_bar_dialog = DialogBuilder( app, "Download Progress", "Downloading Dictionaries...", "Please do not close this window") progress_bar = progress_bar_dialog.addProgressBar((0, 100)) progress_bar_dialog.open() else: logging.info("Found ZIP: %s. No need for re-download", zip_file) should_download = False progress_bar = None if app.thread_placeholder is None: app.thread_placeholder = ExecuteThread( getWordEmbeddings, (path_child, should_download, progress_bar)) def callback(): """ Callback for our thread """ result = app.thread_placeholder.getReturn() if result is True: logging.debug("Summarizer Thread Finished") initializeSummarizer(path_child, app, document) app.thread_placeholder = None app.right_menu.updateSummary() else: logging.error("Thread finished unsuccessfully") app.thread_placeholder.setCallback(callback) app.thread_placeholder.start() else: logging.warning("Thread placeholder already in use") else: logging.info("Found glove.6B.100d.vocab and glove.6B.100d.npy") # fill the dictionary with the word embeddings initializeSummarizer(existing_path, app, document, True)
def openDocument(self, document, path: str, save: bool = True): """ This will open the file with the given path and display it on the document :param document: :param path: :return: returns whether or not the open succeeded """ # if there is already a file open save before the Document's text is overwritten if save and self.current_document is not None: self.saveDocument(document) if self.current_document is None and document.toPlainText() != "": # if the file doesnt exist prompt the user to ask if they want to save it logging.info("File not found") file_not_found_dialog = DialogBuilder(self.app, "File not saved", "This file has not been saved. " "Would you like to save it?") button_box = QDialogButtonBox(QDialogButtonBox.No | QDialogButtonBox.Yes) file_not_found_dialog.addButtonBox(button_box) if file_not_found_dialog.exec(): logging.info("User chose save the current document.") self.newFile(document, data=document.toPlainText()) # if the document is not already open if path not in self.open_documents: # if the user clicks out of the open file prompt do nothing if path == '': logging.info("No File Path Given") return False # retrieve the text from the file you are attempting to open data = self.getFileData(path) if data is None: return False # appends the path to the list of open documents and sets it to the current document self.open_documents[path] = QFileInfo(path) self.current_document = self.open_documents[path] self.file_opened_time = os.path.getatime(self.current_document.absoluteFilePath()) # if the file is not opened in the open tabs bar open it if path not in self.app.bar_open_tabs.open_tabs: self.app.bar_open_tabs.addTab(path) logging.info("Opened Document - %s", path) # if the document has already been opened in this session else: # get the data from the file and set the current document data = self.getFileData(path) if data is None: return False self.current_document = self.open_documents[path] self.file_opened_time = os.path.getatime(self.current_document.absoluteFilePath()) self.app.bar_open_tabs.setCurrentIndex(self.app.bar_open_tabs.open_tabs[path]) logging.info("Document Already Open - %s", path) # check for the proprietary file extension .lef and update the top bar accordingly document.setFormatText(data, self.current_document.suffix() == 'lef') # Update the formatting buttons based on the state self.app.updateFormatBtnsState(self.current_document.suffix() == 'lef') # update the document shown to the user self.app.right_menu.updateDetails(path) # self.app.left_menu.selectItemFromPath(path) return True