mirror of
https://github.com/gryf/pygtktalog.git
synced 2025-12-17 11:30:19 +01:00
* Added support for "menu" key on keyboard.
* Small changes in behaviour of individual popup menus.
This commit is contained in:
23
README
23
README
@@ -1,4 +1,4 @@
|
|||||||
pyGTKtalog 0.8
|
pyGTKtalog 0.9
|
||||||
==============
|
==============
|
||||||
|
|
||||||
pyGTKtalog Linux/FreeBSD program for indexing CD/DVD or directories on
|
pyGTKtalog Linux/FreeBSD program for indexing CD/DVD or directories on
|
||||||
@@ -24,6 +24,7 @@ REQUIREMENTS
|
|||||||
|
|
||||||
pyGTKtalog is written in python with following dependencies:
|
pyGTKtalog is written in python with following dependencies:
|
||||||
|
|
||||||
|
- python 2.4 or higher
|
||||||
- pygtk <http://www.pygtk.org>
|
- pygtk <http://www.pygtk.org>
|
||||||
- pysqlite2 <http://pysqlite.org/> (unnecessary, if python 2.5 is used)
|
- pysqlite2 <http://pysqlite.org/> (unnecessary, if python 2.5 is used)
|
||||||
|
|
||||||
@@ -37,7 +38,7 @@ Additional pyGTKtalog uses EXIF module by Gene Cash which is included in
|
|||||||
sources.
|
sources.
|
||||||
|
|
||||||
pyGTKtalog extensivly uses external programs in unix spirit, however there is
|
pyGTKtalog extensivly uses external programs in unix spirit, however there is
|
||||||
small possibility of using it Windows (probably with liitations) and quite big
|
small possibility of using it Windows (probably with limitations) and quite big
|
||||||
possiblity to run it on other sofisticated unix-like systems (i.e.
|
possiblity to run it on other sofisticated unix-like systems (i.e.
|
||||||
BeOS/ZETA/Haiku, QNX or MacOSX).
|
BeOS/ZETA/Haiku, QNX or MacOSX).
|
||||||
|
|
||||||
@@ -57,11 +58,14 @@ Then, just run pyGTKtalog script.
|
|||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
For version 1.0 following aims have to be done:
|
PyGTKtalog is still under heavy development, however there is small chance to
|
||||||
|
change structure of catalogs (and if it'll change, there will be transparent
|
||||||
|
function to update DB schema).
|
||||||
|
|
||||||
|
For version 1.0 following major aims have to be done:
|
||||||
|
|
||||||
- searching database
|
- searching database
|
||||||
- tagging files (90%)
|
x tagging files
|
||||||
- user definied group of tags (represented by color in cloud tag)
|
|
||||||
x remove nasty bug in redraw of tag cloud
|
x remove nasty bug in redraw of tag cloud
|
||||||
x file details:
|
x file details:
|
||||||
x files properties
|
x files properties
|
||||||
@@ -75,6 +79,10 @@ x generating/saving thumbnails
|
|||||||
x moving hardcoded files extensions into config
|
x moving hardcoded files extensions into config
|
||||||
x statistics
|
x statistics
|
||||||
|
|
||||||
|
There are still minor aims for versions 1.x to be done:
|
||||||
|
- consolidate popup-menus with edit menu
|
||||||
|
- add popup menu for directly removing tag from tag cloud
|
||||||
|
|
||||||
Legend: [-] not done, [x] done.
|
Legend: [-] not done, [x] done.
|
||||||
|
|
||||||
For version 2.0:
|
For version 2.0:
|
||||||
@@ -82,6 +90,9 @@ For version 2.0:
|
|||||||
- command line support: query, adding media to collection etc
|
- command line support: query, adding media to collection etc
|
||||||
- internationalization support
|
- internationalization support
|
||||||
- export to XLS
|
- export to XLS
|
||||||
|
- user definied group of tags (represented by color in cloud tag)
|
||||||
|
- hiding specified files - configurable, like dot prefixed, cfg and manualy
|
||||||
|
selected
|
||||||
|
|
||||||
Removed:
|
Removed:
|
||||||
- filetypes handling (movies, images, archives, documents etc). Now it have
|
- filetypes handling (movies, images, archives, documents etc). Now it have
|
||||||
@@ -100,7 +111,7 @@ Removed:
|
|||||||
Maybe in future versions. Now text file descriptions/notes and tags have to
|
Maybe in future versions. Now text file descriptions/notes and tags have to
|
||||||
be enough for good and fast information search.
|
be enough for good and fast information search.
|
||||||
- file information (date, size, etc) (50%) (no need for?)
|
- file information (date, size, etc) (50%) (no need for?)
|
||||||
|
|
||||||
NOTES
|
NOTES
|
||||||
=====
|
=====
|
||||||
|
|
||||||
|
|||||||
@@ -93,35 +93,9 @@
|
|||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="label" translatable="yes">_Edit</property>
|
<property name="label" translatable="yes">_Edit</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
|
<signal name="activate" handler="on_edit1_activate"/>
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkMenu" id="edit1_menu">
|
<widget class="GtkMenu" id="edit1_menu">
|
||||||
<child>
|
|
||||||
<widget class="GtkImageMenuItem" id="cut1">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="label">gtk-cut</property>
|
|
||||||
<property name="use_underline">True</property>
|
|
||||||
<property name="use_stock">True</property>
|
|
||||||
<signal name="activate" handler="on_cut1_activate"/>
|
|
||||||
</widget>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<widget class="GtkImageMenuItem" id="copy1">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="label">gtk-copy</property>
|
|
||||||
<property name="use_underline">True</property>
|
|
||||||
<property name="use_stock">True</property>
|
|
||||||
<signal name="activate" handler="on_copy1_activate"/>
|
|
||||||
</widget>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<widget class="GtkImageMenuItem" id="paste1">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="label">gtk-paste</property>
|
|
||||||
<property name="use_underline">True</property>
|
|
||||||
<property name="use_stock">True</property>
|
|
||||||
<signal name="activate" handler="on_paste1_activate"/>
|
|
||||||
</widget>
|
|
||||||
</child>
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkImageMenuItem" id="delete1">
|
<widget class="GtkImageMenuItem" id="delete1">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
@@ -129,6 +103,7 @@
|
|||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
<property name="use_stock">True</property>
|
<property name="use_stock">True</property>
|
||||||
<signal name="activate" handler="on_delete1_activate"/>
|
<signal name="activate" handler="on_delete1_activate"/>
|
||||||
|
<accelerator key="Delete" modifiers="" signal="activate"/>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
@@ -177,7 +152,7 @@
|
|||||||
<property name="label" translatable="yes">Add _CD/DVD</property>
|
<property name="label" translatable="yes">Add _CD/DVD</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
<signal name="activate" handler="on_add_cd_activate"/>
|
<signal name="activate" handler="on_add_cd_activate"/>
|
||||||
<accelerator key="a" modifiers="GDK_CONTROL_MASK" signal="activate"/>
|
<accelerator key="c" modifiers="GDK_CONTROL_MASK" signal="activate"/>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
@@ -185,7 +160,7 @@
|
|||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="label" translatable="yes">Add _Directory</property>
|
<property name="label" translatable="yes">Add _Directory</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
<signal name="activate" handler="on_add_directory1_activate"/>
|
<signal name="activate" handler="on_add_directory_activate"/>
|
||||||
<accelerator key="d" modifiers="GDK_CONTROL_MASK" signal="activate"/>
|
<accelerator key="d" modifiers="GDK_CONTROL_MASK" signal="activate"/>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
@@ -371,6 +346,18 @@
|
|||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkToolButton" id="tb_adddir">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||||
|
<property name="label" translatable="yes">Add Dir</property>
|
||||||
|
<property name="stock_id">gtk-directory</property>
|
||||||
|
<signal name="clicked" handler="on_add_directory_activate"/>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkToolButton" id="tb_find">
|
<widget class="GtkToolButton" id="tb_find">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
@@ -501,6 +488,7 @@
|
|||||||
<signal name="button_press_event" handler="on_discs_button_press_event"/>
|
<signal name="button_press_event" handler="on_discs_button_press_event"/>
|
||||||
<signal name="row_activated" handler="on_discs_row_activated"/>
|
<signal name="row_activated" handler="on_discs_row_activated"/>
|
||||||
<signal name="cursor_changed" handler="on_discs_cursor_changed"/>
|
<signal name="cursor_changed" handler="on_discs_cursor_changed"/>
|
||||||
|
<signal name="key_release_event" handler="on_discs_key_release_event"/>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
</widget>
|
</widget>
|
||||||
@@ -672,6 +660,7 @@
|
|||||||
<property name="tooltip" translatable="yes">Double click to open image</property>
|
<property name="tooltip" translatable="yes">Double click to open image</property>
|
||||||
<signal name="button_press_event" handler="on_images_button_press_event"/>
|
<signal name="button_press_event" handler="on_images_button_press_event"/>
|
||||||
<signal name="item_activated" handler="on_images_item_activated"/>
|
<signal name="item_activated" handler="on_images_item_activated"/>
|
||||||
|
<signal name="key_release_event" handler="on_images_key_release_event"/>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
</widget>
|
</widget>
|
||||||
@@ -1025,4 +1014,17 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="GtkMenu" id="tag_popup">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkMenuItem" id="delete_tag2">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||||
|
<property name="label" translatable="yes">Delete tag</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<signal name="activate" handler="on_delete_tag2_activate"/>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
</glade-interface>
|
</glade-interface>
|
||||||
|
|||||||
@@ -47,9 +47,9 @@ import pango
|
|||||||
class MainController(Controller):
|
class MainController(Controller):
|
||||||
"""Controller for main application window"""
|
"""Controller for main application window"""
|
||||||
scan_cd = False
|
scan_cd = False
|
||||||
widgets = ("discs", "files", 'save1', 'save_as1', 'cut1', 'copy1',
|
widgets = ("discs", "files", 'save1', 'save_as1', 'delete1', 'add_cd',
|
||||||
'paste1', 'delete1', 'add_cd', 'add_directory1', 'tb_save',
|
'add_directory1', 'tb_save', 'tb_addcd', 'tb_find', 'nb_dirs',
|
||||||
'tb_addcd', 'tb_find', 'nb_dirs', 'description', 'stat1')
|
'description', 'stat1')
|
||||||
widgets_all = ("discs", "files", 'file1', 'edit1', 'add_cd',
|
widgets_all = ("discs", "files", 'file1', 'edit1', 'add_cd',
|
||||||
'add_directory1', 'help1', 'tb_save', 'tb_addcd', 'tb_find',
|
'add_directory1', 'help1', 'tb_save', 'tb_addcd', 'tb_find',
|
||||||
'tb_new', 'tb_open', 'tb_quit', 'nb_dirs', 'description',
|
'tb_new', 'tb_open', 'tb_quit', 'nb_dirs', 'description',
|
||||||
@@ -72,7 +72,7 @@ class MainController(Controller):
|
|||||||
for widget in self.widgets:
|
for widget in self.widgets:
|
||||||
self.view[widget].set_sensitive(False)
|
self.view[widget].set_sensitive(False)
|
||||||
|
|
||||||
# Make not active "Cancel" button and menuitem
|
# Make not active "Cancel" button and menu_item
|
||||||
for widget in self.widgets_cancel:
|
for widget in self.widgets_cancel:
|
||||||
self.view[widget].set_sensitive(False)
|
self.view[widget].set_sensitive(False)
|
||||||
|
|
||||||
@@ -123,11 +123,14 @@ class MainController(Controller):
|
|||||||
|
|
||||||
# generate recent menu
|
# generate recent menu
|
||||||
self.__generate_recent_menu()
|
self.__generate_recent_menu()
|
||||||
|
|
||||||
|
|
||||||
|
self.view['tag_cloud_textview'].connect("populate-popup",
|
||||||
|
self.on_tag_cloud_textview_popup)
|
||||||
# in case model has opened file, register tags
|
# in case model has opened file, register tags
|
||||||
if self.model.internal_dirname:
|
if self.model.internal_dirname:
|
||||||
self.__tag_cloud()
|
self.__tag_cloud()
|
||||||
|
|
||||||
# Show main window
|
# Show main window
|
||||||
self.view['main'].show();
|
self.view['main'].show();
|
||||||
self.view['main'].drag_dest_set(0, [], 0)
|
self.view['main'].drag_dest_set(0, [], 0)
|
||||||
@@ -144,13 +147,13 @@ class MainController(Controller):
|
|||||||
iter = filestv.get_iter_at_location(x, y)
|
iter = filestv.get_iter_at_location(x, y)
|
||||||
buff = filestv.get_buffer()
|
buff = filestv.get_buffer()
|
||||||
tag_table = buff.get_tag_table()
|
tag_table = buff.get_tag_table()
|
||||||
|
|
||||||
# clear weight of tags
|
# clear weight of tags
|
||||||
def foreach_tag(texttag, user_data):
|
def foreach_tag(texttag, user_data):
|
||||||
"""set every text tag's weight to normal"""
|
"""set every text tag's weight to normal"""
|
||||||
texttag.set_property("underline", pango.UNDERLINE_NONE)
|
texttag.set_property("underline", pango.UNDERLINE_NONE)
|
||||||
tag_table.foreach(foreach_tag, None)
|
tag_table.foreach(foreach_tag, None)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
tag = iter.get_tags()[0]
|
tag = iter.get_tags()[0]
|
||||||
tag.set_property("underline", pango.UNDERLINE_LOW)
|
tag.set_property("underline", pango.UNDERLINE_LOW)
|
||||||
@@ -173,12 +176,16 @@ class MainController(Controller):
|
|||||||
string = str(tuple(ids)).replace(",)", ")")
|
string = str(tuple(ids)).replace(",)", ")")
|
||||||
selection.set(selection.target, 8, string)
|
selection.set(selection.target, 8, string)
|
||||||
|
|
||||||
|
def on_tag_cloud_textview_popup(self, textview, menu):
|
||||||
|
menu = None
|
||||||
|
return True
|
||||||
|
|
||||||
def on_tag_cloud_textview_event_after(self, textview, event):
|
def on_tag_cloud_textview_event_after(self, textview, event):
|
||||||
if event.type != gtk.gdk.BUTTON_RELEASE:
|
if event.type != gtk.gdk.BUTTON_RELEASE:
|
||||||
return False
|
return False
|
||||||
if event.button != 1:
|
if event.button != 1:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
buff = textview.get_buffer()
|
buff = textview.get_buffer()
|
||||||
try:
|
try:
|
||||||
(start, end) = buff.get_selection_bounds()
|
(start, end) = buff.get_selection_bounds()
|
||||||
@@ -192,20 +199,20 @@ class MainController(Controller):
|
|||||||
(x, y) = textview.window_to_buffer_coords(gtk.TEXT_WINDOW_WIDGET,
|
(x, y) = textview.window_to_buffer_coords(gtk.TEXT_WINDOW_WIDGET,
|
||||||
int(event.x), int(event.y))
|
int(event.x), int(event.y))
|
||||||
iterator = textview.get_iter_at_location(x, y)
|
iterator = textview.get_iter_at_location(x, y)
|
||||||
|
|
||||||
tags = iterator.get_tags()
|
tags = iterator.get_tags()
|
||||||
|
|
||||||
if len(tags) == 1:
|
if len(tags) == 1:
|
||||||
tag = tags[0]
|
tag = tags[0]
|
||||||
self.model.add_tag_to_path(tag.get_property('name'))
|
self.model.add_tag_to_path(tag.get_property('name'))
|
||||||
self.view['tag_path_box'].show()
|
self.view['tag_path_box'].show()
|
||||||
|
|
||||||
# fill the path of tag
|
# fill the path of tag
|
||||||
self.view['tag_path'].set_text('')
|
self.view['tag_path'].set_text('')
|
||||||
temp = self.model.selected_tags.values()
|
temp = self.model.selected_tags.values()
|
||||||
self.model.refresh_discs_tree()
|
self.model.refresh_discs_tree()
|
||||||
#self.on_discs_cursor_changed(textview)
|
#self.on_discs_cursor_changed(textview)
|
||||||
|
|
||||||
temp.sort()
|
temp.sort()
|
||||||
for tag1 in temp:
|
for tag1 in temp:
|
||||||
txt = self.view['tag_path'].get_text()
|
txt = self.view['tag_path'].get_text()
|
||||||
@@ -220,7 +227,7 @@ class MainController(Controller):
|
|||||||
|
|
||||||
def on_tag_cloud_textview_drag_data_received(self, widget, context, x, y,
|
def on_tag_cloud_textview_drag_data_received(self, widget, context, x, y,
|
||||||
selection, targetType, time):
|
selection, targetType, time):
|
||||||
"""recive data from source TV"""
|
"""recive data from source TreeView"""
|
||||||
if targetType == self.DND_TARGETS[0][2]:
|
if targetType == self.DND_TARGETS[0][2]:
|
||||||
iter = widget.get_iter_at_location(x, y)
|
iter = widget.get_iter_at_location(x, y)
|
||||||
ids = selection.data.rstrip(")").lstrip("(").split(",")
|
ids = selection.data.rstrip(")").lstrip("(").split(",")
|
||||||
@@ -402,7 +409,7 @@ class MainController(Controller):
|
|||||||
self.view['tag_path_box'].hide()
|
self.view['tag_path_box'].hide()
|
||||||
self.model.selected_tags = []
|
self.model.selected_tags = []
|
||||||
self.model.refresh_discs_tree()
|
self.model.refresh_discs_tree()
|
||||||
|
|
||||||
# cleanup files and detiles
|
# cleanup files and detiles
|
||||||
try:
|
try:
|
||||||
self.model.files_list.clear()
|
self.model.files_list.clear()
|
||||||
@@ -411,18 +418,18 @@ class MainController(Controller):
|
|||||||
self.__hide_details()
|
self.__hide_details()
|
||||||
self.on_discs_cursor_changed(w)
|
self.on_discs_cursor_changed(w)
|
||||||
self.__tag_cloud()
|
self.__tag_cloud()
|
||||||
|
|
||||||
def on_tag_cloud_textview_drag_leave(self, textview, dragcontext, time):
|
def on_tag_cloud_textview_drag_leave(self, textview, dragcontext, time):
|
||||||
"""clean up tags properties"""
|
"""clean up tags properties"""
|
||||||
buff = textview.get_buffer()
|
buff = textview.get_buffer()
|
||||||
tag_table = buff.get_tag_table()
|
tag_table = buff.get_tag_table()
|
||||||
|
|
||||||
# clear weight of tags
|
# clear weight of tags
|
||||||
def foreach_tag(texttag, user_data):
|
def foreach_tag(texttag, user_data):
|
||||||
"""set every text tag's weight to normal"""
|
"""set every text tag's weight to normal"""
|
||||||
texttag.set_property("underline", pango.UNDERLINE_NONE)
|
texttag.set_property("underline", pango.UNDERLINE_NONE)
|
||||||
tag_table.foreach(foreach_tag, None)
|
tag_table.foreach(foreach_tag, None)
|
||||||
|
|
||||||
# NOTE: text view "links" functions
|
# NOTE: text view "links" functions
|
||||||
def on_tag_cloud_textview_visibility_notify_event(self, textview, event):
|
def on_tag_cloud_textview_visibility_notify_event(self, textview, event):
|
||||||
(wx, wy, mod) = textview.window.get_pointer()
|
(wx, wy, mod) = textview.window.get_pointer()
|
||||||
@@ -438,7 +445,7 @@ class MainController(Controller):
|
|||||||
textview = self.view['tag_cloud_textview']
|
textview = self.view['tag_cloud_textview']
|
||||||
# get the iter at the mouse position
|
# get the iter at the mouse position
|
||||||
iter = textview.get_iter_at_location(x, y)
|
iter = textview.get_iter_at_location(x, y)
|
||||||
|
|
||||||
# set _hovering if the iter has the tag "url"
|
# set _hovering if the iter has the tag "url"
|
||||||
tags = iter.get_tags()
|
tags = iter.get_tags()
|
||||||
for tag in tags:
|
for tag in tags:
|
||||||
@@ -457,20 +464,20 @@ class MainController(Controller):
|
|||||||
textview.get_window(gtk.TEXT_WINDOW_TEXT).\
|
textview.get_window(gtk.TEXT_WINDOW_TEXT).\
|
||||||
set_cursor(gtk.gdk.Cursor(gtk.gdk.LEFT_PTR))
|
set_cursor(gtk.gdk.Cursor(gtk.gdk.LEFT_PTR))
|
||||||
|
|
||||||
|
|
||||||
def on_tag_cloud_click(self, tag, textview, event, b_iter, data):
|
def on_tag_cloud_click(self, tag, textview, event, b_iter, data):
|
||||||
"""react on click on connected tag items"""
|
"""react on click on connected tag items"""
|
||||||
tag_cloud = self.view['tag_cloud_textview']
|
tag_cloud = self.view['tag_cloud_textview']
|
||||||
if event.type == gtk.gdk.BUTTON_RELEASE:
|
if event.type == gtk.gdk.BUTTON_RELEASE:
|
||||||
self.model.add_tag_to_path(tag.get_property('name'))
|
self.model.add_tag_to_path(tag.get_property('name'))
|
||||||
self.view['tag_path_box'].show()
|
self.view['tag_path_box'].show()
|
||||||
|
|
||||||
# fill the path of tag
|
# fill the path of tag
|
||||||
self.view['tag_path'].set_text('')
|
self.view['tag_path'].set_text('')
|
||||||
temp = self.model.selected_tags.values()
|
temp = self.model.selected_tags.values()
|
||||||
self.model.refresh_discs_tree()
|
self.model.refresh_discs_tree()
|
||||||
#self.on_discs_cursor_changed(textview)
|
#self.on_discs_cursor_changed(textview)
|
||||||
|
|
||||||
temp.sort()
|
temp.sort()
|
||||||
for tag1 in temp:
|
for tag1 in temp:
|
||||||
txt = self.view['tag_path'].get_text()
|
txt = self.view['tag_path'].get_text()
|
||||||
@@ -479,8 +486,8 @@ class MainController(Controller):
|
|||||||
else:
|
else:
|
||||||
self.view['tag_path'].set_text(txt + ", " +tag1)
|
self.view['tag_path'].set_text(txt + ", " +tag1)
|
||||||
self.__tag_cloud()
|
self.__tag_cloud()
|
||||||
|
|
||||||
|
|
||||||
#elif event.type == gtk.gdk.MOTION_NOTIFY:
|
#elif event.type == gtk.gdk.MOTION_NOTIFY:
|
||||||
# window = tag_cloud.get_window(gtk.TEXT_WINDOW_TEXT)
|
# window = tag_cloud.get_window(gtk.TEXT_WINDOW_TEXT)
|
||||||
# if window:
|
# if window:
|
||||||
@@ -489,7 +496,7 @@ class MainController(Controller):
|
|||||||
# window = tag_cloud.get_window(gtk.TEXT_WINDOW_TEXT)
|
# window = tag_cloud.get_window(gtk.TEXT_WINDOW_TEXT)
|
||||||
# if window:
|
# if window:
|
||||||
# window.set_cursor(None)
|
# window.set_cursor(None)
|
||||||
|
|
||||||
# NOTE: quit / close window
|
# NOTE: quit / close window
|
||||||
def on_main_destroy_event(self, window, event):
|
def on_main_destroy_event(self, window, event):
|
||||||
self.on_quit_activate(window)
|
self.on_quit_activate(window)
|
||||||
@@ -556,7 +563,7 @@ class MainController(Controller):
|
|||||||
"Last mount message:\n%s" % mount)
|
"Last mount message:\n%s" % mount)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def on_add_directory1_activate(self, widget, path=None, label=None,
|
def on_add_directory_activate(self, widget, path=None, label=None,
|
||||||
current_id=None):
|
current_id=None):
|
||||||
"""Show dialog for choose drectory to add from filesystem."""
|
"""Show dialog for choose drectory to add from filesystem."""
|
||||||
if not label or not path:
|
if not label or not path:
|
||||||
@@ -651,7 +658,7 @@ class MainController(Controller):
|
|||||||
|
|
||||||
if not path:
|
if not path:
|
||||||
path = Dialogs.LoadDBFile().run()
|
path = Dialogs.LoadDBFile().run()
|
||||||
|
|
||||||
# cleanup files and details
|
# cleanup files and details
|
||||||
try:
|
try:
|
||||||
self.model.files_list.clear()
|
self.model.files_list.clear()
|
||||||
@@ -662,7 +669,7 @@ class MainController(Controller):
|
|||||||
buf = self.view['tag_cloud_textview'].get_buffer()
|
buf = self.view['tag_cloud_textview'].get_buffer()
|
||||||
buf.set_text('')
|
buf.set_text('')
|
||||||
self.view['tag_cloud_textview'].set_buffer(buf)
|
self.view['tag_cloud_textview'].set_buffer(buf)
|
||||||
|
|
||||||
if path:
|
if path:
|
||||||
if not self.model.open(path):
|
if not self.model.open(path):
|
||||||
Dialogs.Err("Error opening file - pyGTKtalog",
|
Dialogs.Err("Error opening file - pyGTKtalog",
|
||||||
@@ -683,7 +690,7 @@ class MainController(Controller):
|
|||||||
id = self.model.discs_tree.get_value(iter, 0)
|
id = self.model.discs_tree.get_value(iter, 0)
|
||||||
self.model.get_root_entries(id)
|
self.model.get_root_entries(id)
|
||||||
self.__get_item_info(id)
|
self.__get_item_info(id)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def on_discs_row_activated(self, treeview, path, treecolumn):
|
def on_discs_row_activated(self, treeview, path, treecolumn):
|
||||||
@@ -693,37 +700,60 @@ class MainController(Controller):
|
|||||||
else:
|
else:
|
||||||
treeview.expand_row(path, False)
|
treeview.expand_row(path, False)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def on_discs_key_release_event(self, treeview, event):
|
||||||
|
if gtk.gdk.keyval_name(event.keyval) == 'Menu':
|
||||||
|
ids = self.__get_tv_selection_ids(treeview)
|
||||||
|
menu_items = ['update1','rename1','delete2', 'statistics1']
|
||||||
|
for menu_item in menu_items:
|
||||||
|
self.view[menu_item].set_sensitive(not not ids)
|
||||||
|
self.__popup_menu(event, 'discs_popup')
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def on_images_key_release_event(self, iconview, event):
|
||||||
|
if gtk.gdk.keyval_name(event.keyval) == 'Menu':
|
||||||
|
self.__popup_menu(event, 'img_popup')
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def on_images_button_press_event(self, iconview, event):
|
def on_images_button_press_event(self, iconview, event):
|
||||||
try:
|
#try:
|
||||||
path_and_cell = iconview.get_item_at_pos(int(event.x),
|
# path_and_cell = iconview.get_item_at_pos(int(event.x),
|
||||||
int(event.y))
|
# int(event.y))
|
||||||
except TypeError:
|
#except TypeError:
|
||||||
return False
|
# return False
|
||||||
|
|
||||||
if event.button == 3: # Right mouse button. Show context menu.
|
if event.button == 3: # Right mouse button. Show context menu.
|
||||||
try:
|
#try:
|
||||||
iconview.select_path(path_and_cell[0])
|
# iconview.select_path(path_and_cell[0])
|
||||||
except TypeError:
|
#except TypeError:
|
||||||
return False
|
# return False
|
||||||
|
|
||||||
self.__popup_menu(event, 'img_popup')
|
self.__popup_menu(event, 'img_popup')
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def on_img_delete_activate(self, menu_item):
|
def on_img_delete_activate(self, menu_item):
|
||||||
|
"""delete selected images (with thumbnails)"""
|
||||||
|
list_of_paths = self.view['images'].get_selected_items()
|
||||||
|
if not list_of_paths:
|
||||||
|
Dialogs.Inf("Delete images", "No images selected",
|
||||||
|
"You have to select at least one image to delete.")
|
||||||
|
return
|
||||||
|
|
||||||
if self.model.config.confd['delwarn']:
|
if self.model.config.confd['delwarn']:
|
||||||
obj = Dialogs.Qst('Delete images', 'Delete selected images?',
|
obj = Dialogs.Qst('Delete images', 'Delete selected images?',
|
||||||
'Selected images will be permanently removed from catalog.')
|
'Selected images will be permanently removed from catalog.')
|
||||||
if not obj.run():
|
if not obj.run():
|
||||||
return
|
return
|
||||||
list_of_paths = self.view['images'].get_selected_items()
|
|
||||||
model = self.view['images'].get_model()
|
model = self.view['images'].get_model()
|
||||||
for path in list_of_paths:
|
for path in list_of_paths:
|
||||||
iter = model.get_iter(path)
|
iter = model.get_iter(path)
|
||||||
id = model.get_value(iter, 0)
|
id = model.get_value(iter, 0)
|
||||||
self.model.delete_image(id)
|
self.model.delete_image(id)
|
||||||
|
|
||||||
# refresh files tree
|
# refresh files tree
|
||||||
try:
|
try:
|
||||||
path, column = self.view['files'].get_cursor()
|
path, column = self.view['files'].get_cursor()
|
||||||
@@ -742,41 +772,55 @@ class MainController(Controller):
|
|||||||
"""export images (not thumbnails) into desired direcotry"""
|
"""export images (not thumbnails) into desired direcotry"""
|
||||||
dialog = Dialogs.SelectDirectory("Choose directory to save images")
|
dialog = Dialogs.SelectDirectory("Choose directory to save images")
|
||||||
filepath = dialog.run()
|
filepath = dialog.run()
|
||||||
|
|
||||||
if not filepath:
|
if not filepath:
|
||||||
return
|
return
|
||||||
|
|
||||||
list_of_paths = self.view['images'].get_selected_items()
|
list_of_paths = self.view['images'].get_selected_items()
|
||||||
model = self.view['images'].get_model()
|
model = self.view['images'].get_model()
|
||||||
|
|
||||||
count = 0
|
count = 0
|
||||||
|
|
||||||
for path in list_of_paths:
|
if len(list_of_paths) == 0:
|
||||||
icon_iter = model.get_iter(path)
|
# no picture was selected. default to save all of them
|
||||||
img_id = model.get_value(icon_iter, 0)
|
for image in model:
|
||||||
|
if self.model.save_image(image[0], filepath):
|
||||||
|
count += 1
|
||||||
|
else:
|
||||||
|
# some pictures was selected, save them
|
||||||
|
for path in list_of_paths:
|
||||||
|
icon_iter = model.get_iter(path)
|
||||||
|
img_id = model.get_value(icon_iter, 0)
|
||||||
if self.model.save_image(img_id, filepath):
|
if self.model.save_image(img_id, filepath):
|
||||||
count += 1
|
count += 1
|
||||||
if len(list_of_paths) > 0:
|
|
||||||
if count > 0:
|
if count > 0:
|
||||||
Dialogs.Inf("Save images",
|
Dialogs.Inf("Save images",
|
||||||
"%d images was succsefully saved." % count,
|
"%d images was succsefully saved." % count,
|
||||||
"Images are placed in directory:\n%s." % filepath)
|
"Images are placed in directory:\n%s." % filepath)
|
||||||
else:
|
else:
|
||||||
Dialogs.Inf("Save images",
|
Dialogs.Inf("Save images",
|
||||||
"No images was saved.",
|
"No images was saved.",
|
||||||
"Images probably don't have real images - only" + \
|
"Images probably don't have real images - only" + \
|
||||||
" thumbnails.")
|
" thumbnails.")
|
||||||
|
return
|
||||||
|
|
||||||
def on_img_delete2_activate(self, menu_item):
|
def on_img_delete2_activate(self, menu_item):
|
||||||
"""remove images, but keep thumbnails"""
|
"""remove images, but keep thumbnails"""
|
||||||
|
list_of_paths = self.view['images'].get_selected_items()
|
||||||
|
|
||||||
|
if not list_of_paths:
|
||||||
|
Dialogs.Inf("Delete images", "No images selected",
|
||||||
|
"You have to select at least one image to delete.")
|
||||||
|
return
|
||||||
|
|
||||||
if self.model.config.confd['delwarn']:
|
if self.model.config.confd['delwarn']:
|
||||||
obj = Dialogs.Qst('Delete images', 'Delete selected images?',
|
obj = Dialogs.Qst('Delete images', 'Delete selected images?',
|
||||||
'Selected images will be permanently removed from ' + \
|
'Selected images will be permanently removed from ' + \
|
||||||
'catalog,\nthumbnails will be keeped.')
|
'catalog,\nthumbnails will be keeped.')
|
||||||
if not obj.run():
|
if not obj.run():
|
||||||
return
|
return
|
||||||
|
|
||||||
list_of_paths = self.view['images'].get_selected_items()
|
|
||||||
model = self.view['images'].get_model()
|
model = self.view['images'].get_model()
|
||||||
for path in list_of_paths:
|
for path in list_of_paths:
|
||||||
iter = model.get_iter(path)
|
iter = model.get_iter(path)
|
||||||
@@ -795,7 +839,7 @@ class MainController(Controller):
|
|||||||
self.model.unsaved_project = True
|
self.model.unsaved_project = True
|
||||||
self.__set_title(filepath=self.model.filename, modified=True)
|
self.__set_title(filepath=self.model.filename, modified=True)
|
||||||
return
|
return
|
||||||
|
|
||||||
def on_img_add_activate(self, menu_item):
|
def on_img_add_activate(self, menu_item):
|
||||||
self.on_add_image1_activate(menu_item)
|
self.on_add_image1_activate(menu_item)
|
||||||
|
|
||||||
@@ -822,31 +866,29 @@ class MainController(Controller):
|
|||||||
if path not in list_of_paths:
|
if path not in list_of_paths:
|
||||||
treeview.get_selection().unselect_all()
|
treeview.get_selection().unselect_all()
|
||||||
treeview.get_selection().select_path(path)
|
treeview.get_selection().select_path(path)
|
||||||
|
# setup menu
|
||||||
iter = self.model.discs_tree.get_iter(path)
|
ids = self.__get_tv_selection_ids(treeview)
|
||||||
if self.model.discs_tree.get_value(iter, 3) == 1:
|
menu_items = ['update1','rename1','delete2', 'statistics1']
|
||||||
# if ancestor is 'root', then activate "update" menu item
|
for menu_item in menu_items:
|
||||||
self.view['update1'].set_sensitive(True)
|
self.view[menu_item].set_sensitive(not not ids)
|
||||||
else:
|
|
||||||
self.view['update1'].set_sensitive(False)
|
# checkout, if we dealing with disc or directory
|
||||||
|
# if ancestor is 'root', then activate "update" menu item
|
||||||
|
treeiter = self.model.discs_tree.get_iter(path)
|
||||||
|
ancestor = self.model.discs_tree.get_value(treeiter, 3) == 1
|
||||||
|
self.view['update1'].set_sensitive(ancestor)
|
||||||
|
|
||||||
self.__popup_menu(event)
|
self.__popup_menu(event)
|
||||||
|
|
||||||
def on_expand_all1_activate(self, menuitem):
|
def on_expand_all1_activate(self, menu_item):
|
||||||
self.view['discs'].expand_all()
|
self.view['discs'].expand_all()
|
||||||
return
|
return
|
||||||
|
|
||||||
def on_collapse_all1_activate(self, menuitem):
|
def on_collapse_all1_activate(self, menu_item):
|
||||||
self.view['discs'].collapse_all()
|
self.view['discs'].collapse_all()
|
||||||
return
|
return
|
||||||
|
|
||||||
def on_files_button_press_event(self, tree, event):
|
def on_files_button_press_event(self, tree, event):
|
||||||
try:
|
|
||||||
path, column, x, y = tree.get_path_at_pos(int(event.x),
|
|
||||||
int(event.y))
|
|
||||||
except TypeError:
|
|
||||||
tree.get_selection().unselect_all()
|
|
||||||
return False
|
|
||||||
|
|
||||||
if event.button == 3: # Right mouse button. Show context menu.
|
if event.button == 3: # Right mouse button. Show context menu.
|
||||||
try:
|
try:
|
||||||
selection = tree.get_selection()
|
selection = tree.get_selection()
|
||||||
@@ -855,6 +897,14 @@ class MainController(Controller):
|
|||||||
list_of_paths = []
|
list_of_paths = []
|
||||||
|
|
||||||
if len(list_of_paths) == 0:
|
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])
|
selection.select_path(path[0])
|
||||||
|
|
||||||
if len(list_of_paths) > 1:
|
if len(list_of_paths) > 1:
|
||||||
@@ -867,8 +917,8 @@ class MainController(Controller):
|
|||||||
self.view['edit2'].set_sensitive(True)
|
self.view['edit2'].set_sensitive(True)
|
||||||
self.__popup_menu(event, 'files_popup')
|
self.__popup_menu(event, 'files_popup')
|
||||||
return True
|
return True
|
||||||
if event.button == 1:
|
#if event.button == 1:
|
||||||
return False
|
# return False
|
||||||
|
|
||||||
def on_files_cursor_changed(self, treeview):
|
def on_files_cursor_changed(self, treeview):
|
||||||
"""Show details of selected file/directory"""
|
"""Show details of selected file/directory"""
|
||||||
@@ -877,6 +927,17 @@ class MainController(Controller):
|
|||||||
return
|
return
|
||||||
|
|
||||||
def on_files_key_release_event(self, treeview, event):
|
def on_files_key_release_event(self, treeview, event):
|
||||||
|
"""do something with pressed keys"""
|
||||||
|
if gtk.gdk.keyval_name(event.keyval) == 'Menu':
|
||||||
|
try:
|
||||||
|
selection = treeview.get_selection()
|
||||||
|
model, list_of_paths = selection.get_selected_rows()
|
||||||
|
if not list_of_paths:
|
||||||
|
return
|
||||||
|
except TypeError:
|
||||||
|
return
|
||||||
|
self.__popup_menu(event, 'files_popup')
|
||||||
|
|
||||||
if gtk.gdk.keyval_name(event.keyval) == 'BackSpace':
|
if gtk.gdk.keyval_name(event.keyval) == 'BackSpace':
|
||||||
d_path, d_column = self.view['discs'].get_cursor()
|
d_path, d_column = self.view['discs'].get_cursor()
|
||||||
if d_path and d_column:
|
if d_path and d_column:
|
||||||
@@ -903,9 +964,9 @@ class MainController(Controller):
|
|||||||
iter = None
|
iter = None
|
||||||
else:
|
else:
|
||||||
iter = self.model.discs_tree.iter_next(iter)
|
iter = self.model.discs_tree.iter_next(iter)
|
||||||
if gtk.gdk.keyval_name(event.keyval) == 'Delete':
|
#if gtk.gdk.keyval_name(event.keyval) == 'Delete':
|
||||||
for file_id in self.__get_tv_selection_ids(treeview):
|
# for file_id in self.__get_tv_selection_ids(treeview):
|
||||||
self.main.delete(file_id)
|
# self.main.delete(file_id)
|
||||||
|
|
||||||
ids = self.__get_tv_selection_ids(self.view['files'])
|
ids = self.__get_tv_selection_ids(self.view['files'])
|
||||||
|
|
||||||
@@ -951,13 +1012,16 @@ class MainController(Controller):
|
|||||||
return
|
return
|
||||||
|
|
||||||
# NOTE: add tags / images
|
# NOTE: add tags / images
|
||||||
|
def on_delete_tag2_activate(self, menu_item):
|
||||||
|
pass
|
||||||
|
|
||||||
def on_delete_tag_activate(self, menu_item):
|
def on_delete_tag_activate(self, menu_item):
|
||||||
ids = self.__get_tv_selection_ids(self.view['files'])
|
ids = self.__get_tv_selection_ids(self.view['files'])
|
||||||
if not ids:
|
if not ids:
|
||||||
Dialogs.Inf("Remove tags", "No files selected",
|
Dialogs.Inf("Remove tags", "No files selected",
|
||||||
"You have to select some files first.")
|
"You have to select some files first.")
|
||||||
return
|
return
|
||||||
|
|
||||||
tags = self.model.get_tags_by_file_id(ids)
|
tags = self.model.get_tags_by_file_id(ids)
|
||||||
if tags:
|
if tags:
|
||||||
d = Dialogs.TagsRemoveDialog(tags)
|
d = Dialogs.TagsRemoveDialog(tags)
|
||||||
@@ -972,7 +1036,7 @@ class MainController(Controller):
|
|||||||
self.view['files'].set_model(self.model.files_list)
|
self.view['files'].set_model(self.model.files_list)
|
||||||
self.__tag_cloud()
|
self.__tag_cloud()
|
||||||
return
|
return
|
||||||
|
|
||||||
def on_add_tag1_activate(self, menu_item):
|
def on_add_tag1_activate(self, menu_item):
|
||||||
#try:
|
#try:
|
||||||
tags = Dialogs.TagsDialog().run()
|
tags = Dialogs.TagsDialog().run()
|
||||||
@@ -996,8 +1060,8 @@ class MainController(Controller):
|
|||||||
|
|
||||||
def on_add_image1_activate(self, menu_item):
|
def on_add_image1_activate(self, menu_item):
|
||||||
dialog = Dialogs.LoadImageFile(True)
|
dialog = Dialogs.LoadImageFile(True)
|
||||||
toggle = gtk.CheckButton("Don't copy images. \
|
toggle = gtk.CheckButton("Don't copy images. " + \
|
||||||
Generate only thumbnails.")
|
"Generate only thumbnails.")
|
||||||
toggle.show()
|
toggle.show()
|
||||||
dialog.dialog.set_extra_widget(toggle)
|
dialog.dialog.set_extra_widget(toggle)
|
||||||
|
|
||||||
@@ -1039,17 +1103,32 @@ class MainController(Controller):
|
|||||||
if self.model.get_source(path) == self.model.CD:
|
if self.model.get_source(path) == self.model.CD:
|
||||||
self.on_add_cd_activate(menu_item, label, fid)
|
self.on_add_cd_activate(menu_item, label, fid)
|
||||||
elif self.model.get_source(path) == self.model.DR:
|
elif self.model.get_source(path) == self.model.DR:
|
||||||
self.on_add_directory1_activate(menu_item, filepath, label, fid)
|
self.on_add_directory_activate(menu_item, filepath, label, fid)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def on_delete1_activate(self, menu_item):
|
||||||
|
"""Main menu delete dispatcher"""
|
||||||
|
if self.view['files'].is_focus():
|
||||||
|
self.on_delete3_activate(menu_item)
|
||||||
|
if self.view['discs'].is_focus():
|
||||||
|
self.on_delete2_activate(menu_item)
|
||||||
|
if self.view['images'].is_focus():
|
||||||
|
self.on_img_delete_activate(menu_item)
|
||||||
|
|
||||||
def on_delete2_activate(self, menu_item):
|
def on_delete2_activate(self, menu_item):
|
||||||
try:
|
try:
|
||||||
selection = self.view['discs'].get_selection()
|
selection = self.view['discs'].get_selection()
|
||||||
model, selected_iter = selection.get_selected()
|
model, selected_iter = selection.get_selected()
|
||||||
except:
|
except:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if not selected_iter:
|
||||||
|
Dialogs.Inf("Delete disc", "No disc selected",
|
||||||
|
"You have to select disc first before you " +\
|
||||||
|
"can delete it")
|
||||||
|
return
|
||||||
|
|
||||||
if self.model.config.confd['delwarn']:
|
if self.model.config.confd['delwarn']:
|
||||||
name = model.get_value(selected_iter, 1)
|
name = model.get_value(selected_iter, 1)
|
||||||
obj = Dialogs.Qst('Delete %s' % name, 'Delete %s?' % name,
|
obj = Dialogs.Qst('Delete %s' % name, 'Delete %s?' % name,
|
||||||
@@ -1093,11 +1172,16 @@ class MainController(Controller):
|
|||||||
model, list_of_paths = selection.get_selected_rows()
|
model, list_of_paths = selection.get_selected_rows()
|
||||||
except TypeError:
|
except TypeError:
|
||||||
return
|
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']:
|
if self.model.config.confd['delwarn']:
|
||||||
obj = Dialogs.Qst("Delete elements", "Delete items?",
|
obj = Dialogs.Qst("Delete files", "Delete files?",
|
||||||
"Items will be permanently \
|
"Selected files and directories will be" + \
|
||||||
removed from catalog.")
|
" permanently\nremoved from catalog.")
|
||||||
if not obj.run():
|
if not obj.run():
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -1155,7 +1239,15 @@ class MainController(Controller):
|
|||||||
self.model.unsaved_project = True
|
self.model.unsaved_project = True
|
||||||
self.__set_title(filepath=self.model.filename, modified=True)
|
self.__set_title(filepath=self.model.filename, modified=True)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def on_edit1_activate(self, menu_item):
|
||||||
|
"""Make sufficient menu items sensitive in right cases"""
|
||||||
|
# TODO: consolidate popup-menus with edit menu
|
||||||
|
if self.view['tag_cloud_textview'].is_focus():
|
||||||
|
self.view['delete1'].set_sensitive(False)
|
||||||
|
else:
|
||||||
|
self.view['delete1'].set_sensitive(True)
|
||||||
|
|
||||||
def on_debugbtn_clicked(self, widget):
|
def on_debugbtn_clicked(self, widget):
|
||||||
"""Debug. To remove in stable version, including button in GUI"""
|
"""Debug. To remove in stable version, including button in GUI"""
|
||||||
if __debug__:
|
if __debug__:
|
||||||
@@ -1168,7 +1260,10 @@ class MainController(Controller):
|
|||||||
print "abort = %s" % self.model.abort
|
print "abort = %s" % self.model.abort
|
||||||
print "self.model.config.recent = %s" % self.model.config.recent
|
print "self.model.config.recent = %s" % self.model.config.recent
|
||||||
print "source: %s" % self.model.source
|
print "source: %s" % self.model.source
|
||||||
|
print "files have focus", self.view['files'].is_focus()
|
||||||
|
print "discs have focus", self.view['discs'].is_focus()
|
||||||
|
print "images have focus", self.view['images'].is_focus()
|
||||||
|
|
||||||
|
|
||||||
#####################
|
#####################
|
||||||
# observed properetis
|
# observed properetis
|
||||||
@@ -1229,7 +1324,7 @@ class MainController(Controller):
|
|||||||
print "getting selected items"
|
print "getting selected items"
|
||||||
return
|
return
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def __get_tv_id_under_cursor(self, treeview):
|
def __get_tv_id_under_cursor(self, treeview):
|
||||||
"""get id of item form tree view under cursor"""
|
"""get id of item form tree view under cursor"""
|
||||||
path, column = treeview.get_cursor()
|
path, column = treeview.get_cursor()
|
||||||
@@ -1239,7 +1334,7 @@ class MainController(Controller):
|
|||||||
item_id = model.get_value(tm_iter, 0)
|
item_id = model.get_value(tm_iter, 0)
|
||||||
return item_id
|
return item_id
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def __setup_disc_treeview(self):
|
def __setup_disc_treeview(self):
|
||||||
"""Setup TreeView discs widget as tree."""
|
"""Setup TreeView discs widget as tree."""
|
||||||
self.view['discs'].set_model(self.model.discs_tree)
|
self.view['discs'].set_model(self.model.discs_tree)
|
||||||
@@ -1360,8 +1455,9 @@ class MainController(Controller):
|
|||||||
|
|
||||||
def __popup_menu(self, event, menu='discs_popup'):
|
def __popup_menu(self, event, menu='discs_popup'):
|
||||||
"""Popoup desired menu"""
|
"""Popoup desired menu"""
|
||||||
self.view[menu].popup(None, None, None, event.button,
|
self.view[menu].popup(None, None, None, 0, 0)
|
||||||
event.time)
|
#self.view[menu].popup(None, None, None, event.button,
|
||||||
|
# event.time)
|
||||||
self.view[menu].show_all()
|
self.view[menu].show_all()
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -1377,7 +1473,7 @@ class MainController(Controller):
|
|||||||
return
|
return
|
||||||
|
|
||||||
def __get_item_info(self, file_id):
|
def __get_item_info(self, file_id):
|
||||||
|
|
||||||
buf = gtk.TextBuffer()
|
buf = gtk.TextBuffer()
|
||||||
if not file_id:
|
if not file_id:
|
||||||
self.__hide_details()
|
self.__hide_details()
|
||||||
@@ -1423,7 +1519,7 @@ class MainController(Controller):
|
|||||||
tag.set_property('weight', pango.WEIGHT_BOLD)
|
tag.set_property('weight', pango.WEIGHT_BOLD)
|
||||||
buf.insert_with_tags(buf.get_end_iter(), "Note:\n", tag)
|
buf.insert_with_tags(buf.get_end_iter(), "Note:\n", tag)
|
||||||
buf.insert(buf.get_end_iter(), set['note'])
|
buf.insert(buf.get_end_iter(), set['note'])
|
||||||
|
|
||||||
tags = self.model.get_file_tags(file_id)
|
tags = self.model.get_file_tags(file_id)
|
||||||
if tags:
|
if tags:
|
||||||
buf.insert(buf.get_end_iter(), "\n")
|
buf.insert(buf.get_end_iter(), "\n")
|
||||||
@@ -1460,7 +1556,7 @@ class MainController(Controller):
|
|||||||
"""generate tag cloud"""
|
"""generate tag cloud"""
|
||||||
tag_cloud = self.view['tag_cloud_textview']
|
tag_cloud = self.view['tag_cloud_textview']
|
||||||
self.model.get_tags()
|
self.model.get_tags()
|
||||||
|
|
||||||
def insert_blank(buff, b_iter):
|
def insert_blank(buff, b_iter):
|
||||||
if b_iter.is_end() and b_iter.is_start():
|
if b_iter.is_end() and b_iter.is_start():
|
||||||
return b_iter
|
return b_iter
|
||||||
@@ -1470,18 +1566,18 @@ class MainController(Controller):
|
|||||||
return b_iter
|
return b_iter
|
||||||
|
|
||||||
buff = tag_cloud.get_buffer()
|
buff = tag_cloud.get_buffer()
|
||||||
|
|
||||||
# NOTE: remove old tags
|
# NOTE: remove old tags
|
||||||
def foreach_rem(texttag, data):
|
def foreach_rem(texttag, data):
|
||||||
"""remove old tags"""
|
"""remove old tags"""
|
||||||
tag_table.remove(texttag)
|
tag_table.remove(texttag)
|
||||||
|
|
||||||
tag_table = buff.get_tag_table()
|
tag_table = buff.get_tag_table()
|
||||||
while tag_table.get_size() > 0:
|
while tag_table.get_size() > 0:
|
||||||
tag_table.foreach(foreach_rem, None)
|
tag_table.foreach(foreach_rem, None)
|
||||||
|
|
||||||
buff.set_text('')
|
buff.set_text('')
|
||||||
|
|
||||||
if len(self.model.tag_cloud) > 0:
|
if len(self.model.tag_cloud) > 0:
|
||||||
for cloud in self.model.tag_cloud:
|
for cloud in self.model.tag_cloud:
|
||||||
buff_iter = insert_blank(buff, buff.get_end_iter())
|
buff_iter = insert_blank(buff, buff.get_end_iter())
|
||||||
@@ -1490,7 +1586,8 @@ class MainController(Controller):
|
|||||||
tag.set_property('size-points', cloud['size'])
|
tag.set_property('size-points', cloud['size'])
|
||||||
#tag.connect('event', self.on_tag_cloud_click, tag)
|
#tag.connect('event', self.on_tag_cloud_click, tag)
|
||||||
buff.insert_with_tags(buff_iter,
|
buff.insert_with_tags(buff_iter,
|
||||||
cloud['name'] + "(%d)" % cloud['count'],
|
cloud['name'] + "(%d)" % \
|
||||||
|
cloud['count'],
|
||||||
tag)
|
tag)
|
||||||
except:
|
except:
|
||||||
if __debug__:
|
if __debug__:
|
||||||
|
|||||||
@@ -175,12 +175,12 @@ class MainModel(ModelMT):
|
|||||||
ORDER BY t.tag"""
|
ORDER BY t.tag"""
|
||||||
self.db_cursor.execute(sql)
|
self.db_cursor.execute(sql)
|
||||||
res = self.db_cursor.fetchall()
|
res = self.db_cursor.fetchall()
|
||||||
|
|
||||||
retval = {}
|
retval = {}
|
||||||
for tag in res:
|
for tag in res:
|
||||||
retval[tag[0]] = tag[1]
|
retval[tag[0]] = tag[1]
|
||||||
return retval
|
return retval
|
||||||
|
|
||||||
def get_tag_by_id(self, tag_id):
|
def get_tag_by_id(self, tag_id):
|
||||||
"""get tag (string) by its id"""
|
"""get tag (string) by its id"""
|
||||||
# SQL: get tag by id
|
# SQL: get tag by id
|
||||||
@@ -190,10 +190,10 @@ class MainModel(ModelMT):
|
|||||||
if not res:
|
if not res:
|
||||||
return None
|
return None
|
||||||
return res[0]
|
return res[0]
|
||||||
|
|
||||||
def get_file_tags(self, file_id):
|
def get_file_tags(self, file_id):
|
||||||
"""get tags of file"""
|
"""get tags of file"""
|
||||||
|
|
||||||
# SQL: get tag by id
|
# SQL: get tag by id
|
||||||
sql = """SELECT t.id, t.tag FROM tags t
|
sql = """SELECT t.id, t.tag FROM tags t
|
||||||
LEFT JOIN tags_files f ON t.id=f.tag_id
|
LEFT JOIN tags_files f ON t.id=f.tag_id
|
||||||
@@ -201,16 +201,16 @@ class MainModel(ModelMT):
|
|||||||
ORDER BY t.tag"""
|
ORDER BY t.tag"""
|
||||||
self.db_cursor.execute(sql, (int(file_id), ))
|
self.db_cursor.execute(sql, (int(file_id), ))
|
||||||
res = self.db_cursor.fetchall()
|
res = self.db_cursor.fetchall()
|
||||||
|
|
||||||
tmp = {}
|
tmp = {}
|
||||||
if len(res) == 0:
|
if len(res) == 0:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
for row in res:
|
for row in res:
|
||||||
tmp[row[0]] = row[1]
|
tmp[row[0]] = row[1]
|
||||||
|
|
||||||
return tmp
|
return tmp
|
||||||
|
|
||||||
def delete_tags(self, file_id_list, tag_id_list):
|
def delete_tags(self, file_id_list, tag_id_list):
|
||||||
"""remove tags from selected files"""
|
"""remove tags from selected files"""
|
||||||
for file_id in file_id_list:
|
for file_id in file_id_list:
|
||||||
@@ -222,7 +222,17 @@ class MainModel(ModelMT):
|
|||||||
sql = """DELETE FROM tags_files WHERE file_id = ?
|
sql = """DELETE FROM tags_files WHERE file_id = ?
|
||||||
AND tag_id IN """ + sql
|
AND tag_id IN """ + sql
|
||||||
self.db_cursor.execute(sql, (int(file_id), ))
|
self.db_cursor.execute(sql, (int(file_id), ))
|
||||||
|
self.db_connection.commit()
|
||||||
|
|
||||||
|
for tag_id in tag_id_list:
|
||||||
|
sql = """SELECT count(*) FROM tags_files WHERE tag_id=?"""
|
||||||
|
self.db_cursor.execute(sql, (int(tag_id),))
|
||||||
|
res = self.db_cursor.fetchone()
|
||||||
|
if res[0] == 0:
|
||||||
|
sql = """DELETE FROM tags WHERE id=?"""
|
||||||
|
self.db_cursor.execute(sql, (int(tag_id),))
|
||||||
|
self.db_connection.commit()
|
||||||
|
|
||||||
def get_tags(self):
|
def get_tags(self):
|
||||||
"""fill tags dict with values from db"""
|
"""fill tags dict with values from db"""
|
||||||
if not self.selected_tags:
|
if not self.selected_tags:
|
||||||
@@ -237,7 +247,7 @@ class MainModel(ModelMT):
|
|||||||
WHERE f.file_id in """ + str(tuple(id_filter)) + \
|
WHERE f.file_id in """ + str(tuple(id_filter)) + \
|
||||||
"""GROUP BY f.tag_id
|
"""GROUP BY f.tag_id
|
||||||
ORDER BY t.tag"""
|
ORDER BY t.tag"""
|
||||||
|
|
||||||
self.db_cursor.execute(sql)
|
self.db_cursor.execute(sql)
|
||||||
res = self.db_cursor.fetchall()
|
res = self.db_cursor.fetchall()
|
||||||
|
|
||||||
@@ -267,17 +277,17 @@ class MainModel(ModelMT):
|
|||||||
tmp = 1
|
tmp = 1
|
||||||
self.tag_cloud[count]['size'] = tmp + 8
|
self.tag_cloud[count]['size'] = tmp + 8
|
||||||
count += 1
|
count += 1
|
||||||
|
|
||||||
def add_tag_to_path(self, tag_id):
|
def add_tag_to_path(self, tag_id):
|
||||||
"""add tag to filter"""
|
"""add tag to filter"""
|
||||||
temp = {}
|
temp = {}
|
||||||
tag_name = self.get_tag_by_id(tag_id)
|
tag_name = self.get_tag_by_id(tag_id)
|
||||||
for i in self.selected_tags:
|
for i in self.selected_tags:
|
||||||
temp[i] = self.selected_tags[i]
|
temp[i] = self.selected_tags[i]
|
||||||
|
|
||||||
temp[int(tag_id)] = tag_name
|
temp[int(tag_id)] = tag_name
|
||||||
self.selected_tags = temp
|
self.selected_tags = temp
|
||||||
|
|
||||||
def add_image(self, image, file_id, only_thumbs=False):
|
def add_image(self, image, file_id, only_thumbs=False):
|
||||||
"""add single image to file/directory"""
|
"""add single image to file/directory"""
|
||||||
sql = """INSERT INTO images(file_id, thumbnail, filename)
|
sql = """INSERT INTO images(file_id, thumbnail, filename)
|
||||||
@@ -320,7 +330,7 @@ class MainModel(ModelMT):
|
|||||||
sql = """DELETE FROM images WHERE file_id = ?"""
|
sql = """DELETE FROM images WHERE file_id = ?"""
|
||||||
self.db_cursor.execute(sql, (file_id,))
|
self.db_cursor.execute(sql, (file_id,))
|
||||||
self.db_connection.commit()
|
self.db_connection.commit()
|
||||||
|
|
||||||
def save_image(self, image_id, file_path):
|
def save_image(self, image_id, file_path):
|
||||||
"""save image with specified id into file path (directory)"""
|
"""save image with specified id into file path (directory)"""
|
||||||
sql = """SELECT i.filename, f.filename FROM images i
|
sql = """SELECT i.filename, f.filename FROM images i
|
||||||
@@ -333,18 +343,18 @@ class MainModel(ModelMT):
|
|||||||
count = 1
|
count = 1
|
||||||
dest = os.path.join(file_path, res[1] + "_%d." % count + \
|
dest = os.path.join(file_path, res[1] + "_%d." % count + \
|
||||||
res[0].split('.')[-1])
|
res[0].split('.')[-1])
|
||||||
|
|
||||||
while os.path.exists(dest):
|
while os.path.exists(dest):
|
||||||
count += 1
|
count += 1
|
||||||
dest = os.path.join(file_path, res[1] + "_%d." % count + \
|
dest = os.path.join(file_path, res[1] + "_%d." % count + \
|
||||||
res[0].split('.')[-1])
|
res[0].split('.')[-1])
|
||||||
|
|
||||||
shutil.copy(source, dest)
|
shutil.copy(source, dest)
|
||||||
return True
|
return True
|
||||||
#os.unlink()
|
#os.unlink()
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def delete_images_wth_thumbs(self, image_id):
|
def delete_images_wth_thumbs(self, image_id):
|
||||||
"""removes image (without thumbnail) on specified image id"""
|
"""removes image (without thumbnail) on specified image id"""
|
||||||
sql = """SELECT filename FROM images WHERE id=?"""
|
sql = """SELECT filename FROM images WHERE id=?"""
|
||||||
@@ -361,7 +371,7 @@ class MainModel(ModelMT):
|
|||||||
sql = """UPDATE images set filename=NULL WHERE id = ?"""
|
sql = """UPDATE images set filename=NULL WHERE id = ?"""
|
||||||
self.db_cursor.execute(sql, (image_id,))
|
self.db_cursor.execute(sql, (image_id,))
|
||||||
self.db_connection.commit()
|
self.db_connection.commit()
|
||||||
|
|
||||||
def delete_image(self, image_id):
|
def delete_image(self, image_id):
|
||||||
"""removes image on specified image id"""
|
"""removes image on specified image id"""
|
||||||
sql = """SELECT filename, thumbnail FROM images WHERE id=?"""
|
sql = """SELECT filename, thumbnail FROM images WHERE id=?"""
|
||||||
@@ -531,18 +541,18 @@ class MainModel(ModelMT):
|
|||||||
self.db_cursor.execute("update files set filename=? \
|
self.db_cursor.execute("update files set filename=? \
|
||||||
WHERE id=?", (new_name, file_id))
|
WHERE id=?", (new_name, file_id))
|
||||||
self.db_connection.commit()
|
self.db_connection.commit()
|
||||||
|
|
||||||
for row in self.files_list:
|
for row in self.files_list:
|
||||||
if row[0] == file_id:
|
if row[0] == file_id:
|
||||||
row[1] = new_name
|
row[1] = new_name
|
||||||
break
|
break
|
||||||
|
|
||||||
def foreach_discs_tree(model, path, iterator, data):
|
def foreach_discs_tree(model, path, iterator, data):
|
||||||
if model.get_value(iterator, 0) == data[0]:
|
if model.get_value(iterator, 0) == data[0]:
|
||||||
model.set_value(iterator, 1, data[1])
|
model.set_value(iterator, 1, data[1])
|
||||||
|
|
||||||
self.discs_tree.foreach(foreach_discs_tree, (file_id, new_name))
|
self.discs_tree.foreach(foreach_discs_tree, (file_id, new_name))
|
||||||
|
|
||||||
#self.__fetch_db_into_treestore()
|
#self.__fetch_db_into_treestore()
|
||||||
self.unsaved_project = True
|
self.unsaved_project = True
|
||||||
else:
|
else:
|
||||||
@@ -585,12 +595,12 @@ class MainModel(ModelMT):
|
|||||||
else:
|
else:
|
||||||
sql="""SELECT id, filename, size, date FROM files
|
sql="""SELECT id, filename, size, date FROM files
|
||||||
WHERE 1=0"""
|
WHERE 1=0"""
|
||||||
|
|
||||||
if not parent_id and self.selected_tags:
|
if not parent_id and self.selected_tags:
|
||||||
self.db_cursor.execute(sql)
|
self.db_cursor.execute(sql)
|
||||||
else:
|
else:
|
||||||
self.db_cursor.execute(sql, (parent_id,))
|
self.db_cursor.execute(sql, (parent_id,))
|
||||||
|
|
||||||
data = self.db_cursor.fetchall()
|
data = self.db_cursor.fetchall()
|
||||||
for row in data:
|
for row in data:
|
||||||
myiter = self.files_list.insert_before(None, None)
|
myiter = self.files_list.insert_before(None, None)
|
||||||
@@ -633,7 +643,7 @@ class MainModel(ModelMT):
|
|||||||
self.db_cursor.execute(sql)
|
self.db_cursor.execute(sql)
|
||||||
else:
|
else:
|
||||||
self.db_cursor.execute(sql, (parent_id,))
|
self.db_cursor.execute(sql, (parent_id,))
|
||||||
|
|
||||||
data = self.db_cursor.fetchall()
|
data = self.db_cursor.fetchall()
|
||||||
for row in data:
|
for row in data:
|
||||||
myiter = self.files_list.insert_before(None, None)
|
myiter = self.files_list.insert_before(None, None)
|
||||||
@@ -754,7 +764,7 @@ class MainModel(ModelMT):
|
|||||||
"""Remove subtree (item and its children) from main tree, remove tags
|
"""Remove subtree (item and its children) from main tree, remove tags
|
||||||
from database remove all possible data, like thumbnails, images, gthumb
|
from database remove all possible data, like thumbnails, images, gthumb
|
||||||
info, exif etc"""
|
info, exif etc"""
|
||||||
|
|
||||||
fids = []
|
fids = []
|
||||||
|
|
||||||
if not db_cursor:
|
if not db_cursor:
|
||||||
@@ -793,7 +803,13 @@ class MainModel(ModelMT):
|
|||||||
sql = """DELETE FROM tags_files WHERE file_id = ?"""
|
sql = """DELETE FROM tags_files WHERE file_id = ?"""
|
||||||
db_cursor.executemany(sql, generator())
|
db_cursor.executemany(sql, generator())
|
||||||
|
|
||||||
arg = str(tuple(fids))
|
if __debug__:
|
||||||
|
print "m_main.py: delete(): deleting:", fids
|
||||||
|
|
||||||
|
if len(fids) == 1:
|
||||||
|
arg = "(%d)" % fids[0]
|
||||||
|
else:
|
||||||
|
arg = str(tuple(fids))
|
||||||
|
|
||||||
# remove thumbnails
|
# remove thumbnails
|
||||||
sql = """SELECT filename FROM thumbnails WHERE file_id IN %s""" % arg
|
sql = """SELECT filename FROM thumbnails WHERE file_id IN %s""" % arg
|
||||||
@@ -946,6 +962,7 @@ class MainModel(ModelMT):
|
|||||||
"""update note and description"""
|
"""update note and description"""
|
||||||
sql = """UPDATE files SET description=?, note=? WHERE id=?"""
|
sql = """UPDATE files SET description=?, note=? WHERE id=?"""
|
||||||
self.db_cursor.execute(sql, (desc, note, file_id))
|
self.db_cursor.execute(sql, (desc, note, file_id))
|
||||||
|
self.db_connection.commit()
|
||||||
return
|
return
|
||||||
|
|
||||||
# private class functions
|
# private class functions
|
||||||
@@ -1101,11 +1118,11 @@ class MainModel(ModelMT):
|
|||||||
self.db_cursor.execute(sql)
|
self.db_cursor.execute(sql)
|
||||||
self.db_connection.commit()
|
self.db_connection.commit()
|
||||||
|
|
||||||
|
|
||||||
def __filter(self):
|
def __filter(self):
|
||||||
"""return list of ids of files (AND their parent, even if they have no
|
"""return list of ids of files (AND their parent, even if they have no
|
||||||
assigned tags) that corresponds to tags"""
|
assigned tags) that corresponds to tags"""
|
||||||
|
|
||||||
filtered_ids = []
|
filtered_ids = []
|
||||||
count = 0
|
count = 0
|
||||||
for tid in self.selected_tags:
|
for tid in self.selected_tags:
|
||||||
@@ -1117,13 +1134,13 @@ class MainModel(ModelMT):
|
|||||||
data = self.db_cursor.fetchall()
|
data = self.db_cursor.fetchall()
|
||||||
for row in data:
|
for row in data:
|
||||||
temp1.append(row[0])
|
temp1.append(row[0])
|
||||||
|
|
||||||
if count > 0:
|
if count > 0:
|
||||||
filtered_ids = list(set(filtered_ids).intersection(temp1))
|
filtered_ids = list(set(filtered_ids).intersection(temp1))
|
||||||
else:
|
else:
|
||||||
filtered_ids = temp1
|
filtered_ids = temp1
|
||||||
count += 1
|
count += 1
|
||||||
|
|
||||||
parents = []
|
parents = []
|
||||||
for i in filtered_ids:
|
for i in filtered_ids:
|
||||||
sql = """SELECT parent_id
|
sql = """SELECT parent_id
|
||||||
@@ -1143,13 +1160,13 @@ class MainModel(ModelMT):
|
|||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
parents.append(data[0])
|
parents.append(data[0])
|
||||||
|
|
||||||
return list(set(parents).union(filtered_ids))
|
return list(set(parents).union(filtered_ids))
|
||||||
|
|
||||||
def __filter2(self):
|
def __filter2(self):
|
||||||
"""return list of ids of files (WITHOUT their parent) that
|
"""return list of ids of files (WITHOUT their parent) that
|
||||||
corresponds to tags"""
|
corresponds to tags"""
|
||||||
|
|
||||||
filtered_ids = []
|
filtered_ids = []
|
||||||
count = 0
|
count = 0
|
||||||
for tid in self.selected_tags:
|
for tid in self.selected_tags:
|
||||||
@@ -1161,7 +1178,7 @@ class MainModel(ModelMT):
|
|||||||
data = self.db_cursor.fetchall()
|
data = self.db_cursor.fetchall()
|
||||||
for row in data:
|
for row in data:
|
||||||
temp1.append(row[0])
|
temp1.append(row[0])
|
||||||
|
|
||||||
if count > 0:
|
if count > 0:
|
||||||
filtered_ids = list(set(filtered_ids).intersection(temp1))
|
filtered_ids = list(set(filtered_ids).intersection(temp1))
|
||||||
else:
|
else:
|
||||||
@@ -1169,7 +1186,7 @@ class MainModel(ModelMT):
|
|||||||
count += 1
|
count += 1
|
||||||
|
|
||||||
return filtered_ids
|
return filtered_ids
|
||||||
|
|
||||||
def __scan(self):
|
def __scan(self):
|
||||||
"""scan content of the given path"""
|
"""scan content of the given path"""
|
||||||
self.busy = True
|
self.busy = True
|
||||||
|
|||||||
@@ -231,7 +231,7 @@ class SelectDirectory(object):
|
|||||||
self.title = title
|
self.title = title
|
||||||
else:
|
else:
|
||||||
self.title = "Choose directory"
|
self.title = "Choose directory"
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
"""dialog for point the mountpoint"""
|
"""dialog for point the mountpoint"""
|
||||||
dialog = gtk.FileChooserDialog(
|
dialog = gtk.FileChooserDialog(
|
||||||
@@ -247,7 +247,7 @@ class SelectDirectory(object):
|
|||||||
dialog.set_default_response(gtk.RESPONSE_OK)
|
dialog.set_default_response(gtk.RESPONSE_OK)
|
||||||
|
|
||||||
retval = None
|
retval = None
|
||||||
|
|
||||||
if self.URI:
|
if self.URI:
|
||||||
dialog.set_current_folder_uri(self.URI)
|
dialog.set_current_folder_uri(self.URI)
|
||||||
response = dialog.run()
|
response = dialog.run()
|
||||||
@@ -479,7 +479,7 @@ class StatsDialog(object):
|
|||||||
if result == gtk.RESPONSE_OK:
|
if result == gtk.RESPONSE_OK:
|
||||||
return entry.get_text()
|
return entry.get_text()
|
||||||
return None
|
return None
|
||||||
|
|
||||||
class TagsDialog(object):
|
class TagsDialog(object):
|
||||||
"""Sepcific dialog for display stats"""
|
"""Sepcific dialog for display stats"""
|
||||||
|
|
||||||
@@ -498,7 +498,7 @@ class TagsDialog(object):
|
|||||||
if result == gtk.RESPONSE_OK:
|
if result == gtk.RESPONSE_OK:
|
||||||
return entry.get_text()
|
return entry.get_text()
|
||||||
return None
|
return None
|
||||||
|
|
||||||
class TagsRemoveDialog(object):
|
class TagsRemoveDialog(object):
|
||||||
"""Sepcific dialog for display stats"""
|
"""Sepcific dialog for display stats"""
|
||||||
|
|
||||||
@@ -509,34 +509,44 @@ class TagsRemoveDialog(object):
|
|||||||
def run(self):
|
def run(self):
|
||||||
if not self.tag_dict:
|
if not self.tag_dict:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
gladexml = gtk.glade.XML(self.gladefile, "tagRemove")
|
gladexml = gtk.glade.XML(self.gladefile, "tagRemove")
|
||||||
dialog = gladexml.get_widget("tagRemove")
|
dialog = gladexml.get_widget("tagRemove")
|
||||||
|
|
||||||
# fill model with dict
|
# declare model
|
||||||
model = gtk.ListStore(gobject.TYPE_INT,
|
model = gtk.ListStore(gobject.TYPE_INT,
|
||||||
gobject.TYPE_STRING, gobject.TYPE_BOOLEAN)
|
gobject.TYPE_STRING, gobject.TYPE_BOOLEAN)
|
||||||
for tag in self.tag_dict:
|
# sort dict
|
||||||
|
values = self.tag_dict.values()
|
||||||
|
values.sort()
|
||||||
|
keys = []
|
||||||
|
for val in values:
|
||||||
|
for d_key, d_value in self.tag_dict.items():
|
||||||
|
if d_value == val:
|
||||||
|
keys.append(d_key)
|
||||||
|
|
||||||
|
# fill model with dict
|
||||||
|
for count in range(len(keys)):
|
||||||
myiter = model.insert_before(None, None)
|
myiter = model.insert_before(None, None)
|
||||||
model.set_value(myiter, 0, tag)
|
model.set_value(myiter, 0, keys[count])
|
||||||
model.set_value(myiter, 1, self.tag_dict[tag])
|
model.set_value(myiter, 1, values[count])
|
||||||
model.set_value(myiter, 2, None)
|
model.set_value(myiter, 2, None)
|
||||||
|
|
||||||
def toggle(cell, path, model):
|
def toggle(cell, path, model):
|
||||||
model[path][2] = not model[path][2]
|
model[path][2] = not model[path][2]
|
||||||
|
|
||||||
def toggle_all(column, model):
|
def toggle_all(column, model):
|
||||||
for row in model:
|
for row in model:
|
||||||
row[2] = not row[2]
|
row[2] = not row[2]
|
||||||
|
|
||||||
treeview = gladexml.get_widget("treeview1")
|
treeview = gladexml.get_widget("treeview1")
|
||||||
treeview.set_model(model)
|
treeview.set_model(model)
|
||||||
|
|
||||||
renderer = gtk.CellRendererText()
|
renderer = gtk.CellRendererText()
|
||||||
column = gtk.TreeViewColumn("Tag", renderer, text=1)
|
column = gtk.TreeViewColumn("Tag", renderer, text=1)
|
||||||
column.set_property('expand', True)
|
column.set_property('expand', True)
|
||||||
treeview.append_column(column)
|
treeview.append_column(column)
|
||||||
|
|
||||||
renderer = gtk.CellRendererToggle()
|
renderer = gtk.CellRendererToggle()
|
||||||
renderer.set_property('activatable', True)
|
renderer.set_property('activatable', True)
|
||||||
renderer.connect('toggled', toggle, model)
|
renderer.connect('toggled', toggle, model)
|
||||||
@@ -546,7 +556,7 @@ class TagsRemoveDialog(object):
|
|||||||
column.set_property("clickable", True)
|
column.set_property("clickable", True)
|
||||||
column.connect("clicked", toggle_all, model)
|
column.connect("clicked", toggle_all, model)
|
||||||
treeview.append_column(column)
|
treeview.append_column(column)
|
||||||
|
|
||||||
result = dialog.run()
|
result = dialog.run()
|
||||||
|
|
||||||
dialog.destroy()
|
dialog.destroy()
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ class MainView(View):
|
|||||||
self['separatormenuitem4'].hide()
|
self['separatormenuitem4'].hide()
|
||||||
self['list1'].hide()
|
self['list1'].hide()
|
||||||
self['thumbnails1'].hide()
|
self['thumbnails1'].hide()
|
||||||
#self['tag_cloud_textview'].drag_dest_set(0, [], 0)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
pass # end of class
|
pass # end of class
|
||||||
|
|||||||
Reference in New Issue
Block a user