5 assert gtk
.pygtk_version
>= (2, 8)
10 from pysize
.ui
.gtk
.gazpacho_loader
.loader
import ObjectBuilder
12 from pysize
.ui
.gtk
.pysize_widget
import PysizeWidget
13 from pysize
.ui
.utils
import human_unit
, short_string
, sanitize_string
14 from pysize
.core
.compute_size
import size_observable
15 from pysize
.core
import history
17 def hover_changed(main_widget
, hover_node
, status_bar
):
19 node
= hover_node
or main_widget
.tree
.root
20 label
= human_unit(node
.size
) + ' | ' + node
.get_fullname()
21 status_bar
.push(0, label
)
23 def size_observer(progress_bar
):
25 if now
- size_observer
.last_pulse
> 0.04:
26 size_observer
.last_pulse
= now
27 gobject
.idle_add(lambda: progress_bar
.pulse())
28 size_observer
.last_pulse
= time
.time()
30 def hide_pbar(progress_bar
, visible
):
36 def update_action(zoom_fit_action
, main_widget
):
37 # Enable if the zoom is not already 'auto' and there is a tree
38 enable
= main_widget
.options
.min_size
!= 'auto' and \
39 not not main_widget
.tree
.root
.get_fullpaths()
40 zoom_fit_action
.set_sensitive(enable
)
42 def update_title(window
, main_widget
):
43 root
= main_widget
.tree
.root
44 window
.set_title('Pysize - %s | %s' %
45 (human_unit(root
.size
), sanitize_string(root
.get_name())))
47 def update_back_action(back_action
, next_insertion_index
, history
):
48 back_action
.set_sensitive(next_insertion_index
> 1)
50 def update_forward_action(forward_action
, next_insertion_index
, history
):
51 forward_action
.set_sensitive(next_insertion_index
< len(history
))
53 def update_hist_menu(main_widget
, hist_menu
, next_insertion_index
, hist_list
):
54 class activator(object):
55 def __init__(self
, index
):
58 def activate(self
, unused_menu_item
):
59 main_widget
.set_paths(history
.go_to_history(self
.index
))
61 for nr
, item
in enumerate(hist_menu
):
62 if nr
> 2: # Keep 'Back' and 'Forward'
63 hist_menu
.remove(item
)
64 item
= gtk
.SeparatorMenuItem()
67 for nr
, (paths
, name
) in enumerate(hist_list
):
68 item
= gtk
.CheckMenuItem(short_string(sanitize_string(name
), 100))
69 if nr
+ 1 == next_insertion_index
:
71 item
.connect('activate', activator(nr
).activate
)
72 item
.set_draw_as_radio(True)
76 class PysizeWindow(object):
77 def __init__(self
, options
, args
):
78 create_widget
= lambda **unused_kwargs
: PysizeWidget(options
, args
)
79 glade_filename
= os
.path
.join(os
.path
.dirname(__file__
),
81 builder
= ObjectBuilder(glade_filename
,
82 custom
= {'pysize_widget': create_widget
})
84 main_widget
= builder
.get_widget('main_widget')
85 status_bar
= builder
.get_widget('status_bar')
86 main_widget
.connect('hover_changed', hover_changed
, status_bar
)
88 progress_bar
= builder
.get_widget('progress_bar')
89 size_observable
.add_observer(lambda: size_observer(progress_bar
))
90 pbar_hider
= lambda w
, building
: hide_pbar(progress_bar
, building
)
91 main_widget
.connect('building-tree-state-changed', pbar_hider
)
93 max_depth
= builder
.get_widget('max_depth')
94 spin_init
= lambda w
: max_depth
.set_value(main_widget
.options
.max_depth
)
95 main_widget
.connect('realize', spin_init
)
97 ui_manager
= builder
.get_widget('uimanager')
98 zoom_fit_action
= ui_manager
.get_action('ui/toolbar/ZoomFit')
99 action_updater
= lambda w
, building
: update_action(zoom_fit_action
, w
)
100 main_widget
.connect('building-tree-state-changed', action_updater
)
102 # Disable actions when the tree is empty: pysize launched with no arg
103 class disabler(object):
104 def __init__(self
, action
):
106 def disable(self
, main_widget
, building
):
107 sensitive
= not not main_widget
.tree
.root
.get_fullpaths()
108 self
.action
.set_sensitive(sensitive
)
109 for name
in 'ParentDirectory', 'Refresh', 'ZoomIn', 'ZoomOut':
110 action
= ui_manager
.get_action('ui/toolbar/' + name
)
111 action_disabler
= disabler(action
).disable
112 main_widget
.connect('building-tree-state-changed', action_disabler
)
114 back_action
= ui_manager
.get_action('ui/toolbar/Back')
115 back_action
.set_sensitive(False)
116 update_back
= lambda n
, h
: update_back_action(back_action
, n
, h
)
117 history
.history_observable
.add_observer(update_back
)
119 forward_action
= ui_manager
.get_action('ui/toolbar/Forward')
120 forward_action
.set_sensitive(False)
121 update_forw
= lambda n
, h
: update_forward_action(forward_action
, n
, h
)
122 history
.history_observable
.add_observer(update_forw
)
124 hist_menu_action
= ui_manager
.get_action('ui/menubar/HistoryMenu')
125 hist_menu
= hist_menu_action
.get_proxies()[0].get_submenu()
126 upd_hist
= lambda n
, h
: update_hist_menu(main_widget
, hist_menu
, n
, h
)
127 history
.history_observable
.add_observer(upd_hist
)
129 toolbar
= builder
.get_widget('toolbar')
130 toolbar_remaining
= builder
.get_widget('toolbar_remaining')
131 toolbar_remaining
.unparent()
132 tool_item
= gtk
.ToolItem()
133 tool_item
.add(toolbar_remaining
)
134 toolbar
.insert(tool_item
, -1)
136 logo_filename
= os
.path
.join(os
.path
.dirname(__file__
), 'logo.svg')
137 gtk
.window_set_default_icon_from_file(logo_filename
)
140 'quit_action': lambda w
: gtk
.main_quit(),
141 'refresh_tree_action': lambda w
: main_widget
.refresh_tree(),
142 'zoom_fit_action': lambda w
: main_widget
.zoom_fit(),
143 'zoom_in_action': lambda w
: main_widget
.zoom_in(),
144 'zoom_out_action': lambda w
: main_widget
.zoom_out(),
145 'parent_directory_action': lambda w
: main_widget
.parent_directory(),
146 'open_action': lambda w
: main_widget
.open(),
147 'back_action': lambda w
: main_widget
.set_paths(history
.back()),
148 'forw_action': lambda w
: main_widget
.set_paths(history
.forward()),
149 'max_depth_changed': main_widget
.max_depth_changed
151 builder
.signal_autoconnect(callbacks
)
153 window
= builder
.get_widget('main_window')
154 title_updater
= lambda w
, tree
: update_title(window
, main_widget
)
155 main_widget
.connect('building-tree-state-changed', title_updater
)