# This Python file uses the following encoding: utf-8 # # Author: Roman 'gryf' Dobosz gryf@elysium.pl # # Copyright (C) 2007 by Roman 'gryf' Dobosz # # This file is part of pyGTKtalog. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # ------------------------------------------------------------------------- import gtk from gtkmvc import Controller import views.v_dialogs as Dialogs class SearchController(Controller): """Controller for main application window""" def __init__(self, model): """Initialize controller""" Controller.__init__(self, model) self.search_string = "" return def register_view(self, view): Controller.register_view(self, view) # Setup TreeView result widget, as columned list v = self.view['result'] v.set_model(self.model.search_list) v.get_selection().set_mode(gtk.SELECTION_MULTIPLE) c = gtk.TreeViewColumn('Disc', gtk.CellRendererText(), text=1) c.set_sort_column_id(1) c.set_resizable(True) v.append_column(c) c = gtk.TreeViewColumn('Filename') cellpb = gtk.CellRendererPixbuf() cell = gtk.CellRendererText() c.pack_start(cellpb, False) c.pack_start(cell, True) c.set_attributes(cellpb, stock_id=7) c.set_attributes(cell, text=2) c.set_sort_column_id(2) c.set_resizable(True) v.append_column(c) c = gtk.TreeViewColumn('Path', gtk.CellRendererText(), text=3) c.set_sort_column_id(3) c.set_resizable(True) v.append_column(c) c = gtk.TreeViewColumn('Size', gtk.CellRendererText(), text=4) c.set_sort_column_id(4) c.set_resizable(True) v.append_column(c) c = gtk.TreeViewColumn('Date', gtk.CellRendererText(), text=5) c.set_sort_column_id(5) c.set_resizable(True) v.append_column(c) v.set_search_column(2) # combobox self.view['comboboxentry'].set_model(self.model.search_history) self.view['comboboxentry'].set_text_column(0) # statusbar self.context_id = self.view['statusbar'].get_context_id('search') self.view['statusbar'].pop(self.context_id) self.view['search_window'].show() self.model.search_created = True; return ######################################################################### # Connect signals from GUI, like menu objects, toolbar buttons and so on. def on_search_window_delete_event(self, window, event): """if window was closed, reset attributes""" self.model.point = None self.model.search_created = False; return False def on_close_clicked(self, button): """close search window""" self.model.point = None self.model.search_created = False; self.view['search_window'].destroy() def on_search_activate(self, entry): """find button or enter pressed on entry search. Do the search""" search_txt = self.view['search_entry'].get_text() self.search_string = search_txt found = self.model.search(search_txt) self.model.add_search_history(search_txt) self.__set_status_bar(found) def on_result_row_activated(self, treeview, path, treecolumn): """result treeview row activated, change models 'point' observable variable to id of elected item. rest is all in main controler hands.""" model = treeview.get_model() s_iter = model.get_iter(path) self.model.point = model.get_value(s_iter, 0) def on_result_button_release_event(self, tree, event): if event.button == 3: # Right mouse button. Show context menu. try: selection = tree.get_selection() model, list_of_paths = selection.get_selected_rows() except TypeError: list_of_paths = [] if len(list_of_paths) == 0: # try to select item under cursor try: path, column, x, y = tree.get_path_at_pos(int(event.x), int(event.y)) except TypeError: # failed, do not show any popup and return tree.get_selection().unselect_all() return False selection.select_path(path[0]) if len(list_of_paths) > 1: self.view['add_image'].set_sensitive(False) self.view['rename'].set_sensitive(False) self.view['edit'].set_sensitive(False) else: self.view['add_image'].set_sensitive(True) self.view['rename'].set_sensitive(True) self.view['edit'].set_sensitive(True) self.view['files_popup'].popup(None, None, None, 0, 0) self.view['files_popup'].show_all() return True def on_add_tag_activate(self, menu_item): """Add tags to selected files""" tags = Dialogs.TagsDialog().run() if not tags: return ids = self.__get_tv_selection_ids(self.view['result']) for item_id in ids: self.model.add_tags(item_id, tags) self.model.unsaved_project = True return def on_delete_tag_activate(self, menu_item): ids = self.__get_tv_selection_ids(self.view['result']) if not ids: Dialogs.Inf("Remove tags", "No files selected", "You have to select some files first.") return tags = self.model.get_tags_by_file_id(ids) if tags: d = Dialogs.TagsRemoveDialog(tags) retcode, retval = d.run() if retcode=="ok" and not retval: Dialogs.Inf("Remove tags", "No tags selected", "You have to select any tag to remove from files.") return elif retcode == "ok" and retval: self.model.delete_tags(ids, retval) found = self.model.search(self.search_string) self.__set_status_bar(found) def on_add_thumb_activate(self, menu_item): image, only_thumbs = Dialogs.LoadImageFile().run() if not image: return ids = self.__get_tv_selection_ids(self.view['result']) for item_id in ids: self.model.add_thumbnail(image, item_id) self.model.unsaved_project = True return def on_remove_thumb_activate(self, menu_item): if self.model.config.confd['delwarn']: title = 'Delete thumbnails' question = 'Delete thumbnails?' description = "Thumbnails for selected items will be permanently" description += " removed from catalog." obj = Dialogs.Qst(title, question, description) if not obj.run(): return try: ids = self.__get_tv_selection_ids(self.view['result']) for item_id in ids: self.model.del_thumbnail(item_id) except: if __debug__: print "c_search.py: on_remove_thumb_activate(): error on", print "getting selected items or removing thumbnails" return self.model.unsaved_project = True return def on_add_image_activate(self, menu_item): dialog = Dialogs.LoadImageFile(True) msg = "Don't copy images. Generate only thumbnails." toggle = gtk.CheckButton(msg) toggle.show() dialog.dialog.set_extra_widget(toggle) images, only_thumbs = dialog.run() if not images: return for image in images: try: selection = self.view['result'].get_selection() model, list_of_paths = selection.get_selected_rows() fid = model.get_value(model.get_iter(list_of_paths[0]), 0) except: try: path, column = self.view['result'].get_cursor() model = self.view['result'].get_model() fiter = model.get_iter(path) fid = model.get_value(fiter, 0) except: return self.model.add_image(image, fid, only_thumbs) self.model.unsaved_project = True return def on_remove_image_activate(self, menu_item): if self.model.config.confd['delwarn']: title = 'Delete images' question = 'Delete all images?' description = 'All images for selected items will be permanently' description += ' removed from catalog.' obj = Dialogs.Qst(title, question, description) if not obj.run(): return try: ids = self.__get_tv_selection_ids(self.view['result']) for item_id in ids: self.model.del_images(item_id) except: if __debug__: print "c_search.py: on_remove_thumb_activate(): error on", print "getting selected items or removing thumbnails" return self.model.unsaved_project = True return def on_edit_activate(self, menu_item): try: selection = self.view['result'].get_selection() model, list_of_paths = selection.get_selected_rows() fid = model.get_value(model.get_iter(list_of_paths[0]), 0) except TypeError: if __debug__: print "c_main.py: on_edit2_activate(): 0", print "zaznaczonych wierszy" return val = self.model.get_file_info(fid) ret = Dialogs.EditDialog(val).run() if ret: self.model.rename(fid, ret['filename']) self.model.update_desc_and_note(fid, ret['description'], ret['note']) self.model.unsaved_project = True def on_delete_activate(self, menu_item): dmodel = self.model.discs_tree try: selection = self.view['result'].get_selection() model, list_of_paths = selection.get_selected_rows() except TypeError: return if not list_of_paths: Dialogs.Inf("Delete files", "No files selected", "You have to select at least one file to delete.") return if self.model.config.confd['delwarn']: description = "Selected files and directories will be " description += "permanently\n removed from catalog." obj = Dialogs.Qst("Delete files", "Delete files?", description) if not obj.run(): return def foreach_searchtree(zmodel, zpath, ziter, d): if d[0] == zmodel.get_value(ziter, 0): d[1].append(zpath) return False ids = [] for p in list_of_paths: ids.append(model.get_value(model.get_iter(p), 0)) for fid in ids: # delete from db self.model.delete(fid) self.model.unsaved_project = True found = self.model.search(self.search_string) self.__set_status_bar(found) return def on_rename_activate(self, menu_item): try: selection = self.view['result'].get_selection() model, list_of_paths = selection.get_selected_rows() fid = model.get_value(model.get_iter(list_of_paths[0]), 0) except TypeError: if __debug__: print "c_main.py: on_edit2_activate(): 0", print "zaznaczonych wierszy" return fid = model.get_value(model.get_iter(list_of_paths[0]), 0) name = model.get_value(model.get_iter(list_of_paths[0]),2) new_name = Dialogs.InputNewName(name).run() if __debug__: print "c_search.py: on_rename_activate(): label:", new_name if new_name and new_name != name: self.model.rename(fid, new_name) self.model.unsaved_project = True return ##################### # observed properetis ######################### # private class functions def __set_status_bar(self, found): """sets number of founded items in statusbar""" if found == 0: msg = "No files found." elif found == 1: msg = "Found 1 file." else: msg = "Found %d files." % found self.view['statusbar'].push(self.context_id, "%s" % msg) def __get_tv_selection_ids(self, treeview): """get selection from treeview and return coresponding ids' from connected model or None""" ids = [] try: selection = treeview.get_selection() model, list_of_paths = selection.get_selected_rows() for path in list_of_paths: ids.append(model.get_value(model.get_iter(path), 0)) return ids except: # DEBUG: treeview have no selection or smth is broken if __debug__: print "c_search.py: __get_tv_selection_ids(): error on", print "getting selected items" return return None pass # end of class