Пример #1
0
    def __init__(self, parent):
        QWidget.__init__(self, parent)

        self.shell = parent

        # Dict editor:
        truncate = CONF.get(self.ID, 'truncate')
        inplace = CONF.get(self.ID, 'inplace')
        minmax = CONF.get(self.ID, 'minmax')
        collvalue = CONF.get(self.ID, 'collvalue')
        self.editor = RemoteDictEditorTableView(
            parent,
            None,
            truncate=truncate,
            inplace=inplace,
            minmax=minmax,
            collvalue=collvalue,
            get_value_func=self.get_value,
            set_value_func=self.set_value,
            new_value_func=self.set_value,
            remove_values_func=self.remove_values,
            copy_value_func=self.copy_value)
        self.connect(self.editor, SIGNAL('option_changed'),
                     self.option_changed)

        # Setup layout
        vlayout = QVBoxLayout()
        hlayout = QHBoxLayout()
        self.setup_toolbar(hlayout)
        vlayout.addLayout(hlayout)
        vlayout.addWidget(self.editor)
        self.setLayout(vlayout)

        self.connect(self, SIGNAL('option_changed'), self.option_changed)
Пример #2
0
    def __init__(self, parent):
        QWidget.__init__(self, parent)
        
        self.shellwidget = None
        self.is_visible = True
        self.auto_refresh_enabled = True

        # Dict editor:
        truncate = CONF.get(self.ID, 'truncate')
        inplace = CONF.get(self.ID, 'inplace')
        minmax = CONF.get(self.ID, 'minmax')
        collvalue = CONF.get(self.ID, 'collvalue')
        self.editor = RemoteDictEditorTableView(parent, None,
                truncate=truncate, inplace=inplace, minmax=minmax,
                collvalue=collvalue, get_value_func=self.get_value,
                set_value_func=self.set_value, new_value_func=self.set_value,
                remove_values_func=self.remove_values,
                copy_value_func=self.copy_value,
                is_list_func=self.is_list, get_len_func=self.get_len,
                is_array_func=self.is_array, is_dict_func=self.is_dict,
                get_array_shape_func=self.get_array_shape,
                get_array_ndim_func=self.get_array_ndim,
                oedit_func=self.oedit,
                plot_func=self.plot, imshow_func=self.imshow)
        self.connect(self.editor, SIGNAL('option_changed'), self.option_changed)
        
        # Setup layout
        hlayout = QHBoxLayout()
        vlayout = QVBoxLayout()
        self.setup_toolbar(vlayout)
        hlayout.addWidget(self.editor)
        hlayout.addLayout(vlayout)
        self.setLayout(hlayout)
        hlayout.setContentsMargins(0, 0, 0, 0)

        self.connect(self, SIGNAL('option_changed'), self.option_changed)
        
        self.filename = None
        
        self.toggle_auto_refresh(self.auto_refresh_enabled)
Пример #3
0
    def setup(self, check_all=None, exclude_private=None,
              exclude_uppercase=None, exclude_capitalized=None,
              exclude_unsupported=None, excluded_names=None,
              truncate=None, minmax=None, remote_editing=None,
              autorefresh=None):
        """Setup the namespace browser"""
        assert self.shellwidget is not None
        
        self.check_all = check_all
        self.exclude_private = exclude_private
        self.exclude_uppercase = exclude_uppercase
        self.exclude_capitalized = exclude_capitalized
        self.exclude_unsupported = exclude_unsupported
        self.excluded_names = excluded_names
        self.truncate = truncate
        self.minmax = minmax
        self.remote_editing = remote_editing
        self.autorefresh = autorefresh
        
        if self.editor is not None:
            self.editor.setup_menu(truncate, minmax)
            self.exclude_private_action.setChecked(exclude_private)
            self.exclude_uppercase_action.setChecked(exclude_uppercase)
            self.exclude_capitalized_action.setChecked(exclude_capitalized)
            self.exclude_unsupported_action.setChecked(exclude_unsupported)
            # Don't turn autorefresh on for IPython kernels
            # See Issue 1450
            if not self.is_ipykernel:
                self.auto_refresh_button.setChecked(autorefresh)
            self.refresh_table()
            return
        
        # Dict editor:
        if self.is_internal_shell:
            self.editor = DictEditorTableView(self, None, truncate=truncate,
                                              minmax=minmax)
        else:
            self.editor = RemoteDictEditorTableView(self, None,
                            truncate=truncate, minmax=minmax,
                            remote_editing=remote_editing,
                            get_value_func=self.get_value,
                            set_value_func=self.set_value,
                            new_value_func=self.set_value,
                            remove_values_func=self.remove_values,
                            copy_value_func=self.copy_value,
                            is_list_func=self.is_list,
                            get_len_func=self.get_len,
                            is_array_func=self.is_array,
                            is_image_func=self.is_image,
                            is_dict_func=self.is_dict,
                            is_data_frame_func=self.is_data_frame,
                            is_time_series_func=self.is_time_series,                       
                            get_array_shape_func=self.get_array_shape,
                            get_array_ndim_func=self.get_array_ndim,
                            oedit_func=self.oedit,
                            plot_func=self.plot, imshow_func=self.imshow,
                            show_image_func=self.show_image)
        self.editor.sig_option_changed.connect(self.sig_option_changed.emit)
        self.editor.sig_files_dropped.connect(self.import_data)
        
        
        # Setup layout
        hlayout = QHBoxLayout()
        vlayout = QVBoxLayout()
        toolbar = self.setup_toolbar(exclude_private, exclude_uppercase,
                                     exclude_capitalized, exclude_unsupported,
                                     autorefresh)
        vlayout.setAlignment(Qt.AlignTop)
        for widget in toolbar:
            vlayout.addWidget(widget)
        hlayout.addWidget(self.editor)
        hlayout.addLayout(vlayout)
        self.setLayout(hlayout)
        hlayout.setContentsMargins(0, 0, 0, 0)

        self.sig_option_changed.connect(self.option_changed)
