Esempio n. 1
0
 def run(self):
     self.ipython_shell = None
     from __main__ import __dict__ as glbs
     while True:
         if self.ipython_shell is None and '__ipythonshell__' in glbs:
             self.ipython_shell = glbs['__ipythonshell__'].IP
             glbs = self.ipython_shell.user_ns
         try:
             command = read_packet(self.request)
             result = eval(command, glbs, self.locals)
             self.locals["_"] = result
             output = pickle.dumps(result, pickle.HIGHEST_PROTOCOL)
             write_packet(self.request, output)
         except StandardError:
             out = StringIO.StringIO()
             traceback.print_exc(file=out)
             if DEBUG:
                 from spyderlib.config import get_conf_path
                 import time
                 errors = open(get_conf_path('monitor_errors.txt'), 'a')
                 print >>errors, "*"*5, time.ctime(time.time()), "*"*49
                 print >>errors, "command:", command
                 print >>errors, "error:"
                 traceback.print_exc(file=errors)
                 print >>errors, " "
             data = out.getvalue()
             write_packet(self.request, data)
Esempio n. 2
0
def save_session(filename):
    """Save Spyder session"""
    local_fname = get_conf_path(osp.basename(filename))
    filename = osp.abspath(filename)
    old_cwd = os.getcwdu()
    os.chdir(get_conf_path())
    error_message = None
    try:
        tar = tarfile.open(local_fname, "w")
        for fname in SAVED_CONFIG_FILES:
            if osp.isfile(fname):
                tar.add(fname)
        tar.close()
        shutil.move(local_fname, filename)
    except Exception, error:
        error_message = unicode(error)
Esempio n. 3
0
def save_session(filename):
    """Save Spyder session"""
    local_fname = get_conf_path(osp.basename(filename))
    filename = osp.abspath(filename)
    old_cwd = os.getcwdu()
    os.chdir(get_conf_path())
    error_message = None
    try:
        tar = tarfile.open(local_fname, "w")
        for fname in SAVED_CONFIG_FILES:
            if osp.isfile(fname):
                tar.add(fname)
        tar.close()
        shutil.move(local_fname, filename)
    except Exception, error:
        error_message = unicode(error)
Esempio n. 4
0
def reset_session():
    """Remove all config files"""
    print >>STDERR, "*** Reset Spyder settings to defaults ***"
    for fname in SAVED_CONFIG_FILES:
        cfg_fname = get_conf_path(fname)
        if osp.isfile(cfg_fname):
            os.remove(cfg_fname)
            print >>STDERR, "removing:", cfg_fname
Esempio n. 5
0
    def __init__(self, parent=None, namespace=None, commands=None, message="",
                 font=None, debug=False, exitfunc=None, profile=False):
        PythonShellWidget.__init__(self, parent,
                                   get_conf_path('.history_ic.py'),
                                   debug, profile)
        
        if font is not None:
            self.set_font(font)
        
        # Capture all interactive input/output 
        self.initial_stdout = sys.stdout
        self.initial_stderr = sys.stderr
        self.initial_stdin = sys.stdin
        self.stdout = IOHandler('<spyder_stdout>', 'w',
                                write_func=self.write,
                                flush_func=lambda: self.flush(error=False))
        self.stderr = IOHandler('<spyder_stderr>', 'w',
                                write_func=self.write_error,
                                flush_func=lambda: self.flush(error=True))
        self.stdin = IOHandler('<spyder_stdin>', 'r',
                               read_func=self.wait_input)
        self.redirect_stds()
        
        # KeyboardInterrupt support
        self.interrupted = False
        self.connect(self, SIGNAL("keyboard_interrupt()"),
                     self.keyboard_interrupt)
        
        # Code completion / calltips
        getcfg = lambda option: CONF.get('shell', option)
        case_sensitive = getcfg('autocompletion/case-sensitivity')
        show_single = getcfg('autocompletion/select-single')
        from_document = getcfg('autocompletion/from-document')
        self.setup_code_completion(case_sensitive, show_single, from_document)
        
        # keyboard events management
        self.busy = False
        self.eventqueue = []
        
        # Execution Status
        self.more = False

        # Init interpreter
        self.exitfunc = exitfunc
        self.commands = commands
        self.message = message
        self.interpreter = None
        self.start_interpreter(namespace)
        
        # Clear status bar
        self.emit(SIGNAL("status(QString)"), QString())
Esempio n. 6
0
    def __init__(self, parent=None, wdir=None, history_filename=None,
                 show_icontext=True):
        QWidget.__init__(self, parent)
        
        self.run_button = None
        self.kill_button = None
        self.options_button = None
        self.icontext_action = None
        
        if wdir is None:
            wdir = osp.dirname(osp.abspath(self.fname))
        self.wdir = wdir if osp.isdir(wdir) else None
        self.arguments = ""
        
        self.shell = self.SHELL_CLASS(parent, get_conf_path(history_filename))
        self.connect(self.shell, SIGNAL("execute(QString)"),
                     self.send_to_process)
        self.connect(self.shell, SIGNAL("keyboard_interrupt()"),
                     self.keyboard_interrupt)
        # Redirecting some SIGNALs:
        self.connect(self.shell, SIGNAL('redirect_stdio(bool)'),
                     lambda state: self.emit(SIGNAL('redirect_stdio(bool)'),
                                             state))
        
        self.state_label = QLabel()
        self.time_label = QLabel()
                
        hlayout = QHBoxLayout()
        hlayout.addWidget(self.state_label)
        hlayout.addStretch(0)
        hlayout.addWidget(self.time_label)
        hlayout.addStretch(0)
        for button in self.get_toolbar_buttons():
            hlayout.addWidget(button)
        
        vlayout = QVBoxLayout()
        vlayout.addLayout(hlayout)
        vlayout.addWidget(self.get_shell_widget())
        self.setLayout(vlayout)
        self.resize(640, 480)
        if parent is None:
            self.setWindowIcon(self.get_icon())
            self.setWindowTitle(translate('ExternalShellBase', "Console"))

        self.t0 = None
        self.timer = QTimer(self)

        self.process = None
        
        self.is_closing = False
