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, collvalue=None, remote_editing=None, inplace=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.collvalue = collvalue self.inplace = inplace self.remote_editing = remote_editing self.autorefresh = autorefresh if self.editor is not None: if self.is_internal_shell: self.editor.setup_menu(truncate, minmax, inplace, collvalue) else: self.editor.setup_menu(truncate, minmax, inplace, collvalue, remote_editing) 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, inplace=inplace, minmax=minmax, collvalue=collvalue) else: #self.editor = RemoteDictEditorTableView(self, None, self.editor = RemoteDictEditorTreeView( self, None, truncate=truncate, inplace=inplace, minmax=minmax, collvalue=collvalue, 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, 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) # 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 setup(self, check_all=None, exclude_private=None, exclude_uppercase=None, exclude_capitalized=None, exclude_unsupported=None, excluded_names=None, truncate=None, minmax=None, collvalue=None, remote_editing=None, inplace=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.collvalue = collvalue self.inplace = inplace self.remote_editing = remote_editing self.autorefresh = autorefresh if self.editor is not None: if self.is_internal_shell: self.editor.setup_menu(truncate, minmax, inplace, collvalue) else: self.editor.setup_menu(truncate, minmax, inplace, collvalue, remote_editing) 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, inplace=inplace, minmax=minmax, collvalue=collvalue) else: #self.editor = RemoteDictEditorTableView(self, None, self.editor = RemoteDictEditorTreeView(self, None, truncate=truncate, inplace=inplace, minmax=minmax, collvalue=collvalue, 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, 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) # 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)
class NamespaceBrowser(QWidget): """Namespace browser (global variables explorer widget)""" sig_option_changed = pyqtSignal(str, object) def __init__(self, parent): QWidget.__init__(self, parent) self.shellwidget = None self.is_internal_shell = 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.collvalue = None self.inplace = 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, collvalue=None, remote_editing=None, inplace=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.collvalue = collvalue self.inplace = inplace self.remote_editing = remote_editing self.autorefresh = autorefresh if self.editor is not None: if self.is_internal_shell: self.editor.setup_menu(truncate, minmax, inplace, collvalue) else: self.editor.setup_menu(truncate, minmax, inplace, collvalue, remote_editing) 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, inplace=inplace, minmax=minmax, collvalue=collvalue) else: #self.editor = RemoteDictEditorTableView(self, None, self.editor = RemoteDictEditorTreeView( self, None, truncate=truncate, inplace=inplace, minmax=minmax, collvalue=collvalue, 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, 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) # 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 SMlib.widgets import internalshell self.is_internal_shell = isinstance(self.shellwidget, internalshell.InternalShell) try: self.is_ipykernel = self.shellwidget.is_ipykernel except AttributeError: pass if not self.is_internal_shell: shellwidget.set_namespacebrowser(self) 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=get_icon('reload.png'), triggered=self.refresh_table) self.auto_refresh_button = create_toolbutton( self, text=_("Refresh periodically"), icon=get_icon('auto_reload.png'), toggled=self.toggle_auto_refresh) self.auto_refresh_button.setChecked(autorefresh) load_button = create_toolbutton(self, text=_("Import data"), icon=get_icon('fileimport.png'), triggered=self.import_data) self.save_button = create_toolbutton( self, text=_("Save data"), icon=get_icon('filesave.png'), triggered=lambda: self.save_data(self.filename)) self.save_button.setEnabled(False) save_as_button = create_toolbutton(self, text=_("Save data as..."), icon=get_icon('filesaveas.png'), 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=get_icon('tooloptions.png')) 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, editor.inplace_action, editor.collvalue_action ] if is_module_installed('numpy'): actions.append(editor.minmax_action) if not self.is_internal_shell: actions.append(editor.remote_editing_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, unicode(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() 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 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 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 = unicode(_("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 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 SMlib.pyplot; "\ "__fig__ = SMlib.pyplot.figure(); "\ "__items__ = getattr(SMlib.pyplot, '%s')(%s); "\ "SMlib.pyplot.show(); "\ "del __fig__, __items__;" % (funcname, name) self.shellwidget.send_to_process(command) def imshow(self, name): command = "import SMlib.pyplot; " \ "__fig__ = SMlib.pyplot.figure(); " \ "__items__ = SMlib.pyplot.imshow(%s); " \ "SMlib.pyplot.show(); del __fig__, __items__;" % name self.shellwidget.send_to_process(command) def show_image(self, name): command = "%s.show()" % name self.shellwidget.send_to_process(command) def oedit(self, name): command = "from SMlib.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.emit(SIGNAL('collapse()')) def import_data(self, filenames=None): """Import data from text file""" title = _("Import data") if filenames is None: if self.filename is None: basedir = os.getcwdu() else: basedir = osp.dirname(self.filename) filenames, _selfilter = getopenfilenames(self, title, basedir, iofunctions.load_filters) if not filenames: return elif isinstance(filenames, basestring): filenames = [filenames] for filename in filenames: self.filename = unicode(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 = iofunctions.load_extensions.keys() item, ok = QInputDialog.getItem(self, title, _('Open file as:'), formats, 0, False) if ok: ext = iofunctions.load_extensions[unicode(item)] else: return load_func = iofunctions.load_funcs[ext] # 'import_wizard' (self.setup_io) if isinstance(load_func, basestring): # 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, 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 namespace.keys(): new_key = fix_reference_name( key, blacklist=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()
class NamespaceBrowser(QWidget): """Namespace browser (global variables explorer widget)""" sig_option_changed = pyqtSignal(str, object) def __init__(self, parent): QWidget.__init__(self, parent) self.shellwidget = None self.is_internal_shell = 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.collvalue = None self.inplace = 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, collvalue=None, remote_editing=None, inplace=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.collvalue = collvalue self.inplace = inplace self.remote_editing = remote_editing self.autorefresh = autorefresh if self.editor is not None: if self.is_internal_shell: self.editor.setup_menu(truncate, minmax, inplace, collvalue) else: self.editor.setup_menu(truncate, minmax, inplace, collvalue, remote_editing) 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, inplace=inplace, minmax=minmax, collvalue=collvalue) else: #self.editor = RemoteDictEditorTableView(self, None, self.editor = RemoteDictEditorTreeView(self, None, truncate=truncate, inplace=inplace, minmax=minmax, collvalue=collvalue, 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, 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) # 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 SMlib.widgets import internalshell self.is_internal_shell = isinstance(self.shellwidget, internalshell.InternalShell) try: self.is_ipykernel = self.shellwidget.is_ipykernel except AttributeError: pass if not self.is_internal_shell: shellwidget.set_namespacebrowser(self) 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=get_icon('reload.png'), triggered=self.refresh_table) self.auto_refresh_button = create_toolbutton(self, text=_("Refresh periodically"), icon=get_icon('auto_reload.png'), toggled=self.toggle_auto_refresh) self.auto_refresh_button.setChecked(autorefresh) load_button = create_toolbutton(self, text=_("Import data"), icon=get_icon('fileimport.png'), triggered=self.import_data) self.save_button = create_toolbutton(self, text=_("Save data"), icon=get_icon('filesave.png'), triggered=lambda: self.save_data(self.filename)) self.save_button.setEnabled(False) save_as_button = create_toolbutton(self, text=_("Save data as..."), icon=get_icon('filesaveas.png'), 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=get_icon('tooloptions.png')) 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, editor.inplace_action, editor.collvalue_action] if is_module_installed('numpy'): actions.append(editor.minmax_action) if not self.is_internal_shell: actions.append(editor.remote_editing_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, unicode(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() 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 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 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 = unicode(_("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 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 SMlib.pyplot; "\ "__fig__ = SMlib.pyplot.figure(); "\ "__items__ = getattr(SMlib.pyplot, '%s')(%s); "\ "SMlib.pyplot.show(); "\ "del __fig__, __items__;" % (funcname, name) self.shellwidget.send_to_process(command) def imshow(self, name): command = "import SMlib.pyplot; " \ "__fig__ = SMlib.pyplot.figure(); " \ "__items__ = SMlib.pyplot.imshow(%s); " \ "SMlib.pyplot.show(); del __fig__, __items__;" % name self.shellwidget.send_to_process(command) def show_image(self, name): command = "%s.show()" % name self.shellwidget.send_to_process(command) def oedit(self, name): command = "from SMlib.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.emit(SIGNAL('collapse()')) def import_data(self, filenames=None): """Import data from text file""" title = _("Import data") if filenames is None: if self.filename is None: basedir = os.getcwdu() else: basedir = osp.dirname(self.filename) filenames, _selfilter = getopenfilenames(self, title, basedir, iofunctions.load_filters) if not filenames: return elif isinstance(filenames, basestring): filenames = [filenames] for filename in filenames: self.filename = unicode(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 = iofunctions.load_extensions.keys() item, ok = QInputDialog.getItem(self, title, _('Open file as:'), formats, 0, False) if ok: ext = iofunctions.load_extensions[unicode(item)] else: return load_func = iofunctions.load_funcs[ext] # 'import_wizard' (self.setup_io) if isinstance(load_func, basestring): # 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, 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 namespace.keys(): new_key = fix_reference_name(key, blacklist=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()