Пример #4
0
class NamespaceBrowser(QWidget):
    """Namespace browser (global variables explorer widget)"""
    sig_option_changed = Signal(str, object)
    sig_collapse = Signal()
    
    def __init__(self, parent):
        QWidget.__init__(self, parent)
        
        self.shellwidget = None
        self.is_internal_shell = None
        self.ipyclient = None
        self.is_ipykernel = None
        
        self.is_visible = True # Do not modify: light mode won't work!
        
        self.setup_in_progress = None
        
        # Remote dict editor settings
        self.check_all = None
        self.exclude_private = None
        self.exclude_uppercase = None
        self.exclude_capitalized = None
        self.exclude_unsupported = None
        self.excluded_names = None
        self.truncate = None
        self.minmax = None
        self.remote_editing = None
        self.autorefresh = None
        
        self.editor = None
        self.exclude_private_action = None
        self.exclude_uppercase_action = None
        self.exclude_capitalized_action = None
        self.exclude_unsupported_action = None
        
        self.filename = None
            
    def setup(self, check_all=None, exclude_private=None,
              exclude_uppercase=None, exclude_capitalized=None,
              exclude_unsupported=None, excluded_names=None,
              truncate=None, minmax=None, remote_editing=None,
              autorefresh=None):
        """Setup the namespace browser"""
        assert self.shellwidget is not None
        
        self.check_all = check_all
        self.exclude_private = exclude_private
        self.exclude_uppercase = exclude_uppercase
        self.exclude_capitalized = exclude_capitalized
        self.exclude_unsupported = exclude_unsupported
        self.excluded_names = excluded_names
        self.truncate = truncate
        self.minmax = minmax
        self.remote_editing = remote_editing
        self.autorefresh = autorefresh
        
        if self.editor is not None:
            self.editor.setup_menu(truncate, minmax)
            self.exclude_private_action.setChecked(exclude_private)
            self.exclude_uppercase_action.setChecked(exclude_uppercase)
            self.exclude_capitalized_action.setChecked(exclude_capitalized)
            self.exclude_unsupported_action.setChecked(exclude_unsupported)
            # Don't turn autorefresh on for IPython kernels
            # See Issue 1450
            if not self.is_ipykernel:
                self.auto_refresh_button.setChecked(autorefresh)
            self.refresh_table()
            return
        
        # Dict editor:
        if self.is_internal_shell:
            self.editor = DictEditorTableView(self, None, truncate=truncate,
                                              minmax=minmax)
        else:
            self.editor = RemoteDictEditorTableView(self, None,
                            truncate=truncate, minmax=minmax,
                            remote_editing=remote_editing,
                            get_value_func=self.get_value,
                            set_value_func=self.set_value,
                            new_value_func=self.set_value,
                            remove_values_func=self.remove_values,
                            copy_value_func=self.copy_value,
                            is_list_func=self.is_list,
                            get_len_func=self.get_len,
                            is_array_func=self.is_array,
                            is_image_func=self.is_image,
                            is_dict_func=self.is_dict,
                            is_data_frame_func=self.is_data_frame,
                            is_time_series_func=self.is_time_series,                       
                            get_array_shape_func=self.get_array_shape,
                            get_array_ndim_func=self.get_array_ndim,
                            oedit_func=self.oedit,
                            plot_func=self.plot, imshow_func=self.imshow,
                            show_image_func=self.show_image)
        self.editor.sig_option_changed.connect(self.sig_option_changed.emit)
        self.editor.sig_files_dropped.connect(self.import_data)
        
        
        # Setup layout
        hlayout = QHBoxLayout()
        vlayout = QVBoxLayout()
        toolbar = self.setup_toolbar(exclude_private, exclude_uppercase,
                                     exclude_capitalized, exclude_unsupported,
                                     autorefresh)
        vlayout.setAlignment(Qt.AlignTop)
        for widget in toolbar:
            vlayout.addWidget(widget)
        hlayout.addWidget(self.editor)
        hlayout.addLayout(vlayout)
        self.setLayout(hlayout)
        hlayout.setContentsMargins(0, 0, 0, 0)

        self.sig_option_changed.connect(self.option_changed)
        
    def set_shellwidget(self, shellwidget):
        """Bind shellwidget instance to namespace browser"""
        self.shellwidget = shellwidget
        from spyderlib.widgets import internalshell
        self.is_internal_shell = isinstance(self.shellwidget,
                                            internalshell.InternalShell)
        self.is_ipykernel = self.shellwidget.is_ipykernel
        if not self.is_internal_shell:
            shellwidget.set_namespacebrowser(self)
    
    def set_ipyclient(self, ipyclient):
        """Bind ipyclient instance to namespace browser"""
        self.ipyclient = ipyclient
        
    def setup_toolbar(self, exclude_private, exclude_uppercase,
                      exclude_capitalized, exclude_unsupported, autorefresh):
        """Setup toolbar"""
        self.setup_in_progress = True                          
                          
        toolbar = []

        refresh_button = create_toolbutton(self, text=_('Refresh'),
                                           icon=ima.icon('reload'),
                                           triggered=self.refresh_table)
        self.auto_refresh_button = create_toolbutton(self,
                                           text=_('Refresh periodically'),
                                           icon=ima.icon('auto_reload'),
                                           toggled=self.toggle_auto_refresh)
        self.auto_refresh_button.setChecked(autorefresh)
        load_button = create_toolbutton(self, text=_('Import data'),
                                        icon=ima.icon('fileimport'),
                                        triggered=self.import_data)
        self.save_button = create_toolbutton(self, text=_("Save data"),
                            icon=ima.icon('filesave'),
                            triggered=lambda: self.save_data(self.filename))
        self.save_button.setEnabled(False)
        save_as_button = create_toolbutton(self,
                                           text=_("Save data as..."),
                                           icon=ima.icon('filesaveas'),
                                           triggered=self.save_data)
        toolbar += [refresh_button, self.auto_refresh_button, load_button,
                    self.save_button, save_as_button]
        
        self.exclude_private_action = create_action(self,
                _("Exclude private references"),
                tip=_("Exclude references which name starts"
                            " with an underscore"),
                toggled=lambda state:
                self.sig_option_changed.emit('exclude_private', state))
        self.exclude_private_action.setChecked(exclude_private)
        
        self.exclude_uppercase_action = create_action(self,
                _("Exclude all-uppercase references"),
                tip=_("Exclude references which name is uppercase"),
                toggled=lambda state:
                self.sig_option_changed.emit('exclude_uppercase', state))
        self.exclude_uppercase_action.setChecked(exclude_uppercase)
        
        self.exclude_capitalized_action = create_action(self,
                _("Exclude capitalized references"),
                tip=_("Exclude references which name starts with an "
                      "uppercase character"),
                toggled=lambda state:
                self.sig_option_changed.emit('exclude_capitalized', state))
        self.exclude_capitalized_action.setChecked(exclude_capitalized)
        
        self.exclude_unsupported_action = create_action(self,
                _("Exclude unsupported data types"),
                tip=_("Exclude references to unsupported data types"
                            " (i.e. which won't be handled/saved correctly)"),
                toggled=lambda state:
                self.sig_option_changed.emit('exclude_unsupported', state))
        self.exclude_unsupported_action.setChecked(exclude_unsupported)
        
        options_button = create_toolbutton(self, text=_('Options'),
                                           icon=ima.icon('tooloptions'))
        toolbar.append(options_button)
        options_button.setPopupMode(QToolButton.InstantPopup)
        menu = QMenu(self)
        editor = self.editor
        actions = [self.exclude_private_action, self.exclude_uppercase_action,
                   self.exclude_capitalized_action,
                   self.exclude_unsupported_action, None,
                   editor.truncate_action]
        if is_module_installed('numpy'):
            actions.append(editor.minmax_action)
        add_actions(menu, actions)
        options_button.setMenu(menu)
        
        self.setup_in_progress = False
        
        return toolbar

    def option_changed(self, option, value):
        """Option has changed"""
        setattr(self, to_text_string(option), value)
        if not self.is_internal_shell:
            settings = self.get_view_settings()
            communicate(self._get_sock(),
                        'set_remote_view_settings()', settings=[settings])
        
    def visibility_changed(self, enable):
        """Notify the widget whether its container (the namespace browser 
        plugin is visible or not"""
        self.is_visible = enable
        if enable:
            self.refresh_table()

    @Slot(bool)
    def toggle_auto_refresh(self, state):
        """Toggle auto refresh state"""
        self.autorefresh = state
        if not self.setup_in_progress and not self.is_internal_shell:
            communicate(self._get_sock(),
                        "set_monitor_auto_refresh(%r)" % state)
            
    def _get_sock(self):
        """Return socket connection"""
        return self.shellwidget.introspection_socket
    
    def get_internal_shell_filter(self, mode, check_all=None):
        """
        Return internal shell data types filter:
            * check_all: check all elements data types for sequences
              (dict, list, tuple)
            * mode (string): 'editable' or 'picklable'
        """
        assert mode in list(SUPPORTED_TYPES.keys())
        if check_all is None:
            check_all = self.check_all
        def wsfilter(input_dict, check_all=check_all,
                     filters=tuple(SUPPORTED_TYPES[mode])):
            """Keep only objects that can be pickled"""
            return globalsfilter(
                         input_dict, check_all=check_all, filters=filters,
                         exclude_private=self.exclude_private,
                         exclude_uppercase=self.exclude_uppercase,
                         exclude_capitalized=self.exclude_capitalized,
                         exclude_unsupported=self.exclude_unsupported,
                         excluded_names=self.excluded_names)
        return wsfilter

    def get_view_settings(self):
        """Return dict editor view settings"""
        settings = {}
        for name in REMOTE_SETTINGS:
            settings[name] = getattr(self, name)
        return settings

    @Slot()
    def refresh_table(self):
        """Refresh variable table"""
        if self.is_visible and self.isVisible():
            if self.is_internal_shell:
                # Internal shell
                wsfilter = self.get_internal_shell_filter('editable')
                self.editor.set_filter(wsfilter)
                interpreter = self.shellwidget.interpreter
                if interpreter is not None:
                    self.editor.set_data(interpreter.namespace)
                    self.editor.adjust_columns()
            elif self.shellwidget.is_running():
    #            import time; print >>STDOUT, time.ctime(time.time()), "Refreshing namespace browser"
                sock = self._get_sock()
                if sock is None:
                    return
                try:
                    communicate(sock, "refresh()")
                except socket.error:
                    # Process was terminated before calling this method
                    pass                
                
    def process_remote_view(self, remote_view):
        """Process remote view"""
        if remote_view is not None:
            self.set_data(remote_view)
        
    #------ Remote Python process commands ------------------------------------
    def get_value(self, name):
        value = monitor_get_global(self._get_sock(), name)
        if value is None:
            if communicate(self._get_sock(), '%s is not None' % name):
                import pickle
                msg = to_text_string(_("Object <b>%s</b> is not picklable")
                                     % name)
                raise pickle.PicklingError(msg)
        return value
        
    def set_value(self, name, value):
        monitor_set_global(self._get_sock(), name, value)
        self.refresh_table()
        
    def remove_values(self, names):
        for name in names:
            monitor_del_global(self._get_sock(), name)
        self.refresh_table()
        
    def copy_value(self, orig_name, new_name):
        monitor_copy_global(self._get_sock(), orig_name, new_name)
        self.refresh_table()
        
    def is_list(self, name):
        """Return True if variable is a list or a tuple"""
        return communicate(self._get_sock(),
                           'isinstance(%s, (tuple, list))' % name)
        
    def is_dict(self, name):
        """Return True if variable is a dictionary"""
        return communicate(self._get_sock(), 'isinstance(%s, dict)' % name)
        
    def get_len(self, name):
        """Return sequence length"""
        return communicate(self._get_sock(), "len(%s)" % name)
        
    def is_array(self, name):
        """Return True if variable is a NumPy array"""
        return communicate(self._get_sock(), 'is_array("%s")' % name)
        
    def is_image(self, name):
        """Return True if variable is a PIL.Image image"""
        return communicate(self._get_sock(), 'is_image("%s")' % name)
    
    def is_data_frame(self, name):
        """Return True if variable is a data_frame"""
        return communicate(self._get_sock(),
             "isinstance(globals()['%s'], DataFrame)" % name)
    
    def is_time_series(self, name):
        """Return True if variable is a data_frame"""
        return communicate(self._get_sock(),
             "isinstance(globals()['%s'], TimeSeries)" % name)   
        
    def get_array_shape(self, name):
        """Return array's shape"""
        return communicate(self._get_sock(), "%s.shape" % name)
        
    def get_array_ndim(self, name):
        """Return array's ndim"""
        return communicate(self._get_sock(), "%s.ndim" % name)
        
    def plot(self, name, funcname):
        command = "import spyderlib.pyplot; "\
                  "__fig__ = spyderlib.pyplot.figure(); "\
                  "__items__ = getattr(spyderlib.pyplot, '%s')(%s); "\
                  "spyderlib.pyplot.show(); "\
                  "del __fig__, __items__;" % (funcname, name)
        if self.is_ipykernel:
            self.ipyclient.shellwidget.execute("%%varexp --%s %s" % (funcname,
                                                                   name))
        else:
            self.shellwidget.send_to_process(command)
        
    def imshow(self, name):
        command = "import spyderlib.pyplot; " \
                  "__fig__ = spyderlib.pyplot.figure(); " \
                  "__items__ = spyderlib.pyplot.imshow(%s); " \
                  "spyderlib.pyplot.show(); del __fig__, __items__;" % name
        if self.is_ipykernel:
            self.ipyclient.shellwidget.execute("%%varexp --imshow %s" % name)
        else:
            self.shellwidget.send_to_process(command)
        
    def show_image(self, name):
        command = "%s.show()" % name
        if self.is_ipykernel:
            self.ipyclient.shellwidget.execute(command)
        else:
            self.shellwidget.send_to_process(command)
        
    def oedit(self, name):
        command = "from spyderlib.widgets.objecteditor import oedit; " \
                  "oedit('%s', modal=False, namespace=locals());" % name
        self.shellwidget.send_to_process(command)
        
    #------ Set, load and save data -------------------------------------------
    def set_data(self, data):
        """Set data"""
        if data != self.editor.model.get_data():
            self.editor.set_data(data)
            self.editor.adjust_columns()
        
    def collapse(self):
        """Collapse"""
        self.sig_collapse.emit()

    @Slot(list)
    def import_data(self, filenames=None):
        """Import data from text file"""
        title = _("Import data")
        if filenames is None:
            if self.filename is None:
                basedir = getcwd()
            else:
                basedir = osp.dirname(self.filename)
            filenames, _selfilter = getopenfilenames(self, title, basedir,
                                                     iofunctions.load_filters)
            if not filenames:
                return
        elif is_text_string(filenames):
            filenames = [filenames]

        for filename in filenames:
            self.filename = to_text_string(filename)
            ext = osp.splitext(self.filename)[1].lower()

            if ext not in iofunctions.load_funcs:
                buttons = QMessageBox.Yes | QMessageBox.Cancel
                answer = QMessageBox.question(self, title,
                            _("<b>Unsupported file extension '%s'</b><br><br>"
                              "Would you like to import it anyway "
                              "(by selecting a known file format)?"
                              ) % ext, buttons)
                if answer == QMessageBox.Cancel:
                    return
                formats = list(iofunctions.load_extensions.keys())
                item, ok = QInputDialog.getItem(self, title,
                                                _('Open file as:'),
                                                formats, 0, False)
                if ok:
                    ext = iofunctions.load_extensions[to_text_string(item)]
                else:
                    return

            load_func = iofunctions.load_funcs[ext]
                
            # 'import_wizard' (self.setup_io)
            if is_text_string(load_func):
                # Import data with import wizard
                error_message = None
                try:
                    text, _encoding = encoding.read(self.filename)
                    if self.is_internal_shell:
                        self.editor.import_from_string(text)
                    else:
                        base_name = osp.basename(self.filename)
                        editor = ImportWizard(self, text, title=base_name,
                                      varname=fix_reference_name(base_name))
                        if editor.exec_():
                            var_name, clip_data = editor.get_data()
                            monitor_set_global(self._get_sock(),
                                               var_name, clip_data)
                except Exception as error:
                    error_message = str(error)
            else:
                QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
                QApplication.processEvents()
                if self.is_internal_shell:
                    namespace, error_message = load_func(self.filename)
                    interpreter = self.shellwidget.interpreter
                    for key in list(namespace.keys()):
                        new_key = fix_reference_name(key,
                                     blacklist=list(interpreter.namespace.keys()))
                        if new_key != key:
                            namespace[new_key] = namespace.pop(key)
                    if error_message is None:
                        interpreter.namespace.update(namespace)
                else:
                    error_message = monitor_load_globals(self._get_sock(),
                                                         self.filename, ext)
                QApplication.restoreOverrideCursor()
                QApplication.processEvents()
    
            if error_message is not None:
                QMessageBox.critical(self, title,
                                     _("<b>Unable to load '%s'</b>"
                                       "<br><br>Error message:<br>%s"
                                       ) % (self.filename, error_message))
            self.refresh_table()
            
    @Slot()
    def save_data(self, filename=None):
        """Save data"""
        if filename is None:
            filename = self.filename
            if filename is None:
                filename = getcwd()
            filename, _selfilter = getsavefilename(self, _("Save data"),
                                                   filename,
                                                   iofunctions.save_filters)
            if filename:
                self.filename = filename
            else:
                return False
        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
        QApplication.processEvents()
        if self.is_internal_shell:
            wsfilter = self.get_internal_shell_filter('picklable',
                                                      check_all=True)
            namespace = wsfilter(self.shellwidget.interpreter.namespace).copy()
            error_message = iofunctions.save(namespace, filename)
        else:
            settings = self.get_view_settings()
            error_message = monitor_save_globals(self._get_sock(),
                                                 settings, filename)
        QApplication.restoreOverrideCursor()
        QApplication.processEvents()
        if error_message is not None:
            QMessageBox.critical(self, _("Save data"),
                            _("<b>Unable to save current workspace</b>"
                              "<br><br>Error message:<br>%s") % error_message)
        self.save_button.setEnabled(self.filename is not None)
