[Thunar-workers] CVS: design/ui/spatial .cvsignore, NONE, 1.1 Main.py, NONE, 1.1 ThunarFileInfo.py, NONE, 1.1 ThunarMimeDatabase.py, NONE, 1.1 ThunarModel.py, NONE, 1.1 ThunarParentSelector.py, NONE, 1.1 ThunarStatusBar.py, NONE, 1.1 ThunarView.py, NONE, 1.1 ThunarWindow.py, NONE, 1.1 thunar.sh, NONE, 1.1 thunar.ui, NONE, 1.1

Benedikt Meurer benny at xfce.org
Sun Feb 20 23:09:58 CET 2005


Update of /var/cvs/thunar/design/ui/spatial
In directory espresso.foo-projects.org:/tmp/cvs-serv8443/spatial

Added Files:
	.cvsignore Main.py ThunarFileInfo.py ThunarMimeDatabase.py 
	ThunarModel.py ThunarParentSelector.py ThunarStatusBar.py 
	ThunarView.py ThunarWindow.py thunar.sh thunar.ui 
Log Message:
2005-02-20	Benedikt Meurer <benny at xfce.org>

	* spatial/: Imported an initial prototype for a possible spatial
	  Thunar User Interface. This has to be decided later.




--- NEW FILE: .cvsignore ---
*.pyc
.*.swp

--- NEW FILE: Main.py ---
#!/usr/bin/env python
# vi:set ts=4 sw=4 et ai nocindent:
#
# $Id: Main.py,v 1.1 2005/02/20 22:09:55 benny Exp $
#
# Copyright (c) 2005 Benedikt Meurer <benny at xfce.org>
# All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
#

import os

import pygtk
pygtk.require('2.0')
import gtk

from ThunarFileInfo import ThunarFileInfo
from ThunarWindow import ThunarWindow

class Main:
    def __init__(self):
        self.window = ThunarWindow(ThunarFileInfo(os.getcwd()))

    def run(self):
        self.window.show()
        gtk.main()


if __name__ == "__main__":
    main = Main()
    main.run()


--- NEW FILE: ThunarFileInfo.py ---
#!/usr/bin/env python
# vi:set ts=4 sw=4 et ai nocindent:
#
# $Id: ThunarFileInfo.py,v 1.1 2005/02/20 22:09:55 benny Exp $
#
# Copyright (c) 2005 Benedikt Meurer <benny at xfce.org>
# All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
#

import dircache, os, stat, time

import pygtk
pygtk.require('2.0')
import gobject
import gtk

from ThunarMimeDatabase import ThunarMimeDatabase

class ThunarFileInfo(gobject.GObject):
    def __init__(self, path):
        gobject.GObject.__init__(self)
        self.mimedb = ThunarMimeDatabase()

        # build up a normalized path
        self.path = ''
        for name in path.split('/'):
            if name:
                self.path += '/' + name
        if not self.path:
            self.path = '/'

        self.stat = os.stat(self.path)


    def get_mime_info(self):
        return self.mimedb.match(self.path)

    def get_name(self):
        name = os.path.basename(self.path)
        if not name:
            name = '/'
        return name

    def get_path(self):
        return self.path

    def get_visible_name(self):
        name = self.get_name()
        if name == '/':
            name = 'Filesystem'
        return name

    def get_size(self):
        return _humanize_size(self.stat[stat.ST_SIZE])

    def get_mtime(self):
        return time.strftime('%x %X', time.localtime(self.stat[stat.ST_MTIME]))

    def is_directory(self):
        return stat.S_ISDIR(self.stat[stat.ST_MODE])

    def get_parent(self):
        if self.path == '/':
            return None
        else:
            return ThunarFileInfo(self.path[0:self.path.rfind('/')])



def _humanize_size(size):
    if size > 1024 * 1024 * 1024:
        return '%.1f GB' % (size / (1024 * 1024 * 1024))
    elif size > 1024 * 1024:
        return '%.1f MB' % (size / (1024 * 1024))
    elif size > 1024:
        return '%.1f KB' % (size / 1024)
    else:
        return '%d B' % size




--- NEW FILE: ThunarMimeDatabase.py ---
#!/usr/bin/env python
# vi:set ts=4 sw=4 et ai nocindent:
#
# $Id: ThunarMimeDatabase.py,v 1.1 2005/02/20 22:09:55 benny Exp $
#
# Copyright (c) 2005 Benedikt Meurer <benny at xfce.org>
# All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
#

import pygtk
pygtk.require('2.0')
import gobject
import gtk

import rox, rox.mime


class ThunarMimeDatabase:
    def match(self, path):
        type = rox.mime.get_type(path)
        return ThunarMimeInfo(type)


