filemanager.py :  » IDE » PIDA » pida-0.6beta3 » pida » services » filemanager » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » IDE » PIDA 
PIDA » pida 0.6beta3 » pida » services » filemanager » filemanager.py
# -*- coding: utf-8 -*-
"""
    :copyright: 2005-2008 by The PIDA Project
    :license: GPL 2 or later (see README/COPYING/LICENSE)
"""

import gtk

from os import listdir,path

import os
import shutil
import sys

import cgi

import re

# PIDA Imports
from pida.core.service import Service
from pida.core.features import FeaturesConfig
from pida.core.pdbus import DbusConfig,EXPORT
from pida.core.commands import CommandsConfig
from pida.core.events import EventsConfig
from pida.core.actions import ActionsConfig
from pida.core.actions import TYPE_NORMAL,TYPE_MENUTOOL,TYPE_DROPDOWNMENUTOOL,TYPE_RADIO,TYPE_TOGGLE
from pida.core.options import OptionsConfig
from pida.core.environment import get_uidef_path,on_windows
from pida.core.log import get_logger

from pida.utils.gthreads import GeneratorTask,AsyncTask,gcall
from pida.utils.path import homedir

from pida.ui.views import PidaView,WindowConfig
from pida.ui.objectlist import AttrSortCombo
from pida.ui.dropdownmenutoolbutton import DropDownMenuToolButton
from pida.ui.gtkforms import DialogOptions,create_gtk_dialog
from kiwi.ui.objectlist import Column,ColoredColumn,ObjectList

import filehiddencheck

# locale
from pida.core.locale import Locale
locale = Locale('filemanager')
_ = locale.gettext

IEXPORT = EXPORT(suffix='filemanager')

state_text = dict(
        hidden=' ',
        none='?',
        new='A', #XXX
        added='A',
        modified='M',
        ignored=' ',
        normal=' ',
        error='E',
        empty='!',
        conflict='C',
        removed='D',
        missing='!',
        max='+',
        external='>',
        )

state_style = dict( # tuples of (color, is_bold, is_italic)
        unknown=('pida-fm-unknown', False, False),
        hidden=('pida-fm-hidden', False, True),
        ignored=('pida-fm-ignored', False, True),
        #TODO: better handling of normal directories
        clean=('pida-fm-clean', False, False), 
        none=('pida-fm-none', False, True), 
        normal=('pida-fm-normal', False, False),
        error=('pida-fm-error', True, True),
        empty=('pida-fm-empty', False, True),
        modified=('pida-fm-modified', True, False),
        conflict=('pida-fm-conflict', True, True),
        removed=('pida-fm-removed', True, True),
        missing=('pida-fm-missing', True, False),
        new=('pida-fm-new', True, False),
        added=('pida-fm-new', True, False),
        max=('pida-fm-max', False, False),
        external=('pida-fm-external', False, True),
        )


def check_or_home(path):
    if not os.path.isdir(path):
        get_logger('pida.svc.filemanager').info(_("Can't open directory: %s") %path)
        return homedir
    return path

class AlwaysSmall(unicode):
    """
    Helper class to cheat ordering
    """
    def __cmp__(self, other):
        return -1