Пример #5
0
class GlobalsExplorer(QWidget):
    ID = 'external_shell'

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

        self.shell = parent

        # Dict editor:
        truncate = CONF.get(self.ID, 'truncate')
        inplace = CONF.get(self.ID, 'inplace')
        minmax = CONF.get(self.ID, 'minmax')
        collvalue = CONF.get(self.ID, 'collvalue')
        self.editor = RemoteDictEditorTableView(
            parent,
            None,
            truncate=truncate,
            inplace=inplace,
            minmax=minmax,
            collvalue=collvalue,
            get_value_func=self.get_value,
            set_value_func=self.set_value,
            new_value_func=self.set_value,
            remove_values_func=self.remove_values,
            copy_value_func=self.copy_value)
        self.connect(self.editor, SIGNAL('option_changed'),
                     self.option_changed)

        # Setup layout
        vlayout = QVBoxLayout()
        hlayout = QHBoxLayout()
        self.setup_toolbar(hlayout)
        vlayout.addLayout(hlayout)
        vlayout.addWidget(self.editor)
        self.setLayout(vlayout)

        self.connect(self, SIGNAL('option_changed'), self.option_changed)

    def setup_toolbar(self, layout):
        toolbar = []

        explorer_label = QLabel(
            self.tr("<span style=\'color: #444444\'>"
                    "<b>Global variables explorer</b>"
                    "</span>"))
        toolbar.append(explorer_label)

        hide_button = create_toolbutton(self,
                                        text=self.tr("Hide"),
                                        icon=get_icon('hide.png'),
                                        triggered=self.collapse)
        toolbar.append(hide_button)

        refresh_button = create_toolbutton(self,
                                           text=self.tr("Refresh"),
                                           icon=get_icon('reload.png'),
                                           triggered=self.refresh_table)
        toolbar.append(refresh_button)

        exclude_private_action = create_action(
            self,
            self.tr("Exclude private references"),
            tip=self.tr("Exclude references which name starts"
                        " with an underscore"),
            toggled=lambda state: self.emit(SIGNAL('option_changed'),
                                            'exclude_private', state))
        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=lambda state: self.emit(SIGNAL('option_changed'),
                                            'exclude_upper', state))
        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=lambda state: self.emit(SIGNAL('option_changed'),
                                            'exclude_unsupported', state))
        exclude_unsupported_action.setChecked(
            CONF.get(self.ID, 'exclude_unsupported'))

        options_button = create_toolbutton(self,
                                           text=self.tr("Options"),
                                           icon=get_icon('tooloptions.png'))
        toolbar.append(options_button)
        options_button.setPopupMode(QToolButton.InstantPopup)
        menu = QMenu(self)
        editor = self.editor
        actions = [
            exclude_private_action, exclude_upper_action,
            exclude_unsupported_action, None, editor.truncate_action,
            editor.inplace_action, editor.collvalue_action
        ]
        try:
            imp.find_module('numpy')
            actions.append(editor.minmax_action)
        except ImportError:
            pass
        add_actions(menu, actions)
        options_button.setMenu(menu)

        layout.setAlignment(Qt.AlignLeft)
        for widget in toolbar:
            layout.addWidget(widget)
        layout.insertStretch(1, 1)

    def option_changed(self, option, value):
        CONF.set(self.ID, option, value)
        self.refresh_table()

    def refresh_table(self):
        sock = self.shell.monitor_socket
        if sock is None:
            return
        settings = {}
        for name in ('filters', 'itermax', 'exclude_private', 'exclude_upper',
                     'exclude_unsupported', 'excluded_names', 'truncate',
                     'minmax', 'collvalue'):
            settings[name] = CONF.get('external_shell', name)
        self.set_data(monitor_get_remote_view(sock, settings))

    def get_value(self, name):
        return monitor_get_global(self.shell.monitor_socket, name)

    def set_value(self, name, value):
        sock = self.shell.monitor_socket
        monitor_set_global(sock, name, value)
        self.refresh_table()

    def remove_values(self, names):
        sock = self.shell.monitor_socket
        for name in names:
            monitor_del_global(sock, name)
        self.refresh_table()

    def copy_value(self, orig_name, new_name):
        sock = self.shell.monitor_socket
        monitor_copy_global(sock, orig_name, new_name)
        self.refresh_table()

    def set_data(self, data):
        self.editor.set_data(data)
        self.editor.adjust_columns()

    def collapse(self):
        self.emit(SIGNAL('collapse()'))
