"Fossies" - the Fresh Open Source Software Archive

Member "pysize-0.2/pysize/ui/gtk/pysize_window.py" (11 Mar 2007, 10289 Bytes) of package /linux/privat/old/pysize-0.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file.

    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.
    5 #
    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.
   10 #
   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.
   14 #
   15 # See the COPYING file for license information.
   16 #
   17 # Copyright (c) 2006, 2007 Guillaume Chazarain <guichaz@yahoo.fr>
   18 
   19 import os
   20 import pygtk
   21 pygtk.require('2.0')
   22 import gtk
   23 assert gtk.pygtk_version >= (2, 8)
   24 import gobject
   25 import time
   26 import shutil
   27 
   28 from pysize.ui.gtk.gazpacho_loader.loader import ObjectBuilder
   29 
   30 from pysize.ui.gtk.pysize_widget import PysizeWidget
   31 from pysize.ui.utils import human_unit, short_string, sanitize_string
   32 from pysize.core import compute_size
   33 from pysize.core.compute_size import size_observable
   34 from pysize.core import history
   35 from pysize.core.deletion import get_deleted, restore
   36 
   37 def hover_changed(main_widget, hover_node, status_bar):
   38     status_bar.pop(0)
   39     nodes = main_widget.get_selected_nodes()
   40     if not nodes:
   41         if hover_node:
   42             nodes = [hover_node]
   43         else:
   44             nodes = [main_widget.tree.root]
   45     size = sum([node.size for node in nodes])
   46     text = ' + '.join([node.get_fullname() for node in nodes])
   47     label = human_unit(size) + ' | ' + text
   48     status_bar.push(0, label)
   49 
   50 def size_observer(progress_bar):
   51     now = time.time()
   52     if now - size_observer.last_pulse > 0.04:
   53         size_observer.last_pulse = now
   54         gobject.idle_add(lambda: progress_bar.pulse())
   55 size_observer.last_pulse = time.time()
   56 
   57 def hide_pbar(progress_bar, visible):
   58     if visible:
   59         progress_bar.show()
   60     else:
   61         progress_bar.hide()
   62 
   63 def update_action(zoom_fit_action, main_widget):
   64     # Enable if the zoom is not already 'auto' and there is a tree
   65     enable = main_widget.options.min_size != 'auto' and \
   66              not not main_widget.tree.root.get_fullpaths()
   67     zoom_fit_action.set_sensitive(enable)
   68 
   69 def update_title(window, main_widget):
   70     root = main_widget.tree.root
   71     window.set_title('Pysize - %s | %s' %
   72                      (human_unit(root.size), sanitize_string(root.get_name())))
   73 
   74 def update_back_action(back_action, next_insertion_index, history):
   75     back_action.set_sensitive(next_insertion_index > 1)
   76 
   77 def update_forward_action(forward_action, next_insertion_index, history):
   78     forward_action.set_sensitive(next_insertion_index < len(history))
   79 
   80 def update_hist_menu(main_widget, hist_menu, next_insertion_index, hist_list):
   81     class activator(object):
   82         def __init__(self, index):
   83             self.index = index
   84 
   85         def activate(self, unused_menu_item):
   86             main_widget.set_paths(history.go_to_history(self.index))
   87 
   88     for nr, item in enumerate(hist_menu):
   89         if nr > 2: # Keep 'Back' and 'Forward'
   90             hist_menu.remove(item)
   91     item = gtk.SeparatorMenuItem()
   92     item.show()
   93     hist_menu.add(item)
   94     for nr, (paths, name) in enumerate(hist_list):
   95         # We want underscores, not mnemonics
   96         name = short_string(sanitize_string(name), 100).replace('_', '__')
   97         item = gtk.CheckMenuItem(name)
   98         if nr + 1  == next_insertion_index:
   99             item.set_active(True)
  100         item.connect('activate', activator(nr).activate)
  101         item.set_draw_as_radio(True)
  102         item.show()
  103         hist_menu.add(item)
  104 
  105 def show_deleted_files(dialog, treeview):
  106     model = treeview.get_model()
  107     model.clear()
  108     for path in get_deleted():
  109         size = human_unit(compute_size.slow(path, account_deletion=False))
  110         model.append((size, path))
  111     dialog.run()
  112     dialog.hide()
  113 
  114 def iter_selection(treeview):
  115     model = treeview.get_model()
  116     selection = treeview.get_selection().get_selected_rows()[1]
  117     if selection:
  118         selection.reverse()
  119         for treepath in selection:
  120             treeiter = model.get_iter(treepath)
  121             path = model.get_value(treeiter, 1)
  122             yield treeiter, path
  123 
  124 def restore_deleted_files(treeview, main_widget):
  125     if treeview.get_selection().count_selected_rows() > 0:
  126         model = treeview.get_model()
  127         for treeiter, path in iter_selection(treeview):
  128             restore(path)
  129             model.remove(treeiter)
  130         main_widget.schedule_new_tree()
  131 
  132 def delete_deleted_files(treeview):
  133     if treeview.get_selection().count_selected_rows() <= 0:
  134         return;
  135     dialog = gtk.MessageDialog(parent=None, flags=gtk.DIALOG_MODAL,
  136                                type=gtk.MESSAGE_WARNING,
  137                                buttons=gtk.BUTTONS_YES_NO,
  138                                message_format='The selected will be permanently'
  139                                'deleted, do you really want to delete them?')
  140     response = dialog.run()
  141     dialog.destroy()
  142     if response == gtk.RESPONSE_YES:
  143         model = treeview.get_model()
  144         for treeiter, path in iter_selection(treeview):
  145             restore(path)
  146             if os.path.isdir(path):
  147                 shutil.rmtree(path)
  148             else:
  149                 os.remove(path)
  150             model.remove(treeiter)
  151 
  152 class PysizeWindow(object):
  153     def __init__(self, options, args):
  154         create_widget = lambda **unused_kwargs: PysizeWidget(options, args)
  155         glade_filename = os.path.join(os.path.dirname(__file__),
  156                                       'main_window.glade')
  157         builder = ObjectBuilder(glade_filename,
  158                                 custom = {'pysize_widget': create_widget})
  159 
  160         main_widget = builder.get_widget('main_widget')
  161         status_bar = builder.get_widget('status_bar')
  162         main_widget.connect('hover_changed', hover_changed, status_bar)
  163 
  164         progress_bar = builder.get_widget('progress_bar')
  165         size_observable.add_observer(lambda: size_observer(progress_bar))
  166         pbar_hider = lambda w, building: hide_pbar(progress_bar, building)
  167         main_widget.connect('building-tree-state-changed', pbar_hider)
  168 
  169         max_depth = builder.get_widget('max_depth')
  170         spin_init = lambda w: max_depth.set_value(main_widget.options.max_depth)
  171         main_widget.connect('realize', spin_init)
  172 
  173         ui_manager = builder.get_widget('uimanager')
  174         zoom_fit_action = ui_manager.get_action('ui/toolbar/ZoomFit')
  175         action_updater = lambda w, building: update_action(zoom_fit_action, w)
  176         main_widget.connect('building-tree-state-changed', action_updater)
  177 
  178         # Disable actions when the tree is empty: pysize launched with no arg
  179         class disabler(object):
  180             def __init__(self, action):
  181                 self.action = action
  182             def disable(self, main_widget, building):
  183                 sensitive = not not main_widget.tree.root.get_fullpaths()
  184                 self.action.set_sensitive(sensitive)
  185         for name in 'ParentDirectory', 'Refresh', 'ZoomIn', 'ZoomOut':
  186             action = ui_manager.get_action('ui/toolbar/' + name)
  187             action_disabler = disabler(action).disable
  188             main_widget.connect('building-tree-state-changed', action_disabler)
  189 
  190         back_action = ui_manager.get_action('ui/toolbar/Back')
  191         back_action.set_sensitive(False)
  192         update_back = lambda n, h: update_back_action(back_action, n, h)
  193         history.history_observable.add_observer(update_back)
  194 
  195         forward_action = ui_manager.get_action('ui/toolbar/Forward')
  196         forward_action.set_sensitive(False)
  197         update_forw = lambda n, h: update_forward_action(forward_action, n, h)
  198         history.history_observable.add_observer(update_forw)
  199 
  200         hist_menu_action = ui_manager.get_action('ui/menubar/HistoryMenu')
  201         hist_menu = hist_menu_action.get_proxies()[0].get_submenu()
  202         upd_hist = lambda n, h: update_hist_menu(main_widget, hist_menu, n, h)
  203         history.history_observable.add_observer(upd_hist)
  204 
  205         toolbar = builder.get_widget('toolbar')
  206         toolbar_remaining = builder.get_widget('toolbar_remaining')
  207         toolbar_remaining.unparent()
  208         tool_item = gtk.ToolItem()
  209         tool_item.add(toolbar_remaining)
  210         toolbar.insert(tool_item, -1)
  211 
  212         deleted_files_dialog = builder.get_widget('deleted_files_dialog')
  213         deleted_files_treeview = builder.get_widget('deleted_files_treeview')
  214         deleted_files_treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
  215 
  216         logo_filename = os.path.join(os.path.dirname(__file__), 'logo.svg')
  217         gtk.window_set_default_icon_from_file(logo_filename)
  218 
  219         callbacks = {
  220             'quit_action': lambda w: gtk.main_quit(),
  221             'refresh_tree_action': lambda w: main_widget.refresh_tree(),
  222             'zoom_fit_action': lambda w: main_widget.zoom_fit(),
  223             'zoom_in_action': lambda w: main_widget.zoom_in(),
  224             'zoom_out_action': lambda w: main_widget.zoom_out(),
  225             'parent_directory_action': lambda w: main_widget.parent_directory(),
  226             'open_action': lambda w: main_widget.open(),
  227             'back_action': lambda w: main_widget.set_paths(history.back()),
  228             'forw_action': lambda w: main_widget.set_paths(history.forward()),
  229             'deleted_files_action': lambda w:
  230                show_deleted_files(deleted_files_dialog, deleted_files_treeview),
  231             'close_deleted_files': lambda b: deleted_files_dialog.hide(),
  232             'restore_deleted_files': lambda b:
  233                restore_deleted_files(deleted_files_treeview, main_widget),
  234             'delete_deleted_files': lambda b:
  235                delete_deleted_files(deleted_files_treeview),
  236             'max_depth_changed': main_widget.max_depth_changed
  237         }
  238         builder.signal_autoconnect(callbacks)
  239 
  240         window = builder.get_widget('main_window')
  241         title_updater = lambda w, tree: update_title(window, main_widget)
  242         main_widget.connect('building-tree-state-changed', title_updater)
  243         window.show_all()