Maemo 5: Fix window and button layout (Maemo bug 11499)
[gpodder.git] / src / gpodder / gtkui / desktopfile.py
blobb691101786fd38938e7acfa9672223ed48263c23
1 # -*- coding: utf-8 -*-
3 # gPodder - A media aggregator and podcast client
4 # Copyright (c) 2005-2010 Thomas Perl and the gPodder Team
6 # gPodder is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 3 of the License, or
9 # (at your option) any later version.
11 # gPodder is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
22 # libplayers.py -- get list of potential playback apps
23 # thomas perl <thp@perli.net> 20060329
27 import glob
28 import os.path
29 import threading
31 from ConfigParser import RawConfigParser
33 import gobject
34 import gtk
35 import gtk.gdk
37 import gpodder
38 from gpodder.liblogger import log
40 _ = gpodder.gettext
42 # where are the .desktop files located?
43 userappsdirs = [ '/usr/share/applications/', '/usr/local/share/applications/', '/usr/share/applications/kde/' ]
45 # the name of the section in the .desktop files
46 sect = 'Desktop Entry'
48 class PlayerListModel(gtk.ListStore):
49 C_ICON, C_NAME, C_COMMAND, C_CUSTOM = range(4)
51 def __init__(self):
52 gtk.ListStore.__init__(self, gtk.gdk.Pixbuf, str, str, bool)
54 def insert_app(self, pixbuf, name, command):
55 self.append((pixbuf, name, command, False))
57 def get_command(self, index):
58 return self[index][self.C_COMMAND]
60 def get_index(self, value):
61 for index, row in enumerate(self):
62 if value == row[self.C_COMMAND]:
63 return index
65 last_row = self[-1]
66 name = _('Command: %s') % value
67 if last_row[self.C_CUSTOM]:
68 last_row[self.C_COMMAND] = value
69 last_row[self.C_NAME] = name
70 else:
71 self.append((None, name, value, True))
73 return len(self)-1
75 @classmethod
76 def is_separator(cls, model, iter):
77 return model.get_value(iter, cls.C_COMMAND) == ''
79 class UserApplication(object):
80 def __init__(self, name, cmd, mime, icon):
81 self.name = name
82 self.cmd = cmd
83 self.icon = icon
84 self.mime = mime
86 def get_icon(self):
87 if self.icon is not None:
88 # Load it from an absolute filename
89 if os.path.exists(self.icon):
90 try:
91 return gtk.gdk.pixbuf_new_from_file_at_size(self.icon, 24, 24)
92 except gobject.GError, ge:
93 pass
95 # Load it from the current icon theme
96 (icon_name, extension) = os.path.splitext(os.path.basename(self.icon))
97 theme = gtk.IconTheme()
98 if theme.has_icon(icon_name):
99 return theme.load_icon(icon_name, 24, 0)
101 def is_mime(self, mimetype):
102 return self.mime.find(mimetype+'/') != -1
105 class UserAppsReader(object):
106 def __init__(self, mimetypes):
107 self.apps = []
108 self.mimetypes = mimetypes
109 self.__has_read = False
110 self.__finished = threading.Event()
111 self.__has_sep = False
112 self.apps.append(UserApplication(_('Default application'), 'default', ';'.join((mime+'/*' for mime in self.mimetypes)), gtk.STOCK_OPEN))
114 def add_separator(self):
115 self.apps.append(UserApplication('', '', ';'.join((mime+'/*' for mime in self.mimetypes)), ''))
116 self.__has_sep = True
118 def read( self):
119 if self.__has_read:
120 return
122 self.__has_read = True
123 log('start reader', bench_start=True)
124 for dir in userappsdirs:
125 if os.path.exists( dir):
126 for file in glob.glob(os.path.join(dir, '*.desktop')):
127 self.parse_and_append( file)
128 log('end reader', bench_end=True)
129 self.__finished.set()
131 def parse_and_append( self, filename):
132 try:
133 parser = RawConfigParser()
134 parser.read([filename])
135 if not parser.has_section(sect):
136 return
138 # Find out if we need it by comparing mime types
139 app_mime = parser.get(sect, 'MimeType')
140 for needed_type in self.mimetypes:
141 if app_mime.find(needed_type+'/') != -1:
142 log('Player found: %s', filename, sender=self)
143 app_name = parser.get(sect, 'Name')
144 app_cmd = parser.get(sect, 'Exec')
145 app_icon = parser.get(sect, 'Icon')
146 if not self.__has_sep:
147 self.add_separator()
148 self.apps.append(UserApplication(app_name, app_cmd, app_mime, app_icon))
149 return
150 except:
151 return
153 def get_model(self, mimetype):
154 self.__finished.wait()
156 model = PlayerListModel()
157 for app in self.apps:
158 if app.is_mime(mimetype):
159 model.insert_app(app.get_icon(), app.name, app.cmd)
160 return model