def __init__(self, *args, **kwds): super().__init__(*args, **kwds) # Set style/theme try: self.setStyle( pyzo.themes[pyzo.config.settings.theme.lower()]['data']) except Exception as err: print("Could not load theme: " + str(err)) # Set font and zooming self.setFont(pyzo.config.view.fontname) self.setZoom(pyzo.config.view.zoom) # Create timer for autocompletion delay self._delayTimer = QtCore.QTimer(self) self._delayTimer.setSingleShot(True) self._delayTimer.timeout.connect(self._introspectNow) # For buffering autocompletion and calltip info self._callTipBuffer_name = '' self._callTipBuffer_time = 0 self._callTipBuffer_result = '' self._autoCompBuffer_name = '' self._autoCompBuffer_time = 0 self._autoCompBuffer_result = [] self.setAutoCompletionAcceptKeysFromStr( pyzo.config.settings.autoComplete_acceptKeys) self.completer().highlighted.connect(self.updateHelp) self.setIndentUsingSpaces( pyzo.config.settings.defaultIndentUsingSpaces) self.setIndentWidth(pyzo.config.settings.defaultIndentWidth) self.setAutocompletPopupSize(*pyzo.config.view.autoComplete_popupSize)
def setInfo(self, info=None): """ Set the shell info struct, and use it to update the widgets. Not via init, because this function also sets the tab name. """ # If info not given, use default as specified by the KernelInfo struct if info is None: info = KernelInfo() # Name n = self.parent().parent().count() if n > 1: info.name = "Shell config %i" % n # Store info self._info = info # Set widget values according to info try: for key in info: widget = self._shellInfoWidgets.get(key, None) if widget is not None: widget.setTheText(info[key]) except Exception as why: print("Error setting info in shell config:", why) print(info)
def saveTheme(self): """ Saves the current theme to the disk, in appDataDir/themes """ if self.cur_theme["builtin"]: return themeName = self.curThemeCmb.currentText().strip() if not themeName: return # Get user theme dir and make sure it exists dir = os.path.join(pyzo.appDataDir, "themes") if not os.path.isdir(dir): os.mkdir(dir) # Try to delete the old file if it exists (useful if it was renamed) try: os.remove(os.path.join(dir, self.cur_theme_key + ".theme")) except Exception: pass # This is the needed because of the SSDF format: # it doesn't accept dots, so we put underscore instead data = { x.replace(".", "_"): y for x, y in self.cur_theme["data"].items() } fname = os.path.join(dir, themeName + ".theme") ssdf.save(fname, {"name": themeName, "data": data}) print("Saved theme '%s' to '%s'" % (themeName, fname))
def setTheme(self, name): """ Set the theme by its name. The combobox becomes editable only if the theme is not builtin. This method is connected to the signal self.curThemeCmb.currentTextChanged ; so it also filters parasites events """ name = name.lower() if name != self.curThemeCmb.currentText(): # An item was added to the comboBox # But it's not a user action so we quit print(" -> Cancelled because this was not a user action") return if self.cur_theme_key == self.curThemeCmb.currentData(): # The user renamed an existing theme self.cur_theme["name"] = name return if name not in self.themes: return # Sets the curent theme key self.cur_theme_key = name self.cur_theme = self.themes[name] self.saveBtn.setEnabled(not self.cur_theme["builtin"]) self.curThemeCmb.setEditable(not self.cur_theme["builtin"]) for key, le in self.styleEdits.items(): le.setStyle(self.cur_theme["data"][key])
def saveFile(self, editor=None, filename=None): """ Save the file. returns: True if succesfull, False if fails """ # get editor if editor is None: editor = self.getCurrentEditor() elif isinstance(editor, int): index = editor editor = None if index >= 0: item = self._tabs.items()[index] editor = item.editor if editor is None: return False # get filename if filename is None: filename = editor._filename if not filename: return self.saveFileAs(editor) # let the editor do the low level stuff... try: editor.save(filename) except Exception as err: # Notify in logger print("Error saving file:", err) # Make sure the user knows m = QtGui.QMessageBox(self) m.setWindowTitle("Error saving file") m.setText(str(err)) m.setIcon(m.Warning) m.exec_() # Return now return False # get actual normalized filename filename = editor._filename # notify # TODO: message concerining line endings print("saved file: {} ({})".format(filename, editor.lineEndingsHumanReadable)) self._tabs.updateItems() # todo: this is where we once detected whether the file being saved was a style file. # Notify done return True
def saveFile(self, editor=None, filename=None): """ Save the file. returns: True if succesfull, False if fails """ # get editor if editor is None: editor = self.getCurrentEditor() elif isinstance(editor, int): index = editor editor = None if index>=0: item = self._tabs.items()[index] editor = item.editor if editor is None: return False # get filename if filename is None: filename = editor._filename if not filename: return self.saveFileAs(editor) # let the editor do the low level stuff... try: editor.save(filename) except Exception as err: # Notify in logger print("Error saving file:",err) # Make sure the user knows m = QtGui.QMessageBox(self) m.setWindowTitle("Error saving file") m.setText(str(err)) m.setIcon(m.Warning) m.exec_() # Return now return False # get actual normalized filename filename = editor._filename # notify # TODO: message concerining line endings print("saved file: {} ({})".format(filename, editor.lineEndingsHumanReadable)) self._tabs.updateItems() # todo: this is where we once detected whether the file being saved was a style file. # Notify done return True
def loadFile(self, filename, updateTabs=True): """ Load the specified file. On success returns the item of the file, also if it was already open.""" # Note that by giving the name of a tempfile, we can select that # temp file. # normalize path if filename[0] != '<': filename = normalizePath(filename) if not filename: return None # if the file is already open... for item in self._tabs.items(): if item.id == filename: # id gets _filename or _name for temp files break else: item = None if item: self._tabs.setCurrentItem(item) print("File already open: '{}'".format(filename)) return item # create editor try: editor = createEditor(self, filename) except Exception as err: # Notify in logger print("Error loading file: ", err) # Make sure the user knows m = QtGui.QMessageBox(self) m.setWindowTitle("Error loading file") m.setText(str(err)) m.setIcon(m.Warning) m.exec_() return None # create list item item = FileItem(editor) self._tabs.addItem(item, updateTabs) if updateTabs: self._tabs.setCurrentItem(item) # store the path self._lastpath = os.path.dirname(item.filename) return item
def __init__(self, *args, **kwds): super().__init__(*args, **kwds) # Set style/theme try: theme = pyzo.themes[pyzo.config.settings.theme.lower()]["data"] self.setStyle(theme) # autocomplete popup theme if pyzo.config.view.get("autoComplete_withTheme", False): editor_text_theme = theme["editor.text"].split(",") popup_background = editor_text_theme[1].split(":")[1] popup_text = editor_text_theme[0].split(":")[1] autoComplete_theme = "color: {}; background-color:{};".format( popup_text, popup_background) self.completer().popup().setStyleSheet(autoComplete_theme) except Exception as err: print("Could not load theme: " + str(err)) # Set font and zooming self.setFont(pyzo.config.view.fontname) self.setZoom(pyzo.config.view.zoom) self.setShowWhitespace(pyzo.config.view.showWhitespace) self.setHighlightMatchingBracket( pyzo.config.view.highlightMatchingBracket) # Create timer for autocompletion delay self._delayTimer = QtCore.QTimer(self) self._delayTimer.setSingleShot(True) self._delayTimer.timeout.connect(self._introspectNow) # For buffering autocompletion and calltip info self._callTipBuffer_name = "" self._callTipBuffer_time = 0 self._callTipBuffer_result = "" self._autoCompBuffer_name = "" self._autoCompBuffer_time = 0 self._autoCompBuffer_result = [] self.setAutoCompletionAcceptKeysFromStr( pyzo.config.settings.autoComplete_acceptKeys) self.completer().highlighted.connect(self.updateHelp) self.setIndentUsingSpaces( pyzo.config.settings.defaultIndentUsingSpaces) self.setIndentWidth(pyzo.config.settings.defaultIndentWidth) self.setAutocompletPopupSize(*pyzo.config.view.autoComplete_popupSize) self.setAutocompleteMinChars( pyzo.config.settings.autoComplete_minChars) self.setCancelCallback(self.restoreHelp)
def getInfo(self): info = self._info # Set struct values according to widgets try: for key, widget in self._shellInfoWidgets.items(): info[key] = widget.getTheText() except Exception as why: print("Error getting info in shell config:", why) print(info) # Return the original (but modified) ssdf Dict object return info
def getInfo(self): info = self._info # Set struct values according to widgets try: for key, widget in self._shellInfoWidgets.items(): info[key] = widget.getTheText() except Exception as why: print("Error getting info in shell config:", why) print(info) # Return the original (but modified) ssdf struct object return info
def normalizePath(path): """Normalize the path given. All slashes will be made the same (and doubles removed) The real case as stored on the file system is recovered. Returns None on error. """ # normalize path = os.path.abspath(path) # make sure it is defined from the drive up path = os.path.normpath(path) # If does not exist, return as is. # This also happens if the path's case is incorrect and the # file system is case sensitive. That's ok, because the stuff we # do below is intended to get the path right on case insensitive # file systems. if not os.path.isfile(path): return path # split drive name from the rest drive, rest = os.path.splitdrive(path) fullpath = drive.upper() + os.sep # make lowercase and split in parts parts = rest.lower().split(os.sep) parts = [part for part in parts if part] for part in parts: options = [x for x in os.listdir(fullpath) if x.lower() == part] if len(options) > 1: print("Error normalizing path: Ambiguous path names!") return path elif not options: print("Invalid path (part %s) in %s" % (part, fullpath)) return path fullpath = os.path.join(fullpath, options[0]) # remove last sep return fullpath
def normalizePath(path): """ Normalize the path given. All slashes will be made the same (and doubles removed) The real case as stored on the file system is recovered. Returns None on error. """ # normalize path = os.path.abspath(path) # make sure it is defined from the drive up path = os.path.normpath(path) # If does not exist, return as is. # This also happens if the path's case is incorrect and the # file system is case sensitive. That's ok, because the stuff we # do below is intended to get the path right on case insensitive # file systems. if not os.path.isfile(path): return path # split drive name from the rest drive, rest = os.path.splitdrive(path) fullpath = drive.upper() + os.sep # make lowercase and split in parts parts = rest.lower().split(os.sep) parts = [part for part in parts if part] for part in parts: options = [x for x in os.listdir(fullpath) if x.lower()==part] if len(options) > 1: print("Error normalizing path: Ambiguous path names!") return path elif not options: print("Invalid path (part %s) in %s" % (part, fullpath)) return path fullpath = os.path.join(fullpath, options[0]) # remove last sep return fullpath
def loadDir(self, path): """ Create a project with the dir's name and add all files contained in the directory to it. extensions is a komma separated list of extenstions of files to accept... """ # if the path does not exist, stop path = os.path.abspath(path) if not os.path.isdir(path): print("ERROR loading dir: the specified directory does not exist!") return # get extensions extensions = pyzo.config.advanced.fileExtensionsToLoadFromDir extensions = extensions.replace(',', ' ').replace(';', ' ') extensions = [ "." + a.lstrip(".").strip() for a in extensions.split(" ") ] # init item item = None # open all qualified files... self._tabs.setUpdatesEnabled(False) try: filelist = os.listdir(path) for filename in filelist: filename = os.path.join(path, filename) ext = os.path.splitext(filename)[1] if str(ext) in extensions: item = self.loadFile(filename, False) finally: self._tabs.setUpdatesEnabled(True) self._tabs.updateItems() # return lastopened item return item
def _setCurrentOpenFilesAsSsdfList(self, state): """ Set the state of the editor in terms of opened files. The input should be a list object as returned by ._getCurrentOpenFilesAsSsdfList(). """ # Init dict fileItems = {} # Process items for item in state: fname = item[0] if item[1] == 'hist': # select item (to make the history right) if fname in fileItems: self._tabs.setCurrentItem(fileItems[fname]) elif fname: # a file item, create editor-item and store itm = self.loadFile(fname) fileItems[fname] = itm # set position if itm: try: ed = itm.editor cursor = ed.textCursor() cursor.setPosition(int(item[1])) ed.setTextCursor(cursor) # set scrolling ed.verticalScrollBar().setValue(int(item[2])) #ed.centerCursor() #TODO: this does not work properly yet # set main and/or pinned? if 'main' in item: self._tabs._mainFile = itm.id if 'pinned' in item: itm._pinned = True except Exception as err: print('Could not set position for %s' % fname, err)
def _setCurrentOpenFilesAsSsdfList(self, state): """ Set the state of the editor in terms of opened files. The input should be a list object as returned by ._getCurrentOpenFilesAsSsdfList(). """ # Init dict fileItems = {} # Process items for item in state: fname = item[0] if item[1] == 'hist': # select item (to make the history right) if fname in fileItems: self._tabs.setCurrentItem( fileItems[fname] ) elif fname: # a file item, create editor-item and store itm = self.loadFile(fname) fileItems[fname] = itm # set position if itm: try: ed = itm.editor cursor = ed.textCursor() cursor.setPosition(int(item[1])) ed.setTextCursor(cursor) # set scrolling ed.verticalScrollBar().setValue(int(item[2])) #ed.centerCursor() #TODO: this does not work properly yet # set main and/or pinned? if 'main' in item: self._tabs._mainFile = itm.id if 'pinned' in item: itm._pinned = True except Exception as err: print('Could not set position for %s' % fname, err)
def loadDir(self, path): """ Create a project with the dir's name and add all files contained in the directory to it. extensions is a komma separated list of extenstions of files to accept... """ # if the path does not exist, stop path = os.path.abspath(path) if not os.path.isdir(path): print("ERROR loading dir: the specified directory does not exist!") return # get extensions extensions = pyzo.config.advanced.fileExtensionsToLoadFromDir extensions = extensions.replace(',',' ').replace(';',' ') extensions = ["."+a.lstrip(".").strip() for a in extensions.split(" ")] # init item item = None # open all qualified files... self._tabs.setUpdatesEnabled(False) try: filelist = os.listdir(path) for filename in filelist: filename = os.path.join(path, filename) ext = os.path.splitext(filename)[1] if str(ext) in extensions: item = self.loadFile(filename, False) finally: self._tabs.setUpdatesEnabled(True) self._tabs.updateItems() # return lastopened item return item