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)