alacarte.in: Fix indentation
[alacarte.git] / Alacarte / util.py
blob50d836d32d21f36a1f929e4922eaa00836ffb58f
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
19 import os
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():
32 if item is None:
33 continue
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):
43 append = 0
44 while 1:
45 if append == 0:
46 filename = name + extension
47 else:
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):
52 break
53 elif extension == '.directory':
54 path = getUserDirectoryPath()
55 if not os.path.isfile(os.path.join(path, filename)) and not getDirectoryPath(filename):
56 break
57 append += 1
58 return filename
60 def getUniqueRedoFile(filepath):
61 append = 0
62 while 1:
63 new_filepath = filepath + '.redo-' + str(append)
64 if not os.path.isfile(new_filepath):
65 break
66 else:
67 append += 1
68 return new_filepath
70 def getUniqueUndoFile(filepath):
71 filename, extension = os.path.split(filepath)[1].rsplit('.', 1)
72 append = 0
73 while 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):
82 break
83 else:
84 append += 1
85 return 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):
91 return file_path
92 return None
94 def getUserItemPath():
95 item_dir = os.path.join(GLib.get_user_data_dir(), 'applications')
96 if not os.path.isdir(item_dir):
97 os.makedirs(item_dir)
98 return 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):
104 return file_path
105 return None
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)
111 return 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)
117 return 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):
123 return file_path
124 return None
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"
132 return menu_xml
134 def getIcon(item):
135 pixbuf = None
136 if item is None:
137 return None
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()
144 else:
145 return None
147 if gicon is None:
148 return None
150 icon_theme = Gtk.IconTheme.get_default()
151 info = icon_theme.lookup_by_gicon(gicon, 24, 0)
152 if info is None:
153 return None
154 try:
155 pixbuf = info.load_icon()
156 except GError:
157 return None
158 if pixbuf is None:
159 return None
160 if pixbuf.get_width() != 24 or pixbuf.get_height() != 24:
161 pixbuf = pixbuf.scale_simple(24, 24, GdkPixbuf.InterpType.HYPER)
162 return pixbuf
164 def removeWhitespaceNodes(node):
165 remove_list = []
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)