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
|
namespace Menu {
class MenuDir : Object {
public string id { get; set; }
public string name { get; set; }
public string summary { get; set; }
public string icon { get; set; }
public string directory { get; set; }
public string[] included;
public string[] excluded;
public int level;
public void complete (KeyFile file) {
summary = "";
icon = "applications-other";
try {
file.load_from_file ("/usr/share/desktop-directories/%s".printf (directory), 0);
name = file.get_string ("Desktop Entry", "Name");
summary = file.get_string ("Desktop Entry", "Comment");
icon = file.get_string ("Desktop Entry", "Icon");
if (summary == null) {
summary = "";
}
if (icon == null) {
icon = "";
}
} catch (Error e) {
GLib.debug ("Error retrieving datas for %s: %s\n", directory, e.message);
}
}
public MenuDir () {
included = {};
excluded = {};
}
}
class MenuParser {
private const MarkupParser parser = {
opening_item,// when an element opens
closing_item, // when an element closes
get_text, // when text is found
null, // when comments are found
null // when errors occur
};
private string menu_file;
private MarkupParseContext context;
private MenuDir[] dirlist;
private MenuDir[] dirs_level;
private int level = 0;
private string last_item;
private bool include = true;
private KeyFile file;
public MenuDir[] parse () {
string file;
FileUtils.get_contents (menu_file, out file, null);
context.parse (file, file.length);
return dirlist;
}
public MenuParser (string menu_file) {
context = new MarkupParseContext(
parser, // the structure with the callbacks
0, // MarkupParseFlags
this, // extra argument for the callbacks, methods in this case
null // when the parsing ends
);
dirlist = {};
dirs_level = {};
this.menu_file = menu_file;
file = new KeyFile();
}
void opening_item (MarkupParseContext context, string name, string[] attr, string[] vals) throws MarkupError {
last_item = name;
switch (name) {
case "Menu":
MenuDir tmp = new MenuDir();
dirs_level[level] = tmp;
dirlist += tmp;
dirs_level[level].level = level;
level ++;
break;
case "Not":
include = false;
break;
}
}
void closing_item (MarkupParseContext context, string name) throws MarkupError {
switch (name) {
case "Menu":
level --;
dirs_level[level].complete (file);
break;
case "Not":
include = true;
break;
}
}
private bool check_whitespaces (string str) {
return (str.strip() == "" ? true : false);
}
void get_text (MarkupParseContext context, string text, size_t text_len) throws MarkupError {
if (check_whitespaces (text)) { return; }
switch (last_item) {
case "Name":
dirs_level[level-1].name = text;
dirs_level[level-1].id = text;
break;
case "Directory":
dirs_level[level-1].directory = text;
break;
case "Category":
if (include) {
dirs_level[level-1].included += text;
} else {
dirs_level[level-1].excluded += text;
}
break;
}
}
}
}
|