class FileEntry(object):
    """The model for file entries"""

    def __init__(self, name, parent_path, manager, parent_link=False):
        self._manager = manager
        self.state = 'normal'
        self.parent_link = parent_link
        self.name = name

        if parent_link:
            self.lower_name = AlwaysSmall(self.name.lower())
            self.name = AlwaysSmall(name)
            self.path = parent_path
            self.is_dir = True
            self.is_dir_sort = AlwaysSmall(self.lower_name)
        else:
            self.lower_name = self.name.lower()
            self.name = name
            self.path = os.path.join(parent_path, name)
            self.is_dir = os.path.isdir(self.path)
            self.is_dir_sort = not self.is_dir, self.lower_name

        self.parent_path = parent_path
        self.extension = os.path.splitext(self.name)[-1]
        self.extension_sort = self.extension, self.lower_name
        self.is_dir_sort = not self.is_dir, self.lower_name
        self.visible = False

    @property
    def markup(self):
        return self.format(cgi.escape(self.name))

    @property
    def icon_stock_id(self):
        if path.isdir(self.path):
            return 'stock_folder'
        else:
            #TODO: get a real mimetype icon
            return 'text-x-generic'

    @property
    def state_markup(self):
        text = state_text.get(self.state, ' ')
        wrap = '<span weight="ultrabold"><tt>%s</tt></span>'
        return wrap%self.format(text)


    def format(self, text):
        color, b, i = state_style.get(self.state, (None, False, False))
        if color:
            #FIXME to_string is missing on win32
            color = self._manager.file_list.style.lookup_color(color)
            if not on_windows:
                color = color.to_string()
            else:
                color = '#%s%s%s' % (color.red,color.green,color.blue)
        else:
            color = "black"

        if b:
            text = '<b>%s</b>' % text

        if i:
            text = '<i>%s</i>' % text
        return '<span color="%s">%s</span>' % (color, text)