Esempio n. 7
0
def load_session(filename):
    """Load Spyder session"""
    filename = osp.abspath(filename)
    old_cwd = os.getcwdu()
    os.chdir(osp.dirname(filename))
    error_message = None
    renamed = False
    try:
        tar = tarfile.open(filename, "r")
        extracted_files = tar.getnames()
        
        # Rename original config files
        for fname in extracted_files:
            orig_name = get_conf_path(fname)
            bak_name = get_conf_path(fname+'.bak')
            if osp.isfile(bak_name):
                os.remove(bak_name)
            if osp.isfile(orig_name):
                os.rename(orig_name, bak_name)
        renamed = True
        
        tar.extractall()
        
        for fname in extracted_files:
            shutil.move(fname, get_conf_path(fname))
            
    except Exception, error:
        error_message = unicode(error)
        if renamed:
            # Restore original config files
            for fname in extracted_files:
                orig_name = get_conf_path(fname)
                bak_name = get_conf_path(fname+'.bak')
                if osp.isfile(orig_name):
                    os.remove(orig_name)
                if osp.isfile(bak_name):
                    os.rename(bak_name, orig_name)
Esempio n. 8
0
def load_session(filename):
    """Load Spyder session"""
    filename = osp.abspath(filename)
    old_cwd = os.getcwdu()
    os.chdir(osp.dirname(filename))
    error_message = None
    renamed = False
    try:
        tar = tarfile.open(filename, "r")
        extracted_files = tar.getnames()
        
        # Rename original config files
        for fname in extracted_files:
            orig_name = get_conf_path(fname)
            bak_name = get_conf_path(fname+'.bak')
            if osp.isfile(bak_name):
                os.remove(bak_name)
            if osp.isfile(orig_name):
                os.rename(orig_name, bak_name)
        renamed = True
        
        tar.extractall()
        
        for fname in extracted_files:
            shutil.move(fname, get_conf_path(fname))
            
    except Exception, error:
        error_message = unicode(error)
        if renamed:
            # Restore original config files
            for fname in extracted_files:
                orig_name = get_conf_path(fname)
                bak_name = get_conf_path(fname+'.bak')
                if osp.isfile(orig_name):
                    os.remove(orig_name)
                if osp.isfile(bak_name):
                    os.rename(bak_name, orig_name)
Esempio n. 9
0
    def __init__(self, parent=None, wdir=None, history_filename=None):
        QWidget.__init__(self, parent)
        if wdir is None:
            wdir = osp.dirname(osp.abspath(self.fname))
        self.wdir = wdir if osp.isdir(wdir) else None
        self.arguments = ""
        
        self.shell = self.SHELL_CLASS(parent, get_conf_path(history_filename))
        self.connect(self.shell, SIGNAL("execute(QString)"),
                     self.send_to_process)
        self.connect(self.shell, SIGNAL("keyboard_interrupt()"),
                     self.keyboard_interrupt)
        # Redirecting some SIGNALs:
        self.connect(self.shell, SIGNAL('redirect_stdio(bool)'),
                     lambda state: self.emit(SIGNAL('redirect_stdio(bool)'),
                                             state))
        
        self.state_label = QLabel()
        self.time_label = QLabel()
                
        hlayout = QHBoxLayout()
        hlayout.addWidget(self.state_label)
        hlayout.addStretch(0)
        hlayout.addWidget(self.time_label)
        hlayout.addStretch(0)
        for button in self.get_toolbar_buttons():
            hlayout.addWidget(button)
        
        vlayout = QVBoxLayout()
        vlayout.addLayout(hlayout)
        vlayout.addWidget(self.get_shell_widget())
        self.setLayout(vlayout)
        self.resize(640, 480)
        if parent is None:
            self.setWindowIcon(self.get_icon())
            self.setWindowTitle(self.tr("Console"))

        self.t0 = None
        self.timer = QTimer(self)

        self.process = None
        
        self.is_closing = False
Esempio n. 10
0
    def __init__(self, parent=None, namespace=None, commands=[], message="",
                 max_line_count=300, font=None, debug=False, exitfunc=None,
                 profile=False, multithreaded=True):
        PythonShellWidget.__init__(self, parent,
                                   get_conf_path('.history_internal.py'),
                                   debug, profile)
        
        self.multithreaded = multithreaded
        
        self.setMaximumBlockCount(max_line_count)
        
        if font is not None:
            self.set_font(font)
        
        # KeyboardInterrupt support
        self.interrupted = False # used only for not-multithreaded mode
        self.connect(self, SIGNAL("keyboard_interrupt()"),
                     self.keyboard_interrupt)
        
        # Code completion / calltips
        getcfg = lambda option: CONF.get('shell', option)
        case_sensitive = getcfg('codecompletion/case-sensitivity')
        show_single = getcfg('codecompletion/select-single')
        from_document = getcfg('codecompletion/from-document')
        self.setup_code_completion(case_sensitive, show_single, from_document)
        
        # keyboard events management
        self.eventqueue = []

        # Init interpreter
        self.exitfunc = exitfunc
        self.commands = commands
        self.message = message
        self.interpreter = None
        self.start_interpreter(namespace)
        
        # Clear status bar
        self.emit(SIGNAL("status(QString)"), QString())
Esempio n. 11
0
    def __init__(self, parent, history_filename, debug=False, profile=False):
        """
        parent : specifies the parent widget
        """
        ConsoleBaseWidget.__init__(self, parent)

        # Prompt position: tuple (line, index)
        self.current_prompt_pos = None
        self.new_input_line = True

        # History
        self.histidx = None
        self.hist_wholeline = False
        assert isinstance(history_filename, (str, unicode))
        self.history_filename = history_filename
        self.history = self.load_history()

        # Session
        self.historylog_filename = CONF.get('main', 'historylog_filename',
                                            get_conf_path('history.log'))

        # Context menu
        self.menu = None
        self.setup_context_menu()

        # Debug mode
        self.debug = debug

        # Simple profiling test
        self.profile = profile

        # write/flush
        self.__buffer = []
        self.__timestamp = 0.0

        # Give focus to widget
        self.setFocus()
