diff --git a/ui/ChangeLog b/ui/ChangeLog
index fd55297d5d091fa85e05d5164ff2dd3355d646c8..f63a30b4cbcc8d6638e130bb82f05873f0b289e9 100644
--- a/ui/ChangeLog
+++ b/ui/ChangeLog
@@ -1,3 +1,16 @@
+2005-03-06	Benedikt Meurer <benny@xfce.org>
+
+	* ThunarFileInfo.py, ThunarImageLoader.py, ThunarMimeDatabase.py: Add
+	  a separate image loader class with caching.
+	* ThunarWindow.py, ThunarPathBar.py: Rename the ThunarHistory class
+	  to ThunarPathBar.
+	* ThunarBookmarksPane.py: Re-Add the 'Desktop' bookmark.
+	* ThunarMimeDatabase.py, ThunarFileInfo.py: Add caching for the MIME
+	  database.
+	* ThunarFileInfo.py: Support loading of existing thumbnails.
+	* ThunarPropertiesDialog.py: Connect the 'Text view' in the
+	  'Permissions' tab.
+
 2005-03-06	Benedikt Meurer <benny@xfce.org>
 
 	* ThunarWindow.py: Make the GtkFileChooser-like layout the default.
diff --git a/ui/ThunarBookmarksPane.py b/ui/ThunarBookmarksPane.py
index 17d0df2ae0e845869386b565271eedf0ebf4338e..168e9af32c3d3f0b78810bf5a9ccb64e06cfd382 100644
--- a/ui/ThunarBookmarksPane.py
+++ b/ui/ThunarBookmarksPane.py
@@ -65,7 +65,7 @@ class ThunarBookmarksPane(gtk.TreeView):
 
         home = os.getenv('HOME')
 
-        for path in [home, '/']:
+        for path in [home, os.path.join(home, 'Desktop'), '/']:
             try:
                 info = ThunarFileInfo(path)
                 self.model.append([info.get_visible_name(), info.render_icon(self.ICON_SIZE), info])
diff --git a/ui/ThunarFileInfo.py b/ui/ThunarFileInfo.py
index 7d67a0fa54e277dc84595d9f56eb5d99540f0460..a4c38fe5e4c33995bb4fc3e0891cb371d173d4d2 100644
--- a/ui/ThunarFileInfo.py
+++ b/ui/ThunarFileInfo.py
@@ -29,12 +29,14 @@ pygtk.require('2.0')
 import gobject
 import gtk
 
-from ThunarMimeDatabase import ThunarMimeDatabase
+import ThunarImageLoader
+
+import ThunarMimeDatabase
 
 class ThunarFileInfo(gobject.GObject):
     def __init__(self, path):
         gobject.GObject.__init__(self)
-        self.mimedb = ThunarMimeDatabase()
+        self.mimedb = ThunarMimeDatabase.get_default()
 
         # build up a normalized path
         self.path = ''
@@ -50,21 +52,34 @@ class ThunarFileInfo(gobject.GObject):
             self.stat = os.lstat(self.path)
 
 
+    def __try_thumbnail(self, size):
+        import md5
+        uri = 'file://' + self.path
+        name = md5.new(uri).hexdigest() + '.png'
+        path = os.path.join(os.getenv('HOME'), '.thumbnails', 'normal', name)
+        return gtk.gdk.pixbuf_new_from_file_at_size(path, size, size)
+
+
     def render_icon(self, size):
-        theme = gtk.icon_theme_get_default()
+        loader = ThunarImageLoader.get_default()
         icon = None
         try:
-            if self.is_home(): icon = theme.load_icon('gnome-fs-home', size, 0)
+            if self.is_home(): icon = loader.load_icon('gnome-fs-home', size)
         except:
             pass
         try:
-            if not icon and self.is_desktop(): icon = theme.load_icon('gnome-fs-desktop', size, 0)
+            if not icon and self.is_desktop(): icon = loader.load_icon('gnome-fs-desktop', size)
         except:
             pass
         try:
-            if not icon and self.path == '/': icon = theme.load_icon('gnome-dev-harddisk', size, 0)
+            if not icon and self.path == '/': icon = loader.load_icon('gnome-dev-harddisk', size)
         except:
             pass
