diff --git a/ChangeLog b/ChangeLog index 591acd314..83eef394f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2007-06-23 Alex Roitman + * src/plugins/RemoveUnused.py: Rewrite with single-dialog UI. + * src/plugins/unused.glade: Add new file. + * src/plugins/Makefile.am: Ship new file. + 2007-06-23 Brian Matherly * src/Filters/Rules/Person/__init__.py: * src/Filters/Rules/Person/Makefile.am: diff --git a/po/ChangeLog b/po/ChangeLog index e072402ce..630654f91 100644 --- a/po/ChangeLog +++ b/po/ChangeLog @@ -1,5 +1,5 @@ 2007-06-23 Alex Roitman - * POTFILES.in: Add new file. + * POTFILES.in: Add new files. 2007-06-16 Peter Landgren * sv.po: Update. diff --git a/po/POTFILES.in b/po/POTFILES.in index 04121ee30..ae9ea8ddd 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -620,6 +620,7 @@ src/plugins/vcalendarexport.glade src/plugins/vcardexport.glade src/plugins/verify.glade src/plugins/writeftree.glade +src/plugins/unused.glade # # Files to extract from and then merge into # diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am index 94cd7fc1e..f6ca99572 100644 --- a/src/plugins/Makefile.am +++ b/src/plugins/Makefile.am @@ -88,7 +88,8 @@ GLADEFILES = \ genewebexport.glade\ vcardexport.glade\ vcalendarexport.glade\ - checkpoint.glade + checkpoint.glade\ + unused.glade GRAPHICS = diff --git a/src/plugins/RemoveUnused.py b/src/plugins/RemoveUnused.py index 680b09ed9..bb4b2ac6f 100644 --- a/src/plugins/RemoveUnused.py +++ b/src/plugins/RemoveUnused.py @@ -18,7 +18,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# $Id: Check.py 7321 2006-09-13 02:57:45Z dallingham $ +# $Id$ "Find unused objects and remove with the user's permission" @@ -62,34 +62,71 @@ from PluginUtils import Tool, register_tool # #------------------------------------------------------------------------- class RemoveUnused(Tool.Tool,ManagedWindow.ManagedWindow,UpdateCallback): + MARK_COL = 0 + OBJ_ID_COL = 1 + OBJ_NAME_COL = 2 + OBJ_TYPE_COL = 3 + OBJ_HANDLE_COL = 4 + def __init__(self, dbstate, uistate, options_class, name, callback=None): - self.label = _('Remove Unused Objects tool') + self.title = _('Unused Objects') Tool.Tool.__init__(self, dbstate, options_class, name) + + if self.db.readonly: + return + ManagedWindow.ManagedWindow.__init__(self, uistate,[],self.__class__) UpdateCallback.__init__(self,self.uistate.pulse_progressbar) self.dbstate = dbstate self.uistate = uistate - if self.db.readonly: - return + self.tables = { + 'events' : {'get_func': self.db.get_event_from_handle, + 'remove' : self.db.remove_event, + 'editor' : 'EditEvent', + 'stock' : 'gramps-event', + 'name_ix' : 4}, + 'sources' : {'get_func': self.db.get_source_from_handle, + 'remove' : self.db.remove_source, + 'editor' : 'EditSource', + 'stock' : 'gramps-source', + 'name_ix' : 2}, + 'places' : {'get_func': self.db.get_place_from_handle, + 'remove' : self.db.remove_place, + 'editor' : 'EditPlace', + 'stock' : 'gramps-place', + 'name_ix' : 2}, + 'media' : {'get_func': self.db.get_object_from_handle, + 'remove' : self.db.remove_object, + 'editor' : 'EditMedia', + 'stock' : 'gramps-media', + 'name_ix' : 4}, + 'repos' : {'get_func': self.db.get_repository_from_handle, + 'remove' : self.db.remove_repository, + 'editor' : 'EditRepository', + 'stock' : 'gramps-repository', + 'name_ix' : 3}, + } self.init_gui() - def init_gui(self): - window = gtk.Dialog("%s - GRAMPS" % self.label, - buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, - gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)) + def init_gui(): + base = os.path.dirname(__file__) + self.glade_file = base + os.sep + "unused.glade" - window.set_border_width(12) - window.set_has_separator(False) + self.top = gtk.glade.XML(self.glade_file,"unused","gramps") + window = self.top.get_widget("unused") + self.set_window(window,self.top.get_widget('title'),self.title) - self.events_box = gtk.CheckButton(_('Remove unused events')) - self.sources_box = gtk.CheckButton(_('Remove unused sources')) - self.places_box = gtk.CheckButton(_('Remove unused places')) - self.media_box = gtk.CheckButton(_('Remove unused media')) - self.repos_box = gtk.CheckButton(_('Remove unused repositories')) + self.events_box = self.top.get_widget('events_box') + self.sources_box = self.top.get_widget('sources_box') + self.places_box = self.top.get_widget('places_box') + self.media_box = self.top.get_widget('media_box') + self.repos_box = self.top.get_widget('repos_box') + self.find_button = self.top.get_widget('find_button') + self.remove_button = self.top.get_widget('remove_button') self.events_box.set_active(self.options.handler.options_dict['events']) self.sources_box.set_active( @@ -99,31 +136,73 @@ class RemoveUnused(Tool.Tool,ManagedWindow.ManagedWindow,UpdateCallback): self.media_box.set_active(self.options.handler.options_dict['media']) self.repos_box.set_active(self.options.handler.options_dict['repos']) - label = gtk.Label() - window.vbox.add(label) - label.set_padding(12,12) - window.vbox.add(self.events_box) - window.vbox.add(self.sources_box) - window.vbox.add(self.places_box) - window.vbox.add(self.media_box) - window.vbox.add(self.repos_box) - window.vbox.show_all() + self.warn_tree = self.top.get_widget('warn_tree') + self.warn_tree.connect('button_press_event', self.double_click) - self.set_window(window,label,self.label) + self.selection = self.warn_tree.get_selection() + + self.mark_button = self.top.get_widget('mark_button') + self.mark_button.connect('clicked',self.mark_clicked) + + self.unmark_button = self.top.get_widget('unmark_button') + self.unmark_button.connect('clicked',self.unmark_clicked) + + self.invert_button = self.top.get_widget('invert_button') + self.invert_button.connect('clicked',self.invert_clicked) + + self.real_model = gtk.ListStore(bool,str,str,str,str) + self.sort_model = gtk.TreeModelSort(self.real_model) + self.warn_tree.set_model(self.sort_model) + + self.renderer = gtk.CellRendererText() + self.img_renderer = gtk.CellRendererPixbuf() + self.bool_renderer = gtk.CellRendererToggle() + self.bool_renderer.connect('toggled',self.selection_toggled) + + # Add mark column + mark_column = gtk.TreeViewColumn(_('Mark'),self.bool_renderer, + active=RemoveUnused.MARK_COL) + mark_column.set_sort_column_id(RemoveUnused.MARK_COL) + self.warn_tree.append_column(mark_column) + + # Add image column + img_column = gtk.TreeViewColumn(None, self.img_renderer ) + img_column.set_cell_data_func(self.img_renderer,self.get_image) + self.warn_tree.append_column(img_column) + + # Add column with object gramps_id + id_column = gtk.TreeViewColumn(_('ID'), self.renderer, + text=RemoveUnused.OBJ_ID_COL) + id_column.set_sort_column_id(RemoveUnused.OBJ_ID_COL) + self.warn_tree.append_column(id_column) + + # Add column with object name + name_column = gtk.TreeViewColumn(_('Name'), self.renderer, + text=RemoveUnused.OBJ_NAME_COL) + name_column.set_sort_column_id(RemoveUnused.OBJ_NAME_COL) + self.warn_tree.append_column(name_column) + + self.top.signal_autoconnect({ + "destroy_passed_object" : self.close, + "on_remove_button_clicked": self.do_remove, + "on_find_button_clicked" : self.find, + }) + + self.dc_label = self.top.get_widget('dc_label') + + self.sensitive_list = [self.warn_tree,self.mark_button, + self.unmark_button,self.invert_button, + self.dc_label,self.remove_button] + + for item in self.sensitive_list: + item.set_sensitive(False) - self.window.connect('response',self.response_handler) self.show() - def response_handler(self,window,response): - if response == gtk.RESPONSE_ACCEPT: - self.run_tool() - else: - self.close() - def build_menu_names(self,obj): - return (_("Tool settings"),self.label) + return (self.title,None) - def run_tool(self): + def find(self,obj): self.options.handler.options_dict['events'] = \ int(self.events_box.get_active()) self.options.handler.options_dict['sources'] = \ @@ -135,20 +214,19 @@ class RemoveUnused(Tool.Tool,ManagedWindow.ManagedWindow,UpdateCallback): self.options.handler.options_dict['repos'] = \ int(self.repos_box.get_active()) - sr = ShowResults(self.dbstate,self.uistate,self.track) - self.add_results = sr.add_results + for item in self.sensitive_list: + item.set_sensitive(True) self.uistate.window.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH)) self.uistate.progress.show() self.window.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH)) - sr.window.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH)) + self.real_model.clear() self.collect_unused() self.uistate.progress.hide() self.uistate.window.window.set_cursor(None) self.window.window.set_cursor(None) - sr.window.window.set_cursor(None) self.reset() # Save options @@ -191,171 +269,51 @@ class RemoveUnused(Tool.Tool,ManagedWindow.ManagedWindow,UpdateCallback): cursor.close() self.reset() -#------------------------------------------------------------------------- -# -# Show the results -# -#------------------------------------------------------------------------- -class ShowResults(ManagedWindow.ManagedWindow): - MARK_COL = 0 - OBJ_ID_COL = 1 - OBJ_NAME_COL = 2 - OBJ_TYPE_COL = 3 - OBJ_HANDLE_COL = 4 - - def __init__(self,dbstate,uistate,track): - self.title = _('Unused Objects') - - ManagedWindow.ManagedWindow.__init__(self,uistate,track,self.__class__) - - self.dbstate = dbstate - self.db = dbstate.db - - self.tables = { - 'events' : {'get_func': self.db.get_event_from_handle, - 'remove' : self.db.remove_event, - 'editor' : 'EditEvent', - 'stock' : 'gramps-event', - 'name_ix' : 4}, - 'sources' : {'get_func': self.db.get_source_from_handle, - 'remove' : self.db.remove_source, - 'editor' : 'EditSource', - 'stock' : 'gramps-source', - 'name_ix' : 2}, - 'places' : {'get_func': self.db.get_place_from_handle, - 'remove' : self.db.remove_place, - 'editor' : 'EditPlace', - 'stock' : 'gramps-place', - 'name_ix' : 2}, - 'media' : {'get_func': self.db.get_object_from_handle, - 'remove' : self.db.remove_object, - 'editor' : 'EditMedia', - 'stock' : 'gramps-media', - 'name_ix' : 4}, - 'repos' : {'get_func': self.db.get_repository_from_handle, - 'remove' : self.db.remove_repository, - 'editor' : 'EditRepository', - 'stock' : 'gramps-repository', - 'name_ix' : 3}, - } - - base = os.path.dirname(__file__) - self.glade_file = base + os.sep + "verify.glade" - - self.top = gtk.glade.XML(self.glade_file,"verify_result","gramps") - window = self.top.get_widget("verify_result") - self.set_window(window,self.top.get_widget('title'),self.title) - - self.top.signal_autoconnect({ - "destroy_passed_object" : self.close, - }) - - self.warn_tree = self.top.get_widget('warn_tree') - self.warn_tree.connect('button_press_event', self.double_click) - - self.selection = self.warn_tree.get_selection() - - self.hide_button = self.top.get_widget('hide_button') - self.hide_button.destroy() - - self.mark_button = self.top.get_widget('mark_all') - self.mark_button.connect('clicked',self.mark_clicked) - - self.unmark_button = self.top.get_widget('unmark_all') - self.unmark_button.connect('clicked',self.unmark_clicked) - - self.invert_button = self.top.get_widget('invert_all') - self.invert_button.connect('clicked',self.invert_clicked) - - self.real_model = gtk.ListStore(bool,str,str,str,str) - self.sort_model = gtk.TreeModelSort(self.real_model) - self.warn_tree.set_model(self.sort_model) - - self.renderer = gtk.CellRendererText() - self.img_renderer = gtk.CellRendererPixbuf() - self.bool_renderer = gtk.CellRendererToggle() - self.bool_renderer.connect('toggled',self.selection_toggled) - - # Add mark column - mark_column = gtk.TreeViewColumn(_('Mark'),self.bool_renderer, - active=ShowResults.MARK_COL) - mark_column.set_sort_column_id(ShowResults.MARK_COL) - self.warn_tree.append_column(mark_column) - - # Add image column - img_column = gtk.TreeViewColumn(None, self.img_renderer ) - img_column.set_cell_data_func(self.img_renderer,self.get_image) - self.warn_tree.append_column(img_column) - - # Add column with object gramps_id - id_column = gtk.TreeViewColumn(_('ID'), self.renderer, - text=ShowResults.OBJ_ID_COL) - id_column.set_sort_column_id(ShowResults.OBJ_ID_COL) - self.warn_tree.append_column(id_column) - - # Add column with object name - name_column = gtk.TreeViewColumn(_('Name'), self.renderer, - text=ShowResults.OBJ_NAME_COL) - name_column.set_sort_column_id(ShowResults.OBJ_NAME_COL) - self.warn_tree.append_column(name_column) - - # Add a button to remove selected objects - remove_button = self.window.add_button(gtk.STOCK_REMOVE, - gtk.RESPONSE_ACCEPT) - self.window.connect('response',self.response_handler) - - self.window.show_all() - self.window_shown = False - - def response_handler(self,window,response): - if response == gtk.RESPONSE_ACCEPT: - self.do_remove() - - def do_remove(self): + def do_remove(self,obj): trans = self.db.transaction_begin("",batch=False) self.db.disable_signals() for row_num in range(len(self.real_model)-1,-1,-1): path = (row_num,) row = self.real_model[path] - if not row[ShowResults.MARK_COL]: + if not row[RemoveUnused.MARK_COL]: continue - the_type = row[ShowResults.OBJ_TYPE_COL] - handle = row[ShowResults.OBJ_HANDLE_COL] + the_type = row[RemoveUnused.OBJ_TYPE_COL] + handle = row[RemoveUnused.OBJ_HANDLE_COL] remove_func = self.tables[the_type]['remove'] remove_func(handle, trans) - self.real_model.remove(row.iter) + self.real_model.remove(row.iter) self.db.transaction_commit(trans, _("Remove unused objects")) self.db.enable_signals() - self.db.request_rebuild() + self.db.request_rebuild() def selection_toggled(self,cell,path_string): sort_path = tuple([int (i) for i in path_string.split(':')]) real_path = self.sort_model.convert_path_to_child_path(sort_path) row = self.real_model[real_path] - row[ShowResults.MARK_COL] = not row[ShowResults.MARK_COL] + row[RemoveUnused.MARK_COL] = not row[RemoveUnused.MARK_COL] self.real_model.row_changed(real_path,row.iter) def mark_clicked(self,mark_button): for row_num in range(len(self.real_model)): path = (row_num,) row = self.real_model[path] - row[ShowResults.MARK_COL] = True + row[RemoveUnused.MARK_COL] = True def unmark_clicked(self,unmark_button): for row_num in range(len(self.real_model)): path = (row_num,) row = self.real_model[path] - row[ShowResults.MARK_COL] = False + row[RemoveUnused.MARK_COL] = False def invert_clicked(self,invert_button): for row_num in range(len(self.real_model)): path = (row_num,) row = self.real_model[path] - row[ShowResults.MARK_COL] = not row[ShowResults.MARK_COL] + row[RemoveUnused.MARK_COL] = not row[RemoveUnused.MARK_COL] def double_click(self,obj,event): if event.type == gtk.gdk._2BUTTON_PRESS and event.button == 1: @@ -365,8 +323,8 @@ class ShowResults(ManagedWindow.ManagedWindow): sort_path = self.sort_model.get_path(node) real_path = self.sort_model.convert_path_to_child_path(sort_path) row = self.real_model[real_path] - the_type = row[ShowResults.OBJ_TYPE_COL] - handle = row[ShowResults.OBJ_HANDLE_COL] + the_type = row[RemoveUnused.OBJ_TYPE_COL] + handle = row[RemoveUnused.OBJ_HANDLE_COL] self.call_editor(the_type,handle) def call_editor(self,the_type,handle): @@ -380,7 +338,7 @@ class ShowResults(ManagedWindow.ManagedWindow): pass def get_image(self, column, cell, model, iter, user_data=None): - the_type = model.get_value(iter, ShowResults.OBJ_TYPE_COL) + the_type = model.get_value(iter, RemoveUnused.OBJ_TYPE_COL) the_stock = self.tables[the_type]['stock'] cell.set_property('stock-id', the_stock) @@ -393,13 +351,6 @@ class ShowResults(ManagedWindow.ManagedWindow): self.real_model.append(row=[False,gramps_id,name,the_type,handle]) - if not self.window_shown: - self.show() - self.window_shown = True - - def build_menu_names(self,obj): - return (self.title,None) - #------------------------------------------------------------------------ # # diff --git a/src/plugins/unused.glade b/src/plugins/unused.glade new file mode 100644 index 000000000..8cb06db8c --- /dev/null +++ b/src/plugins/unused.glade @@ -0,0 +1,255 @@ + + + + + + True + 500 + 300 + GDK_WINDOW_TYPE_HINT_DIALOG + False + + + + True + + + True + 6 + 6 + + + True + + + False + False + 6 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Search for events + 0 + True + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Search for sources + 0 + True + + + 1 + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Search for places + 0 + True + + + 2 + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Search for media + 0 + True + + + 3 + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Search for repositories + 0 + True + + + 4 + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-find + True + 0 + + + + + + False + 1 + + + + + False + False + 1 + + + + + True + True + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_SHADOW_IN + + + True + True + True + + + + + 6 + 2 + + + + + True + 6 + GTK_BUTTONBOX_SPREAD + + + True + True + True + _Mark all + True + 0 + + + + + True + True + True + _Unmark all + True + 0 + + + 1 + + + + + True + True + True + In_vert marks + True + 0 + + + 2 + + + + + False + False + 3 + + + + + True + <b>Double-click on a row to view/edit data</b> + True + + + False + False + 4 + + + + + 1 + + + + + True + GTK_BUTTONBOX_END + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-remove + True + -3 + + + + + + True + True + True + gtk-close + True + -7 + + + + 1 + + + + + False + GTK_PACK_END + + + + + +