Esempio n. 12
0
    def __init__(self, parent, history_filename, debug=False, profile=False):
        """
        parent : specifies the parent widget
        """
        ConsoleBaseWidget.__init__(self, parent)
        
        # Prompt position: tuple (line, index)
        self.current_prompt_pos = None
        self.new_input_line = True
        
        # History
        self.histidx = None
        self.hist_wholeline = False
        assert isinstance(history_filename, (str, unicode))
        self.history_filename = history_filename
        self.history = self.load_history()
        
        # Session
        self.historylog_filename = CONF.get('main', 'historylog_filename',
                                            get_conf_path('history.log'))
        
        # Context menu
        self.menu = None
        self.setup_context_menu()

        # Debug mode
        self.debug = debug

        # Simple profiling test
        self.profile = profile
        
        # write/flush
        self.__buffer = []
        self.__timestamp = 0.0

        # Give focus to widget
        self.setFocus()
Esempio n. 13
0
class DocViewer(ReadOnlyEditor):
    """
    Docstrings viewer widget
    """
    ID = 'docviewer'
    LOG_PATH = get_conf_path('.docviewer')

    def __init__(self, parent):
        ReadOnlyEditor.__init__(self, parent)

        self.shell = None

        # locked = disable link with Console
        self.locked = False
        self._last_text = None

        # Object name
        layout_edit = QHBoxLayout()
        layout_edit.addWidget(QLabel(self.tr("Object")))
        self.combo = DocComboBox(self)
        layout_edit.addWidget(self.combo)
        self.combo.setMaxCount(CONF.get(self.ID, 'max_history_entries'))
        dvhistory = self.load_dvhistory()
        self.combo.addItems(dvhistory)

        # Doc/source checkbox
        self.help_or_doc = QCheckBox(self.tr("Show source"))
        self.connect(self.help_or_doc, SIGNAL("stateChanged(int)"),
                     self.toggle_help)
        layout_edit.addWidget(self.help_or_doc)
        self.docstring = None
        self.autosource = False
        self.toggle_help(Qt.Unchecked)

        # Lock checkbox
        self.locked_button = create_toolbutton(self,
                                               triggered=self.toggle_locked)
        layout_edit.addWidget(self.locked_button)
        self._update_lock_icon()

        # Main layout
        layout = QVBoxLayout()
        layout.addLayout(layout_edit)
        layout.addWidget(self.editor)
        layout.addWidget(self.find_widget)
        self.setLayout(layout)

    def get_widget_title(self):
        """Return widget title"""
        return self.tr('Doc')

    def get_focus_widget(self):
        """
        Return the widget to give focus to when
        this plugin's dockwidget is raised on top-level
        """
        self.combo.lineEdit().selectAll()
        return self.combo

    def load_dvhistory(self, obj=None):
        """Load history from a text file in user home directory"""
        if osp.isfile(self.LOG_PATH):
            dvhistory = [
                line.replace('\n', '')
                for line in file(self.LOG_PATH, 'r').readlines()
            ]
        else:
            dvhistory = []
        return dvhistory

    def save_dvhistory(self):
        """Save history to a text file in user home directory"""
        file(self.LOG_PATH, 'w').write("\n".join( \
            [ unicode( self.combo.itemText(index) )
                for index in range(self.combo.count()) ] ))

    def toggle_help(self, state):
        """Toggle between docstring and help()"""
        self.docstring = (state == Qt.Unchecked)
        self.refresh(force=True)

    def toggle_locked(self):
        """
        Toggle locked state
        locked = disable link with Console
        """
        self.locked = not self.locked
        self._update_lock_icon()

    def _update_lock_icon(self):
        """Update locked state icon"""
        icon = get_icon("lock.png" if self.locked else "lock_open.png")
        self.locked_button.setIcon(icon)
        tip = self.tr("Unlock") if self.locked else self.tr("Lock")
        self.locked_button.setToolTip(tip)

    def set_shell(self, shell):
        """Bind to shell"""
        self.shell = shell

    def refresh(self, text=None, force=False):
        """Refresh widget"""
        if (self.locked and not force):
            return

        if text is None:
            text = self.combo.currentText()
        else:
            index = self.combo.findText(text)
            while index != -1:
                self.combo.removeItem(index)
                index = self.combo.findText(text)
            self.combo.insertItem(0, text)
            self.combo.setCurrentIndex(0)

        self.set_help(text)
        self.save_dvhistory()
        if hasattr(self.main, 'tabifiedDockWidgets'):
            # 'QMainWindow.tabifiedDockWidgets' was introduced in PyQt 4.5
            if self.dockwidget and self.dockwidget.isVisible() \
               and not self.ismaximized and text != self._last_text:
                dockwidgets = self.main.tabifiedDockWidgets(self.dockwidget)
                if self.main.console.dockwidget not in dockwidgets and \
                   (hasattr(self.main, 'extconsole') and \
                    self.main.extconsole.dockwidget not in dockwidgets):
                    self.dockwidget.raise_()
        self._last_text = text

    def set_help(self, obj_text):
        """Show help"""
        if self.shell is None:
            return
        if isinstance(self.shell, ExtPyQsciShell):
            if not self.shell.externalshell.is_running():
                # Binded external shell was stopped:
                # binding DocViewer to interactive console instead
                self.shell = self.main.console.shell
        obj_text = unicode(obj_text)
        doc_text = self.shell.get_doc(obj_text)
        try:
            source_text = self.shell.get_source(obj_text)
        except (TypeError, IOError):
            source_text = None
        if self.docstring:
            hlp_text = doc_text
            if hlp_text is None:
                hlp_text = source_text
                if hlp_text is None:
                    hlp_text = self.tr("No documentation available.")
        else:
            hlp_text = source_text
            if hlp_text is None:
                hlp_text = doc_text
                if hlp_text is None:
                    hlp_text = self.tr("No source code available.")
        self.editor.set_text(hlp_text)
        self.editor.set_cursor_position('sof')