class FilemanagerView(PidaView):

    _columns = [
        Column("icon_stock_id", use_stock=True),
        Column("state_markup", use_markup=True),
        Column("markup", use_markup=True),
        Column("lower_name", visible=False, searchable=True),
        ]

    label_text = _('Files')
    icon_name = 'file-manager'
    key = 'filemanager.list'

    def create_ui(self):
        self._vbox = gtk.VBox()
        self._vbox.show()
        self.create_toolbar()
        self._file_hidden_check_actions = {}
        self._create_file_hidden_check_toolbar()
        self.create_file_list()
        self._clipboard_file = None
        self._fix_paste_sensitivity()
        self.add_main_widget(self._vbox)

    def create_file_list(self):
        self.file_list = ObjectList()
        self.file_list.set_headers_visible(False)
        self.file_list.set_columns(self._columns);
        self.file_list.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        #XXX: real file
        self.file_list.get_treeview().connect('button-press-event',
            self.on_file_button_press_event)
        self.file_list.connect('selection-changed', self.on_selection_changed)
        self.file_list.connect('row-activated', self.on_file_activated)
        self.file_list.connect('right-click', self.on_file_right_click)
        self.entries = {}
        self.update_to_path(self.svc.path)
        self.file_list.show()
        self._vbox.pack_start(self.file_list)
        self._sort_combo = AttrSortCombo(self.file_list,
            [
                ('is_dir_sort', _('Directories First')),
                ('lower_name', _('File Name')),
                ('name', _('Case Sensitive File Name')),
                ('path', _('File Path')),
                ('extension_sort', _('Extension')),
                ('state', _('Version Control Status')),
            ],
            'is_dir_sort')
        self._sort_combo.show()
        self._vbox.pack_start(self._sort_combo, expand=False)
        self.on_selection_changed(self.file_list, None)

    def create_toolbar(self):
        self._uim = gtk.UIManager()
        self._uim.insert_action_group(self.svc.get_action_group(), 0)
        self._uim.add_ui_from_file(get_uidef_path('filemanager-toolbar.xml'))
        self._uim.ensure_update()
        self._toolbar = self._uim.get_toplevels('toolbar')[0]
        self._toolbar.set_style(gtk.TOOLBAR_ICONS)
        self._toolbar.set_icon_size(gtk.ICON_SIZE_MENU)
        self._vbox.pack_start(self._toolbar, expand=False)
        self._toolbar.show_all()

    def add_or_update_file(self, name, basepath, state, select=False,
                           parent_link=False):
        if basepath != self.path and not parent_link:
            return
        entry = self.entries.setdefault(name,
                                        FileEntry(name, basepath, self,
                                                  parent_link=parent_link))
        entry.state = state

        self.show_or_hide(entry, select=select)

    def show_or_hide(self, entry, select=False):
        from operator import and_
        def check(checker):
            if (checker.identifier in self._file_hidden_check_actions) and \
               (self._file_hidden_check_actions[checker.identifier].get_active()):
                return checker(name=entry.name, path=entry.parent_path,
                    state=entry.state, )
            else:
                return True

        if self.svc.opt('show_hidden') or entry.parent_link:
            show = True
        else:
            show = all(check(x)
                        for x in self.svc.features['file_hidden_check'])

        if show:
            if entry.visible:
                self.file_list.update(entry)
            else:
                self.file_list.append(entry)
                entry.visible = True
            if select:
                self.file_list.select(entry)
        else:
            if entry.visible:
                self.file_list.remove(entry)
                entry.visible = False

    def update_to_path(self, new_path=None, select=None):
        if new_path is None:
            new_path = self.path
        else:
            self.path = check_or_home(new_path)

        self.file_list.clear()
        self.entries.clear()

        if self.svc.opt('show_parent'):
            parent = os.path.normpath(os.path.join(new_path, os.path.pardir))
            # skip if we are already on the root
            if parent != new_path:
                self.add_or_update_file(os.pardir, parent, 
                                        'normal', parent_link=True)

        def work(basepath):
            dir_content = listdir(basepath)
            # add all files from vcs and remove the corresponding items 
            # from dir_content
            for item in self.svc.boss.cmd('versioncontrol', 'list_file_states',
              path=self.path):
                if (item[1] == self.path):
                    try:
                        dir_content.remove(item[0])
                    except:
                        pass
                    yield item
            # handle remaining files
            for filename in dir_content:
                if (path.isdir(path.join(basepath, filename))):
                    state = 'normal'
                else:
                    state = 'unknown'
                yield filename, basepath, state

        # wrap add_or_update_file to set select accordingly
        def _add_or_update_file(name, basepath, state):
            self.add_or_update_file(name, basepath, state, select=(name==select))

        GeneratorTask(work, _add_or_update_file).start(self.path)

        self.create_ancest_tree()

    # This is painful, and will always break
    # So use the following method instead
    def update_single_file(self, name, basepath):
        def _update_file(oname, obasepath, state):
            if oname == name and basepath == obasepath:
                if name not in self.entries:
                    self.entries[oname] = FileEntry(oname, obasepath, self)
                self.entries[oname].state = state
                self.show_or_hide(self.entries[oname])
        for lister in self.svc.features['file_lister']:
            GeneratorTask(lister, _update_file).start(self.path)

    def update_single_file(self, name, basepath, select=False):
        if basepath != self.path:
            return
        if name not in self.entries:
            self.entries[name] = FileEntry(name, basepath, self)
            self.show_or_hide(self.entries[name], select=select)

    def update_removed_file(self, filename):
        entry = self.entries.pop(filename, None)
        if entry is not None and entry.visible:
            self.file_list.remove(entry)

    def on_file_button_press_event(self, file_list, event):
        # unselect all rows if user clicked on the empty space below the last
        # row
        if (file_list.get_path_at_pos(int(event.x), int(event.y)) is None):
            file_list.get_selection().unselect_all()
            if (event.button == 3):
                # right click on base directory
                item = FileEntry(os.path.basename(self.path),
                    os.path.dirname(self.path), self)
                self.on_file_right_click(file_list, item, event)
            return True
        else:
            return False

    def create_dir(self, name=None):
        if not name:
            opts = DialogOptions().add('name', label=_("Directory name"), value="")
            create_gtk_dialog(opts, parent=self.svc.boss.window).run()
            name = opts.name
        if name:
            npath = os.path.join(self.path, opts.name)
            if not os.path.exists(npath):
                os.mkdir(npath)
            self.update_single_file(opts.name, self.path, select=True)
             
    def on_file_activated(self, rowitem, fileentry):
        if os.path.exists(fileentry.path):
            if fileentry.is_dir:
                self.svc.browse(fileentry.path)
            else:
                self.svc.boss.cmd('buffer', 'open_file', file_name=fileentry.path)
        else:
            self.update_removed_file(fileentry.name)

    def on_file_right_click(self, ol, item, event=None):
        if item.is_dir:
            self.svc.boss.cmd('contexts', 'popup_menu', context='dir-menu',
                          dir_name=item.path, event=event, filemanager=True) 
        else:
            self.svc.boss.cmd('contexts', 'popup_menu', context='file-menu',
                          file_name=item.path, event=event, filemanager=True)

    def on_selection_changed(self, ol, item):
        for act_name in ['toolbar_copy', 'toolbar_delete']:
            self.svc.get_action(act_name).set_sensitive(item is not None)

    def rename_file(self, old, new, entry):
        print 'renaming', old, 'to' ,new

    def create_ancest_tree(self):
        task = AsyncTask(self._get_ancestors, self._show_ancestors)
        task.start(self.path)

    def _on_act_up_ancestor(self, action, directory):
        self.svc.browse(directory)

    def _show_ancestors(self, ancs):
        toolitem = self.svc.get_action('toolbar_up').get_proxies()[0]
        menu = gtk.Menu()
        for anc in ancs:
            action = gtk.Action(anc, anc, anc, 'directory')
            action.connect('activate', self._on_act_up_ancestor, anc)
            menuitem = action.create_menu_item()
            menu.add(menuitem)
        menu.show_all()
        toolitem.set_menu(menu)

    def _get_ancestors(self, directory):
        ancs = [directory]
        parent = None
        while True:
            parent = os.path.dirname(directory)
            if parent == directory:
                break
            ancs.append(parent)
            directory = parent
        return ancs

    def _on_act_file_hidden_check(self, action, check):
        if (check.scope == filehiddencheck.SCOPE_GLOBAL):
            # global
            active_checker = self.svc.opt('file_hidden_check')
            if (action.get_active()):
                active_checker.append(check.identifier)
            else:
                active_checker.remove(check.identifier)
            self.svc.set_opt('file_hidden_check', active_checker)
        else:
            # project
            if (self.svc.current_project is not None):
                section = self.svc.current_project.options.get('file_hidden_check', {})
                section[check.identifier] = action.get_active()
                self.svc.current_project.options['file_hidden_check'] = section
        self.update_to_path()
    
    def __file_hidden_check_scope_project_set_active(self, action):
        """sets active state of a file hidden check action with
           scope = project
           relies on action name = identifier of checker"""
        if (self.svc.current_project is not None):
            section = self.svc.current_project.options.get('file_hidden_check')
            action.set_active(
              (section is not None) and
              (action.get_name() in section) and
              (section[action.get_name()] == 'True'))
        else:
            action.set_active(False)
        
    
    def refresh_file_hidden_check(self):
        """refreshes active status of actions of project scope checker"""
        for checker in self.svc.features['file_hidden_check']:
            if (checker.scope == filehiddencheck.SCOPE_PROJECT):
                action = self._file_hidden_check_actions[checker.identifier]
                self.__file_hidden_check_scope_project_set_active(action)
    
    def _create_file_hidden_check_toolbar(self):
        self._file_hidden_check_actions = {}
        menu = gtk.Menu()
        separator = gtk.SeparatorMenuItem()
        project_scope_count = 0
        menu.append(separator)
        for checker in self.svc.features['file_hidden_check']:
            action = gtk.ToggleAction(checker.identifier, checker.label,
              checker.label, None)
            # active?
            if (checker.scope == filehiddencheck.SCOPE_GLOBAL):
                action.set_active(
                    checker.identifier in self.svc.opt('file_hidden_check'))
            else:
                self.__file_hidden_check_scope_project_set_active(action)

            action.connect('activate', self._on_act_file_hidden_check, checker)
            self._file_hidden_check_actions[checker.identifier] = action
            menuitem = action.create_menu_item()
            if (checker.scope == filehiddencheck.SCOPE_GLOBAL):
                menu.prepend(menuitem)
            else:
                menu.append(menuitem)
                project_scope_count += 1
        menu.show_all()
        if (project_scope_count == 0):
            separator.hide()
        toolitem = None
        for proxy in self.svc.get_action('toolbar_hidden_menu').get_proxies():
            if (isinstance(proxy, DropDownMenuToolButton)):
                toolitem = proxy
                break
        if (toolitem is not None):
            toolitem.set_menu(menu)

    def get_selected_filename(self):
        fileentry = self.file_list.get_selected()
        if fileentry is not None:
            return fileentry.path

    def copy_clipboard(self):
        current = self.get_selected_filename()
        if os.path.exists(current):
            self._clipboard_file = current
        else:
            self._clipboard_file = None
        self._fix_paste_sensitivity()

    def _fix_paste_sensitivity(self):
        self.svc.get_action('toolbar_paste').set_sensitive(self._clipboard_file
                                                           is not None)

    def paste_clipboard(self):
        newname = os.path.join(self.path, os.path.basename(self._clipboard_file))
        if newname == self._clipboard_file:
            self.svc.error_dlg(_('Cannot copy files to themselves.'))
            return
        if not os.path.exists(self._clipboard_file):
            self.svc.error_dlg(_('Source file has vanished.'))
            return
        if os.path.exists(newname):
            self.svc.error_dlg(_('Destination already exists.'))
            return
        
        task = AsyncTask(self._paste_clipboard, lambda: None)
        task.start()

    def _paste_clipboard(self):
        #XXX: in thread
        newname = os.path.join(self.path, os.path.basename(self._clipboard_file))
        #XXX: GIO?
        if os.path.isdir(self._clipboard_file):
            shutil.copytree(self._clipboard_file, newname)
        else:
            shutil.copy2(self._clipboard_file, newname)

    def remove_path(self, path):
        task = AsyncTask(self._remove_path, lambda: None)
        task.start(path)

    def _remove_path(self, path):
        if os.path.isdir(path):
            shutil.rmtree(path)
        else:
            os.remove(path)
        if path == self._clipboard_file:
            self._clipboard_file = None
            gcall(self._fix_paste_sensitivity)