+        if not icon:
+            try:
+                icon = self.__try_thumbnail(size)
+            except:
+                pass
         if not icon:
             icon = self.get_mime_info().render_icon(size)
         return icon
diff --git a/ui/ThunarImageLoader.py b/ui/ThunarImageLoader.py
new file mode 100644
index 0000000000000000000000000000000000000000..daf1bfa9011adeeb7681b10ca4b1ca8d00d9b0a2
--- /dev/null
+++ b/ui/ThunarImageLoader.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+# vi:set ts=4 sw=4 et ai nocindent:
+#
+# $Id$
+#
+# Copyright (c) 2005 Benedikt Meurer <benny@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
+
+__ALL__ = [ 'get_default' ]
+
+
+default_loader = None
+def get_default():
+    global default_loader
+    if not default_loader:
+        default_loader = ThunarImageLoader()
+    return default_loader
+
+    
+class ThunarImageLoader:
+    def __init__(self):
+        self.__theme = gtk.icon_theme_get_default()
+        self.__cache = {}
+
+
+    def load_icon(self, name, size):
+        key = '%s@%sx%s' % (name, size, size)
+        if self.__cache.has_key(key):
+            icon = self.__cache[key]
+        else:
+            icon = self.__theme.load_icon(name, size, 0)
+            self.__cache[key] = icon
+        return icon
diff --git a/ui/ThunarMimeDatabase.py b/ui/ThunarMimeDatabase.py
index 5fcf3e003652465c112c54506e579bdfdae6b63d..277ea31638745dc2b7b4e7e793fcdb16f44b679e 100644
--- a/ui/ThunarMimeDatabase.py
+++ b/ui/ThunarMimeDatabase.py
@@ -29,46 +29,73 @@ import gtk
 
 import rox, rox.mime
 
+import ThunarImageLoader
+
+
+__ALL__ = [ 'get_default' ]
+
+
+default_database = None
+def get_default():
+    global default_database
+    if not default_database:
+        default_database = ThunarMimeDatabase()
+    return default_database
+
+
 
 class ThunarMimeDatabase:
+    def __init__(self):
+        self.__cache = {}
+
+
     def match(self, path):
         type = rox.mime.get_type(path)
-        return ThunarMimeInfo(type)
+        name = '%s' % type
+        if self.__cache.has_key(name):
+            type = self.__cache[name]
+        else:
+            type = ThunarMimeInfo(type)
+            self.__cache[name] = type
+        return type
+
 
 
 class ThunarMimeInfo:
     def __init__(self, type):
-        self.theme = gtk.icon_theme_get_default()
-        self.type = type
+        self.__loader = ThunarImageLoader.get_default()
+        self.__type = type
+
 
     def get_comment(self):
-        return self.type.get_comment()
+        return self.__type.get_comment()
+
 
     def render_icon(self, size):
-        type = '%s' % self.type
+        type = '%s' % self.__type
         try:
             name = 'mime-' + type.replace('/', ':')
-            icon = self.theme.load_icon(name, size, 0)
+            icon = self.__loader.load_icon(name, size)
         except gobject.GError:
             try:
                 name = 'gnome-mime-' + type.replace('/', '-')
-                icon = self.theme.load_icon(name, size, 0)
+                icon = self.__loader.load_icon(name, size)
             except gobject.GError:
                 try:
                     name = 'mime-' + type.split('/')[0]
-                    icon = self.theme.load_icon(name, size, 0)
+                    icon = self.__loader.load_icon(name, size)
                 except gobject.GError:
                     try:
                         name = 'gnome-mime-' + type.split('/')[0]
-                        icon = self.theme.load_icon(name, size, 0)
+                        icon = self.__loader.load_icon(name, size)
                     except gobject.GError:
                         try:
                             name = 'mime-application:octet-stream'
-                            icon = self.theme.load_icon(name, size, 0)
+                            icon = self.__loader.load_icon(name, size)
                         except gobject.GError:
                             try:
                                 name = 'gnome-mime-application-octet-stream'
-                                icon = self.theme.load_icon(name, size, 0)
+                                icon = self.__loader.load_icon(name, size)
                             except gobject.GError:
                                 icon = gtk.gdk.pixbuf_new_from_file_at_size('fallback.svg', size, size)
         return icon