Esempio n. 14
0
class Workspace(DictEditorTableView, PluginMixin):
    """
    Workspace widget (namespace explorer)
    """
    ID = 'workspace'
    TEMPFILE_PATH = get_conf_path('.temp.spydata')

    def __init__(self, parent):
        self.interpreter = None
        self.namespace = None
        self.filename = None
        truncate = CONF.get(self.ID, 'truncate')
        inplace = CONF.get(self.ID, 'inplace')
        minmax = CONF.get(self.ID, 'minmax')
        collvalue = CONF.get(self.ID, 'collvalue')
        DictEditorTableView.__init__(self,
                                     parent,
                                     None,
                                     names=True,
                                     truncate=truncate,
                                     inplace=inplace,
                                     minmax=minmax,
                                     collvalue=collvalue)
        PluginMixin.__init__(self, parent)

        self.setup_io()
        self.load_temp_namespace()

        self.setFont(get_font(self.ID))

    def setup_io(self):
        """Setup I/O functions and filters"""
        iofuncs = (
            ('.spydata', translate('Workspace', "Spyder data files"),
             load_dictionary, save_dictionary),
            ('.npy', translate('Workspace', "NumPy arrays"), load_array, None),
            ('.mat', translate('Workspace',
                               "Matlab files"), load_matlab, save_matlab),
            ('.csv', translate('Workspace',
                               "CSV text files"), 'import_wizard', None),
            ('.txt', translate('Workspace',
                               "Text files"), 'import_wizard', None),
            ('.jpg', translate('Workspace', "JPEG images"), load_image, None),
            ('.png', translate('Workspace', "PNG images"), load_image, None),
            ('.gif', translate('Workspace', "GIF images"), load_image, None),
            ('.tif', translate('Workspace', "TIFF images"), load_image, None),
            ('.dcm', translate('Workspace', "DICOM images"), load_dicom, None),
        )
        load_funcs = {}
        save_funcs = {}
        load_filters = []
        save_filters = []
        load_ext = []
        for ext, name, loadfunc, savefunc in iofuncs:
            filter_str = unicode(name + " (*%s)" % ext)
            if loadfunc is not None:
                load_filters.append(filter_str)
                load_funcs[ext] = loadfunc
                load_ext.append(ext)
            if savefunc is not None:
                save_filters.append(filter_str)
                save_funcs[ext] = savefunc
        load_filters.insert(0, unicode(self.tr("Supported files")+" (*"+\
                                       " *".join(load_ext)+")"))
        self.load_filters = "\n".join(load_filters)
        self.save_filters = "\n".join(save_filters)
        self.load_funcs = load_funcs
        self.save_funcs = save_funcs

    def get_widget_title(self):
        """Return widget title"""
        return self.tr('Workspace')

    def get_focus_widget(self):
        """
        Return the widget to give focus to when
        this plugin's dockwidget is raised on top-level
        """
        return self

    def set_interpreter(self, interpreter):
        """Bind to interpreter"""
        self.interpreter = interpreter
        self.refresh()

    def get_namespace(self, itermax=ITERMAX):
        """Return filtered namespace"""
        return wsfilter(self.namespace, itermax=itermax)

    def __clear_namespace(self):
        """Clear namespace"""
        keys = self.get_namespace().keys()
        for key in keys:
            self.namespace.pop(key)
        self.refresh()

    def clear(self):
        """Ask to clear workspace"""
        answer = QMessageBox.question(
            self, self.tr("Clear workspace"),
            self.tr("Do you want to clear all data from workspace?"),
            QMessageBox.Yes | QMessageBox.No)
        if answer == QMessageBox.Yes:
            self.__clear_namespace()

    def refresh(self):
        """Refresh widget"""
        if CONF.get(self.ID, 'autorefresh'):
            self.refresh_editor()

    def refresh_editor(self):
        """Refresh DictEditor"""
        if self.interpreter is not None:
            self.namespace = self.interpreter.namespace
        self.set_filter(wsfilter)
        self.set_data(self.namespace)
        self.adjust_columns()

    def set_actions(self):
        """Setup actions"""
        import_action = create_action(self,
                                      self.tr("Import data..."),
                                      None,
                                      'ws_open.png',
                                      self.tr("Import data to workspace"),
                                      triggered=self.import_data)
        save_as_action = create_action(self,
                                       self.tr("Save workspace as..."),
                                       None,
                                       'ws_save_as.png',
                                       self.tr("Save workspace as..."),
                                       triggered=self.save_as)
        exclude_private_action = create_action(
            self,
            self.tr("Exclude private references"),
            tip=self.tr("Exclude references which name starts"
                        " with an underscore"),
            toggled=self.toggle_exclude_private)
        exclude_private_action.setChecked(CONF.get(self.ID, 'exclude_private'))
        exclude_upper_action = create_action(
            self,
            self.tr("Exclude capitalized references"),
            tip=self.tr("Exclude references which name starts with an "
                        "upper-case character"),
            toggled=self.toggle_exclude_upper)
        exclude_upper_action.setChecked(CONF.get(self.ID, 'exclude_upper'))
        exclude_unsupported_action = create_action(
            self,
            self.tr("Exclude unsupported data types"),
            tip=self.tr("Exclude references to unsupported data types"
                        " (i.e. which won't be handled/saved correctly)"),
            toggled=self.toggle_exclude_unsupported)
        exclude_unsupported_action.setChecked(
            CONF.get(self.ID, 'exclude_unsupported'))

        refresh_action = create_action(self,
                                       self.tr("Refresh workspace"),
                                       None,
                                       'ws_refresh.png',
                                       self.tr("Refresh workspace"),
                                       triggered=self.refresh_editor)

        autorefresh_action = create_action(self,
                                           self.tr("Auto refresh"),
                                           toggled=self.toggle_autorefresh)
        autorefresh_action.setChecked(CONF.get(self.ID, 'autorefresh'))

        autosave_action = create_action(
            self,
            self.tr("Auto save"),
            toggled=self.toggle_autosave,
            tip=self.tr("Automatically save workspace in a temporary file"
                        " when quitting"))
        autosave_action.setChecked(CONF.get(self.ID, 'autosave'))

        clear_action = create_action(
            self,
            self.tr("Clear workspace"),
            icon=get_icon('clear.png'),
            tip=self.tr("Clear all data from workspace"),
            triggered=self.clear)
        font_action1 = create_action(self,
                                     self.tr("Header Font..."),
                                     None,
                                     'font.png',
                                     self.tr("Set font style"),
                                     triggered=self.change_font1)
        font_action2 = create_action(self,
                                     self.tr("Value Font..."),
                                     None,
                                     'font.png',
                                     self.tr("Set font style"),
                                     triggered=self.change_font2)

        option_menu = QMenu(self.tr("Workspace settings"), self)
        option_menu.setIcon(get_icon('tooloptions.png'))
        add_actions(
            option_menu,
            (autosave_action, None, self.truncate_action, self.inplace_action,
             None, exclude_private_action, exclude_upper_action,
             exclude_unsupported_action, font_action1, font_action2))
        menu_actions = (import_action, save_as_action, refresh_action,
                        autorefresh_action, clear_action, option_menu)
        toolbar_actions = (refresh_action, import_action, save_as_action)
        return (menu_actions, toolbar_actions)

    def change_font1(self):
        """Change font"""
        self.__change_font('dicteditor_header')

    def change_font2(self):
        """Change font"""
        self.__change_font('dicteditor')

    def __change_font(self, section):
        font, valid = QFontDialog.getFont(get_font(section), self,
                                          self.tr("Select a new font"))
        if valid:
            set_font(font, section)

    def toggle_autorefresh(self, checked):
        """Toggle autorefresh mode"""
        CONF.set(self.ID, 'autorefresh', checked)
        self.refresh()

    def toggle_autosave(self, checked):
        """Toggle autosave mode"""
        CONF.set(self.ID, 'autosave', checked)

    def closing(self, cancelable=False):
        """Perform actions before parent main window is closed"""
        if CONF.get(self.ID, 'autosave'):
            # Saving workspace
            self.__save(self.TEMPFILE_PATH)
        else:
            workspace = self.get_namespace(itermax=-1)
            if workspace is None:
                return True
            refnb = len(workspace)
            if refnb > 1:
                srefnb = str(refnb)
                s_or_not = 's'
                it_or_them = self.tr('them')
            else:
                srefnb = self.tr('one')
                s_or_not = ''
                it_or_them = self.tr('it')
            if refnb > 0:
                buttons = QMessageBox.Yes | QMessageBox.No
                if cancelable:
                    buttons = buttons | QMessageBox.Cancel
                answer = QMessageBox.question(self, self.get_widget_title(),
                   self.tr("Workspace is currently keeping reference "
                           "to %1 object%2.\n\nDo you want to save %3?") \
                   .arg(srefnb).arg(s_or_not).arg(it_or_them), buttons)
                if answer == QMessageBox.Yes:
                    # Saving workspace
                    self.__save(self.TEMPFILE_PATH)
                elif answer == QMessageBox.Cancel:
                    return False
                elif osp.isfile(self.TEMPFILE_PATH):
                    # Removing last saved workspace
                    os.remove(self.TEMPFILE_PATH)
        return True

    def load_temp_namespace(self):
        """Attempt to load last session namespace"""
        self.filename = self.TEMPFILE_PATH
        if osp.isfile(self.filename):
            self.import_data(self.filename)
        else:
            self.namespace = None
            self.refresh()

    def import_data(self, filename=None):
        """
        Import data from workspace
        or other data type (not implemented yet)
        """
        title = self.tr("Import data")
        if filename is None:
            self.emit(SIGNAL('redirect_stdio(bool)'), False)
            basedir = osp.dirname(self.filename)
            filename = QFileDialog.getOpenFileName(self, title, basedir,
                                                   self.load_filters)
            self.emit(SIGNAL('redirect_stdio(bool)'), True)
            if filename:
                filename = unicode(filename)
            else:
                return
        self.filename = unicode(filename)
        ext = osp.splitext(self.filename)[1]

        if ext not in self.load_funcs:
            buttons = QMessageBox.Yes | QMessageBox.Cancel
            answer = QMessageBox.question(self, title,
                       self.tr("<b>Unsupported file type '%1'</b><br><br>"
                               "Would you like to import it as a text file?") \
                       .arg(ext), buttons)
            if answer == QMessageBox.Cancel:
                return
            else:
                load_func = 'import_wizard'
        else:
            load_func = self.load_funcs[ext]

        if isinstance(load_func,
                      basestring):  # 'import_wizard' (self.setup_io)
            # Import data with import wizard
            error_message = None
            try:
                from spyderlib.utils import encoding
                text, _encoding = encoding.read(self.filename)
                self.import_from_string(text)
            except Exception, error:
                error_message = str(error)
        else:
