1 # -*- coding: utf-8 -*-
2 # Alacarte Menu Editor - Simple fd.o Compliant Menu Editor
3 # Copyright (C) 2006 Travis Watkins
5 # This library is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU Library General Public
7 # License as published by the Free Software Foundation; either
8 # version 2 of the License, or (at your option) any later version.
10 # This library is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 # Library General Public License for more details.
15 # You should have received a copy of the GNU Library General Public
16 # License along with this library; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 import xml
.dom
.minidom
21 from collections
import Sequence
22 from gi
.repository
import Gtk
, GdkPixbuf
, GMenu
, GLib
24 # XXX: look into pygobject error marshalling
25 from gi
._glib
import GError
27 DESKTOP_GROUP
= GLib
.KEY_FILE_DESKTOP_GROUP
28 KEY_FILE_FLAGS
= GLib
.KeyFileFlags
.KEEP_COMMENTS | GLib
.KeyFileFlags
.KEEP_TRANSLATIONS
30 def fillKeyFile(keyfile
, items
):
31 for key
, item
in items
.iteritems():
35 if isinstance(item
, bool):
36 keyfile
.set_boolean(DESKTOP_GROUP
, key
, item
)
37 elif isinstance(item
, Sequence
):
38 keyfile
.set_string_list(DESKTOP_GROUP
, key
, item
)
39 elif isinstance(item
, basestring
):
40 keyfile
.set_string(DESKTOP_GROUP
, key
, item
)
42 def getUniqueFileId(name
, extension
):
46 filename
= name
+ extension
48 filename
= name
+ '-' + str(append
) + extension
49 if extension
== '.desktop':
50 path
= getUserItemPath()
51 if not os
.path
.isfile(os
.path
.join(path
, filename
)) and not getItemPath(filename
):
53 elif extension
== '.directory':
54 path
= getUserDirectoryPath()
55 if not os
.path
.isfile(os
.path
.join(path
, filename
)) and not getDirectoryPath(filename
):
60 def getUniqueRedoFile(filepath
):
63 new_filepath
= filepath
+ '.redo-' + str(append
)
64 if not os
.path
.isfile(new_filepath
):
70 def getUniqueUndoFile(filepath
):
71 filename
, extension
= os
.path
.split(filepath
)[1].rsplit('.', 1)
74 if extension
== 'desktop':
75 path
= getUserItemPath()
76 elif extension
== 'directory':
77 path
= getUserDirectoryPath()
78 elif extension
== 'menu':
79 path
= getUserMenuPath()
80 new_filepath
= os
.path
.join(path
, filename
+ '.' + extension
+ '.undo-' + str(append
))
81 if not os
.path
.isfile(new_filepath
):
87 def getItemPath(file_id
):
88 for path
in GLib
.get_system_data_dirs():
89 file_path
= os
.path
.join(path
, 'applications', file_id
)
90 if os
.path
.isfile(file_path
):
94 def getUserItemPath():
95 item_dir
= os
.path
.join(GLib
.get_user_data_dir(), 'applications')
96 if not os
.path
.isdir(item_dir
):
100 def getDirectoryPath(file_id
):
101 for path
in GLib
.get_system_data_dirs():
102 file_path
= os
.path
.join(path
, 'desktop-directories', file_id
)
103 if os
.path
.isfile(file_path
):
107 def getUserDirectoryPath():
108 menu_dir
= os
.path
.join(GLib
.get_user_data_dir(), 'desktop-directories')
109 if not os
.path
.isdir(menu_dir
):
110 os
.makedirs(menu_dir
)
113 def getUserMenuPath():
114 menu_dir
= os
.path
.join(GLib
.get_user_config_dir(), 'menus')
115 if not os
.path
.isdir(menu_dir
):
116 os
.makedirs(menu_dir
)
119 def getSystemMenuPath(file_id
):
120 for path
in GLib
.get_system_config_dirs():
121 file_path
= os
.path
.join(path
, 'menus', file_id
)
122 if os
.path
.isfile(file_path
):
126 def getUserMenuXml(tree
):
127 system_file
= getSystemMenuPath(os
.path
.basename(tree
.get_canonical_menu_path()))
128 name
= tree
.get_root_directory().get_menu_id()
129 menu_xml
= "<!DOCTYPE Menu PUBLIC '-//freedesktop//DTD Menu 1.0//EN' 'http://standards.freedesktop.org/menu-spec/menu-1.0.dtd'>\n"
130 menu_xml
+= "<Menu>\n <Name>" + name
+ "</Name>\n "
131 menu_xml
+= "<MergeFile type=\"parent\">" + system_file
+ "</MergeFile>\n</Menu>\n"
139 if isinstance(item
, GMenu
.TreeDirectory
):
140 gicon
= item
.get_icon()
141 elif isinstance(item
, GMenu
.TreeEntry
):
142 app_info
= item
.get_app_info()
143 gicon
= app_info
.get_icon()
150 icon_theme
= Gtk
.IconTheme
.get_default()
151 info
= icon_theme
.lookup_by_gicon(gicon
, 24, 0)
155 pixbuf
= info
.load_icon()
160 if pixbuf
.get_width() != 24 or pixbuf
.get_height() != 24:
161 pixbuf
= pixbuf
.scale_simple(24, 24, GdkPixbuf
.InterpType
.HYPER
)
164 def removeWhitespaceNodes(node
):
166 for child
in node
.childNodes
:
167 if child
.nodeType
== xml
.dom
.minidom
.Node
.TEXT_NODE
:
168 child
.data
= child
.data
.strip()
169 if not child
.data
.strip():
170 remove_list
.append(child
)
171 elif child
.hasChildNodes():
172 removeWhitespaceNodes(child
)
173 for node
in remove_list
:
174 node
.parentNode
.removeChild(node
)