class FilemanagerEvents(EventsConfig):

    def create(self):
        self.publish(
                'browsed_path_changed',
                'file_renamed')
        
        self.subscribe('file_renamed', self.svc.rename_file)

    def subscribe_all_foreign(self):
        self.subscribe_foreign('project', 'project_switched',
                                     self.svc.on_project_switched)
        self.subscribe_foreign('plugins', 'plugin_started',
            self.on_plugin_started)
        self.subscribe_foreign('plugins', 'plugin_stopped',
            self.on_plugin_stopped);
        self.subscribe_foreign('contexts', 'show-menu',
            self.on_contexts__show_menu)
        self.subscribe_foreign('contexts', 'menu-deactivated',
            self.on_contexts__menu_deactivated)

    def on_plugin_started(self, plugin):
        if (plugin.features.has_foreign('filemanager', 'file_hidden_check')):
            self.svc.refresh_file_hidden_check_menu()
    
    def on_plugin_stopped(self, plugin):
        self.svc.refresh_file_hidden_check_menu()

    def on_contexts__show_menu(self, menu, context, **kw):        
        if (kw.has_key('filemanager')):
            if (context == 'file-menu'):
                self.svc.get_action('delete-file').set_visible(kw['file_name'] is not None)
            else:
                self.svc.get_action('delete-dir').set_visible(
                    kw['dir_name'] != self.svc.get_view().path)
        else:
            self.svc.get_action('delete-file').set_visible(False)
            self.svc.get_action('delete-dir').set_visible(False)            
            self.svc.get_action('browse-for-file').set_visible(
                (kw.has_key('file_name') and kw['file_name'] is not None) or
                (kw.has_key('dir_name') and kw['dir_name'] is not None))

    def on_contexts__menu_deactivated(self, menu, context, **kw):
        if (kw.has_key('filemanager')):
            if (context == 'file-menu'):
                self.svc.get_action('delete-file').set_visible(False)
            else:
                self.svc.get_action('delete-dir').set_visible(False)