Пример #6
0
class NamespaceBrowser(QWidget):
    ID = 'external_shell'
    
    def __init__(self, parent):
        QWidget.__init__(self, parent)
        
        self.shellwidget = None
        self.is_visible = True
        self.auto_refresh_enabled = True

        # Dict editor:
        truncate = CONF.get(self.ID, 'truncate')
        inplace = CONF.get(self.ID, 'inplace')
        minmax = CONF.get(self.ID, 'minmax')
        collvalue = CONF.get(self.ID, 'collvalue')
        self.editor = RemoteDictEditorTableView(parent, None,
                truncate=truncate, inplace=inplace, minmax=minmax,
                collvalue=collvalue, get_value_func=self.get_value,
                set_value_func=self.set_value, new_value_func=self.set_value,
                remove_values_func=self.remove_values,
                copy_value_func=self.copy_value,
                is_list_func=self.is_list, get_len_func=self.get_len,
                is_array_func=self.is_array, is_dict_func=self.is_dict,
                get_array_shape_func=self.get_array_shape,
                get_array_ndim_func=self.get_array_ndim,
                oedit_func=self.oedit,
                plot_func=self.plot, imshow_func=self.imshow)
        self.connect(self.editor, SIGNAL('option_changed'), self.option_changed)
        
        # Setup layout
        hlayout = QHBoxLayout()
        vlayout = QVBoxLayout()
        self.setup_toolbar(vlayout)
        hlayout.addWidget(self.editor)
        hlayout.addLayout(vlayout)
        self.setLayout(hlayout)
        hlayout.setContentsMargins(0, 0, 0, 0)

        self.connect(self, SIGNAL('option_changed'), self.option_changed)
        
        self.filename = None
        
        self.toggle_auto_refresh(self.auto_refresh_enabled)
        
    def set_shellwidget(self, shellwidget):
        self.shellwidget = shellwidget
        
    def setup_toolbar(self, layout):
        toolbar = []

        refresh_button = create_toolbutton(self, text=self.tr("Refresh"),
                                           icon=get_icon('reload.png'),
                                           triggered=self.refresh_table,
                                           text_beside_icon=False)
        self.auto_refresh_button = create_toolbutton(self,
                                           text=self.tr("Refresh periodically"),
                                           icon=get_icon('auto_reload.png'),
                                           toggled=self.toggle_auto_refresh,
                                           text_beside_icon=False)
        load_button = create_toolbutton(self, text=self.tr("Import data"),
                                        icon=get_icon('fileimport.png'),
                                        triggered=self.import_data,
                                        text_beside_icon=False)
        self.save_button = create_toolbutton(self, text=self.tr("Save data"),
                                icon=get_icon('filesave.png'),
                                triggered=lambda: self.save_data(self.filename),
                                text_beside_icon=False)
        self.save_button.setEnabled(False)
        save_as_button = create_toolbutton(self,
                                           text=self.tr("Save data as..."),
                                           icon=get_icon('filesaveas.png'),
                                           triggered=self.save_data,
                                           text_beside_icon=False)
        toolbar += [refresh_button, self.auto_refresh_button, load_button,
                    self.save_button, save_as_button]
        
        exclude_private_action = create_action(self,
                self.tr("Exclude private references"),
                tip=self.tr("Exclude references which name starts"
                            " with an underscore"),
                toggled=lambda state:self.emit(SIGNAL('option_changed'),
                                               'exclude_private', state))
        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=lambda state:self.emit(SIGNAL('option_changed'),
                                               'exclude_upper', state))
        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=lambda state:self.emit(SIGNAL('option_changed'),
                                               'exclude_unsupported', state))
        exclude_unsupported_action.setChecked(CONF.get(self.ID,
                                              'exclude_unsupported'))
        
        options_button = create_toolbutton(self, text=self.tr("Options"),
                                           icon=get_icon('tooloptions.png'),
                                           text_beside_icon=False)
        toolbar.append(options_button)
        options_button.setPopupMode(QToolButton.InstantPopup)
        menu = QMenu(self)
        editor = self.editor
        actions = [exclude_private_action, exclude_upper_action,
                   exclude_unsupported_action, None, editor.truncate_action,
                   editor.inplace_action, editor.collvalue_action]
        if is_module_installed('numpy'):
            actions.append(editor.minmax_action)
        add_actions(menu, actions)
        options_button.setMenu(menu)

        layout.setAlignment(Qt.AlignTop)
        for widget in toolbar:
            layout.addWidget(widget)

    def option_changed(self, option, value):
        CONF.set(self.ID, option, value)
        self.refresh_table()
        
    def visibility_changed(self, enable):
        """Notify the widget whether its container (the namespace browser 
        plugin is visible or not"""
        self.is_visible = enable
        
    def toggle_auto_refresh(self, state):
        self.auto_refresh_button.setChecked(state)
        self.auto_refresh_enabled = state
        
    def auto_refresh(self):
        if self.auto_refresh_enabled:
            self.refresh_table()
        
    def refresh_table(self):
        if self.is_visible and self.isVisible() \
           and self.shellwidget.is_running():