class ThunarMimeInfo:
    def __init__(self, type):
        self.theme = gtk.icon_theme_get_default()
        self.type = type

    def get_comment(self):
        return self.type.get_comment()

    def render_icon(self, size):
        type = '%s' % self.type
        try:
            name = 'mime-' + type.replace('/', ':')
            icon = self.theme.load_icon(name, size, 0)
        except gobject.GError:
            try:
                name = 'gnome-mime-' + type.replace('/', '-')
                icon = self.theme.load_icon(name, size, 0)
            except gobject.GError:
                try:
                    name = 'mime-' + type.split('/')[0]
                    icon = self.theme.load_icon(name, size, 0)
                except gobject.GError:
                    try:
                        name = 'gnome-mime-' + type.split('/')[0]
                        icon = self.theme.load_icon(name, size, 0)
                    except gobject.GError:
                        name = 'gnome-mime-application-octet-stream'
                        icon = self.theme.load_icon(name, size, 0)
        return icon

--- NEW FILE: ThunarModel.py ---
#!/usr/bin/env python
# vi:set ts=4 sw=4 et ai nocindent:
#
# $Id: ThunarModel.py,v 1.1 2005/02/20 22:09:55 benny Exp $
#
# Copyright (c) 2005 Benedikt Meurer <benny at xfce.org>
# All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
#

import dircache, os

import pygtk
pygtk.require('2.0')
import gobject
import gtk

from ThunarFileInfo import ThunarFileInfo

class ThunarModel(gtk.ListStore):
    COLUMN_ICON     = 0
    COLUMN_NAME     = 1
    COLUMN_SIZE     = 2
    COLUMN_MTIME    = 3
    COLUMN_KIND     = 4
    COLUMN_FILEINFO = 5

    def __init__(self, dir_info):
        gtk.ListStore.__init__(self, gtk.gdk.Pixbuf,\
                               gobject.TYPE_STRING, \
                               gobject.TYPE_STRING, \
                               gobject.TYPE_STRING, \
                               gobject.TYPE_STRING, \
                               ThunarFileInfo)

        for name in dircache.listdir(dir_info.get_path()):
            if name.startswith('.'):
                continue

            file_info = ThunarFileInfo(os.path.join(dir_info.get_path(), name))
            mime_info = file_info.get_mime_info()

            self.append([
                mime_info.render_icon(16),
                file_info.get_visible_name(),
                file_info.get_size(),
                file_info.get_mtime(),
                mime_info.get_comment(),
                file_info
            ])




--- NEW FILE: ThunarParentSelector.py ---
#!/usr/bin/env python
# vi:set ts=4 sw=4 et ai nocindent:
#
# $Id: ThunarParentSelector.py,v 1.1 2005/02/20 22:09:55 benny Exp $
#
# Copyright (c) 2005 Benedikt Meurer <benny at xfce.org>
# All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
#

import pygtk
pygtk.require('2.0')
import gobject
import gtk

from ThunarFileInfo import ThunarFileInfo

signals_registered = False

class ThunarParentSelector(gtk.Button):
    def __init__(self, dir_info):
        gtk.Button.__init__(self)

        # register signals
        global signals_registered
        if not signals_registered:
            gobject.signal_new('selected', self, gobject.SIGNAL_RUN_LAST, \
                               gobject.TYPE_NONE, [ThunarFileInfo])
            signals_registered = True

        self.unset_flags(gtk.CAN_FOCUS)
        self.set_relief(gtk.RELIEF_NONE)
        self.connect('clicked', lambda self: self._selector_clicked())
        self.file_info = dir_info

        box = gtk.HBox(False, 6)
        self.add(box)
        box.show()

        mime_info = self.file_info.get_mime_info()
        self.image = gtk.Image()
        self.image.set_from_pixbuf(mime_info.render_icon(16))
        box.pack_start(self.image, False, False, 0)
        self.image.show()

        self.label = gtk.Label(self.file_info.get_visible_name())
        box.pack_start(self.label, False, False, 0)
        self.label.show()

        arrow = gtk.Arrow(gtk.ARROW_DOWN, gtk.SHADOW_NONE)
        box.pack_start(arrow, False, False, 0)
        arrow.show()


    def _popup_pos(self, menu):
        menu_w, menu_h = menu.size_request()
        self_w, self_h = self.size_request()

        x0, y0 = self.translate_coordinates(self.get_toplevel(), 0, 0)

        x, y = self.window.get_position()

        y -= menu_h - self_h
        y += y0
        x += x0

        return (x, y, True)


    def _selector_clicked(self):
        first = None
        menu = gtk.Menu()
        file_info = self.file_info
        while file_info:
            mime_info = file_info.get_mime_info()
            name = file_info.get_visible_name()
            icon = mime_info.render_icon(16)

            image = gtk.Image()
            image.set_from_pixbuf(icon)

            item = gtk.ImageMenuItem(name)
            item.set_image(image)
            item.set_data('info', file_info)
            item.connect('activate', lambda item: self.emit('selected', item.get_data('info')))
            menu.prepend(item)
            item.show()
            if not first: first = item

            file_info = file_info.get_parent()

        loop = gobject.MainLoop()

        menu.connect('deactivate', lambda menu, loop: loop.quit(), loop)

        menu.grab_add()
        menu.popup(None, None, lambda menu: self._popup_pos(menu), 0, gtk.get_current_event_time())
        menu.select_item(first)
        loop.run()
        menu.grab_remove()