class FilemanagerCommandsConfig(CommandsConfig):
    def browse(self, new_path):
        self.svc.browse(new_path)

    def get_browsed_path(self):
        return self.svc.path

    def get_view(self):
        return self.svc.get_view()

    def present_view(self):
        return self.svc.boss.cmd('window', 'present_view',
            view=self.svc.get_view())

    def update_file(self, filename, dirname):
        if dirname == self.svc.get_view().path:
            self.svc.get_view().update_single_file(filename, dirname)

    def update_removed_file(self, filename, dirname):
        if dirname == self.svc.get_view().path:
            self.svc.get_view().update_removed_file(filename)

    def refresh(self):
        self.svc.get_view().update_to_path()


class FilemanagerWindowConfig(WindowConfig):
    key = FilemanagerView.key
    label_text = FilemanagerView.label_text
    description = _("Filebrowser")

class FilemanagerFeatureConfig(FeaturesConfig):

    def create(self):
        self.publish('file_manager')
        self.publish('file_hidden_check')
        self.subscribe('file_hidden_check', self.dot_files)
        self.subscribe('file_hidden_check', self.regex)

    def subscribe_all_foreign(self):
        self.subscribe_foreign('contexts', 'file-menu',
            (self.svc.get_action_group(), 'filemanager-file-menu.xml'))
        self.subscribe_foreign('contexts', 'dir-menu',
            (self.svc.get_action_group(), 'filemanager-dir-menu.xml'))
        self.subscribe_foreign('window', 'window-config',
                               FilemanagerWindowConfig)

    # File Hidden Checks
    @filehiddencheck.fhc(filehiddencheck.SCOPE_GLOBAL, _("Hide Dot-Files"))
    def dot_files(self, name, path, state):
        return len(name) and name[0] != '.'

    @filehiddencheck.fhc(filehiddencheck.SCOPE_GLOBAL, 
        _("Hide by User defined Regular Expression"))
    def regex(self, name, path, state):
        _re = self.svc.opt('hide_regex')
        if not re:
            return True
        else:
            return re.match(_re, name) is None