#            import time; print >>STDOUT, time.ctime(time.time()), "Refreshing namespace browser"
            sock = self.shellwidget.monitor_socket
            if sock is None:
                return
            settings = get_settings()
            try:
                self.set_data( monitor_get_remote_view(sock, settings) )
            except socket.error:
                # Process was terminated before calling this methods
                pass
        
    def get_value(self, name):
        return monitor_get_global(self.shellwidget.monitor_socket, name)
        
    def set_value(self, name, value):
        sock = self.shellwidget.monitor_socket
        monitor_set_global(sock, name, value)
        self.refresh_table()
        
    def remove_values(self, names):
        sock = self.shellwidget.monitor_socket
        for name in names:
            monitor_del_global(sock, name)
        self.refresh_table()
        
    def copy_value(self, orig_name, new_name):
        sock = self.shellwidget.monitor_socket
        monitor_copy_global(sock, orig_name, new_name)
        self.refresh_table()
        
    def is_list(self, name):
        """Return True if variable is a list or a tuple"""
        return communicate(self.shellwidget.monitor_socket,
                           "isinstance(globals()['%s'], (tuple, list))" % name,
                           pickle_try=True)
        
    def is_dict(self, name):
        """Return True if variable is a dictionary"""
        return communicate(self.shellwidget.monitor_socket,
                           "isinstance(globals()['%s'], dict)" % name,
                           pickle_try=True)
        
    def get_len(self, name):
        """Return sequence length"""
        return communicate(self.shellwidget.monitor_socket,
                           "len(globals()['%s'])" % name,
                           pickle_try=True)
        
    def is_array(self, name):
        """Return True if variable is a NumPy array"""
        return monitor_is_array(self.shellwidget.monitor_socket, name)
        
    def get_array_shape(self, name):
        """Return array's shape"""
        return communicate(self.shellwidget.monitor_socket,
                           "globals()['%s'].shape" % name,
                           pickle_try=True)
        
    def get_array_ndim(self, name):
        """Return array's ndim"""
        return communicate(self.shellwidget.monitor_socket,
                           "globals()['%s'].ndim" % name,
                           pickle_try=True)
        
    def plot(self, name):
        command = "import spyderlib.pyplot as plt; " \
                  "plt.figure(); plt.plot(%s); plt.show();" % name
        self.shellwidget.send_to_process(command)
        
    def imshow(self, name):
        command = "import spyderlib.pyplot as plt; " \
                  "plt.figure(); plt.imshow(%s); plt.show();" % name
        self.shellwidget.send_to_process(command)
        
    def oedit(self, name):
        command = "from spyderlib.widgets.objecteditor import oedit; " \
                  "oedit(%s);" % name
        self.shellwidget.send_to_process(command)
        
    def set_data(self, data):
        if data != self.editor.model.get_data():
            self.editor.set_data(data)
            self.editor.adjust_columns()
        
    def collapse(self):
        self.emit(SIGNAL('collapse()'))
        
    def import_data(self):
        sock = self.shellwidget.monitor_socket
        
        title = self.tr("Import data")
        if self.filename is None:
            basedir = os.getcwdu()
        else:
            basedir = osp.dirname(self.filename)
        filename = iofunctions.get_open_filename(self, basedir, title)
        if filename:
            filename = unicode(filename)
        else:
            return
        self.filename = filename
        ext = osp.splitext(self.filename)[1].lower()
        
        if ext not in iofunctions.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 = iofunctions.load_funcs[ext]
            
        if isinstance(load_func, basestring): # 'import_wizard' (self.setup_io)
            # Import data with import wizard
            error_message = None
            try:
                text, _encoding = encoding.read(self.filename)
                base_name = osp.basename(self.filename)
                editor = ImportWizard(self, text, title=base_name,
                                      varname=fix_reference_name(base_name))
                if editor.exec_():
                    var_name, clip_data = editor.get_data()
                    monitor_set_global(sock, var_name, clip_data)
            except Exception, error:
                error_message = str(error)
        else:
Пример #7
0
    def setup(self,
              check_all=None,
              exclude_private=None,
              exclude_uppercase=None,
              exclude_capitalized=None,
              exclude_unsupported=None,
              excluded_names=None,
              truncate=None,
              minmax=None,
              remote_editing=None,
              autorefresh=None):
        """Setup the namespace browser"""
        assert self.shellwidget is not None

        self.check_all = check_all
        self.exclude_private = exclude_private
        self.exclude_uppercase = exclude_uppercase
        self.exclude_capitalized = exclude_capitalized
        self.exclude_unsupported = exclude_unsupported
        self.excluded_names = excluded_names
        self.truncate = truncate
        self.minmax = minmax
        self.remote_editing = remote_editing
        self.autorefresh = autorefresh

        if self.editor is not None:
            self.editor.setup_menu(truncate, minmax)
            self.exclude_private_action.setChecked(exclude_private)
            self.exclude_uppercase_action.setChecked(exclude_uppercase)
            self.exclude_capitalized_action.setChecked(exclude_capitalized)
            self.exclude_unsupported_action.setChecked(exclude_unsupported)
            # Don't turn autorefresh on for IPython kernels
            # See Issue 1450
            if not self.is_ipykernel:
                self.auto_refresh_button.setChecked(autorefresh)
            self.refresh_table()
            return

        # Dict editor:
        if self.is_internal_shell:
            self.editor = DictEditorTableView(self,
                                              None,
                                              truncate=truncate,
                                              minmax=minmax)
        else:
            self.editor = RemoteDictEditorTableView(
                self,
                None,
                truncate=truncate,
                minmax=minmax,
                remote_editing=remote_editing,
                get_value_func=self.get_value,
                set_value_func=self.set_value,
                new_value_func=self.set_value,
                remove_values_func=self.remove_values,
                copy_value_func=self.copy_value,
                is_list_func=self.is_list,
                get_len_func=self.get_len,
                is_array_func=self.is_array,
                is_image_func=self.is_image,
                is_dict_func=self.is_dict,
                is_data_frame_func=self.is_data_frame,
                is_time_series_func=self.is_time_series,
                get_array_shape_func=self.get_array_shape,
                get_array_ndim_func=self.get_array_ndim,
                oedit_func=self.oedit,
                plot_func=self.plot,
                imshow_func=self.imshow,
                show_image_func=self.show_image)
        self.editor.sig_option_changed.connect(self.sig_option_changed.emit)
        self.editor.sig_files_dropped.connect(self.import_data)

        # Menu
        options_button = create_toolbutton(self,
                                           text=_('Options'),
                                           icon=ima.icon('tooloptions'))
        options_button.setPopupMode(QToolButton.InstantPopup)
        menu = QMenu(self)
        editor = self.editor
        actions = [
            self.exclude_private_action, self.exclude_uppercase_action,
            self.exclude_capitalized_action, self.exclude_unsupported_action,
            None, editor.truncate_action
        ]
        if is_module_installed('numpy'):
            actions.append(editor.minmax_action)
        add_actions(menu, actions)
        options_button.setMenu(menu)

        # Setup layout
        layout = QVBoxLayout()
        blayout = QHBoxLayout()
        toolbar = self.setup_toolbar(exclude_private, exclude_uppercase,
                                     exclude_capitalized, exclude_unsupported,
                                     autorefresh)
        for widget in toolbar:
            blayout.addWidget(widget)
        blayout.addStretch()
        blayout.addWidget(options_button)
        layout.addLayout(blayout)
        layout.addWidget(self.editor)
        self.setLayout(layout)
        layout.setContentsMargins(0, 0, 0, 0)

        self.sig_option_changed.connect(self.option_changed)
