ed_theme.py
14.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
###############################################################################
# Name: ed_theme.py #
# Purpose: Icon theme management for Editra #
# Author: Cody Precord <cprecord@editra.org> #
# Copyright: (c) 2007 Cody Precord <staff@editra.org> #
# License: wxWindows License #
###############################################################################
"""
Provide an interface for creating icon themes for Editra. This will allow for
themes to be created, installed, and managed as plugins, which means that they
can be installed as single file instead of dozens of individual image files.
@summary: Editra's theme interface and implementation
"""
__author__ = "Cody Precord <cprecord@editra.org>"
__svnid__ = "$Id: ed_theme.py 72247 2012-07-28 22:32:37Z CJP $"
__revision__ = "$Revision: 72247 $"
#--------------------------------------------------------------------------#
# Imports
import os
import wx
# Local Imports
import ed_glob
import util
import plugin
from profiler import Profile_Get, Profile_Set
import syntax.synglob as synglob
from syntax.syntax import SYNTAX_IDS
#--------------------------------------------------------------------------#
class ThemeI(plugin.Interface):
"""Interface for defining an icon theme in Editra
When a icon theme is active Editra's ArtProvider will ask the active
theme that implements this interface to give it a bitmap. The requests
for bitmaps will be numerical ID values that come from ed_glob. These
ID's are associated with different objects in the interface. The names
are descriptive of the object they represent, for reference however
see the implementation of the two main themes (Tango and Nuovo).
@see: L{ed_glob}
@see: L{syntax.synglob}
"""
def GetName(self):
"""Return the name of this theme. This is used to identify the
theme when the provider looks for resources based on user preferences
@return: name string
"""
def GetMenuBitmap(self, bmp_id):
"""Get the menu bitmap associated with the object id
If this theme does not have a resource to provide for this
object return a wx.NullBitmap.
@return: 16x16 pixel bitmap
"""
return wx.NullBitmap
def GetFileBitmap(self, bmp_id):
"""Get the filetype bitmap associated with the object id, the
valid object ids are defined in the module syntax.synglob and
are used to request images for menu's and page tabs. The theme
implimenting this interface should at least be able to
provide an image for plain text files and return that for any
unmapped types.
If this theme does not have a resource to provide for this
object return a wx.NullBitmap.
@return: 16x16 pixel bitmap
"""
return wx.NullBitmap
def GetOtherBitmap(self, bmp_id):
"""Get the bitmap from the 'other' icon resources. Valid id's are
identified by a mapping in the ART dictionary.
If this theme does not have a resource to provide for this
object return a wx.NullBitmap.
@return: wx.Bitmap
"""
return wx.NullBitmap
def GetToolbarBitmap(self, bmp_id):
"""Get the toolbar bitmap associated with the object id. The
toolbar icons must be returned as a 32x32 pixel bitmap any
scaling that is needed will be handled by the art provider that
requests the resource.
If this theme does not have a resource to provide for this
object return a wx.NullBitmap.
@return: 32x32 pixel bitmap
"""
return wx.NullBitmap
#-----------------------------------------------------------------------------#
class BitmapProvider(plugin.Plugin):
"""Plugin that fetches requested icons from the current active theme.
"""
observers = plugin.ExtensionPoint(ThemeI)
def __GetCurrentProvider(self):
"""Gets the provider of the current theme resources
@return: ThemeI object
"""
theme = Profile_Get('ICONS', 'str', u'')
for prov in self.observers:
if theme == prov.GetName():
return prov
# Case if a theme was deleted while it was the active theme
if theme.lower() != u'default':
Profile_Set('ICONS', u'Default')
return None
def _GetTango(self, bmp_id, client):
"""Try to get the icon from the default tango theme"""
theme = None
bmp = wx.NullBitmap
for prov in self.observers:
if prov.GetName() == TangoTheme.name:
theme = prov
break
else:
return bmp
if client == wx.ART_TOOLBAR:
bmp = theme.GetToolbarBitmap(bmp_id)
elif client == wx.ART_MENU:
bmp = theme.GetMenuBitmap(bmp_id)
elif client == wx.ART_OTHER:
bmp = theme.GetOtherBitmap(bmp_id)
else:
pass
return bmp
def GetThemes(self):
"""Gets a list of the installed and activated themes
@return: list of strings
"""
return [ name.GetName() for name in self.observers ]
def GetBitmap(self, bmp_id, client):
"""Gets a 16x16 or 32x32 pixel bitmap depending on client value.
May return a NullBitmap if no suitable bitmap can be
found.
@param bmp_id: id of bitmap to lookup
@param client: wxART_MENU, wxART_TOOLBAR
@see: L{ed_glob}
"""
prov = self.__GetCurrentProvider()
if prov is not None:
if client == wx.ART_MENU:
bmp = prov.GetMenuBitmap(bmp_id)
elif client == wx.ART_OTHER:
# Backwards compatibility for older interface
if hasattr(prov, 'GetOtherBitmap'):
bmp = prov.GetOtherBitmap(bmp_id)
else:
bmp = wx.NullBitmap
else:
bmp = prov.GetToolbarBitmap(bmp_id)
if bmp.IsOk():
return bmp
# Try to fallback to tango theme when icon lookup fails
bmp = self._GetTango(bmp_id, client)
if bmp.IsOk():
return bmp
return wx.NullBitmap
#-----------------------------------------------------------------------------#
# Default theme data maps
ART = { ed_glob.ID_ABOUT : u'about.png',
ed_glob.ID_ADD : u'add.png',
ed_glob.ID_ADD_BM : u'bmark_add.png',
ed_glob.ID_ADVANCED : u'advanced.png',
ed_glob.ID_BACKWARD : u'backward.png',
ed_glob.ID_BIN_FILE : u'bin_file.png',
ed_glob.ID_CDROM : u'cdrom.png',
ed_glob.ID_CONTACT : u'mail.png',
ed_glob.ID_COPY : u'copy.png',
ed_glob.ID_COMPUTER : u'computer.png',
ed_glob.ID_CUT : u'cut.png',
ed_glob.ID_DELETE : u'delete.png',
ed_glob.ID_DELETE_ALL : u'delete_all.png',
ed_glob.ID_DOCPROP : u'doc_props.png',
ed_glob.ID_DOCUMENTATION : u'docs.png',
ed_glob.ID_DOWN : u'down.png',
ed_glob.ID_EXIT : u'quit.png',
ed_glob.ID_FILE : u'file.png',
ed_glob.ID_FIND : u'find.png',
ed_glob.ID_FIND_REPLACE : u'findr.png',
ed_glob.ID_FIND_RESULTS : u'find.png',
ed_glob.ID_FLOPPY : u'floppy.png',
ed_glob.ID_FOLDER : u'folder.png',
ed_glob.ID_FONT : u'font.png',
ed_glob.ID_FORWARD : u'forward.png',
ed_glob.ID_HARDDISK : u'harddisk.png',
ed_glob.ID_HOMEPAGE : u'web.png',
ed_glob.ID_HTML_GEN : u'html_gen.png',
ed_glob.ID_INDENT : u'indent.png',
ed_glob.ID_LOGGER : u'log.png',
ed_glob.ID_NEW : u'new.png',
ed_glob.ID_NEW_FOLDER : u'newfolder.png',
ed_glob.ID_NEW_WINDOW: u'newwin.png',
ed_glob.ID_NEXT_MARK : u'bmark_next.png',
ed_glob.ID_NEXT_POS : u'forward.png',
ed_glob.ID_OPEN : u'open.png',
ed_glob.ID_PACKAGE : u'package.png',
ed_glob.ID_PASTE : u'paste.png',
ed_glob.ID_PLUGMGR : u'plugin.png',
ed_glob.ID_PRE_MARK : u'bmark_pre.png',
ed_glob.ID_PRE_POS : u'backward.png',
ed_glob.ID_PREF : u'pref.png',
ed_glob.ID_PRINT : u'print.png',
ed_glob.ID_PRINT_PRE : u'printpre.png',
ed_glob.ID_PYSHELL : u'pyshell.png',
ed_glob.ID_REDO : u'redo.png',
ed_glob.ID_REFRESH : u'refresh.png',
ed_glob.ID_REMOVE : u'remove.png',
ed_glob.ID_RTF_GEN : u'rtf_gen.png',
ed_glob.ID_SAVE : u'save.png',
ed_glob.ID_SAVEALL : u'saveall.png',
ed_glob.ID_SAVEAS : u'saveas.png',
ed_glob.ID_SELECTALL : u'selectall.png',
ed_glob.ID_STOP : u'stop.png',
ed_glob.ID_STYLE_EDIT : u'style_edit.png',
ed_glob.ID_TEX_GEN : u'tex_gen.png',
ed_glob.ID_THEME : u'theme.png',
ed_glob.ID_UNDO : u'undo.png',
ed_glob.ID_UNINDENT : u'outdent.png',
ed_glob.ID_UP : u'up.png',
ed_glob.ID_USB : u'usb.png',
ed_glob.ID_WEB : u'web.png',
ed_glob.ID_ZOOM_IN : u'zoomi.png',
ed_glob.ID_ZOOM_OUT : u'zoomo.png',
ed_glob.ID_ZOOM_NORMAL : u'zoomd.png',
ed_glob.ID_READONLY : u'readonly.png',
# code elements
ed_glob.ID_CLASS_TYPE : u'class.png',
ed_glob.ID_FUNCT_TYPE : u'function.png',
ed_glob.ID_ELEM_TYPE : u'element.png',
ed_glob.ID_VARIABLE_TYPE : u'variable.png',
ed_glob.ID_ATTR_TYPE : u'attribute.png',
ed_glob.ID_PROPERTY_TYPE : u'property.png',
ed_glob.ID_METHOD_TYPE : u'method.png'
}
# File Type Art
MIME_ART = { synglob.ID_LANG_ADA : u'ada.png',
synglob.ID_LANG_BASH : u'shell.png',
synglob.ID_LANG_BOO : u'boo.png',
synglob.ID_LANG_BOURNE : u'shell.png',
synglob.ID_LANG_C : u'c.png',
synglob.ID_LANG_CPP : u'cpp.png',
synglob.ID_LANG_CSH : u'shell.png',
synglob.ID_LANG_CSS : u'css.png',
synglob.ID_LANG_DIFF : u'diff.png',
synglob.ID_LANG_HTML : u'html.png',
synglob.ID_LANG_JAVA : u'java.png',
synglob.ID_LANG_KSH : u'shell.png',
synglob.ID_LANG_LATEX : u'tex.png',
synglob.ID_LANG_MAKE : u'makefile.png',
synglob.ID_LANG_PASCAL : u'pascal.png',
synglob.ID_LANG_PERL : u'perl.png',
synglob.ID_LANG_PHP : u'php.png',
synglob.ID_LANG_PS : u'postscript.png',
synglob.ID_LANG_PYTHON : u'python.png',
synglob.ID_LANG_RUBY : u'ruby.png',
synglob.ID_LANG_TCL : u'tcl.png',
synglob.ID_LANG_TEX : u'tex.png',
synglob.ID_LANG_TXT : u'text.png',
synglob.ID_LANG_XML : u'xml.png'
}
#-----------------------------------------------------------------------------#
class TangoTheme(plugin.Plugin):
"""Represents the Tango Icon theme for Editra"""
plugin.Implements(ThemeI)
name = u'Tango'
def __GetArtPath(self, client, mime=False):
"""Gets the path of the resource directory to get
the bitmaps from.
@param client: wx.ART_MENU/wx.ART_TOOLBAR
@keyword mime: is this a filetype icon lookup
@return: path of art resource
@rtype: string
"""
clients = { wx.ART_MENU : u"menu",
wx.ART_TOOLBAR : u"toolbar",
wx.ART_OTHER : u"other" }
# Get the path
if ed_glob.CONFIG['THEME_DIR'] == u'':
theme = util.ResolvConfigDir(os.path.join(u"pixmaps", u"theme"))
ed_glob.CONFIG['THEME_DIR'] = theme
if mime:
path = os.path.join(ed_glob.CONFIG['THEME_DIR'],
self.GetName(), u'mime')
else:
path = os.path.join(ed_glob.CONFIG['THEME_DIR'],
self.GetName(),
clients.get(client, u"menu"))
path += os.sep
if os.path.exists(path):
return path
else:
return None
def GetName(self):
"""Get the name of this theme
@return: string
"""
return TangoTheme.name
def GetMenuBitmap(self, bmp_id):
"""Get a menu bitmap
@param bmp_id: Id of bitmap to look for
"""
if bmp_id in ART:
path = self.__GetArtPath(wx.ART_MENU, mime=False)
if path is not None:
path = path + ART[bmp_id]
if os.path.exists(path):
return wx.Bitmap(path, wx.BITMAP_TYPE_PNG)
else:
return self.GetFileBitmap(bmp_id)
return wx.NullBitmap
def GetFileBitmap(self, bmp_id):
"""Get a mime type bitmap from the theme
@param bmp_id: Id of filetype bitmap to look up
@see: L{syntax.synglob}
"""
path = self.__GetArtPath(wx.ART_MENU, mime=True)
if path is not None and bmp_id in SYNTAX_IDS:
if bmp_id in MIME_ART:
req = path + MIME_ART[bmp_id]
if os.path.exists(req):
return wx.Bitmap(req, wx.BITMAP_TYPE_PNG)
# Try to fall back to bmp for plain text when above is not found
bkup = path + MIME_ART[synglob.ID_LANG_TXT]
if os.path.exists(bkup):
return wx.Bitmap(bkup, wx.BITMAP_TYPE_PNG)
return wx.NullBitmap
def GetOtherBitmap(self, bmp_id):
"""Get a other catagory bitmap.
@param bmp_id: Id of art resource
"""
if bmp_id in ART:
path = self.__GetArtPath(wx.ART_OTHER, mime=False)
if path is not None:
path = path + ART[bmp_id]
if os.path.exists(path):
return wx.Bitmap(path, wx.BITMAP_TYPE_PNG)
return wx.NullBitmap
def GetToolbarBitmap(self, bmp_id):
"""Get a toolbar bitmap
@param bmp_id: Id of bitmap to look for
@return: wx.NullBitmap or a 32x32 bitmap
"""
if bmp_id in ART:
# size = Profile_Get('ICON_SZ', default=(24, 24))
path = self.__GetArtPath(wx.ART_TOOLBAR, mime=False)
if path is not None:
# tpath = os.path.join(path, '24', ART[bmp_id])
# if size[0] == 24 and os.path.exists(tpath):
# path = tpath
# else:
path = path + ART[bmp_id]
if os.path.exists(path):
return wx.Bitmap(path, wx.BITMAP_TYPE_PNG)
return wx.NullBitmap