class FileManagerOptionsConfig(OptionsConfig):
    def create_options(self):
        self.create_option(
                'show_hidden',
                _('Show hidden files'),
                bool,
                True,
                _('Shows hidden files'),
                workspace=True)

        self.create_option(
                'show_parent',
                _('Show parent entry'),
                bool,
                True,
                _('Shows a ".." entry in the filebrowser'))

        self.create_option(
                'file_hidden_check',
                _('Used file hidden checker'),
                list,
                [],
                _('The used file hidden checker'),
                workspace=True)
        
        self.create_option(
                'last_browsed_remember',
                _('Remember last Path'),
                bool,
                True,
                _('Remembers the last browsed path'))
        
        self.create_option(
                'last_browsed',
                _('Last browsed Path'),
                str,
                path.expanduser('~'),
                _('The last browsed path'),
                safe=False,
                workspace=True)
        
        self.create_option(
                'hide_regex',
                _('Hide regex'),
                str,
                '^\.|.*~|.*\.py[co]$',
                _('Hides files that match the regex'))

class FilemanagerDbusConfig(DbusConfig):
    @IEXPORT(in_signature="s")
    def browse(self, path):
        self.svc.browse(path)

    @IEXPORT(out_signature="s")
    def get_browsed_path(self):
        return self.svc.path

    @IEXPORT(in_signature="s")
    def create_dir(self, path):
        self.svc.create_dir(path)

    @IEXPORT()
    def go_current_file(self):
        self.svc.go_current_file()

    @IEXPORT()
    def go_up(self):
        self.svc.go_up()

    @IEXPORT()
    def refresh_file_hidden_check_menu(self):
        self.svc.refresh_file_hidden_check_menu()

    @IEXPORT()
    def present_view(self):
        self.svc.commands.present_view()

    @IEXPORT()
    def refresh(self):
        self.svc.commands.refresh()



