mirror of
https://github.com/gryf/pygtktalog.git
synced 2025-12-17 19:40:21 +01:00
* Added right click menu support under searcher window.
This commit is contained in:
@@ -22,16 +22,18 @@
|
|||||||
|
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
|
|
||||||
from gtkmvc import Controller
|
|
||||||
|
|
||||||
import gtk
|
import gtk
|
||||||
|
|
||||||
|
from gtkmvc import Controller
|
||||||
|
import views.v_dialogs as Dialogs
|
||||||
|
|
||||||
class SearchController(Controller):
|
class SearchController(Controller):
|
||||||
"""Controller for main application window"""
|
"""Controller for main application window"""
|
||||||
|
|
||||||
def __init__(self, model):
|
def __init__(self, model):
|
||||||
"""Initialize controller"""
|
"""Initialize controller"""
|
||||||
Controller.__init__(self, model)
|
Controller.__init__(self, model)
|
||||||
|
self.search_string = ""
|
||||||
return
|
return
|
||||||
|
|
||||||
def register_view(self, view):
|
def register_view(self, view):
|
||||||
@@ -102,17 +104,10 @@ class SearchController(Controller):
|
|||||||
def on_search_activate(self, entry):
|
def on_search_activate(self, entry):
|
||||||
"""find button or enter pressed on entry search. Do the search"""
|
"""find button or enter pressed on entry search. Do the search"""
|
||||||
search_txt = self.view['search_entry'].get_text()
|
search_txt = self.view['search_entry'].get_text()
|
||||||
|
self.search_string = search_txt
|
||||||
found = self.model.search(search_txt)
|
found = self.model.search(search_txt)
|
||||||
self.model.add_search_history(search_txt)
|
self.model.add_search_history(search_txt)
|
||||||
|
self.__set_status_bar(found)
|
||||||
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 on_result_row_activated(self, treeview, path, treecolumn):
|
def on_result_row_activated(self, treeview, path, treecolumn):
|
||||||
"""result treeview row activated, change models 'point' observable
|
"""result treeview row activated, change models 'point' observable
|
||||||
@@ -121,14 +116,268 @@ class SearchController(Controller):
|
|||||||
s_iter = model.get_iter(path)
|
s_iter = model.get_iter(path)
|
||||||
self.model.point = model.get_value(s_iter, 0)
|
self.model.point = model.get_value(s_iter, 0)
|
||||||
|
|
||||||
def on_comboboxentry_changed(self, comboentry):
|
def on_result_button_release_event(self, tree, event):
|
||||||
"""comboentry has changed, fill entry with selected item"""
|
if event.button == 3: # Right mouse button. Show context menu.
|
||||||
print "TODO: implement me!"
|
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
|
||||||
|
|
||||||
|
for p in list_of_paths:
|
||||||
|
val = model.get_value(model.get_iter(p), 0)
|
||||||
|
if model.get_value(model.get_iter(p), 4) == self.model.DIR:
|
||||||
|
# remove from disctree model aswell
|
||||||
|
dpath = []
|
||||||
|
dmodel.foreach(foreach_searchtree, (val, dpath))
|
||||||
|
for dp in dpath:
|
||||||
|
dmodel.remove(dmodel.get_iter(dp))
|
||||||
|
|
||||||
|
# delete from db
|
||||||
|
self.model.delete(val)
|
||||||
|
|
||||||
|
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
|
# observed properetis
|
||||||
|
|
||||||
#########################
|
#########################
|
||||||
# private class functions
|
# 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
|
pass # end of class
|
||||||
|
|||||||
Reference in New Issue
Block a user