Esempio n. 15
0
    except Exception, error:
        error_message = unicode(error)
        if renamed:
            # Restore original config files
            for fname in extracted_files:
                orig_name = get_conf_path(fname)
                bak_name = get_conf_path(fname+'.bak')
                if osp.isfile(orig_name):
                    os.remove(orig_name)
                if osp.isfile(bak_name):
                    os.rename(bak_name, orig_name)
                    
    finally:
        # Removing backup config files
        for fname in extracted_files:
            bak_name = get_conf_path(fname+'.bak')
            if osp.isfile(bak_name):
                os.remove(bak_name)
        
    os.chdir(old_cwd)
    return error_message


from PyQt4.QtGui import QFileDialog
from PyQt4.QtCore import QObject

class IOFunctions(QObject):
    def __init__(self):
        QObject.__init__(self)
        self.load_filters = None
        self.save_filters = None
Esempio n. 16
0
class PylintWidget(QWidget):
    """
    Pylint widget
    """
    DATAPATH = get_conf_path('.pylint.results')
    VERSION = '1.0.2'

    def __init__(self, parent, max_entries=100):
        QWidget.__init__(self, parent)

        self.output = None
        self.error_output = None

        self.max_entries = max_entries
        self.data = [self.VERSION]
        if osp.isfile(self.DATAPATH):
            try:
                data = cPickle.load(file(self.DATAPATH))
                if data[0] == self.VERSION:
                    self.data = data
            except EOFError:
                pass

        self.filecombo = PythonModulesComboBox(self)
        if self.data:
            self.remove_obsolete_items()
            self.filecombo.addItems(self.get_filenames())

        self.start_button = create_toolbutton(self,
                                              get_icon('run.png'),
                                              translate('Pylint', "Analyze"),
                                              tip=translate(
                                                  'Pylint', "Run analysis"),
                                              triggered=self.start)
        self.stop_button = create_toolbutton(self,
                                             get_icon('terminate.png'),
                                             translate('Pylint', "Stop"),
                                             tip=translate(
                                                 'Pylint',
                                                 "Stop current analysis"))
        self.connect(self.filecombo, SIGNAL('valid(bool)'),
                     self.start_button.setEnabled)
        self.connect(self.filecombo, SIGNAL('valid(bool)'), self.show_data)

        browse_button = create_toolbutton(self,
                                          get_icon('fileopen.png'),
                                          tip=translate(
                                              'Pylint',
                                              'Select Python script'),
                                          triggered=self.select_file)

        self.ratelabel = QLabel()
        self.datelabel = QLabel()
        self.log_button = create_toolbutton(self,
                                            get_icon('log.png'),
                                            translate('Pylint', "Output"),
                                            tip=translate(
                                                'Pylint',
                                                "Complete Pylint output"),
                                            triggered=self.show_log)
        self.treewidget = ResultsTree(self)

        hlayout1 = QHBoxLayout()
        hlayout1.addWidget(self.filecombo)
        hlayout1.addWidget(browse_button)
        hlayout1.addWidget(self.start_button)
        hlayout1.addWidget(self.stop_button)

        hlayout2 = QHBoxLayout()
        hlayout2.addWidget(self.ratelabel)
        hlayout2.addStretch()
        hlayout2.addWidget(self.datelabel)
        hlayout2.addStretch()
        hlayout2.addWidget(self.log_button)

        layout = QVBoxLayout()
        layout.addLayout(hlayout1)
        layout.addLayout(hlayout2)
        layout.addWidget(self.treewidget)
        self.setLayout(layout)

        self.process = None
        self.set_running_state(False)

        if not is_pylint_installed():
            for widget in (self.treewidget, self.filecombo, self.start_button,
                           self.stop_button):
                widget.setDisabled(True)
            text = translate('Pylint', 'Please install <b>pylint</b>:')
            url = 'http://www.logilab.fr'
            text += ' <a href=%s>%s</a>' % (url, url)
            self.ratelabel.setText(text)
        else:
            self.show_data()

    def analyze(self, filename):
        if not is_pylint_installed():
            return
        filename = unicode(filename)  # filename is a QString instance
        self.kill_if_running()
        index, _data = self.get_data(filename)
        if index is None:
            self.filecombo.addItem(filename)
            self.filecombo.setCurrentIndex(self.filecombo.count() - 1)
        else:
            self.filecombo.setCurrentIndex(index)
        self.filecombo.selected()
        if self.filecombo.is_valid():
            self.start()

    def select_file(self):
        self.emit(SIGNAL('redirect_stdio(bool)'), False)
        filename = QFileDialog.getOpenFileName(
            self, translate('Pylint', "Select Python script"), os.getcwdu(),
            translate('Pylint', "Python scripts") + " (*.py ; *.pyw)")
        self.emit(SIGNAL('redirect_stdio(bool)'), False)
        if filename:
            self.analyze(filename)

    def remove_obsolete_items(self):
        """Removing obsolete items"""
        self.data = [self.VERSION] + \
                    [(filename, data) for filename, data in self.data[1:]
                     if is_module_or_package(filename)]

    def get_filenames(self):
        return [filename for filename, _data in self.data[1:]]

    def get_data(self, filename):
        filename = osp.abspath(filename)
        for index, (fname, data) in enumerate(self.data[1:]):
            if fname == filename:
                return index, data
        else:
            return None, None

    def set_data(self, filename, data):
        filename = osp.abspath(filename)
        index, _data = self.get_data(filename)
        if index is not None:
            self.data.pop(index)
        self.data.append((filename, data))
        self.save()

    def set_max_entries(self, max_entries):
        self.max_entries = max_entries
        self.save()

    def save(self):
        while len(self.data) > self.max_entries + 1:
            self.data.pop(1)
        cPickle.dump(self.data, file(self.DATAPATH, 'w'))

    def show_log(self):
        if self.output:
            TextEditor(self.output,
                       title=translate('Pylint', "Pylint output"),
                       readonly=True,
                       size=(700, 500)).exec_()

    def start(self):
        filename = unicode(self.filecombo.currentText())

        self.process = QProcess(self)
        self.process.setProcessChannelMode(QProcess.SeparateChannels)
        self.process.setWorkingDirectory(osp.dirname(filename))
        self.connect(self.process, SIGNAL("readyReadStandardOutput()"),
                     self.read_output)
        self.connect(self.process, SIGNAL("readyReadStandardError()"),
                     lambda: self.read_output(error=True))
        self.connect(self.process,
                     SIGNAL("finished(int,QProcess::ExitStatus)"),
                     self.finished)
        self.connect(self.stop_button, SIGNAL("clicked()"), self.process.kill)

        self.output = ''
        self.error_output = ''
        p_args = [osp.basename(filename)]
        self.process.start(PYLINT_PATH, p_args)

        running = self.process.waitForStarted()
        self.set_running_state(running)
        if not running:
            QMessageBox.critical(
                self, translate('Pylint', "Error"),
                translate('Pylint', "Process failed to start"))

    def set_running_state(self, state=True):
        self.start_button.setEnabled(not state)
        self.stop_button.setEnabled(state)

    def read_output(self, error=False):
        if error:
            self.process.setReadChannel(QProcess.StandardError)
        else:
            self.process.setReadChannel(QProcess.StandardOutput)
        bytes = QByteArray()
        while self.process.bytesAvailable():
            if error:
                bytes += self.process.readAllStandardError()
            else:
                bytes += self.process.readAllStandardOutput()
        text = unicode(QString.fromLocal8Bit(bytes.data()))
        if error:
            self.error_output += text
        else:
            self.output += text

    def finished(self):
        self.set_running_state(False)
        if not self.output:
            return

        # Convention, Refactor, Warning, Error
        results = {'C:': [], 'R:': [], 'W:': [], 'E:': []}
        txt_module = '************* Module '

        module = ''  # Should not be needed - just in case something goes wrong
        for line in self.output.splitlines():
            if line.startswith(txt_module):
                # New module
                module = line[len(txt_module):]
                continue
            for prefix in results:
                if line.startswith(prefix):
                    break
            else:
                continue
            i1 = line.find(':')
            if i1 == -1:
                continue
            i2 = line.find(':', i1 + 1)
            if i2 == -1:
                continue
            line_nb = line[i1 + 1:i2].strip()
            if not line_nb:
                continue
            line_nb = int(line_nb)
            message = line[i2 + 1:]
            item = (module, line_nb, message)
            results[line[:i1 + 1]].append(item)

        # Rate
        rate = None
        txt_rate = 'Your code has been rated at '
        i_rate = self.output.find(txt_rate)
        if i_rate > 0:
            i_rate_end = self.output.find('/10', i_rate)
            if i_rate_end > 0:
                rate = self.output[i_rate + len(txt_rate):i_rate_end]

        # Previous run
        previous = ''
        if rate is not None:
            txt_prun = 'previous run: '
            i_prun = self.output.find(txt_prun, i_rate_end)
            if i_prun > 0:
                i_prun_end = self.output.find('/10', i_prun)
                previous = self.output[i_prun + len(txt_prun):i_prun_end]

        filename = unicode(self.filecombo.currentText())
        self.set_data(filename, (time.localtime(), rate, previous, results))
        self.output = self.error_output + self.output
        self.show_data(justanalyzed=True)

    def kill_if_running(self):
        if self.process is not None:
            if self.process.state() == QProcess.Running:
                self.process.kill()
                self.process.waitForFinished()

    def show_data(self, justanalyzed=False):
        if not justanalyzed:
            self.output = None
        self.log_button.setEnabled(self.output is not None \
                                   and len(self.output) > 0)
        self.kill_if_running()
        filename = unicode(self.filecombo.currentText())
        if not filename:
            return

        _index, data = self.get_data(filename)
        if data is None:
            text = translate('Pylint', 'Source code has not been rated yet.')
            self.treewidget.clear()
            date_text = ''
        else:
            datetime, rate, previous_rate, results = data
            if rate is None:
                text = translate(
                    'Pylint', 'Analysis did not succeed '
                    '(see output for more details).')
                self.treewidget.clear()
                date_text = ''
            else:
                text_style = "<span style=\'color: #444444\'><b>%s </b></span>"
                rate_style = "<span style=\'color: %s\'><b>%s</b></span>"
                prevrate_style = "<span style=\'color: #666666\'>%s</span>"
                color = "#FF0000"
                if float(rate) > 5.:
                    color = "#22AA22"
                elif float(rate) > 3.:
                    color = "#EE5500"
                text = translate('Pylint', 'Global evaluation:')
                text = (text_style % text) + (rate_style % (color,
                                                            ('%s/10' % rate)))
                if previous_rate:
                    text_prun = translate('Pylint', 'previous run:')
                    text_prun = ' (%s %s/10)' % (text_prun, previous_rate)
                    text += prevrate_style % text_prun
                self.treewidget.set_results(filename, results)
                date_text = text_style % time.strftime("%d %b %Y %H:%M",
                                                       datetime)

        self.ratelabel.setText(text)
        self.datelabel.setText(date_text)