class FileManagerActionsConfig(ActionsConfig):

    def create_actions(self):
        self.create_action(
            'delete-file',
            TYPE_NORMAL,
            _('Delete File'),
            _('Delete selected file'),
            gtk.STOCK_DELETE,
            self.on_delete
        )

        self.create_action(
            'browse-for-file',
            TYPE_NORMAL,
            _('Browse the file directory'),
            _('Browse the parent directory of this file'),
            'file-manager',
            self.on_browse_for_file,
        )

        self.create_action(
            'delete-dir',
            TYPE_NORMAL,
            _('Delete Directory'),
            _('Delete selected directory'),
            gtk.STOCK_DELETE,
            self.on_delete
        )

        self.create_action(
            'browse-for-dir',
            TYPE_NORMAL,
            _('Browse the directory'),
            _('Browse the directory'),
            'file-manager',
            self.on_browse_for_dir,
        )

        self.create_action(
            'show_filebrowser',
            TYPE_NORMAL,
            _('Show _file browser'),
            _('Show the file browser view'),
            'file-manager',
            self.on_show_filebrowser,
            '<Shift><Control>f',
            global_=True
        )

        self.create_action(
            'toolbar_up',
            TYPE_MENUTOOL,
            _('Go Up'),
            _('Go to the parent directory'),
            gtk.STOCK_GO_UP,
            self.on_toolbar_up,
            '<Shift><Control>Up',
        )

        self.create_action(
            'toolbar_terminal',
            TYPE_NORMAL,
            _('Open Terminal'),
            _('Open a terminal in this directory'),
            'terminal',
            self.on_toolbar_terminal,
        )

        self.create_action(
            'toolbar_refresh',
            TYPE_NORMAL,
            _('Refresh Directory'),
            _('Refresh the current directory'),
            gtk.STOCK_REFRESH,
            self.on_toolbar_refresh,
        )

        self.create_action(
            'toolbar_search',
            TYPE_NORMAL,
            _('Find in directory'),
            _('Find in directory'),
            gtk.STOCK_FIND,
            self.on_toolbar_find,
        )


        self.create_action(
            'toolbar_projectroot',
            TYPE_NORMAL,
            _('Project Root'),
            _('Browse the root of the current project'),
            'user-home',
            self.on_toolbar_projectroot,
        )

        self.create_action(
            'toolbar_create_dir',
            TYPE_NORMAL,
            _('Create Directory'),
            _('Create a new directory'),
            gtk.STOCK_DIRECTORY,
            self.on_toolbar_create_dir,
        )

        self.create_action(
            'toolbar_home',
            TYPE_NORMAL,
            _('Home'),
            _('Browse your home directory'),
            'user-home',
            self.on_toolbar_home,
        )

        self.create_action(
            'toolbar_current_file',
            TYPE_NORMAL,
            _('Current Directory'),
            _('Browse directory of current file'),
            gtk.STOCK_GOTO_FIRST,
            self.on_toolbar_current_file,
        )


        self.create_action(
            'toolbar_copy',
            TYPE_NORMAL,
            _('Copy File'),
            _('Copy selected file to the clipboard'),
            gtk.STOCK_COPY,
            self.on_toolbar_copy,
        )

        self.create_action(
            'toolbar_paste',
            TYPE_NORMAL,
            _('Paste File'),
            _('Paste selected file from the clipboard'),
            gtk.STOCK_PASTE,
            self.on_toolbar_paste,
        )

        self.create_action(
            'toolbar_delete',
            TYPE_NORMAL,
            _('Delete File'),
            _('Delete the selected file'),
            gtk.STOCK_DELETE,
            self.on_delete,
        )
        self.create_action(
            'toolbar_toggle_hidden',
            TYPE_TOGGLE,
            _('Show Hidden Files'),
            _('Show hidden files'),
            gtk.STOCK_SELECT_ALL,
            self.on_toggle_hidden,
        )
        self.create_action(
            'toolbar_hidden_menu',
            TYPE_DROPDOWNMENUTOOL,
            None,
            _('Setup which kind of files should be hidden'),
            None,
            None,
        )


    def on_toolbar_find(self, action):
        self.svc.boss.get_service('grepper').show_grepper(self.svc.path)

    def on_browse_for_file(self, action):
        new_path = path.dirname(action.contexts_kw['file_name'])
        self.svc.cmd('browse', new_path=new_path)
        self.svc.cmd('present_view')


    def on_browse_for_dir(self, action):
        new_path = action.contexts_kw['dir_name']
        self.svc.cmd('browse', new_path=new_path)
        self.svc.cmd('present_view')

    def on_show_filebrowser(self, action):
        self.svc.cmd('present_view')

    def on_toolbar_create_dir(self, action):
        self.svc.create_dir()

    def on_toolbar_up(self, action):
        self.svc.go_up()

    def on_toolbar_home(self, action):
        self.svc.cmd('browse', new_path=homedir)
    
    def on_toolbar_current_file(self, action):
        self.svc.go_current_file()

    def on_toolbar_terminal(self, action):
        self.svc.boss.cmd('commander','execute_shell', cwd=self.svc.path)

    def _on_menu_down(self, menu, action):
        action.set_active(False)
        print "down"
    
    def on_toggle_hidden(self, action):
        self.svc.set_opt('show_hidden', action.get_active())
        self.on_toolbar_refresh(action)

    def on_toolbar_refresh(self, action):
        self.svc.get_view().update_to_path()

    def on_toolbar_projectroot(self, action):
        self.svc.browse(self.svc.current_project.source_directory)

    def on_toolbar_copy(self, action):
        self.svc.get_view().copy_clipboard()

    def on_toolbar_paste(self, action):
        self.svc.get_view().paste_clipboard()

    def on_delete(self, action):
        current = self.svc.get_view().get_selected_filename()
        if current is not None:
            if self.svc.yesno_dlg(
                _('Are you sure you want to delete the selected file: %s?'
                % current)
            ):
                self.svc.get_view().remove_path(current)

                if not self.svc.boss.get_service('filewatcher').started:
                    self.svc.get_view().update_to_path()



