site_manager.py
来自「CoralFTP是一款用Python语言编写的工作在GTK2环境下的FTP客户端」· Python 代码 · 共 920 行 · 第 1/3 页
PY
920 行
'update' : self.on_delete_action_update, 'execute' : self.on_delete_action_execute}, 'rename' : { 'sensitive' : FALSE, 'update' : self.on_rename_action_update, 'execute' : self.on_rename_action_execute}, } MENU_ACTIONS = { 'mi_sm_connect' : 'connect', 'mi_sm_new_site' : 'new_site', 'mi_sm_new_group' : 'new_group', 'mi_sm_delete' : 'delete', 'mi_sm_rename' : 'rename' } self.__coralftp = coralftp self.__site_manager = coralftp.get_site_manager() self.__site_manager.connect('after-add-node', self.on_site_manager_add_node) self.__site_manager.connect('before-delete-node', self.on_site_manager_delete_node) self.__xml = get_glade_xml('site_manager_dialog') self.__xml.signal_autoconnect(self) # initialize action list self.actions = ActionList(ACTIONS) self.actions['connect'].attach( self.__xml.get_widget('btn_connect')) self.actions['close'].attach( self.__xml.get_widget('btn_close')) self.actions['apply'].attach( self.__xml.get_widget('btn_apply')) self.actions['new_site'].attach( self.__xml.get_widget('btn_new_site')) self.actions['new_group'].attach( self.__xml.get_widget('btn_new_group')) self.actions['delete'].attach( self.__xml.get_widget('btn_delete')) self.__dialog = self.__xml.get_widget('site_manager_dialog') self.__tree = self.__xml.get_widget('sites_tree') self.__model = TreeStore(TYPE_STRING, TYPE_PYOBJECT, gtk.gdk.Pixbuf) self.__tree.set_model(self.__model) tree_selection = self.__tree.get_selection() tree_selection.set_mode(gtk.SELECTION_BROWSE) column = TreeViewColumn("Name") renderer = CellRendererPixbuf() column.pack_start(renderer, expand=FALSE) column.add_attribute(renderer, 'pixbuf',SiteManagerDialog.COL_ICON) renderer = CellRendererText() column.pack_start(renderer, expand=TRUE) column.add_attribute(renderer, 'text', SiteManagerDialog.COL_NAME) self.__tree.append_column(column) # drag & drop # drag and drop only happens in the tree widget## TARGET_SITEINFO = (("coralftp siteinfo", TARGET_SAME_WIDGET, 80),)## self.__tree.drag_source_set(BUTTON1_MASK,## TARGET_SITEINFO,## ACTION_COPY)## self.__tree.drag_dest_set(DEST_DEFAULT_ALL,## TARGET_SITEINFO,## ACTION_COPY)## self.__tree.connect("drag-data-get", self.on_drag_data_get)## self.__tree.connect("drag-data-received", self.on_drag_data_recv)## self.__tree.connect("drag-drop", self.on_drag_drop) self.__tree.set_reorderable(TRUE) # popup menu self.__menu_xml = get_glade_xml('site_manager_menu') self.__menu = self.__menu_xml.get_widget('site_manager_menu') for widget_name, action_name in MENU_ACTIONS.items(): widget = self.__menu_xml.get_widget(widget_name) self.actions[action_name].attach(widget) self.__build_tree() return def run(self): resp = None while 1: resp = self.__dialog.run() if resp == RESPONSE_OK: break elif resp == RESPONSE_CLOSE or resp == RESPONSE_DELETE_EVENT: break return resp def destroy(self): for name, action in self.actions.items(): action.remove() self.__dialog.destroy() return def __get_folder_icon(self): return gdk.pixbuf_new_from_file(coralftp_datadir + '/folder.png') def __get_site_icon(self): return gdk.pixbuf_new_from_file(coralftp_datadir + '/computer.png') def __build_tree(self): def process(data, start_iter): for key, value in data.items(): if isinstance(value, SiteFolder): icon = self.__get_folder_icon() else: icon = self.__get_site_icon() child_iter = self.__model.append(start_iter) self.__model.set_value(child_iter, SiteManagerDialog.COL_NAME, key) self.__model.set_value(child_iter, SiteManagerDialog.COL_SITEINFO, value) self.__model.set_value(child_iter, SiteManagerDialog.COL_ICON, icon) if isinstance(value, SiteFolder): process(value, child_iter) iter = self.__model.get_iter_root() process(self.__site_manager.data, iter) self.__xml.get_widget('sites_tree').expand_all() return def __find_iter(self, path): # find the folder of the item iter = None for part in string.split(path[1:], '/'): found = False if iter == None: child = self.__model.get_iter_root() else: child = self.__model.iter_children(iter) while child != None: name = self.__model.get_value( child, SiteManagerDialog.COL_NAME) if name == part: found = True iter = child break child = self.__model.iter_next(child) if not found: # create a coresponding folder parent_folder = self.__model.get_value( iter, SiteManagerDialog.COL_SITEINFO) child_folder = parent_folder[part] iter = self.__model.append(iter, None) icon = self.__get_folder_icon() self.__model.set_value( iter, SiteManagerDialog.COL_ICON, icon) self.__model.set_value( iter, SiteManagerDialog.COL_NAME, part) self.__model.set_value( iter, SiteManagerDialog.COL_SITEINFO, child_folder) return iter def on_site_manager_add_node(self, obj, node, *args): "Add node to TreeView." path = self.__site_manager.get_path(node) pos = path.rfind('/') self.__old_selected = None self.__parent = self.__find_iter(path[:pos]) if isinstance(node, SiteFolder): icon = self.__get_folder_icon() else: icon = self.__get_site_icon() row = (path[pos+1:], node, icon) self.__selected = self.__model.append(self.__parent, row) self.__node = node self.__tree.get_selection().select_iter(self.__selected) self.__tree.emit('cursor-changed') return def on_site_manager_delete_node(self, obj, node, *args): "Delete node from TreeView." path = self.__site_manager.get_path(node) iter = self.__find_iter(path) parent = self.__model.iter_parent(iter) self.__model.remove(iter) if parent != None: self.__tree.get_selection().select_iter(parent) self.__tree.emit('cursor-changed') self.__selected = parent self.__node = self.__model.get_value(self.__selected, SiteManagerDialog.COL_SITEINFO) self.__parent = self.__model.iter_parent(self.__selected) self.__old_selected = None return def __check_change(self, selected): """Check if the data in the panel has been changed.""" si = self.__model.get_value(selected, SiteManagerDialog.COL_SITEINFO) if not isinstance(si, SiteInfo): raise ValueError, "The selected should be a site" changed = False for item in SiteManagerDialog.WIDGETS: data_name = item[SiteManagerDialog.DATA_NAME] widget_name = item[SiteManagerDialog.WIDGET_NAME] widget = self.__xml.get_widget(widget_name) if not changed and isinstance(widget, Entry): v = widget.get_text() if not changed and isinstance(widget, CheckButton): v = widget.get_property('active').__str__() if not changed and isinstance(widget, TextView): buf = widget.get_buffer() v = buf.get_text(buf.get_start_iter(), buf.get_end_iter()) changed = (not si.has_key(data_name) and v != item[SiteManagerDialog.DATA_DEFAULT]) changed = changed or (si.has_key(data_name) and v != si[data_name]) if changed: break return changed def __load_from_data(self, selected): attrs = self.__model.get_value(selected, SiteManagerDialog.COL_SITEINFO) active = isinstance(attrs, SiteInfo) if active: for item in SiteManagerDialog.WIDGETS: if not attrs.has_key(item[SiteManagerDialog.DATA_NAME]): item_value = item[SiteManagerDialog.DATA_DEFAULT] else: item_value = attrs[item[SiteManagerDialog.DATA_NAME]] widget = self.__xml.get_widget( item[SiteManagerDialog.WIDGET_NAME]) if isinstance(widget, Entry): widget.set_text(item_value) elif isinstance(widget, CheckButton): if item_value == 'True': widget.set_property('active', TRUE) else: widget.set_property('active', FALSE) elif isinstance(widget, TextView): buf = widget.get_buffer() buf.set_text(item_value) return def __save_to_data(self, selected): si = self.__model.get_value(selected, SiteManagerDialog.COL_SITEINFO) # if the name of the site has been changed, update the dictionary key widget = self.__xml.get_widget('entry_sitename') new_name = string.strip(widget.get_text()) old_name = si['site_name'] if new_name != old_name: parent = self.__model.iter_parent(selected) parent_node = self.__model.get_value( parent, SiteManagerDialog.COL_SITEINFO) del parent_node[old_name] parent_node[new_name] = si # save all values in widgets for item in SiteManagerDialog.WIDGETS: widget = self.__xml.get_widget( item[SiteManagerDialog.WIDGET_NAME]) data_name = item[SiteManagerDialog.DATA_NAME] if isinstance(widget, Entry): if widget.get_visibility(): si[data_name] = string.strip(widget.get_text()) else: si[data_name] = widget.get_text() elif isinstance(widget, CheckButton): si[data_name] = widget.get_property('active').__str__() elif isinstance(widget, TextView): buf = widget.get_buffer() si[data_name] = buf.get_text(buf.get_start_iter(), buf.get_end_iter()) self.__site_manager.save() return def __validate_node_name(self, name, parent, node=None, is_folder=False): "Check if the new name of the node is validate." error_message = None if name == '': if is_folder: error_message = "The name of the site should not be empty." else: error_message = "The name of the site should not be empty." if name.find('/') >= 0: if is_folder: error_message = "The name of the folder should not contain backslash('/')." else: error_message = "The name of the site should not contain backslash('/')." if parent.has_key(name) and parent[name] != node: error_message = "The site or folder named %s already exists." % name return error_message def on_btn_local_path_browse_clicked(self, obj, *args): """This method is used to choose a local path.""" dlg = FileSelection(title='Local Path') resp = dlg.run() if resp == RESPONSE_OK: widget = self.__xml.get_widget('entry_local_path') widget.set_text(dlg.get_property('filename')) dlg.destroy() return def on_sites_tree_button_press_event(self, obj, event): """This method is used to process left mouse click. If current item is a site, just connect.""" pass
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?