Esempio n. 1
0
    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)
Esempio n. 2
0
    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)
Esempio n. 3
0
 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)
Esempio n. 4
0
    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))
Esempio n. 5
0
    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])
Esempio n. 6
0
    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
Esempio n. 7
0
    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
Esempio n. 8
0
    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
Esempio n. 9
0
 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
Esempio n. 10
0
    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)
Esempio n. 11
0
 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
Esempio n. 12
0
    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
Esempio n. 13
0
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
Esempio n. 14
0
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
Esempio n. 15
0
    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
Esempio n. 16
0
    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)
Esempio n. 17
0
 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)
Esempio n. 18
0
 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