Esempio n. 17
0
class WorkingDirectory(QToolBar, PluginMixin):
    """
    Working directory changer widget
    """
    ID = 'workingdir'
    #    allowed_areas = Qt.TopDockWidgetArea | Qt.BottomDockWidgetArea
    #    location = Qt.TopDockWidgetArea
    LOG_PATH = get_conf_path('.workingdir')

    def __init__(self, parent, workdir=None):
        QToolBar.__init__(self, parent)
        PluginMixin.__init__(self, parent)

        self.setWindowTitle(self.get_widget_title())  # Toolbar title
        self.setObjectName(
            self.get_widget_title())  # Used to save Window state

        self.addWidget(QLabel(self.tr("Working directory:") + " "))

        # Previous dir action
        self.history = []
        self.histindex = None
        self.previous_action = create_action(self,
                                             "previous",
                                             None,
                                             get_icon('previous.png'),
                                             self.tr('Back'),
                                             triggered=self.previous_directory)
        self.addAction(self.previous_action)

        # Next dir action
        self.history = []
        self.histindex = None
        self.next_action = create_action(self,
                                         "next",
                                         None,
                                         get_icon('next.png'),
                                         self.tr('Next'),
                                         triggered=self.next_directory)
        self.addAction(self.next_action)

        # Enable/disable previous/next actions
        self.connect(self, SIGNAL("set_previous_enabled(bool)"),
                     self.previous_action.setEnabled)
        self.connect(self, SIGNAL("set_next_enabled(bool)"),
                     self.next_action.setEnabled)

        # Path combo box
        adjust = CONF.get('shell', 'working_dir_adjusttocontents', False)
        self.pathedit = PathComboBox(self, adjust_to_contents=adjust)
        self.pathedit.setToolTip(self.tr("Working directory"))
        self.connect(self.pathedit, SIGNAL("open_dir(QString)"),
                     self.pathedit_activated)
        self.pathedit.setMaxCount(CONF.get('shell', 'working_dir_history'))
        wdhistory = self.load_wdhistory(workdir)
        if workdir is None:
            if wdhistory:
                workdir = wdhistory[0]
            else:
                workdir = "."
        self.chdir(workdir)
        self.pathedit.addItems(wdhistory)
        self.refresh()
        self.addWidget(self.pathedit)

        # Browse action
        browse_action = create_action(self,
                                      "browse",
                                      None,
                                      get_std_icon('DirOpenIcon'),
                                      self.tr('Browse a working directory'),
                                      triggered=self.select_directory)
        self.addAction(browse_action)

        # Parent dir action
        parent_action = create_action(self,
                                      "parent",
                                      None,
                                      get_icon('up.png'),
                                      self.tr('Change to parent directory'),
                                      triggered=self.parent_directory)
        self.addAction(parent_action)

    def get_widget_title(self):
        """Return widget title"""
        return self.tr('Working directory')

    def set_actions(self):
        """Setup actions"""
        return (None, None)

    def closing(self, cancelable=False):
        """Perform actions before parent main window is closed"""
        return True

    def load_wdhistory(self, workdir=None):
        """Load history from a text file in user home directory"""
        if osp.isfile(self.LOG_PATH):
            wdhistory, _ = encoding.readlines(self.LOG_PATH)
            wdhistory = [name for name in wdhistory if os.path.isdir(name)]
        else:
            if workdir is None:
                workdir = os.getcwdu()
            wdhistory = [workdir]
        return wdhistory

    def save_wdhistory(self):
        """Save history to a text file in user home directory"""
        text = [ unicode( self.pathedit.itemText(index) ) \
                 for index in range(self.pathedit.count()) ]
        encoding.writelines(text, self.LOG_PATH)

    def refresh(self):
        """Refresh widget"""
        curdir = os.getcwdu()
        index = self.pathedit.findText(curdir)
        while index != -1:
            self.pathedit.removeItem(index)
            index = self.pathedit.findText(curdir)
        self.pathedit.insertItem(0, curdir)
        self.pathedit.setCurrentIndex(0)
        self.save_wdhistory()
        self.emit(SIGNAL("set_previous_enabled(bool)"),
                  self.histindex is not None and self.histindex > 0)
        self.emit(SIGNAL("set_next_enabled(bool)"),
                  self.histindex is not None and \
                  self.histindex < len(self.history)-1)

    def select_directory(self):
        """Select directory"""
        self.emit(SIGNAL('redirect_stdio(bool)'), False)
        directory = QFileDialog.getExistingDirectory(
            self.main, self.tr("Select directory"), os.getcwdu())
        if not directory.isEmpty():
            self.chdir(directory)
        self.emit(SIGNAL('redirect_stdio(bool)'), True)

    def previous_directory(self):
        """Back to previous directory"""
        self.histindex -= 1
        self.chdir(browsing_history=True)

    def next_directory(self):
        """Return to next directory"""
        self.histindex += 1
        self.chdir(browsing_history=True)

    def parent_directory(self):
        """Change working directory to parent directory"""
        self.chdir(os.path.join(os.getcwdu(), os.path.pardir))

    def chdir(self, directory=None, browsing_history=False):
        """Set directory as working directory"""
        # Working directory history management
        if browsing_history:
            directory = self.history[self.histindex]
        else:
            if self.histindex is None:
                self.history = []
            else:
                self.history = self.history[:self.histindex + 1]
            self.history.append(osp.abspath((unicode(directory))))
            self.histindex = len(self.history) - 1

        # Changing working directory
        os.chdir(unicode(directory))
        self.refresh()
        if not isinstance(self.sender(), Explorer):
            # Explorer is not the sender: let's refresh it
            self.emit(SIGNAL("refresh_explorer()"))
        self.emit(SIGNAL("refresh_findinfiles()"))

    def pathedit_activated(self, directory):
        """Path combo box activated"""
        if self.main is not None:
            # Give focus to interactive shell
            self.main.console.shell.setFocus()
        self.chdir(directory)
