/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/PackageSourcesWidget.cs

https://github.com/directhex/monodevelop · C# · 292 lines · 253 code · 39 blank · 0 comment · 10 complexity · b708b956df35e17688733e4fd3073fbf MD5 · raw file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.Specialized;
  4. using System.Linq;
  5. using Gtk;
  6. using MonoDevelop.PackageManagement;
  7. using MonoDevelop.Core;
  8. using MonoDevelop.Components;
  9. using MonoDevelop.Components.AutoTest;
  10. using System.ComponentModel;
  11. namespace MonoDevelop.PackageManagement
  12. {
  13. [System.ComponentModel.ToolboxItem(true)]
  14. internal partial class PackageSourcesWidget : Gtk.Bin
  15. {
  16. RegisteredPackageSourcesViewModel viewModel;
  17. ListStore packageSourcesStore;
  18. const int IsEnabledCheckBoxColumn = 1;
  19. const int PackageSourceIconColumn = 2;
  20. const int PackageSourceViewModelColumn = 3;
  21. public PackageSourcesWidget (RegisteredPackageSourcesViewModel viewModel)
  22. {
  23. this.Build ();
  24. this.viewModel = viewModel;
  25. this.InitializeTreeView ();
  26. this.LoadPackageSources ();
  27. AddEventHandlers ();
  28. UpdateEnabledButtons ();
  29. }
  30. void AddEventHandlers ()
  31. {
  32. this.removeButton.Clicked += RemoveButtonClicked;
  33. this.addButton.Clicked += AddButtonClicked;
  34. this.viewModel.PackageSourceViewModels.CollectionChanged += PackageSourceViewModelsCollectionChanged;
  35. this.viewModel.PackageSourceChanged += PackageSourceChanged;
  36. }
  37. public override void Dispose ()
  38. {
  39. this.viewModel.PackageSourceViewModels.CollectionChanged -= PackageSourceViewModelsCollectionChanged;
  40. this.viewModel.PackageSourceChanged -= PackageSourceChanged;
  41. this.viewModel.Dispose ();
  42. base.Dispose ();
  43. }
  44. void InitializeTreeView ()
  45. {
  46. packageSourcesStore = new ListStore (typeof (object), typeof (bool), typeof (IconId), typeof (PackageSourceViewModel));
  47. SemanticModelAttribute modelAttr = new SemanticModelAttribute ("store__Data", "store__Selected",
  48. "store__IconId", "store__Model");
  49. TypeDescriptor.AddAttributes (packageSourcesStore, modelAttr);
  50. packageSourcesTreeView.Model = packageSourcesStore;
  51. packageSourcesTreeView.SearchColumn = -1; // disable the interactive search
  52. packageSourcesTreeView.AppendColumn (CreateTreeViewColumn ());
  53. packageSourcesTreeView.Selection.Changed += PackageSourcesTreeViewSelectionChanged;
  54. packageSourcesTreeView.RowActivated += PackageSourcesTreeViewRowActivated;
  55. packageSourcesTreeView.Reorderable = true;
  56. packageSourcesTreeView.DragEnd += PackageSourcesTreeViewDragEnded;
  57. }
  58. TreeViewColumn CreateTreeViewColumn ()
  59. {
  60. var column = new TreeViewColumn ();
  61. column.Spacing = 0;
  62. var dummyRenderer = new CellRendererImage ();
  63. dummyRenderer.Width = 1;
  64. dummyRenderer.Xpad = 0;
  65. column.PackStart (dummyRenderer, false);
  66. var checkBoxRenderer = new CellRendererToggle ();
  67. checkBoxRenderer.Toggled += PackageSourceCheckBoxToggled;
  68. checkBoxRenderer.Xpad = 7;
  69. checkBoxRenderer.Ypad = 12;
  70. checkBoxRenderer.Xalign = 0;
  71. checkBoxRenderer.Yalign = 0;
  72. column.PackStart (checkBoxRenderer, false);
  73. column.AddAttribute (checkBoxRenderer, "active", IsEnabledCheckBoxColumn);
  74. var iconRenderer = new CellRendererImage ();
  75. iconRenderer.StockSize = IconSize.Dnd;
  76. iconRenderer.Xalign = 0;
  77. iconRenderer.Xpad = 0;
  78. column.PackStart (iconRenderer, false);
  79. column.AddAttribute (iconRenderer, "icon-id", PackageSourceIconColumn);
  80. var packageSourceRenderer = new PackageSourceCellRenderer ();
  81. packageSourceRenderer.Mode = CellRendererMode.Activatable;
  82. column.PackStart (packageSourceRenderer, true);
  83. column.AddAttribute (packageSourceRenderer, "package-source", PackageSourceViewModelColumn);
  84. return column;
  85. }
  86. void LoadPackageSources ()
  87. {
  88. AddPackageSourcesToTreeView (viewModel.PackageSourceViewModels);
  89. }
  90. void AddPackageSourcesToTreeView (IEnumerable<PackageSourceViewModel> packageSourceViewModels)
  91. {
  92. foreach (PackageSourceViewModel packageSourceViewModel in packageSourceViewModels) {
  93. AddPackageSourceToTreeView (packageSourceViewModel);
  94. }
  95. }
  96. void AddPackageSourceToTreeView (PackageSourceViewModel packageSourceViewModel)
  97. {
  98. packageSourcesStore.AppendValues (
  99. null,
  100. packageSourceViewModel.IsEnabled,
  101. new IconId ("md-nuget-package-source"),
  102. packageSourceViewModel);
  103. }
  104. void PackageSourceCheckBoxToggled (object o, ToggledArgs args)
  105. {
  106. TreeIter iter;
  107. packageSourcesStore.GetIterFromString (out iter, args.Path);
  108. PackageSourceViewModel packageSourceViewModel = GetPackageSourceViewModel (iter);
  109. packageSourceViewModel.IsEnabled = !packageSourceViewModel.IsEnabled;
  110. packageSourcesStore.SetValue (iter, IsEnabledCheckBoxColumn, packageSourceViewModel.IsEnabled);
  111. }
  112. PackageSourceViewModel GetPackageSourceViewModel (TreeIter iter)
  113. {
  114. return packageSourcesStore.GetValue (iter, PackageSourceViewModelColumn) as PackageSourceViewModel;
  115. }
  116. void PackageSourcesTreeViewSelectionChanged (object sender, EventArgs e)
  117. {
  118. viewModel.SelectedPackageSourceViewModel = GetSelectedPackageSourceViewModel ();
  119. UpdateEnabledButtons ();
  120. }
  121. PackageSourceViewModel GetSelectedPackageSourceViewModel ()
  122. {
  123. TreeIter iter;
  124. if (packageSourcesTreeView.Selection.GetSelected (out iter)) {
  125. return GetPackageSourceViewModel (iter);
  126. }
  127. return null;
  128. }
  129. void UpdateEnabledButtons ()
  130. {
  131. this.removeButton.Sensitive = viewModel.CanRemovePackageSource;
  132. }
  133. void PackageSourceViewModelsCollectionChanged (object sender, NotifyCollectionChangedEventArgs e)
  134. {
  135. switch (e.Action) {
  136. case NotifyCollectionChangedAction.Add:
  137. AddNewPackageSources (e);
  138. break;
  139. case NotifyCollectionChangedAction.Remove:
  140. RemovePackageSources (e);
  141. break;
  142. case NotifyCollectionChangedAction.Move:
  143. MovePackageSources (e);
  144. break;
  145. }
  146. UpdateEnabledButtons ();
  147. }
  148. void AddNewPackageSources (NotifyCollectionChangedEventArgs e)
  149. {
  150. AddPackageSourcesToTreeView (e.NewItems.OfType<PackageSourceViewModel>());
  151. }
  152. void RemovePackageSources (NotifyCollectionChangedEventArgs e)
  153. {
  154. foreach (PackageSourceViewModel packageSourceViewModel in e.OldItems.OfType<PackageSourceViewModel>()) {
  155. TreeIter iter = GetTreeIter (packageSourceViewModel);
  156. packageSourcesStore.Remove (ref iter);
  157. }
  158. }
  159. TreeIter GetTreeIter (PackageSourceViewModel packageSourceViewModel)
  160. {
  161. TreeIter foundIter = TreeIter.Zero;
  162. packageSourcesStore.Foreach ((model, path, iter) => {
  163. var currentViewModel = model.GetValue (iter, PackageSourceViewModelColumn) as PackageSourceViewModel;
  164. if (currentViewModel == packageSourceViewModel) {
  165. foundIter = iter;
  166. return true;
  167. }
  168. return false;
  169. });
  170. return foundIter;
  171. }
  172. void MovePackageSources (NotifyCollectionChangedEventArgs e)
  173. {
  174. TreeIter sourceIter = GetTreeIter (e.NewItems[0] as PackageSourceViewModel);
  175. TreeIter destinationIter = GetTreeIter (e.NewStartingIndex);
  176. packageSourcesStore.Swap (sourceIter, destinationIter);
  177. }
  178. TreeIter GetTreeIter (int index)
  179. {
  180. TreeIter foundIter = TreeIter.Zero;
  181. int currentIndex = 0;
  182. packageSourcesStore.Foreach ((model, path, iter) => {
  183. if (currentIndex == index) {
  184. foundIter = iter;
  185. return true;
  186. }
  187. currentIndex++;
  188. return false;
  189. });
  190. return foundIter;
  191. }
  192. void RemoveButtonClicked (object sender, EventArgs e)
  193. {
  194. viewModel.RemovePackageSource ();
  195. UpdateEnabledButtons ();
  196. }
  197. void AddButtonClicked (object sender, EventArgs e)
  198. {
  199. viewModel.IsEditingSelectedPackageSource = false;
  200. using (var dialog = new AddPackageSourceDialog (viewModel)) {
  201. if (ShowDialogWithParent (dialog) == Xwt.Command.Ok) {
  202. UpdateSelectedPackageSource ();
  203. }
  204. UpdateEnabledButtons ();
  205. }
  206. }
  207. Xwt.Command ShowDialogWithParent (AddPackageSourceDialog dialog)
  208. {
  209. Xwt.WindowFrame parent = Xwt.Toolkit.CurrentEngine.WrapWindow (Toplevel);
  210. return dialog.Run (parent);
  211. }
  212. void UpdateSelectedPackageSource ()
  213. {
  214. TreeIter iter = GetTreeIter (viewModel.SelectedPackageSourceViewModel);
  215. if (iter.Equals (TreeIter.Zero)) {
  216. packageSourcesTreeView.Selection.UnselectAll ();
  217. } else {
  218. packageSourcesTreeView.Selection.SelectIter (iter);
  219. }
  220. }
  221. void PackageSourcesTreeViewRowActivated (object o, RowActivatedArgs args)
  222. {
  223. viewModel.IsEditingSelectedPackageSource = true;
  224. using (var dialog = new AddPackageSourceDialog (viewModel)) {
  225. ShowDialogWithParent (dialog);
  226. UpdateEnabledButtons ();
  227. }
  228. }
  229. void PackageSourcesTreeViewDragEnded (object o, DragEndArgs args)
  230. {
  231. HasPackageSourcesOrderChanged = true;
  232. }
  233. public bool HasPackageSourcesOrderChanged { get; private set; }
  234. public IEnumerable<PackageSourceViewModel> GetOrderedPackageSources ()
  235. {
  236. var packageSourceViewModels = new List<PackageSourceViewModel> ();
  237. packageSourcesStore.Foreach ((model, path, iter) => {
  238. var currentViewModel = model.GetValue (iter, PackageSourceViewModelColumn) as PackageSourceViewModel;
  239. packageSourceViewModels.Add (currentViewModel);
  240. return false;
  241. });
  242. return packageSourceViewModels;
  243. }
  244. void PackageSourceChanged (object sender, PackageSourceViewModelChangedEventArgs e)
  245. {
  246. TreeIter iter = GetTreeIter (e.PackageSource);
  247. packageSourcesStore.SetValue (
  248. iter,
  249. PackageSourceViewModelColumn,
  250. e.PackageSource);
  251. }
  252. }
  253. }