PageRenderTime 42ms CodeModel.GetById 13ms app.highlight 26ms RepoModel.GetById 0ms app.codeStats 0ms

/main/src/addins/Deployment/MonoDevelop.Deployment.Linux/MonoDevelop.Deployment.Linux/DotDesktopViewWidget.cs

https://github.com/jfcantin/monodevelop
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}