--- NEW FILE: ThunarStatusBar.py ---
#!/usr/bin/env python
# vi:set ts=4 sw=4 et ai nocindent:
#
# $Id: ThunarStatusBar.py,v 1.1 2005/02/20 22:09:55 benny Exp $
#
# Copyright (c) 2005 Benedikt Meurer <benny at xfce.org>
# All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
#

import pygtk
pygtk.require('2.0')
import gobject
import gtk

from ThunarFileInfo import ThunarFileInfo
from ThunarParentSelector import ThunarParentSelector

signals_registered = False

class ThunarStatusBar(gtk.Statusbar):
    def __init__(self, dir_info):
        gtk.Statusbar.__init__(self)

        # register signals
        global signals_registered
        if not signals_registered:
            gobject.signal_new('selected', self, gobject.SIGNAL_RUN_LAST, \
                               gobject.TYPE_NONE, [ThunarFileInfo])
            signals_registered = True

        frame = gtk.Frame()
        shadow_type = self.style_get_property('shadow_type')
        frame.set_property('shadow_type', shadow_type)
        self.pack_start(frame, False, False, 0)
        self.reorder_child(frame, 0)
        frame.show()

        selector = ThunarParentSelector(dir_info)
        selector.connect('selected', lambda widget, info: self.emit('selected', info))
        frame.add(selector)
        selector.show()

--- NEW FILE: ThunarView.py ---
#!/usr/bin/env python
# vi:set ts=4 sw=4 et ai nocindent:
#
# $Id: ThunarView.py,v 1.1 2005/02/20 22:09:55 benny Exp $
#
# Copyright (c) 2005 Benedikt Meurer <benny at xfce.org>
# All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
#

import pygtk
pygtk.require('2.0')
import gobject
import gtk

from ThunarFileInfo import ThunarFileInfo
from ThunarModel import ThunarModel

signals_registered = False

class ThunarView(gtk.TreeView):
    def __init__(self, dir_info):
        gtk.TreeView.__init__(self)

        # register signals
        global signals_registered
        if not signals_registered:
            gobject.signal_new('selected', self, gobject.SIGNAL_RUN_LAST, \
                               gobject.TYPE_NONE, [ThunarFileInfo])
            signals_registered = True

        self.set_model(ThunarModel(dir_info))

        column = gtk.TreeViewColumn('Name')
        renderer = gtk.CellRendererPixbuf()
        column.pack_start(renderer, False)
        column.add_attribute(renderer, 'pixbuf', ThunarModel.COLUMN_ICON)
        renderer = gtk.CellRendererText()
        column.pack_start(renderer, True)
        column.add_attribute(renderer, 'text', ThunarModel.COLUMN_NAME)
        self.append_column(column)
        self.set_expander_column(column)

        column = gtk.TreeViewColumn('Size')
        renderer = gtk.CellRendererText()
        column.pack_start(renderer, False)
        column.add_attribute(renderer, 'text', ThunarModel.COLUMN_SIZE)
        self.append_column(column)

        column = gtk.TreeViewColumn('Modified')
        renderer = gtk.CellRendererText()
        column.pack_start(renderer, False)
        column.add_attribute(renderer, 'text', ThunarModel.COLUMN_MTIME)
        self.append_column(column)

        column = gtk.TreeViewColumn('Kind')
        renderer = gtk.CellRendererText()
        column.pack_start(renderer, False)
        column.add_attribute(renderer, 'text', ThunarModel.COLUMN_KIND)
        self.append_column(column)

        self.set_rules_hint(True)
        self.set_headers_clickable(True)

        self.connect('row-activated', lambda tree, path, column: tree._activated(path))


    def _activated(self, path):
        iter = self.get_model().get_iter(path)
        info = self.get_model().get(iter, ThunarModel.COLUMN_FILEINFO)[0]
        if info.is_directory():
            self.emit('selected', info)