# Service class
class Filemanager(Service):
    """the Filemanager service"""

    options_config = FileManagerOptionsConfig
    features_config = FilemanagerFeatureConfig
    events_config = FilemanagerEvents
    dbus_config = FilemanagerDbusConfig
    commands_config = FilemanagerCommandsConfig
    actions_config = FileManagerActionsConfig

    def pre_start(self):
        self.path = check_or_home(self.opt('last_browsed'))
        self.current_project = None
        self.file_view = FilemanagerView(self)


    def start(self):
        self.on_project_switched(self.current_project)
        self.emit('browsed_path_changed', path=self.path)
        self.get_action('toolbar_toggle_hidden').set_active(
                self.opt('show_hidden'))
        # FIXME: WTF WTF WTF WTF is fixing this the empty icons. 
        # I don't get it ! and why the hack is this happening
        for x in self.actions.list_actions():
            for p in x.get_proxies():
                if hasattr(x.props, "stock_id") and \
                   hasattr(p, "set_stock_id") and \
                   x.props.stock_id is not None:
                    p.set_stock_id(x.props.stock_id)

    def get_view(self):
        return self.file_view
   
    def browse(self, new_path, select=None):
        new_path = path.abspath(new_path)

        if new_path == self.path:
            return
        else:
            self.path = new_path
            self.set_opt('last_browsed', new_path)
            self.file_view.update_to_path(new_path, select=select)
        self.emit('browsed_path_changed', path=new_path)

    def create_dir(self, name=None):
        self.file_view.create_dir(name=name)

    def go_current_file(self):
        cd = self.boss.cmd('buffer', 'get_current')
        if cd and not cd.is_new:
            self.browse(cd.directory)

    def go_up(self):
        oldname = path.basename(self.path)
        dir = path.dirname(self.path)
        if not dir:
            dir = "/" #XXX: unportable, what about non-unix
        self.browse(dir, select=oldname)

    def rename_file(self, old, new, basepath):
        pass

    def refresh_file_hidden_check_menu(self):
        self.get_view()._create_file_hidden_check_toolbar()
    
    def on_project_switched(self, project):
        self.current_project = project
        self.get_action('toolbar_projectroot').set_sensitive(project is not None)
        if self.file_view:
            self.file_view.refresh_file_hidden_check()

# Required Service attribute for service loading
Service = Filemanager



# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.