Update copyright year
[pysize.git] / pysize / ui / gtk / pysize_widget.py
blob4468b6feb257f99739667be82c3a8cb150f4487c
1 # This program is free software; you can redistribute it and/or modify
2 # it under the terms of the GNU General Public License as published by
3 # the Free Software Foundation; either version 2 of the License, or
4 # (at your option) any later version.
6 # This program is distributed in the hope that it will be useful,
7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 # GNU Library General Public License for more details.
11 # You should have received a copy of the GNU General Public License
12 # along with this program; if not, write to the Free Software
13 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15 # See the COPYING file for license information.
17 # Copyright (c) 2006, 2007 Guillaume Chazarain <guichaz@yahoo.fr>
19 import pygtk
20 pygtk.require('2.0')
21 import gtk
22 assert gtk.pygtk_version >= (2, 8)
23 import gobject
25 from pysize.core.pysize_global_fs_cache import drop_caches
26 from pysize.core.pysize_fs_tree import pysize_tree
27 from pysize.core import history
28 from pysize.core import deletion
29 from pysize.ui.utils import min_size_to_consider
30 from pysize.ui.gtk.threaded_pysize_tree import threaded_pysize_tree
32 from pysize.ui.gtk.pysize_widget_draw import PysizeWidget_Draw
33 from pysize.ui.gtk.pysize_widget_menu import PysizeWidget_Menu
34 from pysize.ui.gtk.pysize_widget_mouse import PysizeWidget_Mouse
37 class PysizeWidget(gtk.DrawingArea, PysizeWidget_Draw,
38 PysizeWidget_Menu, PysizeWidget_Mouse):
39 __gsignals__ = {
40 'hover-changed':
41 (gobject.SIGNAL_RUN_LAST,
42 gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,)),
43 'building-tree-state-changed':
44 (gobject.SIGNAL_RUN_LAST,
45 gobject.TYPE_NONE, (gobject.TYPE_BOOLEAN,))
48 def __init__(self, options, args):
49 gtk.DrawingArea.__init__(self)
50 PysizeWidget_Draw.__init__(self, options, args)
51 PysizeWidget_Menu.__init__(self, options, args)
52 PysizeWidget_Mouse.__init__(self, options, args)
53 self.connect('realize', type(self)._realize)
54 self.connect('key-press-event', type(self)._key_press)
55 self.connect('configure-event', type(self)._configure)
56 self.set_flags(gtk.CAN_FOCUS)
57 self.options = options
58 self.selected_paths = set()
59 self.paths = args
60 self.tree = pysize_tree([], 0, 0, self.options)
61 self.tree_builder = threaded_pysize_tree()
62 self.tree_builder.completion.add_observer(self._new_tree_callback)
64 def _realize(self):
65 events = self.window.get_events()
66 events |= gtk.gdk.POINTER_MOTION_MASK
67 events |= gtk.gdk.POINTER_MOTION_HINT_MASK
68 events |= gtk.gdk.KEY_PRESS_MASK
69 events |= gtk.gdk.BUTTON_PRESS_MASK
70 events |= gtk.gdk.BUTTON_RELEASE_MASK
71 self.window.set_events(events)
73 def _key_press(self, event):
74 directions = {
75 gtk.keysyms.Left: self.tree.get_parent,
76 gtk.keysyms.Up: self.tree.get_previous_sibling,
77 gtk.keysyms.Right: self.tree.get_first_child,
78 gtk.keysyms.Down: self.tree.get_next_sibling
81 action = directions.get(event.keyval, None)
82 if action and self.cursor_node is not None:
83 new_selection = action(self.cursor_node)
84 if new_selection not in (None, self.tree.root):
85 self.queue_node_redraw(self.cursor_node)
86 self.queue_node_redraw(new_selection)
87 self.set_cursor_node(new_selection)
88 return action is not None
90 # Called when the threaded_pysize_tree built a new tree for us
91 def _new_tree_callback(self, tree):
92 if tree:
93 self.tree = tree
94 self.queue_draw()
95 self.invalidate_tree()
96 history.add_entry(tree)
97 self.emit('building-tree-state-changed', not tree)
98 if tree:
99 if self.options.min_size == 'auto':
100 height = self.get_parent().allocation.height - 2
101 else:
102 height = int(self._get_requested_height())
103 self.set_size_request(-1, height)
105 def refresh_tree(self):
106 drop_caches()
107 self.schedule_new_tree()
109 def min_size_requested(self):
110 return min_size_to_consider(self.options.min_size,
111 self.max_number_of_nodes())
113 def set_paths(self, paths):
114 if paths:
115 self.paths = paths
116 self.schedule_new_tree()
118 def schedule_new_tree(self):
119 self.tree_builder.schedule(self.paths, self.options.max_depth,
120 self.min_size_requested(), self.options)
122 def _configure(self, event):
123 if self.options.min_size == 'auto':
124 self.schedule_new_tree()
126 def invalidate_tree(self):
127 self.emit('hover-changed', None)
129 def parent_directory(self):
130 self.set_paths([self.tree.root.get_dirname()])
132 def max_depth_changed(self, spin):
133 value = spin.get_value()
134 self.options.max_depth = value
135 self.schedule_new_tree()
137 def open(self):
138 action = gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER
139 buttons = gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, \
140 gtk.STOCK_OPEN, gtk.RESPONSE_ACCEPT
141 dialog = gtk.FileChooserDialog(title='Select a directory',
142 action=action, buttons=buttons)
143 dialog.set_select_multiple(True)
144 response = dialog.run()
145 if response == gtk.RESPONSE_ACCEPT:
146 self.set_paths(dialog.get_filenames())
147 dialog.destroy()
149 def schedule_delete(self, nodes):
150 deletion.schedule(nodes)
151 self.schedule_new_tree()