--- NEW FILE: ThunarWindow.py ---
#!/usr/bin/env python
# vi:set ts=4 sw=4 et ai nocindent:
#
# $Id: ThunarWindow.py,v 1.1 2005/02/20 22:09:55 benny Exp $
#
# Copyright (c) 2005 Benedikt Meurer <benny at xfce.org>
# All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
#

import weakref, gc

import pygtk
pygtk.require('2.0')
import gtk

from ThunarStatusBar import ThunarStatusBar
from ThunarView import ThunarView

windows = weakref.WeakValueDictionary()

class ThunarWindow(gtk.Window):
    def destroyed(self):
        del windows[self.dir_info.get_path()] 
        gc.collect()
        if len(windows) == 0:
            gtk.main_quit()

    def __init__(self, dir_info):
        gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
        self.connect('destroy', lambda self: self.destroyed())

        global windows
        self.dir_info = dir_info
        windows[dir_info.get_path()] = self

        self.set_title(dir_info.get_visible_name())
        self.set_default_size(400,350)

        action_group = gtk.ActionGroup('thunar-window')
        action_group.add_actions([
          ('file-menu', None, '_File'),
          ('close-parent-folders', None, 'Close _Parent Folders', '<Control><Shift>W', None, lambda ign, self: self._close_parent_folders()),
          ('close-window', gtk.STOCK_CLOSE, '_Close', '<Control>W', None, lambda ign, self: self.destroy()),
        ], self)
        action_group.add_actions([
          ('window-menu', None, '_Window'),
        ], self)
        action_group.add_actions([
          ('help-menu', None, '_Help'),
          ('contents', gtk.STOCK_HELP, '_Contents', 'F1'),
          ('report-bug', None, '_Report bug'),
          ('about', gtk.STOCK_DIALOG_INFO, '_About'),
        ], self)

        self.ui_manager = gtk.UIManager()
        self.ui_manager.insert_action_group(action_group, 0)
        self.ui_manager.add_ui_from_file('thunar.ui')
        self.add_accel_group(self.ui_manager.get_accel_group())

        main_vbox = gtk.VBox(False, 0)
        self.add(main_vbox)
        main_vbox.show()

        menu_bar = self.ui_manager.get_widget('/main-menu')
        main_vbox.pack_start(menu_bar, False, False, 0)
        menu_bar.show()

        swin = gtk.ScrolledWindow(None, None)
        swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        main_vbox.pack_start(swin, True, True, 0)
        swin.show()

        self.view = ThunarView(dir_info)
        self.view.connect('selected', lambda widget, info: self.open_dir(info))
        swin.add(self.view)
        self.view.show()

        self.status_bar = ThunarStatusBar(dir_info)
        self.status_bar.connect('selected', lambda widget, info: self.open_dir(info))
        main_vbox.pack_start(self.status_bar, False, False, 0)
        self.status_bar.show()


    def _close_parent_folders(self):
        dir_info = self.dir_info.get_parent()
        while dir_info:
            if windows.has_key(dir_info.get_path()):
                windows[dir_info.get_path()].destroy()
            dir_info = dir_info.get_parent()


    def open_dir(self, dir_info):
        gc.collect()
        try:
            window = windows[dir_info.get_path()]
            window.present()
        except:
            window = ThunarWindow(dir_info)
            window.show()

--- NEW FILE: thunar.sh ---
#!/bin/sh
# vi:set ts=2 sw=2 et ai:
#
# $Id: thunar.sh,v 1.1 2005/02/20 22:09:55 benny Exp $
#
# Copyright (c) 2005 Benedikt Meurer <benny at xfce.org>
# All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
#

exec python Main.py

--- NEW FILE: thunar.ui ---
<?xml version="1.0" encoding="UTF-8"?>

<!--
  vi:set ts=2 sw=2 et ai nocindent:

  $Id: thunar.ui,v 1.1 2005/02/20 22:09:55 benny Exp $

  Copyright (c) 2005 Benedikt Meurer <benny at xfce.org>

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2, or (at your option)
  any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  02111-1307, USA.
-->

<ui>
  <menubar name="main-menu">
    <menu action="file-menu">
      <menuitem action="close-parent-folders" />
      <menuitem action="close-window" />
    </menu>

    <menu action="window-menu">
    </menu>

    <menu action="help-menu">
      <menuitem action="contents" />
      <menuitem action="report-bug" />
      <menuitem action="about" />
    </menu>
  </menubar>
</ui>




More information about the Thunar-workers mailing list