Пример #8
0
    def setup(self, check_all=None, exclude_private=None,
              exclude_uppercase=None, exclude_capitalized=None,
              exclude_unsupported=None, excluded_names=None,
              truncate=None, minmax=None, remote_editing=None,
              autorefresh=None):
        """Setup the namespace browser"""
        assert self.shellwidget is not None
        
        self.check_all = check_all
        self.exclude_private = exclude_private
        self.exclude_uppercase = exclude_uppercase
        self.exclude_capitalized = exclude_capitalized
        self.exclude_unsupported = exclude_unsupported
        self.excluded_names = excluded_names
        self.truncate = truncate
        self.minmax = minmax
        self.remote_editing = remote_editing
        self.autorefresh = autorefresh
        
        if self.editor is not None:
            self.editor.setup_menu(truncate, minmax)
            self.exclude_private_action.setChecked(exclude_private)
            self.exclude_uppercase_action.setChecked(exclude_uppercase)
            self.exclude_capitalized_action.setChecked(exclude_capitalized)
            self.exclude_unsupported_action.setChecked(exclude_unsupported)
            # Don't turn autorefresh on for IPython kernels
            # See Issue 1450
            if not self.is_ipykernel:
                self.auto_refresh_button.setChecked(autorefresh)
            self.refresh_table()
            return
        
        # Dict editor:
        if self.is_internal_shell:
            self.editor = DictEditorTableView(self, None, truncate=truncate,
                                              minmax=minmax)
        else:
            self.editor = RemoteDictEditorTableView(self, None,
                            truncate=truncate, minmax=minmax,
                            remote_editing=remote_editing,
                            get_value_func=self.get_value,
                            set_value_func=self.set_value,
                            new_value_func=self.set_value,
                            remove_values_func=self.remove_values,
                            copy_value_func=self.copy_value,
                            is_list_func=self.is_list,
                            get_len_func=self.get_len,
                            is_array_func=self.is_array,
                            is_image_func=self.is_image,
                            is_dict_func=self.is_dict,
                            is_data_frame_func=self.is_data_frame,
                            is_time_series_func=self.is_time_series,                       
                            get_array_shape_func=self.get_array_shape,
                            get_array_ndim_func=self.get_array_ndim,
                            oedit_func=self.oedit,
                            plot_func=self.plot, imshow_func=self.imshow,
                            show_image_func=self.show_image)
        self.editor.sig_option_changed.connect(self.sig_option_changed.emit)
        self.editor.sig_files_dropped.connect(self.import_data)
        
        # Menu
        options_button = create_toolbutton(self, text=_('Options'),
                                           icon=ima.icon('tooloptions'))
        options_button.setPopupMode(QToolButton.InstantPopup)
        menu = QMenu(self)
        editor = self.editor
        actions = [self.exclude_private_action, self.exclude_uppercase_action,
                   self.exclude_capitalized_action,
                   self.exclude_unsupported_action, None,
                   editor.truncate_action]
        if is_module_installed('numpy'):
            actions.append(editor.minmax_action)
        add_actions(menu, actions)
        options_button.setMenu(menu)

        # Setup layout
        layout = QVBoxLayout()
        blayout = QHBoxLayout()
        toolbar = self.setup_toolbar(exclude_private, exclude_uppercase,
                                     exclude_capitalized, exclude_unsupported,
                                     autorefresh)
        for widget in toolbar:
            blayout.addWidget(widget)
        blayout.addStretch()
        blayout.addWidget(options_button)
        layout.addLayout(blayout)
        layout.addWidget(self.editor)
        self.setLayout(layout)
        layout.setContentsMargins(0, 0, 0, 0)

        self.sig_option_changed.connect(self.option_changed)