/main/src/addins/Deployment/MonoDevelop.Deployment.Linux/MonoDevelop.Deployment.Linux/DotDesktopViewWidget.cs
C# | 501 lines | 412 code | 81 blank | 8 comment | 61 complexity | d8d5d3e213f74b6da4800a5b2558f5d0 MD5 | raw file
1
2using System;
3using System.Collections;
4using System.Collections.Specialized;
5using System.Xml;
6using Gtk;
7using MonoDevelop.Ide;
8
9namespace MonoDevelop.Deployment.Linux
10{
11 [System.ComponentModel.Category("widget")]
12 [System.ComponentModel.ToolboxItem(true)]
13 public partial class DotDesktopViewWidget : Gtk.Bin
14 {
15 public event EventHandler Changed;
16
17 DesktopEntry entry;
18
19 ListStore storeEnvs;
20 ListStore storeCategs;
21 ListStore storeMimeTypes;
22 ListStore storeEntries;
23 int loading;
24
25 CellRendererText entryKeyCell;
26 CellRendererText mimeTypeCell;
27
28 XmlDocument desktopInfo = DesktopEntry.GetDesktopInfo ();
29
30 public DotDesktopViewWidget()
31 {
32 this.Build();
33 notebook.Page = 0;
34
35 // Environments tree
36
37 storeEnvs = new ListStore (typeof(bool), typeof(string), typeof(string));
38 treeEnvs.Model = storeEnvs;
39 treeEnvs.HeadersVisible = false;
40
41 TreeViewColumn col = new TreeViewColumn ();
42 Gtk.CellRendererToggle tog = new CellRendererToggle ();
43 col.PackStart (tog, false);
44 tog.Toggled += OnEnvironmentClicked;
45
46 Gtk.CellRendererText crt = new CellRendererText ();
47 col.PackStart (crt, true);
48
49 col.AddAttribute (tog, "active", 0);
50 col.AddAttribute (crt, "text", 1);
51 treeEnvs.AppendColumn (col);
52
53 // Selected categories tree
54
55 storeCategs = new ListStore (typeof(string), typeof(string));
56 treeCategories.Model = storeCategs;
57 treeCategories.HeadersVisible = false;
58 treeCategories.AppendColumn ("", new CellRendererText (), "text", 0);
59
60 // Mime types
61
62 storeMimeTypes = new ListStore (typeof(string), typeof(string));
63 treeMimeTypes.Model = storeMimeTypes;
64 mimeTypeCell = new CellRendererText ();
65 mimeTypeCell.Edited += new Gtk.EditedHandler (HandleOnEditMimeType);
66 mimeTypeCell.EditingCanceled += new EventHandler (HandleOnEditMimeTypeCancelled);
67 mimeTypeCell.Editable = true;
68 treeMimeTypes.AppendColumn (Mono.Unix.Catalog.GetString ("Mime Type"), mimeTypeCell, "text", 0);
69 treeMimeTypes.AppendColumn (Mono.Unix.Catalog.GetString ("Description"), new CellRendererText (), "text", 1);
70
71 // Other entries
72
73 storeEntries = new ListStore (typeof(string), typeof(string), typeof(string));
74 treeEntries.Model = storeEntries;
75 entryKeyCell = new CellRendererText ();
76 entryKeyCell.Edited += new Gtk.EditedHandler (HandleOnEditKey);
77 entryKeyCell.EditingCanceled += new EventHandler (HandleOnEditKeyCancelled);
78 entryKeyCell.Editable = false;
79 treeEntries.AppendColumn (Mono.Unix.Catalog.GetString ("Key"), entryKeyCell, "markup", 0);
80 crt = new CellRendererText ();
81 crt.Edited += new Gtk.EditedHandler (HandleOnEditValue);
82 crt.Editable = true;
83 treeEntries.AppendColumn (Mono.Unix.Catalog.GetString ("Value"), crt, "text", 2);
84 }
85
86 void NotifyChanged ()
87 {
88 if (loading == 0 && Changed != null)
89 Changed (this, EventArgs.Empty);
90 }
91
92 public DesktopEntry DesktopEntry {
93 get { return entry; }
94 set { entry = value; Fill (); }
95 }
96
97 void Fill ()
98 {
99 loading++;
100
101 comboType.Active = (int) entry.Type;
102 entryExec.Text = entry.Exec;
103 entryTryExec.Text = entry.TryExec;
104 entryPath.Text = entry.Path;
105 entryUrl.Text = entry.Url;
106 checkTerminal.Active = entry.Terminal;
107
108 comboLocales.AppendText (Mono.Unix.Catalog.GetString ("<Default>"));
109 comboLocales.Active = 0;
110
111 foreach (string loc in entry.GetLocales ())
112 comboLocales.AppendText (loc);
113
114 // Environments list
115
116 if (entry.OnlyShowIn.Count > 0) {
117 radioOnlyShowIn.Active = true;
118 } else if (entry.NotShowIn.Count > 0) {
119 radioNotShowIn.Active = true;
120 } else
121 radioAlwaysShow.Active = true;
122
123 FillEnvironments ();
124
125 // Fill mime types
126
127 ArrayList sortedmt = new ArrayList ();
128 sortedmt.AddRange (entry.MimeTypes);
129 sortedmt.Sort ();
130
131 foreach (string mt in sortedmt) {
132 string desc = DesktopService.GetMimeTypeDescription (mt);
133 storeMimeTypes.AppendValues (mt, desc);
134 }
135
136 checkShowInMenu.Active = !entry.NoDisplay;
137
138 foreach (string s in entry.GetUnknownEntries ()) {
139 storeEntries.AppendValues ("<b>" + s + "</b>", s, entry.GetEntry (s));
140 }
141
142 FillNames ();
143 FillCategs ();
144 UpdateType ();
145 UpdateShowInMenu ();
146
147 loading--;
148 }
149
150 void UpdateType ()
151 {
152 tableCommand.Visible = entry.Type == DesktopEntryType.Application;
153 boxUrl.Visible = entry.Type == DesktopEntryType.Link;
154 tableMimeTypes.Visible = entry.Type == DesktopEntryType.Application;
155 boxCategories.Visible = entry.Type == DesktopEntryType.Application;
156 }
157
158 void UpdateShowInMenu ()
159 {
160 foreach (Gtk.Widget w in boxMenu.Children) {
161 if (w != checkShowInMenu)
162 w.Sensitive = checkShowInMenu.Active;
163 }
164 }
165
166 void FillEnvironments ()
167 {
168 StringCollection envCol = null;
169 if (entry.OnlyShowIn.Count > 0) {
170 envCol = entry.OnlyShowIn;
171 } else if (entry.NotShowIn.Count > 0) {
172 envCol = entry.NotShowIn;
173 }
174
175 treeEnvs.Sensitive = envCol != null;
176
177 storeEnvs.Clear ();
178 foreach (XmlElement elem in desktopInfo.DocumentElement.SelectNodes ("Environments/Environment")) {
179 bool sel = envCol != null && envCol.Contains (elem.GetAttribute ("name"));
180 storeEnvs.AppendValues (sel, elem.GetAttribute ("_label"), elem.GetAttribute ("name"));
181 }
182 }
183
184 void FillNames ()
185 {
186 loading++;
187 entryName.Text = entry.Name;
188 entryGenericName.Text = entry.GenericName;
189 entryComment.Text = entry.Comment;
190 entryIcon.Text = entry.Icon;
191 loading--;
192 }
193
194 void FillCategs ()
195 {
196 storeCategs.Clear ();
197 XmlElement cats = desktopInfo.DocumentElement ["Categories"];
198 foreach (string cat in entry.Categories) {
199 XmlNode node = cats.SelectSingleNode ("Category[@name='" + cat + "']/@_label");
200 string catName;
201 if (node != null)
202 catName = node.InnerText;
203 else
204 catName = cat;
205 storeCategs.AppendValues (Mono.Unix.Catalog.GetString (catName), cat);
206 }
207 }
208
209 void OnEnvironmentClicked (object s, Gtk.ToggledArgs args)
210 {
211 TreeIter iter;
212 storeEnvs.GetIterFromString (out iter, args.Path);
213
214 bool sel = (bool) storeEnvs.GetValue (iter, 0);
215 string env = (string) storeEnvs.GetValue (iter, 2);
216 StringCollection col = radioOnlyShowIn.Active ? entry.OnlyShowIn : entry.NotShowIn;
217 if (sel)
218 col.Remove (env);
219 else
220 col.Add (env);
221
222 storeEnvs.SetValue (iter, 0, !sel);
223 NotifyChanged ();
224 }
225
226 protected virtual void OnButtonAddCategoriesClicked(object sender, System.EventArgs e)
227 {
228 MenuCategorySelectorDialog dlg = new MenuCategorySelectorDialog ();
229 if (MessageService.RunCustomDialog (dlg) == (int) Gtk.ResponseType.Ok) {
230 foreach (string s in dlg.Selection)
231 entry.Categories.Add (s);
232 FillCategs ();
233 NotifyChanged ();
234 }
235 dlg.Destroy ();
236 }
237
238 protected virtual void OnButtonRemoveCategoryClicked(object sender, System.EventArgs e)
239 {
240 TreeIter iter;
241 if (treeCategories.Selection.GetSelected (out iter)) {
242 string cat = (string) storeCategs.GetValue (iter, 1);
243 entry.Categories.Remove (cat);
244 storeCategs.Remove (ref iter);
245 if (!iter.Equals (TreeIter.Zero))
246 treeCategories.Selection.SelectIter (iter);
247 NotifyChanged ();
248 }
249 }
250
251 protected virtual void OnRadioAlwaysShowClicked(object sender, System.EventArgs e)
252 {
253 if (loading > 0) return;
254
255 entry.NotShowIn.Clear ();
256 entry.OnlyShowIn.Clear ();
257 NotifyChanged ();
258 FillEnvironments ();
259 treeEnvs.Sensitive = false;
260 }
261
262 protected virtual void OnRadioOnlyShowInClicked(object sender, System.EventArgs e)
263 {
264 if (loading > 0) return;
265
266 foreach (string s in entry.NotShowIn)
267 entry.OnlyShowIn.Add (s);
268 entry.NotShowIn.Clear ();
269
270 treeEnvs.Sensitive = true;
271 NotifyChanged ();
272 }
273
274 protected virtual void OnRadioNotShowInClicked(object sender, System.EventArgs e)
275 {
276 if (loading > 0) return;
277
278 foreach (string s in entry.OnlyShowIn)
279 entry.NotShowIn.Add (s);
280 entry.OnlyShowIn.Clear ();
281
282 treeEnvs.Sensitive = true;
283 NotifyChanged ();
284 }
285
286 protected virtual void OnButtonAddMimeTypeClicked(object sender, System.EventArgs e)
287 {
288 TreeIter it = storeMimeTypes.AppendValues ("", "");
289 treeMimeTypes.Selection.SelectIter (it);
290 treeMimeTypes.SetCursor (storeMimeTypes.GetPath (it), treeMimeTypes.Columns [0], true);
291 }
292
293
294 void HandleOnEditMimeType (object o, Gtk.EditedArgs e)
295 {
296 Gtk.TreeIter iter;
297 if (storeMimeTypes.GetIterFromString (out iter, e.Path)) {
298 string mt = e.NewText;
299 string oldmt = (string) storeMimeTypes.GetValue (iter, 0);
300 if (mt.Length > 0) {
301 if (!entry.MimeTypes.Contains (mt)) {
302 entry.MimeTypes.Add (mt);
303 storeMimeTypes.SetValue (iter, 0, mt);
304 storeMimeTypes.SetValue (iter, 1, DesktopService.GetMimeTypeDescription (mt));
305
306 if (!string.IsNullOrEmpty (oldmt))
307 // It is a modification. Remove the old name.
308 entry.MimeTypes.Remove (oldmt);
309 else {
310 // Add a new line, so the user can add several types at a time
311 TreeIter newit = storeMimeTypes.AppendValues ("", "");
312 treeMimeTypes.Selection.SelectIter (newit);
313 treeMimeTypes.ScrollToCell (storeMimeTypes.GetPath (newit), treeMimeTypes.Columns [0], false, 0f, 0f);
314 treeMimeTypes.SetCursor (storeMimeTypes.GetPath (newit), treeMimeTypes.Columns [0], true);
315 NotifyChanged ();
316 }
317 }
318 }
319 else {
320 storeMimeTypes.Remove (ref iter);
321 if (!string.IsNullOrEmpty (oldmt))
322 entry.MimeTypes.Remove (oldmt);
323 }
324 }
325 }
326
327 void HandleOnEditMimeTypeCancelled (object s, EventArgs args)
328 {
329 entryKeyCell.Editable = false;
330
331 Gtk.TreeIter iter;
332 if (treeEntries.Selection.GetSelected (out iter)) {
333 string oldmt = (string) storeMimeTypes.GetValue (iter, 0);
334 if (string.IsNullOrEmpty (oldmt))
335 storeEntries.Remove (ref iter);
336 }
337 }
338
339 protected virtual void OnButtonRemoveMimeTypeClicked(object sender, System.EventArgs e)
340 {
341 TreeIter it;
342 if (treeMimeTypes.Selection.GetSelected (out it)) {
343 string mt = (string) storeMimeTypes.GetValue (it, 0);
344 entry.MimeTypes.Remove (mt);
345 storeMimeTypes.Remove (ref it);
346 if (!it.Equals (TreeIter.Zero))
347 treeMimeTypes.Selection.SelectIter (it);
348 NotifyChanged ();
349 }
350 }
351
352 protected virtual void OnComboLocalesChanged(object sender, System.EventArgs e)
353 {
354 if (loading > 0) return;
355 if (comboLocales.Active == 0)
356 entry.CurrentLocale = null;
357 else
358 entry.CurrentLocale = comboLocales.ActiveText;
359
360 FillNames ();
361 }
362
363 protected virtual void OnComboTypeChanged(object sender, System.EventArgs e)
364 {
365 if (loading > 0) return;
366 NotifyChanged ();
367 entry.Type = (DesktopEntryType) comboType.Active;
368 UpdateType ();
369 }
370
371 protected virtual void OnCheckShowInMenuClicked(object sender, System.EventArgs e)
372 {
373 if (loading > 0) return;
374 NotifyChanged ();
375 UpdateShowInMenu ();
376 }
377
378 protected virtual void OnEntryNameChanged(object sender, System.EventArgs e)
379 {
380 if (loading > 0) return;
381 NotifyChanged ();
382 entry.Name = entryName.Text;
383 }
384
385 protected virtual void OnEntryUrlChanged(object sender, System.EventArgs e)
386 {
387 if (loading > 0) return;
388 NotifyChanged ();
389 entry.Url = entryUrl.Text;
390 }
391
392 protected virtual void OnEntryExecChanged(object sender, System.EventArgs e)
393 {
394 if (loading > 0) return;
395 NotifyChanged ();
396 entry.Exec = entryExec.Text;
397 }
398
399 protected virtual void OnEntryTryExecChanged(object sender, System.EventArgs e)
400 {
401 if (loading > 0) return;
402 NotifyChanged ();
403 entry.TryExec = entryTryExec.Text;
404 }
405
406 protected virtual void OnEntryPathChanged(object sender, System.EventArgs e)
407 {
408 if (loading > 0) return;
409 NotifyChanged ();
410 entry.Path = entryPath.Text;
411 }
412
413 protected virtual void OnEntryCommentChanged(object sender, System.EventArgs e)
414 {
415 if (loading > 0) return;
416 NotifyChanged ();
417 entry.Comment = entryComment.Text;
418 }
419
420 protected virtual void OnEntryGenericNameChanged(object sender, System.EventArgs e)
421 {
422 if (loading > 0) return;
423 NotifyChanged ();
424 entry.GenericName = entryGenericName.Text;
425 }
426
427 protected virtual void OnEntryIconChanged(object sender, System.EventArgs e)
428 {
429 if (loading > 0) return;
430 NotifyChanged ();
431 entry.Icon = entryIcon.Text;
432 }
433
434 protected virtual void OnCheckTerminalClicked(object sender, System.EventArgs e)
435 {
436 if (loading > 0) return;
437 entry.Terminal = checkTerminal.Active;
438 }
439
440 protected virtual void OnButtonAddEntryClicked(object sender, System.EventArgs e)
441 {
442 TreeIter it = storeEntries.AppendValues ("", "", "");
443 treeEntries.Selection.SelectIter (it);
444 entryKeyCell.Editable = true;
445 treeEntries.SetCursor (storeEntries.GetPath (it), treeEntries.Columns [0], true);
446 }
447
448 void HandleOnEditValue (object o, Gtk.EditedArgs e)
449 {
450 Gtk.TreeIter iter;
451 if (storeEntries.GetIterFromString (out iter, e.Path)) {
452 string key = (string) storeEntries.GetValue (iter, 1);
453 entry.SetEntry (key, e.NewText);
454 storeEntries.SetValue (iter, 2, e.NewText);
455 NotifyChanged ();
456 }
457 }
458
459 void HandleOnEditKey (object o, Gtk.EditedArgs e)
460 {
461 entryKeyCell.Editable = false;
462
463 Gtk.TreeIter iter;
464 if (storeEntries.GetIterFromString (out iter, e.Path)) {
465 string key = e.NewText;
466 if (key.Length > 0) {
467 entry.SetEntry (key, "");
468 storeEntries.SetValue (iter, 0, "<b>" + key + "</b>");
469 storeEntries.SetValue (iter, 1, key);
470 treeEntries.SetCursor (storeEntries.GetPath (iter), treeEntries.Columns [1], true);
471 NotifyChanged ();
472 }
473 else {
474 storeEntries.Remove (ref iter);
475 }
476 }
477 }
478
479 void HandleOnEditKeyCancelled (object s, EventArgs args)
480 {
481 entryKeyCell.Editable = false;
482
483 Gtk.TreeIter iter;
484 if (treeEntries.Selection.GetSelected (out iter)) {
485 storeEntries.Remove (ref iter);
486 }
487 }
488
489 protected virtual void OnButtonRemoveEntryClicked(object sender, System.EventArgs e)
490 {
491 Gtk.TreeIter iter;
492 if (treeEntries.Selection.GetSelected (out iter)) {
493 string key = (string) storeEntries.GetValue (iter, 1);
494 entry.RemoveEntry (key);
495 storeEntries.Remove (ref iter);
496 if (!iter.Equals (TreeIter.Zero))
497 treeEntries.Selection.SelectIter (iter);
498 }
499 }
500 }
501}