diff --git a/ui/ThunarHistory.py b/ui/ThunarPathBar.py
similarity index 96%
rename from ui/ThunarHistory.py
rename to ui/ThunarPathBar.py
index 6c07e0cde921f498371f717a9d07375ad54eb407..39936435a9fda61380083e0314714b13e4093a12 100644
--- a/ui/ThunarHistory.py
+++ b/ui/ThunarPathBar.py
@@ -31,7 +31,7 @@ import gtk
 
 from ThunarFileInfo import ThunarFileInfo
 
-class ThunarHistory(gtk.HBox):
+class ThunarPathBar(gtk.HBox):
     def __init__(self):
         gtk.HBox.__init__(self)
         self.set_spacing(2)
@@ -122,8 +122,8 @@ class ThunarHistory(gtk.HBox):
 
 
 
-gobject.type_register(ThunarHistory)
-gobject.signal_new('directory-changed', ThunarHistory, \
+gobject.type_register(ThunarPathBar)
+gobject.signal_new('directory-changed', ThunarPathBar, \
                    gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, \
                    [ThunarFileInfo])
 
diff --git a/ui/ThunarPropertiesDialog.py b/ui/ThunarPropertiesDialog.py
index 8299cfaf6ad78f4af2b0faf10ab2f6469ae19512..ebd288cfa68bf5e0ed0633bf1ec1320fdff1a0ca 100644
--- a/ui/ThunarPropertiesDialog.py
+++ b/ui/ThunarPropertiesDialog.py
@@ -408,7 +408,7 @@ class ThunarPropertiesDialog(gtk.Dialog):
         table.attach(label, 0, 1, row, row + 1, gtk.FILL, gtk.FILL)
         label.show()
 
-        label = gtk.Label('-rw-r--r--')
+        label = gtk.Label(info.get_permissions())
         label.set_alignment(0.0, 0.5)
         table.attach(label, 1, 4, row, row + 1, gtk.EXPAND | gtk.FILL, gtk.FILL)
         label.show()
diff --git a/ui/ThunarWindow.py b/ui/ThunarWindow.py
index 69a6bfb9e20a65655078a53f0b97f1057b5e0c69..f24eb9b868d61b481f9ab080d7aa3c15fd2e1cff 100644
--- a/ui/ThunarWindow.py
+++ b/ui/ThunarWindow.py
@@ -29,7 +29,7 @@ pygtk.require('2.0')
 import gtk
 
 from ThunarModel import ThunarModel
-from ThunarHistory import ThunarHistory
+from ThunarPathBar import ThunarPathBar
 from ThunarFileInfo import ThunarFileInfo
 from ThunarListView import ThunarListView
 from ThunarColumnsView import ThunarColumnsView
@@ -165,11 +165,11 @@ class ThunarWindow(gtk.Window):
         self.main_hbox.pack2(vbox, True, False)
         vbox.show()
 
-        self.history = ThunarHistory()
-        self.history.set_info(self.info)
-        self.history.connect('directory-changed', lambda history, info: self._action_open_dir(info))
-        vbox.pack_start(self.history, False, False, 0)
-        self.history.show()
+        self.pathbar = ThunarPathBar()
+        self.pathbar.set_info(self.info)
+        self.pathbar.connect('directory-changed', lambda history, info: self._action_open_dir(info))
+        vbox.pack_start(self.pathbar, False, False, 0)
+        self.pathbar.show()
 
         self.swin = gtk.ScrolledWindow(None, None)
         self.swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
@@ -227,10 +227,10 @@ class ThunarWindow(gtk.Window):
         value = self.action_group.get_action('view-gtkfilechooser').get_active()
         self.sidepane.set_gtkfilechooser_like(value)
         if value:
-            self.history.show()
+            self.pathbar.show()
             self.main_hbox.set_border_width(6)
         else:
-            self.history.hide()
+            self.pathbar.hide()
             self.main_hbox.set_border_width(0)
 
 
@@ -300,7 +300,7 @@ class ThunarWindow(gtk.Window):
         self.sidepane.select_by_info(info)
         self.sidepane.handler_unblock(self.sidepane_selection_id)
 
-        self.history.set_info(info)
+        self.pathbar.set_info(info)
 
         # scroll to (0,0)
         self.swin.get_hadjustment().set_value(0)