Esempio n. 18
0
    except Exception, error:
        error_message = unicode(error)
        if renamed:
            # Restore original config files
            for fname in extracted_files:
                orig_name = get_conf_path(fname)
                bak_name = get_conf_path(fname+'.bak')
                if osp.isfile(orig_name):
                    os.remove(orig_name)
                if osp.isfile(bak_name):
                    os.rename(bak_name, orig_name)
                    
    finally:
        # Removing backup config files
        for fname in extracted_files:
            bak_name = get_conf_path(fname+'.bak')
            if osp.isfile(bak_name):
                os.remove(bak_name)
        
    os.chdir(old_cwd)
    return error_message


if __name__ == "__main__":
    import datetime
    testdict = {'d': 1, 'a': np.random.rand(10, 10), 'b': [1, 2]}
    testdate = datetime.date(1945, 5, 8)
    example = {'str': 'kjkj kj k j j kj k jkj',
               'unicode': u'éù',
               'list': [1, 3, [4, 5, 6], 'kjkj', None],
               'tuple': ([1, testdate, testdict], 'kjkj', None),
Esempio n. 19
0
def reset_session():
    """Remove all config files"""
    for fname in SAVED_CONFIG_FILES:
        cfg_fname = get_conf_path(fname)
        if osp.isfile(cfg_fname):
            os.remove(cfg_fname)