diff options
author | Lluis Sanchez <lluis@novell.com> | 2010-03-17 15:36:18 +0300 |
---|---|---|
committer | Lluis Sanchez <lluis@novell.com> | 2010-03-17 15:36:18 +0300 |
commit | 26073c35357e7c57940985325dc1d9479225476a (patch) | |
tree | 96f16599e515cf9109cb6d7fc085211934161937 /main | |
parent | 66453b10734206c23f1668ccd5c673750be919b5 (diff) | |
parent | 585086f0ea0a49166046bb8f48d2def87907d0e0 (diff) |
Merged MD.Projects into MD.Core, and MD.Projects.Gui, MD.Core.Gui and MD.Components into MD.Ide.
svn path=/trunk/monodevelop/; revision=153732
Diffstat (limited to 'main')
20 files changed, 3886 insertions, 0 deletions
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/AddFileDialog.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/AddFileDialog.cs new file mode 100644 index 0000000000..3bda3f87d8 --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/AddFileDialog.cs @@ -0,0 +1,111 @@ +// +// AddFileDialog.cs +// +// Author: +// Lluis Sanchez Gual <lluis@novell.com> +// +// Copyright (c) 2010 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +
+using System; +using MonoDevelop.Components.Extensions; +using MonoDevelop.Ide.Extensions; +using MonoDevelop.Components; +using Gtk; +using MonoDevelop.Core;
+
+
+namespace MonoDevelop.Ide.Projects
+{ + /// <summary> + /// Dialog which allows selecting files to be added to a project + /// </summary>
+ public class AddFileDialog: SelectFileDialog<IAddFileDialogHandler, AddFileDialogData>
+ {
+ public AddFileDialog (string title)
+ { + Title = title; + data.SelectMultiple = true;
+ } +
+ /// <summary> + /// Build actions from which the user can select the one to apply to the new file. + /// </summary> + public string[] BuildActions { + get { return data.BuildActions; } + set { data.BuildActions = value; } + } + + /// <summary> + /// Selected build action. + /// </summary> + public string OverrideAction { + get { return data.OverrideAction; } + } + + /// <summary> + /// Shows the dialog + /// </summary> + /// <returns> + /// True if the user clicked on OK. + /// </returns> + public bool Run () + { + if (Handler != null) + return Handler.Run (data); + + FileSelector fdiag = new FileSelector (data.Title); + fdiag.SetCurrentFolder (data.CurrentFolder); + fdiag.SelectMultiple = data.SelectMultiple; + fdiag.TransientFor = data.TransientFor; + + //add a combo that can be used to override the default build action + ComboBox combo = new ComboBox (data.BuildActions ?? new string[0]); + combo.Sensitive = false; + combo.Active = 0; + combo.RowSeparatorFunc = delegate (TreeModel model, TreeIter iter) { + return "--" == ((string) model.GetValue (iter, 0)); + }; + + CheckButton check = new CheckButton (GettextCatalog.GetString ("Override default build action")); + check.Toggled += delegate { combo.Sensitive = check.Active; }; + + HBox box = new HBox (); + fdiag.ExtraWidget = box; + box.PackStart (check, false, false, 4); + box.PackStart (combo, false, false, 4); + box.ShowAll (); + + int result; + + try { + result = fdiag.Run (); + data.SelectedFiles = fdiag.Filenames; + if (check.Active) + data.OverrideAction = combo.ActiveText; + else + data.OverrideAction = null; + return result == (int) Gtk.ResponseType.Ok; + } finally { + fdiag.Destroy (); + } + } + }
+}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/AddMimeTypeDialog.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/AddMimeTypeDialog.cs new file mode 100644 index 0000000000..a551e06cf3 --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/AddMimeTypeDialog.cs @@ -0,0 +1,120 @@ +// +// AddMimeTypeDialog.cs +// +// Author: +// Lluis Sanchez Gual <lluis@novell.com> +// +// Copyright (c) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Linq; +using System.Collections.Generic; +using MonoDevelop.Core; +using System.IO; + +namespace MonoDevelop.Ide.Projects +{ + internal partial class AddMimeTypeDialog : Gtk.Dialog + { + string mimeType; + IEnumerable<string> currentTypes; + + public AddMimeTypeDialog (IEnumerable<string> types) + { + this.Build (); + currentTypes = types; + buttonOk.Sensitive = false; + } + + protected virtual void OnEntryChanged (object sender, System.EventArgs e) + { + string name = entry.Text; + if (string.IsNullOrEmpty (name)) { + buttonOk.Sensitive = false; + labelDesc.Text = string.Empty; + image.Visible = false; + return; + } + + image.Visible = true; + + Gdk.Pixbuf img; + string desc; + + string mt = TryGetFileType (name); + if (mt != null && mt != "text/plain") { + desc = DesktopService.GetMimeTypeDescription (mt); + img = DesktopService.GetPixbufForType (mt, Gtk.IconSize.Menu); + mimeType = mt; + } + else if (name.IndexOf ('/') != -1) { + desc = DesktopService.GetMimeTypeDescription (name); + img = DesktopService.GetPixbufForType (name, Gtk.IconSize.Menu); + mimeType = name; + } else { + img = ImageService.GetPixbuf (Gtk.Stock.DialogError, Gtk.IconSize.Menu); + desc = GettextCatalog.GetString ("Unknown type"); + mimeType = null; + } + if (mimeType != null && currentTypes.Contains (mimeType)) { + img = ImageService.GetPixbuf (Gtk.Stock.DialogError, Gtk.IconSize.Menu); + desc = GettextCatalog.GetString ("Type '{0}' already registered", desc); + mimeType = null; + } + if (string.IsNullOrEmpty (desc)) + desc = mt; + buttonOk.Sensitive = mimeType != null; + labelDesc.Text = desc ?? string.Empty; + image.Pixbuf = img; + } + + string TryGetFileType (string name) + { + if (name.StartsWith (".")) + name = name.Substring (1); + + string tmpFile = null; + try { + tmpFile = System.IO.Path.GetTempFileName (); + string f = System.IO.Path.ChangeExtension (tmpFile, "." + name); + File.Move (tmpFile, f); + tmpFile = f; + return DesktopService.GetMimeTypeForUri (tmpFile); + } catch { + return null; + } finally { + if (tmpFile != null) { + try { + if (File.Exists (tmpFile)) + File.Delete (tmpFile); + } catch { + } + } + } + } + + public string MimeType { + get { + return mimeType; + } + } + } +} diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/AssemblyReferencePanel.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/AssemblyReferencePanel.cs new file mode 100644 index 0000000000..490ed40148 --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/AssemblyReferencePanel.cs @@ -0,0 +1,102 @@ +// AssemblyReferencePanel.cs +// +// Author: +// Todd Berman <tberman@sevenl.net> +// Lluis Sanchez Gual <lluis@novell.com> +// +// Copyright (c) 2004 Todd Berman +// Copyright (c) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + + +using System; +using System.IO; +using System.Text; +using MonoDevelop.Projects; +using MonoDevelop.Core; +using MonoDevelop.Components; + +using Gtk; + +namespace MonoDevelop.Ide.Projects +{ + internal class AssemblyReferencePanel : HBox, IReferencePanel + { + SelectReferenceDialog selectDialog; + FileChooserWidget chooser; + + public AssemblyReferencePanel (SelectReferenceDialog selectDialog) + { + this.selectDialog = selectDialog; + + chooser = new FileChooserWidget (FileChooserAction.Open, ""); + chooser.SetCurrentFolder (Environment.GetFolderPath (Environment.SpecialFolder.Personal)); + chooser.SelectMultiple = true; + + // this should only allow dll's and exe's + FileFilter filter = new FileFilter (); + filter.Name = GettextCatalog.GetString ("Assemblies"); + filter.AddPattern ("*.[Dd][Ll][Ll]"); + filter.AddPattern ("*.[Ee][Xx][Ee]"); + chooser.AddFilter (filter); + chooser.FileActivated += new EventHandler (SelectReferenceDialog); + + PackStart (chooser, true, true, 0); + + PackStart (new Gtk.VSeparator(), false, false, 0); + + VBox box = new VBox (); + Gtk.Button addButton = new Gtk.Button (Gtk.Stock.Add); + addButton.Clicked += new EventHandler(SelectReferenceDialog); + box.PackStart (addButton, false, false, 0); + PackStart (box, false, false, 0); + + BorderWidth = 6; + Spacing = 6; + ShowAll(); + } + + public void SetBasePath (string path) + { + chooser.SetCurrentFolder (path); + } + + void SelectReferenceDialog(object sender, EventArgs e) + { + string[] selectedFiles = new string[chooser.Filenames.Length]; + chooser.Filenames.CopyTo(selectedFiles, 0); + + foreach (string file in selectedFiles) { + bool isAssembly = true; + try { + System.Reflection.AssemblyName.GetAssemblyName(System.IO.Path.GetFullPath (file)); + } catch { + isAssembly = false; + } + + if (isAssembly) { + selectDialog.AddReference (new ProjectReference (ReferenceType.Assembly, file)); + } else { + MessageService.ShowError (GettextCatalog.GetString ("File '{0}' is not a valid .Net Assembly", file)); + } + } + } + } +} diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/CombineEntryFeatureSelector.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/CombineEntryFeatureSelector.cs new file mode 100644 index 0000000000..5c54abb186 --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/CombineEntryFeatureSelector.cs @@ -0,0 +1,200 @@ +// CombineEntryFeatureSelector.cs +// +// Author: +// Lluis Sanchez Gual <lluis@novell.com> +// +// Copyright (c) 2007 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// + + +using System; +using System.Collections.Generic; +using Gtk; +using MonoDevelop.Ide.Templates; +using MonoDevelop.Projects; +using MonoDevelop.Core; + +namespace MonoDevelop.Ide.Projects +{ + [System.ComponentModel.Category("MonoDevelop.Ide")] + [System.ComponentModel.ToolboxItem(true)] + public partial class CombineEntryFeatureSelector : Gtk.Bin + { + List<ISolutionItemFeature> selectedFeatures = new List<ISolutionItemFeature> (); + List<Gtk.Widget> selectedEditors = new List<Gtk.Widget> (); + SolutionItem entry; + SolutionFolder parentCombine; + VBox box = new VBox (); + Gdk.Cursor handCursor; + + public CombineEntryFeatureSelector () + { + this.Build(); + handCursor = new Gdk.Cursor (Gdk.CursorType.Hand1); + box.Spacing = 6; + box.BorderWidth = 3; + box.Show (); + } + + public void Fill (SolutionFolder parentCombine, SolutionItem entry, ISolutionItemFeature[] features) + { + selectedFeatures.Clear (); + selectedEditors.Clear (); + + this.entry = entry; + this.parentCombine = parentCombine; + + foreach (Gtk.Widget w in box.Children) { + box.Remove (w); + w.Destroy (); + } + // Show enabled features at the beginning + foreach (ISolutionItemFeature feature in features) + if (feature.GetSupportLevel (parentCombine, entry) == FeatureSupportLevel.Enabled) { + Gtk.Widget editor = AddFeature (feature); + selectedFeatures.Add (feature); + selectedEditors.Add (editor); + } + foreach (ISolutionItemFeature feature in features) + if (feature.GetSupportLevel (parentCombine, entry) != FeatureSupportLevel.Enabled) + AddFeature (feature); + + if (box.Children.Length == 0) { + // No features + Label lab = new Label (); + lab.Xalign = 0; + lab.Text = GettextCatalog.GetString ("There are no additional features available for this project."); + box.PackStart (lab, false, false, 0); + lab.Show (); + } + scrolled.AddWithViewport (box); + } + + Gtk.Widget AddFeature (ISolutionItemFeature feature) + { + Gtk.HBox cbox = new Gtk.HBox (); + CheckButton check = null; + + Label fl = new Label (); + fl.Wrap = true; + fl.WidthRequest = 630; + fl.Markup = "<b>" + feature.Title + "</b>\n<small>" + feature.Description + "</small>"; + bool enabledByDefault = feature.GetSupportLevel (parentCombine, entry) == FeatureSupportLevel.Enabled; + + if (enabledByDefault) { + Alignment al = new Alignment (0,0,0,0); + al.SetPadding (6,6,6,6); + al.Add (fl); + cbox.PackStart (al, false, false, 0); + } + else { + check = new CheckButton (); + check.Image = fl; + cbox.PackStart (check, false, false, 0); + check.ModifyBg (StateType.Prelight, Style.MidColors [(int)StateType.Normal]); + check.BorderWidth = 3; + } + EventBox eb = new EventBox (); + if (!enabledByDefault) { + eb.Realized += delegate { + eb.GdkWindow.Cursor = handCursor; + }; + } + eb.ModifyBg (StateType.Normal, Style.MidColors[(int)StateType.Normal]); + eb.Add (cbox); + eb.ShowAll (); + box.PackStart (eb, false, false, 0); + + HBox fbox = new HBox (); + Gtk.Widget editor = feature.CreateFeatureEditor (parentCombine, entry); + if (editor != null) { + Label sp = new Label (""); + sp.WidthRequest = 24; + sp.Show (); + fbox.PackStart (sp, false, false, 0); + editor.Show (); + fbox.PackStart (editor, false, false, 0); + box.PackStart (fbox, false, false, 0); + } + + if (check != null) { + ISolutionItemFeature f = feature; + check.Toggled += delegate { + OnClickFeature (f, check, fbox, editor); + }; + } else { + fbox.Show (); + } + return editor; + } + + void OnClickFeature (ISolutionItemFeature feature, CheckButton check, HBox fbox, Gtk.Widget editor) + { + if (editor != null) + fbox.Visible = check.Active; + if (check.Active) { + selectedFeatures.Add (feature); + selectedEditors.Add (editor); + } else { + selectedFeatures.Remove (feature); + selectedEditors.Remove (editor); + } + } + + public bool Validate () + { + for (int n=0; n<selectedFeatures.Count; n++) { + ISolutionItemFeature pf = selectedFeatures [n]; + string msg = pf.Validate (parentCombine, entry, selectedEditors [n]); + if (!string.IsNullOrEmpty (msg)) { + msg = pf.Title + ": " + msg; + MessageService.ShowError ((Gtk.Window)this.Toplevel, msg); + return false; + } + } + return true; + } + + public void ApplyFeatures () + { + for (int n=0; n<selectedFeatures.Count; n++) { + try { + ISolutionItemFeature pf = selectedFeatures [n]; + pf.ApplyFeature (parentCombine, entry, selectedEditors [n]); + } + catch (Exception ex) { + MessageService.ShowException (ex); + } + } + } + + protected override void OnDestroyed () + { + if (handCursor != null) { + handCursor.Dispose (); + handCursor = null; + } + base.OnDestroyed (); + } + + } +} diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/CombineOptionsDialog.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/CombineOptionsDialog.cs new file mode 100644 index 0000000000..9218b96190 --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/CombineOptionsDialog.cs @@ -0,0 +1,48 @@ +// +// CombineOptionsDialog.cs +// +// Author: +// Lluis Sanchez Gual +// +// Copyright (C) 2005 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; + +using Mono.Addins; +using MonoDevelop.Core; +using MonoDevelop.Projects; +using MonoDevelop.Ide.Gui.Dialogs; + +namespace MonoDevelop.Ide.Projects +{ + public class CombineOptionsDialog : MultiConfigItemOptionsDialog + { + public CombineOptionsDialog (Gtk.Window parentWindow, Solution solution) : base (parentWindow, solution) + { + this.Title = GettextCatalog.GetString ("Solution Options") + " - " + solution.Name; + } + } +} diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/ConfirmProjectDeleteDialog.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/ConfirmProjectDeleteDialog.cs new file mode 100644 index 0000000000..3306b6d74a --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/ConfirmProjectDeleteDialog.cs @@ -0,0 +1,278 @@ +// +// ConfirmProjectDeleteDialog.cs +// +// Author: +// Lluis Sanchez Gual <lluis@novell.com> +// +// Copyright (c) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.IO; +using System.Collections.Generic; +using MonoDevelop.Core; +using MonoDevelop.Projects; + +using Gtk; + +namespace MonoDevelop.Ide.Projects +{ + public partial class ConfirmProjectDeleteDialog : Gtk.Dialog + { + TreeStore store; + IWorkspaceFileObject item; + Dictionary<FilePath, TreeIter> paths = new Dictionary<FilePath, TreeIter> (); + + enum ChildInfo { + None = 0, + AllSelected = 1, + SomeSelected = 2, + HasProjectFiles = 4 + } + + static IList<string> knownExtensions = new string [] { + ".pidb", ".userprefs", ".usertasks" + }; + static IList<string> knownSubdirs = new string [] { + "bin" + }; + + public ConfirmProjectDeleteDialog (IWorkspaceFileObject item) + { + this.Build (); + this.item = item; + + store = new TreeStore (typeof(bool), typeof(Gdk.Pixbuf), typeof(string), typeof(string), typeof(string)); + fileList.Model = store; + + TreeViewColumn col = new TreeViewColumn (); + + CellRendererToggle crt = new CellRendererToggle (); + crt.Toggled += CrtToggled; + col.PackStart (crt, false); + col.AddAttribute (crt, "active", 0); + + CellRendererPixbuf crp = new CellRendererPixbuf (); + col.PackStart (crp, false); + col.AddAttribute (crp, "pixbuf", 1); + + CellRendererText cre = new CellRendererText (); + col.PackStart (cre, true); + col.AddAttribute (cre, "text", 2); + col.AddAttribute (cre, "foreground", 4); + + fileList.AppendColumn (col); + store.SetSortColumnId (2, SortType.Ascending); + + labelProjectDir.Text = item.BaseDirectory.FullPath; + + HashSet<string> itemFiles = new HashSet<string> (); + HashSet<string> knownPaths = new HashSet<string> (); + + foreach (FilePath file in item.GetItemFiles (true)) { + itemFiles.Add (file.FullPath); + knownPaths.Add (file.FullPath + "~"); + } + + foreach (string ext in knownExtensions) + knownPaths.Add (item.FileName.ChangeExtension (ext)); + + FillDirRec (TreeIter.Zero, item, itemFiles, knownPaths, item.BaseDirectory, false); + + if (item.BaseDirectory != item.ItemDirectory) { + // If the project has a custom base directory, make sure the project files + // from the item directory are shown in the list + foreach (FilePath f in item.GetItemFiles (false)) { + if (!f.IsChildPathOf (item.BaseDirectory)) { + Gdk.Pixbuf pix = DesktopService.GetPixbufForFile (f, IconSize.Menu); + paths [f] = store.AppendValues (true, pix, f.FileName, f.ToString ()); + } + } + } + + if (item.BaseDirectory.FileName == item.Name) { + radioDeleteAll.Active = true; + fileList.Sensitive = false; + } + else { + radioDeleteSel.Active = true; + Focus = radioDeleteSel; + } + } + + public List<FilePath> GetFilesToDelete () + { + List<FilePath> files = new List<FilePath> (); + + if (radioDeleteAll.Active) { + files.Add (item.BaseDirectory); + if (item.BaseDirectory != item.ItemDirectory) { + foreach (FilePath f in item.GetItemFiles (false)) { + if (!f.IsChildPathOf (item.BaseDirectory)) + files.Add (f); + } + } + return files; + } + + foreach (Gtk.TreeIter it in paths.Values) { + if ((bool) store.GetValue (it, 0)) + files.Add ((string) store.GetValue (it, 3)); + } + + // If a directory is selected, remove all files of that directory, + // since the dir will be deleted as a whole + + List<FilePath> cleaned = new List<FilePath> (files); + foreach (FilePath path in files) { + if (Directory.Exists (path)) { + for (int n=0; n<cleaned.Count; n++) { + if (cleaned [n].IsChildPathOf (path)) { + cleaned.RemoveAt (n); + n--; + } + } + } + } + return cleaned; + } + + ChildInfo FillDirRec (Gtk.TreeIter iter, IWorkspaceFileObject item, HashSet<string> itemFiles, HashSet<string> knownPaths, FilePath dir, bool forceSet) + { + ChildInfo cinfo = ChildInfo.AllSelected; + bool hasChildren = false; + + foreach (string sd in knownSubdirs) { + if (dir == item.BaseDirectory.Combine (sd)) { + forceSet = true; + break; + } + } + + TreeIter dit; + if (!iter.Equals (TreeIter.Zero)) { + dit = store.AppendValues (iter, false, DesktopService.GetPixbufForFile (dir, IconSize.Menu), dir.FileName.ToString (), dir.ToString ()); + fileList.ExpandRow (store.GetPath (iter), false); + } + else + dit = store.AppendValues (false, DesktopService.GetPixbufForFile (dir, IconSize.Menu), dir.FileName.ToString (), dir.ToString ()); + + paths [dir] = dit; + + foreach (string file in Directory.GetFiles (dir)) { + string path = System.IO.Path.GetFileName (file); + Gdk.Pixbuf pix = DesktopService.GetPixbufForFile (file, IconSize.Menu); + bool active = itemFiles.Contains (file); + string color = null; + if (!active) { + pix = ImageService.MakeTransparent (pix, 0.5); + color = "dimgrey"; + } else + cinfo |= ChildInfo.HasProjectFiles; + + active = active || forceSet || knownPaths.Contains (file); + if (!active) + cinfo &= ~ChildInfo.AllSelected; + else + cinfo |= ChildInfo.SomeSelected; + + paths [file] = store.AppendValues (dit, active, pix, path, file, color); + if (!hasChildren) { + hasChildren = true; + fileList.ExpandRow (store.GetPath (dit), false); + } + } + foreach (string cdir in Directory.GetDirectories (dir)) { + hasChildren = true; + ChildInfo ci = FillDirRec (dit, item, itemFiles, knownPaths, cdir, forceSet); + if ((ci & ChildInfo.AllSelected) == 0) + cinfo &= ~ChildInfo.AllSelected; + cinfo |= ci & (ChildInfo.SomeSelected | ChildInfo.HasProjectFiles); + } + if ((cinfo & ChildInfo.AllSelected) != 0 && hasChildren) + store.SetValue (dit, 0, true); + if ((cinfo & ChildInfo.HasProjectFiles) == 0) { + Gdk.Pixbuf pix = DesktopService.GetPixbufForFile (dir, IconSize.Menu); + pix = ImageService.MakeTransparent (pix, 0.5); + store.SetValue (dit, 1, pix); + store.SetValue (dit, 4, "dimgrey"); + } + if ((cinfo & ChildInfo.SomeSelected) != 0 && (cinfo & ChildInfo.AllSelected) == 0) { + fileList.ExpandRow (store.GetPath (dit), false); + } else { + fileList.CollapseRow (store.GetPath (dit)); + } + return cinfo; + } + + void CrtToggled (object o, ToggledArgs args) + { + TreeIter iter; + if (!store.GetIterFromString (out iter, args.Path)) + return; + + bool currentVal = !(bool) store.GetValue (iter, 0); + string path = (string) store.GetValue (iter, 3); + + store.SetValue (iter, 0, currentVal); + + if (Directory.Exists (path)) + SelectWholeDirectory (path, currentVal); + + UpdateDirectoryToggle (System.IO.Path.GetDirectoryName (path)); + } + + void SelectWholeDirectory (string path, bool sel) + { + FilePath basePath = path; + foreach (Gtk.TreeIter it in paths.Values) { + FilePath cpath = (string) store.GetValue (it, 3); + if (cpath.IsChildPathOf (basePath)) + store.SetValue (it, 0, sel); + } + } + + void UpdateDirectoryToggle (string path) + { + bool allChildrenSet = true; + FilePath basePath = path; + Gtk.TreeIter itDir = Gtk.TreeIter.Zero; + foreach (Gtk.TreeIter it in paths.Values) { + FilePath cpath = (string) store.GetValue (it, 3); + if (cpath == basePath) + itDir = it; + else if (cpath.IsChildPathOf (basePath) && !(bool)store.GetValue (it, 0)) + allChildrenSet = false; + } + + if (!itDir.Equals (TreeIter.Zero)) { + if (allChildrenSet != (bool) store.GetValue (itDir, 0)) { + store.SetValue (itDir, 0, allChildrenSet); + UpdateDirectoryToggle (basePath.ParentDirectory); + } + } + } + + protected virtual void OnRadioDeleteAllToggled (object sender, System.EventArgs e) + { + fileList.Sensitive = radioDeleteSel.Active; + } + } +} diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/DefaultPolicyOptionsDialog.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/DefaultPolicyOptionsDialog.cs new file mode 100644 index 0000000000..ac5e0e001e --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/DefaultPolicyOptionsDialog.cs @@ -0,0 +1,47 @@ +// +// DefaultPolicyOptionsDialog.cs +// +// Author: +// Michael Hutchinson <mhutchinson@novell.com> +// +// Copyright (C) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using Mono.Addins; +using MonoDevelop.Ide.Projects.OptionPanels; +using MonoDevelop.Core; +using MonoDevelop.Ide.Gui.Dialogs; +using MonoDevelop.Projects.Policies; + +namespace MonoDevelop.Ide.Projects +{ + public class DefaultPolicyOptionsDialog : OptionsDialog + { + public DefaultPolicyOptionsDialog (Gtk.Window parentWindow) + : base (parentWindow, PolicyService.GetUserDefaultPolicySet (), + "/MonoDevelop/ProjectModel/Gui/DefaultPolicyPanels") + { + this.Title = GettextCatalog.GetString ("Default Policies"); + } + } +} diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/DeleteConfigDialog.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/DeleteConfigDialog.cs new file mode 100644 index 0000000000..f0c0f8e034 --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/DeleteConfigDialog.cs @@ -0,0 +1,43 @@ +// DeleteConfigDialog.cs +// +//Author: +// Lluis Sanchez Gual +// +//Copyright (c) 2007 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// + +using System; + +namespace MonoDevelop.Ide.Projects +{ + internal partial class DeleteConfigDialog: Gtk.Dialog + { + public DeleteConfigDialog() + { + Build (); + } + + public bool DeleteChildren { + get { return deleteChildrenCheck.Active; } + } + } +} diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/ExportProjectDialog.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/ExportProjectDialog.cs new file mode 100644 index 0000000000..039e4bad67 --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/ExportProjectDialog.cs @@ -0,0 +1,77 @@ +// ExportProjectDialog.cs +// +// Author: +// Lluis Sanchez Gual <lluis@novell.com> +// +// Copyright (c) 2007 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// + + +using System; +using System.IO; +using MonoDevelop.Components; +using MonoDevelop.Projects; + +namespace MonoDevelop.Ide.Projects +{ + public partial class ExportProjectDialog : Gtk.Dialog + { + FileFormat[] formats; + + public ExportProjectDialog (IWorkspaceObject entry, FileFormat selectedFormat) + { + this.Build(); + + FileFormat f = entry is WorkspaceItem ? ((WorkspaceItem)entry).FileFormat : ((SolutionEntityItem)entry).FileFormat; + labelNewFormat.Text = f.Name; + + formats = Services.ProjectService.FileFormats.GetFileFormatsForObject (entry); + foreach (FileFormat format in formats) + comboFormat.AppendText (format.Name); + + int sel = Array.IndexOf (formats, selectedFormat); + if (sel == -1) sel = 0; + comboFormat.Active = sel; + + folderEntry.Path = entry.ItemDirectory; + UpdateControls (); + } + + public FileFormat Format { + get { return formats [comboFormat.Active]; } + } + + public string TargetFolder { + get { return folderEntry.Path; } + } + + void UpdateControls () + { + buttonOk.Sensitive = folderEntry.Path.Length > 0; + } + + protected virtual void OnFolderEntryPathChanged(object sender, System.EventArgs e) + { + UpdateControls (); + } + } +} diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/FeatureSelectorDialog.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/FeatureSelectorDialog.cs new file mode 100644 index 0000000000..1eab8d9141 --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/FeatureSelectorDialog.cs @@ -0,0 +1,51 @@ +// FeatureSelectorDialog.cs +// +// Author: +// Lluis Sanchez Gual <lluis@novell.com> +// +// Copyright (c) 2007 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// + + +using System; +using MonoDevelop.Projects; +using MonoDevelop.Ide.Templates; + +namespace MonoDevelop.Ide.Projects +{ + + + public partial class FeatureSelectorDialog : Gtk.Dialog + { + public FeatureSelectorDialog (SolutionFolder parentCombine, SolutionItem entry) + { + this.Build(); + featureList.Fill (parentCombine, entry, SolutionItemFeatures.GetFeatures (parentCombine, entry)); + } + + protected virtual void OnButtonOkClicked(object sender, System.EventArgs e) + { + featureList.ApplyFeatures (); + Respond (Gtk.ResponseType.Ok); + } + } +} diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/GacReferencePanel.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/GacReferencePanel.cs new file mode 100644 index 0000000000..cef21e48a9 --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/GacReferencePanel.cs @@ -0,0 +1,163 @@ +// GacReferencePanel.cs +// +// Author: +// Todd Berman <tberman@sevenl.net> +// Viktoria Dudka <viktoriad@remobjects.com> +// +// Copyright (c) 2004 Todd Berman +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Gtk; +using MonoDevelop.Core.Assemblies; +using MonoDevelop.Projects; +using MonoDevelop.Core; +using System.Globalization; + +namespace MonoDevelop.Ide.Projects +{ + internal class GacReferencePanel : VBox, IReferencePanel + { + ListStore store = null; + private TreeView treeView = null; + + private SelectReferenceDialog selectDialog = null; + + public GacReferencePanel (SelectReferenceDialog selectDialog) + { + this.selectDialog = selectDialog; + + store = new ListStore (typeof (string), typeof (string), typeof (SystemAssembly), typeof (bool), typeof (string), typeof (string)); + treeView = new TreeView (store); + + TreeViewColumn firstColumn = new TreeViewColumn (); + CellRendererToggle tog_render = new CellRendererToggle (); + tog_render.Toggled += new Gtk.ToggledHandler (AddReference); + firstColumn.PackStart (tog_render, false); + firstColumn.AddAttribute (tog_render, "active", 3); + + treeView.AppendColumn (firstColumn); + + TreeViewColumn secondColumn = new TreeViewColumn (); + secondColumn.Title = GettextCatalog.GetString ("Assembly"); + CellRendererPixbuf crp = new CellRendererPixbuf (); + secondColumn.PackStart (crp, false); + crp.StockId = "md-package"; + + CellRendererText text_render = new CellRendererText (); + secondColumn.PackStart (text_render, true); + secondColumn.AddAttribute (text_render, "text", 0); + + treeView.AppendColumn (secondColumn); + + treeView.AppendColumn (GettextCatalog.GetString ("Version"), new CellRendererText (), "text", 1); + treeView.AppendColumn (GettextCatalog.GetString ("Package"), new CellRendererText (), "text", 5); + + treeView.Columns[1].Resizable = true; + + store.SetSortColumnId (0, SortType.Ascending); + store.SetSortFunc (0, new TreeIterCompareFunc (Sort)); + + ScrolledWindow sc = new ScrolledWindow (); + sc.ShadowType = Gtk.ShadowType.In; + sc.Add (treeView); + this.PackStart (sc, true, true, 0); + ShowAll (); + BorderWidth = 6; + } + + private IAssemblyContext targetContext; + private TargetFramework targetVersion; + public void SetTargetFramework (IAssemblyContext targetContext, TargetFramework targetVersion) + { + this.targetContext = targetContext; + this.targetVersion = targetVersion; + } + + public void Reset () + { + store.Clear (); + + foreach (SystemAssembly systemAssembly in targetContext.GetAssemblies (targetVersion)) { + if (systemAssembly.Package.IsFrameworkPackage && systemAssembly.Name == "mscorlib") + continue; + + if (systemAssembly.Package.IsInternalPackage) { + store.AppendValues (systemAssembly.Name, + systemAssembly.Version, + systemAssembly, + false, + systemAssembly.FullName, + systemAssembly.Package.Name + " " + GettextCatalog.GetString ("(Provided by MonoDevelop)")); + } + else { + store.AppendValues (systemAssembly.Name, systemAssembly.Version, systemAssembly, false, systemAssembly.FullName, systemAssembly.Package.Name); + } + } + } + + public void SignalRefChange (ProjectReference refInfo, bool newState) + { + TreeIter iter = new TreeIter (); + + if (store.GetIterFirst (out iter)) { + do { + SystemAssembly systemAssembly = store.GetValue(iter, 2) as SystemAssembly; + + if ( (refInfo.Reference == systemAssembly.FullName) && (refInfo.Package == systemAssembly.Package) ) { + store.SetValue(iter, 3, newState); + return; + } + } while (store.IterNext (ref iter)); + } + + } + + private int Sort (TreeModel model, TreeIter left, TreeIter right) + { + int result = String.Compare ((string)model.GetValue (left, 0), (string)model.GetValue (right, 0), StringComparison.InvariantCultureIgnoreCase); + + if (result != 0) + return result; + + return String.Compare ((string)model.GetValue (left, 1), (string)model.GetValue (right, 1), StringComparison.InvariantCultureIgnoreCase); + } + + public void AddReference (object sender, Gtk.ToggledArgs e) + { + Gtk.TreeIter iter; + store.GetIterFromString (out iter, e.Path); + if ((bool)store.GetValue (iter, 3) == false) { + store.SetValue (iter, 3, true); + ProjectReference pr = new ProjectReference ((SystemAssembly)store.GetValue (iter, 2)); + selectDialog.AddReference (pr); + } + else { + store.SetValue (iter, 3, false); + selectDialog.RemoveReference (ReferenceType.Gac, (string)store.GetValue (iter, 4)); + } + } + } +} diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/IncludeNewFilesDialog.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/IncludeNewFilesDialog.cs new file mode 100644 index 0000000000..c51fcf7b1c --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/IncludeNewFilesDialog.cs @@ -0,0 +1,201 @@ +// +// IncludeNewFilesDialog.cs +// +// Author: +// Mike Krüger <mkrueger@novell.com> +// +// Copyright (c) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using Gtk; +using System.Collections.Generic; +using MonoDevelop.Projects; +using MonoDevelop.Core; +using System.IO; + +namespace MonoDevelop.Ide.Projects +{ + partial class IncludeNewFilesDialog : Gtk.Dialog + { + TreeStore store; + Project project; + + static class Columns { + public static int IconOpened = 0; + public static int IconClosed = 1; + public static int Text = 2; + public static int FileName = 3; + public static int IsToggled = 4; + } + + public IncludeNewFilesDialog (Project project) + { + this.Build (); + this.Title = GettextCatalog.GetString ("Found new files in {0}", project.Name); + this.project = project; + store = new TreeStore (typeof (Gdk.Pixbuf), // Image + typeof (Gdk.Pixbuf), // Image - closed + typeof (string), // Text + typeof (string), // FileName + typeof (bool) // IsToggled + ); + treeviewFiles.Model = store; + + treeviewFiles.HeadersVisible = false; // Headers are untranslated because they're hidden as default + + TreeViewColumn textColumn = new TreeViewColumn (); + + CellRendererToggle toggleRender = new CellRendererToggle (); + toggleRender.Toggled += ToggleRenderToggled; + textColumn.PackStart (toggleRender, false); + textColumn.AddAttribute (toggleRender, "active", Columns.IsToggled); + + textColumn.Title = "Name"; + var pixbufRenderer = new CellRendererPixbuf (); + textColumn.PackStart (pixbufRenderer, false); + textColumn.AddAttribute (pixbufRenderer, "pixbuf", Columns.IconOpened); + textColumn.AddAttribute (pixbufRenderer, "pixbuf-expander-open", Columns.IconOpened); + textColumn.AddAttribute (pixbufRenderer, "pixbuf-expander-closed", Columns.IconClosed); + + CellRendererText textRenderer = new CellRendererText (); + textColumn.PackStart (textRenderer, false); + textColumn.AddAttribute (textRenderer, "text", Columns.Text); + treeviewFiles.AppendColumn (textColumn); + buttonExcludeAll.Clicked += ButtonExcludeAllClicked; + buttonIncludeAll.Clicked += ButtonIncludeAllClicked; + buttonOk.Clicked += ButtonOkClicked; + } + + void ButtonOkClicked (object sender, EventArgs e) + { + TraverseSubtree (TreeIter.Zero, delegate (TreeIter currentIter) { + bool isToggled = (bool) store.GetValue (currentIter, Columns.IsToggled); + string fileName = (string) store.GetValue (currentIter, Columns.FileName); + if (fileName != null) { + if (isToggled) { + project.AddFile (fileName); + } else { + ProjectFile projectFile = project.AddFile (fileName, BuildAction.None); + if (projectFile != null) + projectFile.Visible = false; + } + } + }); + IdeApp.ProjectOperations.Save (project); + } + + void ButtonIncludeAllClicked (object sender, EventArgs e) + { + SetSubtreeIsToggled (TreeIter.Zero, true); + } + + void ButtonExcludeAllClicked (object sender, EventArgs e) + { + SetSubtreeIsToggled (TreeIter.Zero, false); + } + + void ToggleRenderToggled (object o, ToggledArgs args) + { + Gtk.TreeIter iter; + if (store.GetIterFromString(out iter, args.Path)) { + bool isToggled = !(bool)store.GetValue (iter, Columns.IsToggled); + store.SetValue (iter, Columns.IsToggled, isToggled); + if (store.IterHasChild (iter)) + SetSubtreeIsToggled (iter, isToggled); + } + } + + void TraverseSubtree (TreeIter iter, Action<TreeIter> action) + { + TreeIter newIter; + if (store.IterIsValid (iter)) { + store.IterNthChild (out newIter, iter, 0); + } else { + store.IterNthChild (out newIter, 0); + } + do { + action (newIter); + if (store.IterHasChild (newIter)) + TraverseSubtree (newIter, action); + } while (store.IterNext (ref newIter)); + } + + void SetSubtreeIsToggled (TreeIter iter, bool isToggled) + { + TraverseSubtree (iter, delegate (TreeIter newIter) { + store.SetValue (newIter, Columns.IsToggled, isToggled); + }); + } + + public void AddFiles (IEnumerable<string> newFiles) + { + foreach (string fileName in newFiles) { + AddFile (fileName); + } + treeviewFiles.ExpandAll (); + } + + TreeIter SearchPath (TreeIter parent, string path) + { + TreeIter iter; + if (store.IterChildren (out iter, parent)) { + do { + string name = (string)store.GetValue (iter, Columns.Text); + if (name == path) + return iter; + } while (store.IterNext (ref iter)); + } + return store.AppendValues (parent, ImageService.GetPixbuf (MonoDevelop.Ide.Gui.Stock.OpenFolder, IconSize.Menu), ImageService.GetPixbuf (MonoDevelop.Ide.Gui.Stock.ClosedFolder, IconSize.Menu), path, null, false); + } + + TreeIter GetPath (string fullPath) + { + if (string.IsNullOrEmpty (fullPath)) + return TreeIter.Zero; + string[] paths = fullPath.Split (System.IO.Path.DirectorySeparatorChar, System.IO.Path.AltDirectorySeparatorChar); + TreeIter iter; + if (!store.GetIterFirst (out iter)) + return TreeIter.Zero; + for (int i = 0; i < paths.Length; i++) { + iter = SearchPath (iter, paths[i]); + } + return iter; + } + + void AddFile (string fileName) + { + string relativePath = FileService.AbsoluteToRelativePath (project.BaseDirectory, fileName); + TreeIter iter = GetPath (System.IO.Path.GetDirectoryName (relativePath)); + object[] values = new object[] { + DesktopService.GetPixbufForFile (fileName, IconSize.Menu), + null, + System.IO.Path.GetFileName (fileName), + fileName, + false + }; + if (!store.IterIsValid (iter)) { + store.AppendValues (values); + return; + } + store.AppendValues (iter, values); + } + } +} diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/NewConfigurationDialog.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/NewConfigurationDialog.cs new file mode 100644 index 0000000000..bfb5c529d3 --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/NewConfigurationDialog.cs @@ -0,0 +1,89 @@ +// NewConfigurationDialog.cs +// +// Author: +// Lluis Sanchez Gual <lluis@novell.com> +// +// Copyright (c) 2007 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// + +using System.Collections.Generic; +using MonoDevelop.Core; +using MonoDevelop.Projects; +using MonoDevelop.Ide.Gui.Dialogs; + +namespace MonoDevelop.Ide.Projects +{ + partial class NewConfigurationDialog : Gtk.Dialog + { + ItemConfigurationCollection<ItemConfiguration> configurations; + + public NewConfigurationDialog (ItemConfigurationCollection<ItemConfiguration> configurations) + { + this.Build(); + this.configurations = configurations; + HashSet<string> configs = new HashSet<string> (); + HashSet<string> platforms = new HashSet<string> (); + foreach (ItemConfiguration conf in configurations) { + if (configs.Add (conf.Name)) + comboName.AppendText (conf.Name); + string plat = MultiConfigItemOptionsPanel.GetPlatformName (conf.Platform); + if (platforms.Add (plat)) + comboPlatform.AppendText (plat); + } + comboPlatform.Entry.Text = MultiConfigItemOptionsPanel.GetPlatformName (""); + } + + public string ConfigName { + get { + string plat = MultiConfigItemOptionsPanel.GetPlatformId (comboPlatform.Entry.Text.Trim ()); + if (string.IsNullOrEmpty (plat)) + return comboName.Entry.Text.Trim (); + else + return comboName.Entry.Text.Trim () + "|" + plat; + } + set { + int i = value.LastIndexOf ('|'); + if (i == -1) { + comboName.Entry.Text = value; + comboPlatform.Entry.Text = string.Empty; + } else { + comboName.Entry.Text = value.Substring (0, i); + comboPlatform.Entry.Text = MultiConfigItemOptionsPanel.GetPlatformName (value.Substring (i+1)); + } + } + } + + public bool CreateChildren { + get { return createChildrenCheck.Active; } + } + + protected virtual void OnOkbutton1Clicked (object sender, System.EventArgs e) + { + if (comboName.Entry.Text.Trim ().Length == 0 || comboName.Entry.Text.IndexOf ('|') != -1) { + MessageService.ShowWarning (this, GettextCatalog.GetString ("Please enter a valid configuration name.")); + } else if (configurations [ConfigName] != null) { + MessageService.ShowWarning (this, GettextCatalog.GetString ("A configuration with the name '{0}' already exists.", ConfigName)); + } else + Respond (Gtk.ResponseType.Ok); + } + } +} diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/NewFileDialog.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/NewFileDialog.cs new file mode 100644 index 0000000000..1df3984092 --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/NewFileDialog.cs @@ -0,0 +1,636 @@ +// NewFileDialog.cs +// +// Author: +// Todd Berman <tberman@off.net> +// Viktoria Dudka <viktoriad@remobjects.com> +// +// Copyright (c) 2004 Todd Berman +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.IO; + +using MonoDevelop.Ide.Gui.Dialogs; +using MonoDevelop.Core; +using Mono.Addins; +using MonoDevelop.Ide.Templates; +using MonoDevelop.Ide.Gui; +using MonoDevelop.Projects; + +using Gtk; +using MonoDevelop.Components; +using IconView = MonoDevelop.Components.IconView; +using Gdk; + +namespace MonoDevelop.Ide.Projects +{ + /// <summary> + /// This class is for creating a new "empty" file + /// </summary> + internal partial class NewFileDialog : Dialog + { + List<TemplateItem> alltemplates = new List<TemplateItem> (); + List<Category> categories = new List<Category> (); + Dictionary<string, bool> activeLangs = new Dictionary<string, bool> (); + + TreeStore catStore; + + // Add To Project widgets + string[] projectNames; + Project[] projectRefs; + + Project parentProject; + string basePath; + + string userEditedEntryText = null; + string previousDefaultEntryText = null; + + public NewFileDialog (Project parentProject, string basePath) + { + Build (); + this.parentProject = parentProject; + this.basePath = basePath; + + BorderWidth = 6; + TransientFor = IdeApp.Workbench.RootWindow; + HasSeparator = false; + + InitializeComponents (); + + nameEntry.GrabFocus (); + + } + + + void InitializeView () + { + InsertCategories (TreeIter.Zero, categories); + + TreeIter treeIter; + if (!FindCatIter (PropertyService.Get (GetCategoryPropertyKey (parentProject), "General"), out treeIter)) { + if (!FindCatIter ("Misc", out treeIter)) + if (!catStore.GetIterFirst (out treeIter)) + return; + } + catView.Selection.SelectIter (treeIter); + } + + void InsertCategories (TreeIter node, List<Category> catarray) + { + foreach (Category category in catarray) { + if (TreeIter.Zero.Equals (node)) + InsertCategories (catStore.AppendValues (category.Name, category.Categories, category.Templates, ImageService.GetPixbuf ("md-closed-folder")), category.Categories); + else + InsertCategories (catStore.AppendValues (node, category.Name, category.Categories, category.Templates, ImageService.GetPixbuf ("md-closed-folder")), category.Categories); + } + } + + Category GetCategory (string categoryname) + { + return GetCategory (categories, categoryname); + } + + Category GetCategory (List<Category> catList, string categoryname) + { + foreach (Category category in catList) { + if (category.Name == categoryname) + return category; + } + + Category cat = new Category (categoryname); + catList.Add (cat); + return cat; + + } + + void CategoryChange (object sender, EventArgs e) + { + TreeModel treeModel; + TreeIter treeIter; + + if (catView.Selection.GetSelected (out treeModel, out treeIter)) { + okButton.Sensitive = false; + FillCategoryTemplates (treeIter); + } + } + + + + void InitializeDialog (bool update) + { + if (update) { + alltemplates.Clear (); + categories.Clear (); + catStore.Clear (); + activeLangs.Clear (); + } + + InitializeTemplates (); + + if (update) { + iconView.Clear (); + InitializeView (); + } + } + + + protected override void OnDestroyed () + { + if (catStore != null) { + catStore.Dispose (); + catStore = null; + } + base.OnDestroyed (); + } + + static string GetCategoryPropertyKey (Project proj) + { + string key = "Dialogs.NewFileDialog.LastSelectedCategory"; + if (proj != null) { + key += "." + proj.ProjectType; + if (proj is DotNetProject) + key += "." + ((DotNetProject)proj).LanguageName; + } + return key; + } + + bool FindCatIter (string catPath, out TreeIter iter) + { + string[] cats = catPath.Split ('/'); + iter = TreeIter.Zero; + + TreeIter nextIter; + if (!catStore.GetIterFirst (out nextIter)) + return false; + + for (int i = 0; i < cats.Length; i++) { + if (FindCategoryAtCurrentLevel (cats[i], ref nextIter)) { + iter = nextIter; + if (i >= cats.Length - 1 || !catStore.IterChildren (out nextIter, nextIter)) + return true; + } + } + return false; + } + + bool FindCategoryAtCurrentLevel (string category, ref TreeIter iter) + { + TreeIter trial = iter; + do { + string val = (string)catStore.GetValue (trial, 0); + if (val == category) { + iter = trial; + return true; + } + } while (catStore.IterNext (ref trial)); + return false; + } + + string GetCatPath (TreeIter iter) + { + TreeIter currentIter = iter; + string path = (string)catStore.GetValue (currentIter, 0); + while (catStore.IterParent (out currentIter, currentIter)) { + path = ((string)catStore.GetValue (currentIter, 0)) + "/" + path; + } + return path; + } + + + + public void SelectTemplate (string id) + { + TreeIter iter; + catStore.GetIterFirst (out iter); + SelectTemplate (iter, id); + } + + public bool SelectTemplate (TreeIter iter, string id) + { + do { + foreach (TemplateItem item in (List<TemplateItem>)(catStore.GetValue (iter, 2))) { + if (item.Template.Id == id) { + catView.ExpandToPath (catStore.GetPath (iter)); + catView.Selection.SelectIter (iter); + CategoryChange (null, null); + iconView.CurrentlySelected = item; + return true; + } + } + + TreeIter citer; + if (catStore.IterChildren (out citer, iter)) { + do { + if (SelectTemplate (citer, id)) + return true; + } while (catStore.IterNext (ref citer)); + } + + } while (catStore.IterNext (ref iter)); + return false; + } + + + + void InitializeTemplates () + { + Project project = null; + + if (!boxProject.Visible || projectAddCheckbox.Active) + project = parentProject; + + foreach (FileTemplate template in FileTemplate.GetFileTemplates (project, basePath)) { + List<string> langs = template.GetCompatibleLanguages (project, basePath); + if (langs != null) { + foreach (string language in langs) { + AddTemplate (new TemplateItem (template, language), language); + //count the number of active languages + activeLangs[language] = true; + } + } + + } + } + + void AddTemplate (TemplateItem titem, string templateLanguage) + { + Project project = null; + Category cat = null; + + if (!boxProject.Visible || projectAddCheckbox.Active) + project = parentProject; + + if (project != null) { + if ((templateLanguage != "") && (activeLangs.Count > 2)) { + // The template requires a language, but the project does not have a single fixed + // language type (plus empty match), so create a language category + cat = GetCategory (templateLanguage); + cat = GetCategory (cat.Categories, titem.Template.Category); + } else { + cat = GetCategory (titem.Template.Category); + } + } else { + if (templateLanguage != "") { + // The template requires a language, but there is no current language set, so + // create a category for it + cat = GetCategory (templateLanguage); + cat = GetCategory (cat.Categories, titem.Template.Category); + } else { + cat = GetCategory (titem.Template.Category); + } + } + + cat.Templates.Add (titem); + + if (cat.Selected == false && titem.Template.WizardPath == null) { + cat.Selected = true; + } + + if (!cat.HasSelectedTemplate && titem.Template.Files.Count == 1) { + if (((FileDescriptionTemplate)titem.Template.Files[0]).Name.StartsWith ("Empty")) { + //titem.Selected = true; + cat.HasSelectedTemplate = true; + } + } + + alltemplates.Add (titem); + } + + //tree view event handler for double-click + //toggle the expand collapse methods. + void CategoryActivated (object sender, RowActivatedArgs args) + { + if (!catView.GetRowExpanded (args.Path)) { + catView.ExpandRow (args.Path, false); + } else { + catView.CollapseRow (args.Path); + } + } + + void FillCategoryTemplates (TreeIter iter) + { + iconView.Clear (); + foreach (TemplateItem item in (List<TemplateItem>)(catStore.GetValue (iter, 2))) { + iconView.AddIcon (new Gtk.Image (ImageService.GetPixbuf (item.Template.Icon, Gtk.IconSize.Dnd)), GettextCatalog.GetString (item.Name), item); + } + } + + // list view event handlers + void SelectedIndexChange (object sender, EventArgs e) + { + UpdateOkStatus (); + } + + void NameChanged (object sender, EventArgs e) + { + UpdateOkStatus (); + } + + void UpdateOkStatus () + { + try { + TemplateItem sel = (TemplateItem)iconView.CurrentlySelected; + if (sel == null) { + okButton.Sensitive = false; + return; + } + + FileTemplate item = sel.Template; + + if (item != null) { + infoLabel.Text = item.Description; + + //desensitise the text entry if the name is fixed + //careful to store user-entered text so we can replace it if they change their selection + if (item.IsFixedFilename) { + if (userEditedEntryText == null) + userEditedEntryText = nameEntry.Text; + nameEntry.Text = item.DefaultFilename; + nameEntry.Sensitive = false; + } else { + if (userEditedEntryText != null) { + nameEntry.Text = userEditedEntryText; + userEditedEntryText = null; + } + nameEntry.Sensitive = true; + } + + //fill in a default name if text entry is empty or contains a default name + if ((string.IsNullOrEmpty (nameEntry.Text) || (previousDefaultEntryText == nameEntry.Text)) && !string.IsNullOrEmpty (item.DefaultFilename)) { + nameEntry.Text = item.DefaultFilename; + previousDefaultEntryText = item.DefaultFilename; + } + + okButton.Sensitive = item.IsValidName (nameEntry.Text, sel.Language); + } else { + nameEntry.Sensitive = true; + okButton.Sensitive = false; + } + } catch (Exception ex) { + LoggingService.LogError (ex.ToString ()); + } + } + + // button events + + protected void CheckedChange (object sender, EventArgs e) + { + //((ListView)ControlDictionary["templateListView"]).View = ((RadioButton)ControlDictionary["smallIconsRadioButton"]).Checked ? View.List : View.LargeIcon; + } + + public event EventHandler OnOked; + + void OpenEvent (object sender, EventArgs e) + { + if (!okButton.Sensitive) + return; + + //FIXME: we need to set this up + //PropertyService.Set("Dialogs.NewProjectDialog.LargeImages", ((RadioButton)ControlDictionary["largeIconsRadioButton"]).Checked); + TreeIter selectedIter; + if (catView.Selection.GetSelected (out selectedIter)) + PropertyService.Set (GetCategoryPropertyKey (parentProject), GetCatPath (selectedIter)); + + if (iconView.CurrentlySelected != null && nameEntry.Text.Length > 0) { + TemplateItem titem = (TemplateItem)iconView.CurrentlySelected; + FileTemplate item = titem.Template; + Project project = null; + string path = null; + + if (!boxProject.Visible || projectAddCheckbox.Active) { + project = parentProject; + path = basePath; + } + + try { + if (!item.Create (project, project, path, titem.Language, nameEntry.Text)) + return; + } catch (Exception ex) { + MessageService.ShowException (ex); + return; + } + + if (project != null) + IdeApp.ProjectOperations.Save (project); + + if (OnOked != null) + OnOked (null, null); + Respond (Gtk.ResponseType.Ok); + Destroy (); + } + } + + + /// <summary> + /// Represents a new file template + /// </summary> + private class TemplateItem + { + public TemplateItem (FileTemplate template, string language) + { + this.template = template; + this.language = language; + } + + private string language; + public string Language { + get { return language; } + } + + public string Name { + get { return template.Name; } + } + + private FileTemplate template = null; + public FileTemplate Template { + get { return template; } + } + + } + + void cancelClicked (object o, EventArgs e) + { + Destroy (); + } + + void AddToProjectToggled (object o, EventArgs e) + { + projectAddCombo.Sensitive = projectAddCheckbox.Active; + projectPathLabel.Sensitive = projectAddCheckbox.Active; + projectFolderEntry.Sensitive = projectAddCheckbox.Active; + + TemplateItem titem = (TemplateItem)iconView.CurrentlySelected; + + if (projectAddCheckbox.Active) { + AddToProjectComboChanged (null, null); + } else { + parentProject = null; + InitializeDialog (true); + } + + if (titem != null) + SelectTemplate (titem.Template.Id); + } + + void AddToProjectComboChanged (object o, EventArgs e) + { + int which = projectAddCombo.Active; + Project project = null; + + try { + project = projectRefs[which]; + } catch (IndexOutOfRangeException) { } + + if (project != null) { + if (basePath == null || basePath == String.Empty || (parentProject != null && basePath == parentProject.BaseDirectory)) { + basePath = project.BaseDirectory; + projectFolderEntry.Path = basePath; + } + + parentProject = project; + + InitializeDialog (true); + } + } + + void AddToProjectPathChanged (object o, EventArgs e) + { + basePath = projectFolderEntry.Path; + } + + void InitializeComponents () + { + catStore = new TreeStore (typeof(string), typeof(List<Category>), typeof(List<TemplateItem>), typeof(Pixbuf)); + + TreeViewColumn treeViewColumn = new TreeViewColumn (); + treeViewColumn.Title = "categories"; + CellRenderer cellRenderer = new CellRendererText (); + treeViewColumn.PackStart (cellRenderer, true); + treeViewColumn.AddAttribute (cellRenderer, "text", 0); + catView.AppendColumn (treeViewColumn); + + catStore.SetSortColumnId (0, SortType.Ascending); + catView.Model = catStore; + + okButton.Clicked += new EventHandler (OpenEvent); + cancelButton.Clicked += new EventHandler (cancelClicked); + + nameEntry.Changed += new EventHandler (NameChanged); + nameEntry.Activated += new EventHandler (OpenEvent); + + ReadOnlyCollection<Project> projects = null; + if (parentProject == null) + projects = IdeApp.Workspace.GetAllProjects (); + + if (projects != null) { + Project curProject = IdeApp.ProjectOperations.CurrentSelectedProject; + + boxProject.Visible = true; + projectAddCheckbox.Active = curProject != null; + projectAddCheckbox.Toggled += new EventHandler (AddToProjectToggled); + + projectNames = new string[projects.Count]; + projectRefs = new Project[projects.Count]; + int i = 0; + + bool singleSolution = IdeApp.Workspace.Items.Count == 1 && IdeApp.Workspace.Items[0] is Solution; + + foreach (Project project in projects) { + projectRefs[i] = project; + if (singleSolution) + projectNames[i++] = project.Name; else + projectNames[i++] = project.ParentSolution.Name + "/" + project.Name; + } + + Array.Sort (projectNames, projectRefs); + i = Array.IndexOf (projectRefs, curProject); + + foreach (string pn in projectNames) + projectAddCombo.AppendText (pn); + + projectAddCombo.Active = i != -1 ? i : 0; + projectAddCombo.Sensitive = projectAddCheckbox.Active; + projectAddCombo.Changed += new EventHandler (AddToProjectComboChanged); + + projectPathLabel.Sensitive = projectAddCheckbox.Active; + projectFolderEntry.Sensitive = projectAddCheckbox.Active; + if (curProject != null) + projectFolderEntry.Path = curProject.BaseDirectory; + projectFolderEntry.PathChanged += new EventHandler (AddToProjectPathChanged); + + if (curProject != null) { + basePath = curProject.BaseDirectory; + parentProject = curProject; + } + } else { + boxProject.Visible = false; + } + + catView.Selection.Changed += new EventHandler (CategoryChange); + catView.RowActivated += new RowActivatedHandler (CategoryActivated); + iconView.IconSelected += new EventHandler (SelectedIndexChange); + iconView.IconDoubleClicked += new EventHandler (OpenEvent); + InitializeDialog (false); + InitializeView (); + UpdateOkStatus (); + } + + class Category + { + List<Category> categories = new List<Category> (); + List<TemplateItem> templates = new List<TemplateItem> (); + string name; + + public Category (string name) + { + this.name = name; + } + + public string Name { + get { return name; } + } + public List<Category> Categories { + get { return categories; } + } + public List<TemplateItem> Templates { + get { return templates; } + } + + private bool selected; + public bool Selected { + get { return selected; } + set { selected = value; } + } + + private bool hasSelectedTemplate; + public bool HasSelectedTemplate { + get { return hasSelectedTemplate; } + set { hasSelectedTemplate = value; } + } + } + } + + +} diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/NewProjectDialog.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/NewProjectDialog.cs new file mode 100644 index 0000000000..dd7cba848b --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/NewProjectDialog.cs @@ -0,0 +1,784 @@ +// NewProjectDialog.cs +// +// Todd Berman <tberman@off.net> +// Lluis Sanchez Gual <lluis@novell.com> +// Viktoria Dudka <viktoriad@remobjects.com> +// +// Copyright (c) 2004 Todd Berman +// Copyright (c) 2009 Novell, Inc (http://www.novell.com) +// Copyright (c) 2009 RemObjects Software +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// + +using System; +using System.Collections; +using System.IO; +using System.Text; + +using Mono.Addins; +using MonoDevelop.Core; +using MonoDevelop.Projects; +using MonoDevelop.Ide.Templates; +using MonoDevelop.Ide.Gui; +using MonoDevelop.Ide.Gui.Dialogs; + +using MonoDevelop.Components; +using IconView = MonoDevelop.Components.IconView; +using Gtk; +using System.Collections.Generic; +using MonoDevelop.Ide.Gui.Components; + +namespace MonoDevelop.Ide.Projects { + /// <summary> + /// This class displays a new project dialog and sets up and creates a a new project, + /// the project types are described in an XML options file + /// </summary> + public partial class NewProjectDialog: Gtk.Dialog + { + ArrayList alltemplates = new ArrayList(); + List<Category> categories = new List<Category> (); + + TemplateView templateView; + TreeStore catStore; + + bool openSolution; + string basePath; + bool newSolution; + string lastName = ""; + ProjectTemplate selectedItem; + SolutionItem currentEntry; + SolutionFolder parentFolder; + CombineEntryFeatureSelector featureList; + IWorkspaceFileObject newItem; + Category recentCategory; + List<string> recentIds = new List<string> (); + + public NewProjectDialog (SolutionFolder parentFolder, bool openCombine, string basePath) + { + Build (); + featureList = new CombineEntryFeatureSelector (); + vbox5.PackEnd (featureList, true, true, 0); + vbox5.ShowAll (); + notebook.Page = 0; + notebook.ShowTabs = false; + + this.parentFolder = parentFolder; + this.basePath = basePath; + this.newSolution = parentFolder == null; + this.openSolution = openCombine; + TransientFor = IdeApp.Workbench.RootWindow; + Title = newSolution ? GettextCatalog.GetString ("New Solution") : GettextCatalog.GetString ("New Project"); + + InitializeTemplates (); + + if (!newSolution) { + txt_subdirectory.Hide (); + chk_combine_directory.Active = false; + chk_combine_directory.Hide (); + lbl_subdirectory.Hide (); + } + } + + public void SelectTemplate (string id) + { + TreeIter iter; + catStore.GetIterFirst (out iter); + SelectTemplate (iter, id); + } + + ProjectTemplate GetTemplate (string id) + { + foreach (ProjectTemplate template in ProjectTemplate.ProjectTemplates) { + if (template.Id == id) + return template; + } + return null; + } + + bool SelectTemplate (TreeIter iter, string id) + { + do { + foreach (TemplateItem item in ((Category)catStore.GetValue (iter, 1)).Templates) { + if (item.Template.Id == id) { + lst_template_types.Selection.SelectIter (iter); + templateView.CurrentlySelected = item.Template; + return true; + } + } + + TreeIter citer; + if (catStore.IterChildren (out citer, iter)) { + do { + if (SelectTemplate (citer, id)) + return true; + } while (catStore.IterNext (ref citer)); + } + + } while (catStore.IterNext (ref iter)); + return false; + } + + bool FindCategoryAtCurrentLevel (string category, ref TreeIter iter) + { + TreeIter trial = iter; + do { + string val = (string)catStore.GetValue (trial, 0); + if (val == category) { + iter = trial; + return true; + } + } while (catStore.IterNext (ref trial)); + return false; + } + + void SelectCategory (string category) + { + string[] cats = category.Split ('/'); + + TreeIter iter; + if (!catStore.GetIterFirst (out iter)) + return; + + TreeIter nextIter = iter; + for (int i = 0; i < cats.Length; i++) { + if (FindCategoryAtCurrentLevel (cats[i], ref nextIter)) { + iter = nextIter; + if (i >= cats.Length - 1 || !catStore.IterChildren (out nextIter, nextIter)) + break; + } else if (i == 0) { + FindCategoryAtCurrentLevel ("C#", ref iter); + break; + } + } + + lst_template_types.ExpandToPath (catStore.GetPath (iter)); + lst_template_types.Selection.SelectIter (iter); + } + + void InitializeView() + { + InsertCategories (TreeIter.Zero, categories); + if (recentCategory.Templates.Count == 0) + SelectCategory (PropertyService.Get<string> ("Dialogs.NewProjectDialog.LastSelectedCategory", "C#")); + else + SelectTemplate (recentCategory.Templates [0].Template.Id); + ShowAll (); + } + + protected override void OnDestroyed () + { + if (catStore != null) { + catStore.Dispose (); + catStore = null; + } + + if (catColumn != null) { + catColumn.Destroy (); + catColumn = null; + } + + if (cat_text_render != null) { + cat_text_render.Destroy (); + cat_text_render = null; + } + base.OnDestroyed (); + } + + + + Category GetCategory (string categoryname) + { + return GetCategory (categories, categoryname); + } + + Category GetCategory (List<Category> catList, string categoryname) + { + int i = categoryname.IndexOf ('/'); + if (i != -1) { + string cn = categoryname.Substring (0, i).Trim (); + Category rootCat = GetCategory (catList, cn); + return GetCategory (rootCat.Categories, categoryname.Substring (i+1)); + } + + foreach (Category category in catList) { + if (category.Name == categoryname) + return category; + } + Category newcategory = new Category (categoryname); + catList.Add(newcategory); + return newcategory; + } + + + + + + string GetValidDir (string name) + { + name = name.Trim (); + StringBuilder sb = new StringBuilder (); + for (int n=0; n<name.Length; n++) { + char c = name [n]; + if (Array.IndexOf (System.IO.Path.GetInvalidPathChars(), c) != -1) + continue; + if (c == System.IO.Path.DirectorySeparatorChar || c == System.IO.Path.AltDirectorySeparatorChar || c == System.IO.Path.VolumeSeparatorChar) + continue; + sb.Append (c); + } + return sb.ToString (); + } + + bool CreateSolutionDirectory { + get { return chk_combine_directory.Active && chk_combine_directory.Sensitive; } + } + + string SolutionLocation { + get { + if (CreateSolutionDirectory) + return System.IO.Path.Combine (entry_location.Path, GetValidDir (txt_subdirectory.Text)); + else + return System.IO.Path.Combine (entry_location.Path, GetValidDir (txt_name.Text)); + } + } + + string ProjectLocation { + get { + string path = entry_location.Path; + if (CreateSolutionDirectory) + path = System.IO.Path.Combine (path, GetValidDir (txt_subdirectory.Text)); + + return System.IO.Path.Combine (path, GetValidDir (txt_name.Text)); + } + } + + public IWorkspaceObject NewItem { + get { + return newItem; + } + } + + protected void SolutionCheckChanged (object sender, EventArgs e) + { + if (CreateSolutionDirectory && txt_subdirectory.Text == "") + txt_subdirectory.Text = txt_name.Text; + + PathChanged (null, null); + } + + protected void NameChanged (object sender, EventArgs e) + { + if (CreateSolutionDirectory && txt_subdirectory.Text == lastName) + txt_subdirectory.Text = txt_name.Text; + + lastName = txt_name.Text; + PathChanged (null, null); + } + + void PathChanged (object sender, EventArgs e) + { + ActivateIfReady (); + lbl_will_save_in.Text = GettextCatalog.GetString("Project will be saved at") + " " + ProjectLocation; + } + + void OpenEvent (object sender, EventArgs e) + { + if (!btn_new.Sensitive) + return; + if (notebook.Page == 0) { + + if (!CreateProject ()) + return; + + Solution parentSolution = null; + + if (parentFolder == null) { + WorkspaceItem item = (WorkspaceItem) newItem; + parentSolution = item as Solution; + if (parentSolution != null) { + if (parentSolution.RootFolder.Items.Count > 0) + currentEntry = parentSolution.RootFolder.Items [0] as SolutionItem; + parentFolder = parentSolution.RootFolder; + } + } else { + SolutionItem item = (SolutionItem) newItem; + parentSolution = parentFolder.ParentSolution; + currentEntry = item; + } + + if (btn_new.Label == Gtk.Stock.GoForward) { + // There are features to show. Go to the next page + if (currentEntry != null) { + try { + featureList.Fill (parentFolder, currentEntry, SolutionItemFeatures.GetFeatures (parentFolder, currentEntry)); + } + catch (Exception ex) { + LoggingService.LogError (ex.ToString ()); + } + } + notebook.Page++; + btn_new.Label = Gtk.Stock.Ok; + return; + } + + } else { + // Already in fetatures page + if (!featureList.Validate ()) + return; + } + + // New combines (not added to parent combines) already have the project as child. + if (!newSolution) { + // Make sure the new item is saved before adding. In this way the + // version control add-in will be able to put it under version control. + if (currentEntry is SolutionEntityItem) { + // Inherit the file format from the solution + SolutionEntityItem eitem = (SolutionEntityItem) currentEntry; + eitem.FileFormat = parentFolder.ParentSolution.FileFormat; + IdeApp.ProjectOperations.Save (eitem); + } + parentFolder.AddItem (currentEntry, true); + } + + if (notebook.Page == 1) + featureList.ApplyFeatures (); + + if (parentFolder != null) + IdeApp.ProjectOperations.Save (parentFolder.ParentSolution); + else + IdeApp.ProjectOperations.Save (newItem); + + if (openSolution) + selectedItem.OpenCreatedSolution(); + Respond (ResponseType.Ok); + } + + bool CreateProject () + { + if (templateView.CurrentlySelected != null) { + PropertyService.Set ("Dialogs.NewProjectDialog.LastSelectedCategory", ((ProjectTemplate)templateView.CurrentlySelected).Category); + recentIds.Remove (templateView.CurrentlySelected.Id); + recentIds.Insert (0, templateView.CurrentlySelected.Id); + if (recentIds.Count > 15) + recentIds.RemoveAt (recentIds.Count - 1); + string strRecent = string.Join (",", recentIds.ToArray ()); + PropertyService.Set ("Dialogs.NewProjectDialog.RecentTemplates", strRecent); + PropertyService.SaveProperties (); + //PropertyService.Set("Dialogs.NewProjectDialog.LargeImages", ((RadioButton)ControlDictionary["largeIconsRadioButton"]).Checked); + } + + string solution = txt_subdirectory.Text; + string name = txt_name.Text; + string location = entry_location.Path; + + if(solution.Equals("")) solution = name; //This was empty when adding after first combine + + if ( + !FileService.IsValidPath (solution) || + !FileService.IsValidFileName(name) || + !FileService.IsValidPath(location)) + { + MessageService.ShowError (GettextCatalog.GetString ("Illegal project name.\nOnly use letters, digits, space, '.' or '_'.")); + return false; + } + + if (parentFolder != null && parentFolder.ParentSolution.FindProjectByName (name) != null) { + MessageService.ShowError (GettextCatalog.GetString ("A Project with that name is already in your Project Space")); + return false; + } + + PropertyService.Set ( + "MonoDevelop.Core.Gui.Dialogs.NewProjectDialog.AutoCreateProjectSubdir", + CreateSolutionDirectory); + + if (templateView.CurrentlySelected == null || name.Length == 0) + return false; + + ProjectTemplate item = (ProjectTemplate) templateView.CurrentlySelected; + + try { + System.IO.Directory.CreateDirectory (ProjectLocation); + } catch (IOException) { + MessageService.ShowError (GettextCatalog.GetString ("Could not create directory {0}. File already exists.", ProjectLocation)); + return false; + } catch (UnauthorizedAccessException) { + MessageService.ShowError (GettextCatalog.GetString ("You do not have permission to create to {0}", ProjectLocation)); + return false; + } + + ProjectCreateInformation cinfo = CreateProjectCreateInformation (); + + try { + if (newSolution) + newItem = item.CreateWorkspaceItem (cinfo); + else + newItem = item.CreateProject (parentFolder, cinfo); + } catch (Exception ex) { + MessageService.ShowException (ex, GettextCatalog.GetString ("The project could not be created")); + return false; + } + selectedItem = item; + return true; + } + + ProjectCreateInformation CreateProjectCreateInformation () + { + ProjectCreateInformation cinfo = new ProjectCreateInformation (); + cinfo.SolutionPath = SolutionLocation; + cinfo.ProjectBasePath = ProjectLocation; + cinfo.ProjectName = txt_name.Text; + cinfo.SolutionName = CreateSolutionDirectory ? txt_subdirectory.Text : txt_name.Text; + + // Guess a good default platform for the project + + if (parentFolder != null && parentFolder.ParentSolution != null) { + ItemConfiguration conf = parentFolder.ParentSolution.GetConfiguration (IdeApp.Workspace.ActiveConfiguration); + if (conf != null) + cinfo.DefaultPlatform = conf.Platform; + else { + string curName, curPlatform; + ItemConfiguration.ParseConfigurationId (IdeApp.Workspace.ActiveConfigurationId, out curName, out curPlatform); + foreach (ItemConfiguration ic in parentFolder.ParentSolution.Configurations) { + if (ic.Platform == curPlatform) { + cinfo.DefaultPlatform = curPlatform; + break; + } + if (ic.Name == curName) + cinfo.DefaultPlatform = ic.Platform; + } + } + } + + return cinfo; + } + + // icon view event handlers + void SelectedIndexChange(object sender, EventArgs e) + { + if (templateView.CurrentlySelected != null) { + ProjectTemplate ptemplate = (ProjectTemplate) templateView.CurrentlySelected; + lbl_template_descr.Text = StringParserService.Parse (ptemplate.Description); + labelTemplateTitle.Markup = "<b>" + GLib.Markup.EscapeText (ptemplate.Name) + "</b>"; + + if (ptemplate.SolutionDescriptor.EntryDescriptors.Length == 0) { + txt_subdirectory.Sensitive = false; + chk_combine_directory.Sensitive = false; + lbl_subdirectory.Sensitive = false; + btn_new.Label = Gtk.Stock.Ok; + } else { + txt_subdirectory.Sensitive = true; + chk_combine_directory.Sensitive = true; + lbl_subdirectory.Sensitive = true; + txt_subdirectory.Text = txt_name.Text; + + ProjectCreateInformation cinfo = CreateProjectCreateInformation (); + if (ptemplate.HasItemFeatures (parentFolder, cinfo)) + btn_new.Label = Gtk.Stock.GoForward; + else + btn_new.Label = Gtk.Stock.Ok; + } + } + else { + lbl_template_descr.Text = String.Empty; + labelTemplateTitle.Text = ""; + } + + PathChanged (null, null); + } + + protected void cancelClicked (object o, EventArgs e) + { + Respond (ResponseType.Cancel); + } + + void ActivateIfReady () + { + if (templateView.CurrentlySelected == null || txt_name.Text.Trim () == "" || (txt_subdirectory.Sensitive && chk_combine_directory.Active && txt_subdirectory.Text.Trim ().Length == 0)) + btn_new.Sensitive = false; + else + btn_new.Sensitive = true; + + txt_subdirectory.Sensitive = CreateSolutionDirectory; + } + + TreeViewColumn catColumn; + CellRendererText cat_text_render; + void InitializeComponents() + { + catStore = new Gtk.TreeStore (typeof (string), typeof (Category)); + lst_template_types.Model = catStore; + lst_template_types.WidthRequest = 160; + + lst_template_types.Selection.Changed += new EventHandler (CategoryChange); + + catColumn = new TreeViewColumn (); + catColumn.Title = "categories"; + cat_text_render = new CellRendererText (); + catColumn.PackStart (cat_text_render, true); + catColumn.AddAttribute (cat_text_render, "text", 0); + + lst_template_types.AppendColumn (catColumn); + + templateView = new TemplateView (); + + boxTemplates.Add (templateView); + + if (basePath == null) + basePath = IdeApp.ProjectOperations.ProjectsDefaultPath; + + entry_location.Path = basePath; + + PathChanged (null, null); + + templateView.SelectionChanged += SelectedIndexChange; + templateView.DoubleClicked += OpenEvent; + entry_location.PathChanged += PathChanged; + InitializeView (); + } + + + /// <summary> + /// Holds a new file template + /// </summary> + internal class TemplateItem + { + ProjectTemplate template; + string name; + + public TemplateItem (ProjectTemplate template) + { + name = StringParserService.Parse(template.Name); + this.template = template; + } + + public string Name { + get { return name; } + } + + public ProjectTemplate Template { + get { + return template; + } + } + } + + private void InitializeTemplates () + { + foreach (ProjectTemplate projectTemplate in ProjectTemplate.ProjectTemplates) { + if (!newSolution && projectTemplate.SolutionDescriptor.EntryDescriptors.Length == 0) + continue; + TemplateItem templateItem = new TemplateItem (projectTemplate); + + Category category = GetCategory(templateItem.Template.Category); + if (category != null ) + category.Templates.Add (templateItem); + + alltemplates.Add(templateItem); + } + + recentCategory = new Category (GettextCatalog.GetString ("Recent")); + string strRecent = PropertyService.Get<string> ("Dialogs.NewProjectDialog.RecentTemplates", ""); + recentIds = new List<string> (strRecent.Split (new char[] {','}, StringSplitOptions.RemoveEmptyEntries)); + + foreach (string id in recentIds) { + ProjectTemplate pt = GetTemplate (id); + if (pt != null) + recentCategory.Templates.Add (new TemplateItem (pt)); + } + + InitializeComponents (); + } + + private void InsertCategories (TreeIter node, List<Category> listCategories) + { + listCategories.Sort (); + if (TreeIter.Zero.Equals (node)) + listCategories.Insert (0, recentCategory); + foreach (Category category in listCategories) { + if (TreeIter.Zero.Equals (node)) + InsertCategories (catStore.AppendValues (category.Name, category), category.Categories); + else { + InsertCategories (catStore.AppendValues (node, category.Name, category), category.Categories); + } + } + } + + private void CategoryChange (System.Object o, EventArgs e) + { + TreeModel treeModel; + TreeIter treeIter; + + if (lst_template_types.Selection.GetSelected(out treeModel, out treeIter)) { + templateView.Clear(); + + foreach ( TemplateItem templateItem in (catStore.GetValue(treeIter, 1) as Category).Templates) { + templateView.Add (templateItem); + } + + btn_new.Sensitive = false; + } + + } + + protected virtual void OnBoxInfoSizeAllocated (object o, Gtk.SizeAllocatedArgs args) + { + } + + protected virtual void OnScrolledInfoSizeAllocated (object o, Gtk.SizeAllocatedArgs args) + { + if (labelTemplateTitle.WidthRequest != scrolledInfo.Allocation.Width) { + labelTemplateTitle.WidthRequest = scrolledInfo.Allocation.Width; + lbl_template_descr.WidthRequest = scrolledInfo.Allocation.Width; + } + } + + internal class Category: IComparable<Category> + { + private string name; + public string Name + { + get { return name; } + } + + public Category (string name) + { + this.name = name; + } + + private List<TemplateItem> templates = new List<TemplateItem>(); + public List<TemplateItem> Templates + { + get { return templates; } + } + + private List<Category> categories = new List<Category>(); + public List<Category> Categories + { + get { return categories; } + } + + public int CompareTo (Category other) + { + return name.CompareTo (other.name); + } + } + + class TemplateView: ScrolledWindow + { + TemplateTreeView tree; + + public TemplateView () + { + tree = new TemplateTreeView (); + tree.Selection.Changed += delegate { + if (SelectionChanged != null) + SelectionChanged (this, EventArgs.Empty); + }; + tree.RowActivated += delegate { + if (DoubleClicked != null) + DoubleClicked (this, EventArgs.Empty); + }; + Add (tree); + HscrollbarPolicy = PolicyType.Automatic; + VscrollbarPolicy = PolicyType.Automatic; + ShadowType = ShadowType.In; + ShowAll (); + } + + public ProjectTemplate CurrentlySelected { + get { return tree.CurrentlySelected; } + set { tree.CurrentlySelected = value; } + } + + public void Add (TemplateItem templateItem) + { + tree.Add (templateItem); + } + + public void Clear () + { + tree.Clear (); + } + + public event EventHandler SelectionChanged; + public event EventHandler DoubleClicked; + } + + class TemplateTreeView: TreeView + { + Gtk.ListStore templateStore; + + public TemplateTreeView () + { + HeadersVisible = false; + templateStore = new ListStore (typeof(string), typeof(string), typeof(ProjectTemplate)); + Model = templateStore; + + TreeViewColumn col = new TreeViewColumn (); + CellRendererIcon crp = new CellRendererIcon (); + crp.StockSize = (uint) Gtk.IconSize.Dnd; + crp.Ypad = 2; + col.PackStart (crp, false); + col.AddAttribute (crp, "stock-id", 0); + + CellRendererText crt = new CellRendererText (); + col.PackStart (crt, false); + col.AddAttribute (crt, "markup", 1); + + AppendColumn (col); + ShowAll (); + } + + public ProjectTemplate CurrentlySelected { + get { + Gtk.TreeIter iter; + if (!Selection.GetSelected (out iter)) + return null; + return (ProjectTemplate) templateStore.GetValue (iter, 2); + } + set { + Gtk.TreeIter iter; + if (templateStore.GetIterFirst (out iter)) { + do { + ProjectTemplate t = (ProjectTemplate) templateStore.GetValue (iter, 2); + if (t == value) { + Selection.SelectIter (iter); + return; + } + } while (templateStore.IterNext (ref iter)); + } + } + } + + public void Add (TemplateItem templateItem) + { + string name = GLib.Markup.EscapeText (templateItem.Name); + if (!string.IsNullOrEmpty (templateItem.Template.LanguageName)) + name += "\n<span foreground='darkgrey'><small>" + templateItem.Template.LanguageName + "</small></span>"; + templateStore.AppendValues (templateItem.Template.Icon.IsNull ? "md-project" : templateItem.Template.Icon.ToString (), name, templateItem.Template); + } + + public void Clear () + { + templateStore.Clear (); + } + } + } +} diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/ProjectFileSelectorDialog.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/ProjectFileSelectorDialog.cs new file mode 100644 index 0000000000..2be5714765 --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/ProjectFileSelectorDialog.cs @@ -0,0 +1,279 @@ +// +// ProjectFileSelectorDialog.cs +// +// Author: +// Michael Hutchinson <mhutchinson@novell.com> +// +// Copyright (c) 2009 Novell, Inc. (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Collections.Generic; +using Gtk; +using MonoDevelop.Core; +using MonoDevelop.Projects; + +namespace MonoDevelop.Ide.Projects +{ + public partial class ProjectFileSelectorDialog : Gtk.Dialog + { + List<string> filters; + string defaultFilterName; + string defaultFilterPattern; + Project project; + TreeStore dirStore = new TreeStore (typeof (string)); + ListStore fileStore = new ListStore (typeof (ProjectFile), typeof (Gdk.Pixbuf)); + + // NOTE: these should not be disposed, since they come from the icon scheme, and must instead be unref'd + // and the only way to unref is to let the finalizer handle it. + Gdk.Pixbuf projBuf, dirOpenBuf, dirClosedBuf; + + public ProjectFileSelectorDialog (Project project) + : this (project, GettextCatalog.GetString ("All files"), "*") + { + } + + public ProjectFileSelectorDialog (Project project, string defaultFilterName, string defaultFilterPattern) + { + + this.project = project; + this.defaultFilterName = defaultFilterName; + this.defaultFilterPattern = defaultFilterPattern ?? "*"; + + this.Build(); + + projBuf = ImageService.GetPixbuf (project.StockIcon, IconSize.Menu); + dirClosedBuf = ImageService.GetPixbuf (MonoDevelop.Ide.Gui.Stock.ClosedFolder, IconSize.Menu); + dirOpenBuf = ImageService.GetPixbuf (MonoDevelop.Ide.Gui.Stock.OpenFolder, IconSize.Menu); + + TreeViewColumn projectCol = new TreeViewColumn (); + projectCol.Title = GettextCatalog.GetString ("Project Folders"); + var pixRenderer = new CellRendererPixbuf (); + CellRendererText txtRenderer = new CellRendererText (); + projectCol.PackStart (pixRenderer, false); + projectCol.PackStart (txtRenderer, true); + projectCol.SetCellDataFunc (pixRenderer, new TreeCellDataFunc (PixDataFunc)); + projectCol.SetCellDataFunc (txtRenderer, new TreeCellDataFunc (TxtDataFunc)); + projectTree.Model = dirStore; + projectTree.AppendColumn (projectCol); + TreeIter projectIter = dirStore.AppendValues (""); + InitDirs (projectIter); + projectTree.ExpandAll (); + projectTree.RowActivated += delegate { + fileList.GrabFocus (); + }; + projectTree.KeyPressEvent += ProjectListKeyPressEvent; + + TreeViewColumn fileCol = new TreeViewColumn (); + var filePixRenderer = new CellRendererPixbuf (); + fileCol.Title = GettextCatalog.GetString ("Files"); + fileCol.PackStart (filePixRenderer, false); + fileCol.PackStart (txtRenderer, true); + fileCol.AddAttribute (filePixRenderer, "pixbuf", 1); + fileCol.SetCellDataFunc (txtRenderer, new TreeCellDataFunc (TxtFileDataFunc)); + fileList.Model = fileStore; + fileList.AppendColumn (fileCol); + fileList.RowActivated += delegate { + TreeIter iter; + if (fileList.Selection.GetSelected (out iter)) + Respond (ResponseType.Ok); + }; + fileList.KeyPressEvent += FileListKeyPressEvent; + fileList.KeyReleaseEvent += FileListKeyReleaseEvent; + + TreeIter root; + if (dirStore.GetIterFirst (out root)) + projectTree.Selection.SelectIter (root); + + UpdateFileList (null, null); + + projectTree.Selection.Changed += UpdateFileList; + fileList.Selection.Changed += UpdateSensitivity; + + + this.DefaultResponse = ResponseType.Cancel; + } + + [GLib.ConnectBefore] + void FileListKeyReleaseEvent (object o, KeyReleaseEventArgs args) + { + if (args.Event.Key == Gdk.Key.Escape) { + args.RetVal = true; + } + } + + const Gdk.ModifierType modifiers = + Gdk.ModifierType.ControlMask | + Gdk.ModifierType.ShiftMask | + Gdk.ModifierType.Mod1Mask | + Gdk.ModifierType.SuperMask | + Gdk.ModifierType.HyperMask | + Gdk.ModifierType.MetaMask; + + [GLib.ConnectBefore] + void FileListKeyPressEvent (object o, KeyPressEventArgs args) + { + if (args.Event.Key == Gdk.Key.Escape || args.Event.Key == Gdk.Key.BackSpace + || (args.Event.Key == Gdk.Key.Left && (args.Event.State & modifiers) == 0)) { + args.RetVal = true; + projectTree.GrabFocus (); + } + } + + [GLib.ConnectBefore] + void ProjectListKeyPressEvent (object o, KeyPressEventArgs args) + { + if (args.Event.Key == Gdk.Key.Right && (args.Event.State & modifiers) == 0) { + args.RetVal = true; + fileList.GrabFocus (); + } + } + + //FIXME: this is horribly inefficient + void InitDirs (TreeIter parent) + { + HashSet<string> hash = new HashSet<string> (); + foreach (ProjectFile pf in project.Files) { + string dirname; + if (pf.Subtype == Subtype.Directory) + dirname = pf.FilePath; + else + dirname = System.IO.Path.GetDirectoryName (pf.FilePath); + hash.Add (dirname); + } + + List<string> dirList = new List<string> (hash); + dirList.Sort (); + InitDirs (parent, dirList, project.BaseDirectory); + } + + void InitDirs (TreeIter parent, List<string> dirs, string path) + { + foreach (string s in dirs) + if (s.StartsWith (path) && s.Length > path.Length && s.IndexOf (System.IO.Path.DirectorySeparatorChar, s.Length) < 0) + InitDirs (dirStore.AppendValues (parent, s), dirs, s); + } + + void PixDataFunc (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter) + { + var pixRenderer = (CellRendererPixbuf) cell; + string dirname = (string) tree_model.GetValue (iter, 0); + + if (dirname.Length == 0) { + pixRenderer.PixbufExpanderOpen = pixRenderer.PixbufExpanderClosed = projBuf; + return; + } + pixRenderer.PixbufExpanderOpen = dirOpenBuf; + pixRenderer.PixbufExpanderClosed = pixRenderer.Pixbuf = dirClosedBuf; + } + + void TxtDataFunc (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter) + { + CellRendererText txtRenderer = (CellRendererText) cell; + string dirname = (string) tree_model.GetValue (iter, 0); + if (dirname.Length == 0) { + txtRenderer.Text = project.Name; + return; + } + + int lastSlash = dirname.LastIndexOf (System.IO.Path.DirectorySeparatorChar); + txtRenderer.Text = lastSlash < 0? dirname : dirname.Substring (lastSlash + 1); + } + + void TxtFileDataFunc (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter) + { + CellRendererText txtRenderer = (CellRendererText) cell; + ProjectFile pf = (ProjectFile)tree_model.GetValue (iter, 0); + txtRenderer.Text = System.IO.Path.GetFileName (pf.FilePath); + } + + public void AddFileFilter (string name, string pattern) + { + if (filters == null) { + filters = new List<string> (); + if (defaultFilterPattern != null) { + filters.Add (defaultFilterPattern); + fileTypeCombo.AppendText (defaultFilterName); + } + typeBox.Visible = false; + typeBox.ShowAll (); + } + + filters.Add (name); + fileTypeCombo.AppendText (pattern); + } + + public ProjectFile SelectedFile { get; private set; }
+
+ FilePath GetSelectedDirectory ( ) + { + TreeIter iter; + if (!projectTree.Selection.GetSelected (out iter)) + return project.BaseDirectory; + string dir = (string)dirStore.GetValue (iter, 0); + return project.BaseDirectory.Combine (dir); + } + + void UpdateFileList (object sender, EventArgs args) + { + fileStore.Clear (); + + string pattern = defaultFilterPattern; + if (filters != null) { + pattern = filters[fileTypeCombo.Active]; + } + pattern = System.Text.RegularExpressions.Regex.Escape (pattern); + pattern = pattern.Replace ("\\*",".*"); + pattern = pattern.Replace ("\\?","."); + pattern = pattern.Replace ("\\|","$|^"); + pattern = "^" + pattern + "$"; + System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex (pattern);
+
+ string dir = GetSelectedDirectory ().ToString (); + foreach (ProjectFile pf in project.Files) { + string pathStr = pf.FilePath.ToString (); + if (pf.Subtype == Subtype.Directory || !pathStr.StartsWith (dir)) + continue; + + int split = pathStr.LastIndexOf (System.IO.Path.DirectorySeparatorChar); + if (split != dir.Length) + continue; + + if (regex.IsMatch (pf.FilePath.FileName)) + fileStore.AppendValues (pf, DesktopService.GetPixbufForFile (pf.FilePath, Gtk.IconSize.Menu)); + } + + TreeIter root; + if (fileStore.GetIterFirst (out root)) + fileList.Selection.SelectIter (root); + + UpdateSensitivity (null, null); + } + + void UpdateSensitivity (object sender, EventArgs args) + { + TreeIter iter; + bool selected = fileList.Selection.GetSelected (out iter); + buttonOk.Sensitive = selected; + this.DefaultResponse = selected? ResponseType.Ok : ResponseType.Cancel; + SelectedFile = selected? (ProjectFile) fileStore.GetValue (iter, 0) : null; + } + } +} diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/ProjectOptionsDialog.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/ProjectOptionsDialog.cs new file mode 100644 index 0000000000..b15807e8cd --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/ProjectOptionsDialog.cs @@ -0,0 +1,106 @@ +// ProjectOptionsDialog.cs +// +// Author: +// Lluis Sanchez Gual <lluis@novell.com> +// +// Copyright (c) 2008 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// + +using System; +using System.IO; +using System.Collections; +using System.ComponentModel; + +using Mono.Addins; +using MonoDevelop.Core; +using MonoDevelop.Projects; +using MonoDevelop.Components.Commands; +using MonoDevelop.Ide.Gui.Dialogs; + +namespace MonoDevelop.Ide.Projects +{ + /// <summary> + /// Dialog for viewing the project options. + /// </summary> + public class ProjectOptionsDialog : MultiConfigItemOptionsDialog + { + public ProjectOptionsDialog (Gtk.Window parentWindow, SolutionEntityItem project) : base (parentWindow, project) + { + this.Title = GettextCatalog.GetString ("Project Options") + " - " + project.Name; + } + + public static void RenameItem (IWorkspaceFileObject item, string newName) + { + if (newName == item.Name) + return; + + if (!FileService.IsValidFileName (newName)) { + MessageService.ShowError (GettextCatalog.GetString ("Illegal project name.\nOnly use letters, digits, space, '.' or '_'.")); + return; + } + + FilePath oldFile = item.FileName; + string oldName = item.Name; + + try { + item.Name = newName; + item.NeedsReload = false; + if (oldFile != item.FileName) { + // File name changed, rename the project file + if (!RenameItemFile (oldFile, item.FileName)) { + item.Name = oldName; + item.NeedsReload = false; + return; + } + } + else if (oldFile.FileNameWithoutExtension == oldName) { + FilePath newFile = oldFile.ParentDirectory.Combine (newName + oldFile.Extension); + if (newFile != oldFile) { + if (!RenameItemFile (oldFile, newFile)) { + item.Name = oldName; + item.NeedsReload = false; + return; + } + item.FileName = newFile; + } + } + } catch (Exception ex) { + item.Name = oldName; + MessageService.ShowException (ex, GettextCatalog.GetString ("The project could not be renamed.")); + return; + } + item.NeedsReload = false; + } + + static bool RenameItemFile (FilePath oldFile, FilePath newFile) + { + if (File.Exists (newFile)) { + string msg = GettextCatalog.GetString ("The file '{0}' already exist. Do you want to replace it?", newFile.FileName); + if (!MessageService.Confirm (msg, AlertButton.Replace)) + return false; + FileService.DeleteFile (newFile); + } + FileService.RenameFile (oldFile, newFile.FileName); + return true; + } + } +} diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/ProjectReferencePanel.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/ProjectReferencePanel.cs new file mode 100644 index 0000000000..bf78b4cc0a --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/ProjectReferencePanel.cs @@ -0,0 +1,213 @@ +// +// ProjectReferencePanel.cs +// +// Author: +// Todd Berman <tberman@sevenl.net> +// Lluis Sanchez Gual <lluis@novell.com> +// +// Copyright (c) 2004 Todd Berman +// Copyright (c) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + + +using System; +using System.Collections.Generic; +using MonoDevelop.Projects; +using MonoDevelop.Core; +using MonoDevelop.Ide.Gui; + +using Gtk; + +namespace MonoDevelop.Ide.Projects { + + internal class ProjectReferencePanel : VBox, IReferencePanel + { + SelectReferenceDialog selectDialog; + + ListStore store; + TreeView treeView; + + public ProjectReferencePanel (SelectReferenceDialog selectDialog) : base (false, 6) + { + this.selectDialog = selectDialog; + + store = new ListStore (typeof (string), typeof (string), typeof(Project), typeof(bool), typeof(Gdk.Pixbuf), typeof(bool), typeof(string)); + store.SetSortFunc (0, CompareNodes); + treeView = new TreeView (store); + + TreeViewColumn firstColumn = new TreeViewColumn (); + TreeViewColumn secondColumn = new TreeViewColumn (); + + CellRendererToggle tog_render = new CellRendererToggle (); + tog_render.Xalign = 0; + tog_render.Toggled += new Gtk.ToggledHandler (AddReference); + firstColumn.PackStart (tog_render, false); + firstColumn.AddAttribute (tog_render, "active", 3); + firstColumn.AddAttribute (tog_render, "visible", 5); + + secondColumn.Title = GettextCatalog.GetString ("Project"); + Gtk.CellRendererPixbuf pix_render = new Gtk.CellRendererPixbuf (); + secondColumn.PackStart (pix_render, false); + secondColumn.AddAttribute (pix_render, "pixbuf", 4); + + CellRendererText text_render = new CellRendererText (); + secondColumn.PackStart (text_render, true); + secondColumn.AddAttribute (text_render, "text", 0); + secondColumn.AddAttribute (text_render, "foreground", 6); + + treeView.AppendColumn (firstColumn); + treeView.AppendColumn (secondColumn); + treeView.AppendColumn (GettextCatalog.GetString ("Directory"), new CellRendererText (), "markup", 1); + + ScrolledWindow sc = new ScrolledWindow (); + sc.ShadowType = Gtk.ShadowType.In; + sc.Add (treeView); + PackStart (sc, true, true, 0); + + store.SetSortColumnId (0, SortType.Ascending); + ShowAll (); + + BorderWidth = 6; + } + + public void SetProject (DotNetProject configureProject) + { + store.Clear (); + PopulateListView (configureProject); + } + + public void AddReference(object sender, Gtk.ToggledArgs e) + { + Gtk.TreeIter iter; + store.GetIterFromString (out iter, e.Path); + Project project = (Project) store.GetValue (iter, 2); + + if ((bool)store.GetValue (iter, 3) == false) { + store.SetValue (iter, 3, true); + selectDialog.AddReference (new ProjectReference (project)); + + } else { + store.SetValue (iter, 3, false); + selectDialog.RemoveReference(ReferenceType.Project, project.Name); + } + } + + public void SignalRefChange (string refLoc, bool newstate) + { + Gtk.TreeIter looping_iter; + if (!store.GetIterFirst (out looping_iter)) { + return; + } + + do { + Project project = (Project) store.GetValue (looping_iter, 2); + if (project == null) + return; + if (project.Name == refLoc) { + store.SetValue (looping_iter, 3, newstate); + return; + } + } while (store.IterNext (ref looping_iter)); + } + + int CompareNodes (Gtk.TreeModel model, Gtk.TreeIter a, Gtk.TreeIter b) + { + string s1 = (string) store.GetValue (a, 0); + string s2 = (string) store.GetValue (b, 0); + if (s1 == string.Empty) return 1; + if (s2 == string.Empty) return -1; + return String.Compare (s1, s2, true); + } + + void PopulateListView (DotNetProject configureProject) + { + Solution openSolution = configureProject.ParentSolution; + + if (openSolution == null) { + return; + } + + Dictionary<DotNetProject,bool> references = new Dictionary<DotNetProject, bool> (); + + foreach (Project projectEntry in openSolution.GetAllSolutionItems<Project>()) { + + if (projectEntry == configureProject) + continue; + + string txt = projectEntry.Name; + bool allowSelecting = true; + DotNetProject netProject = projectEntry as DotNetProject; + if (netProject != null) { + if (ProjectReferencesProject (references, null, netProject, configureProject.Name)) { + txt += " " + GettextCatalog.GetString ("(Cyclic dependencies not allowed)"); + allowSelecting = false; + } + else if (!configureProject.TargetFramework.IsCompatibleWithFramework (netProject.TargetFramework.Id)) { + txt += " " + GettextCatalog.GetString ("(Incompatible target framework: v{0})", netProject.TargetFramework.Id); + allowSelecting = false; + } + } + + Gdk.Pixbuf icon = ImageService.GetPixbuf (projectEntry.StockIcon, IconSize.Menu); + if (!allowSelecting) + icon = ImageService.MakeTransparent (icon, 0.5); + Gtk.TreeIter it = store.AppendValues (txt, projectEntry.BaseDirectory.ToString (), projectEntry, false, icon, allowSelecting); + if (!allowSelecting) + store.SetValue (it, 6, "dimgrey"); + } + } + + bool ProjectReferencesProject (Dictionary<DotNetProject,bool> references, HashSet<string> parentDeps, + DotNetProject project, string targetProject) + { + bool res; + if (references.TryGetValue (project, out res)) + return res; + foreach (ProjectReference pr in project.References) { + if (pr.Reference == targetProject) { + references [project] = true; + return true; + } + + DotNetProject pref = project.ParentSolution.FindProjectByName (pr.Reference) as DotNetProject; + if (pref != null) { + if (parentDeps == null) { + parentDeps = new HashSet<string> (); + } else if (parentDeps.Contains (pref.Name)) { + LoggingService.LogWarning ("Cyclic dependency detected between projects '{0}' and '{1}'", project.Name, pref.Name); + references [project] = true; + return true; + } + parentDeps.Add (pref.Name); + bool referencesTarget = ProjectReferencesProject (references, parentDeps, pref, targetProject); + parentDeps.Remove (pref.Name); + + if (referencesTarget) { + references [project] = true; + return true; + } + } + } + references [project] = false; + return false; + } + } +} + diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/RenameConfigDialog.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/RenameConfigDialog.cs new file mode 100644 index 0000000000..55fb38bd93 --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/RenameConfigDialog.cs @@ -0,0 +1,78 @@ +// RenameConfigDialog.cs +// +//Author: +// Lluis Sanchez Gual +// +//Copyright (c) 2007 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// + +using System; +using MonoDevelop.Core; +using MonoDevelop.Projects; + +namespace MonoDevelop.Ide.Projects +{ + partial class RenameConfigDialog: Gtk.Dialog + { + string platform; + ItemConfigurationCollection<ItemConfiguration> configurations; + + public RenameConfigDialog(ItemConfigurationCollection<ItemConfiguration> configurations) + { + Build (); + this.configurations = configurations; + } + + public string ConfigName { + get { + if (string.IsNullOrEmpty (platform)) + return nameEntry.Text; + else + return nameEntry.Text + "|" + platform; + } + set { + int i = value.LastIndexOf ('|'); + if (i == -1) { + nameEntry.Text = value; + platform = string.Empty; + } else { + nameEntry.Text = value.Substring (0, i); + platform = value.Substring (i+1); + } + } + } + + public bool RenameChildren { + get { return renameChildrenCheck.Active; } + } + + protected virtual void OnButtonOkClicked (object sender, System.EventArgs e) + { + if (nameEntry.Text.Trim ().Length == 0 || nameEntry.Text.IndexOf ('|') != -1) { + MessageService.ShowWarning (GettextCatalog.GetString ("Please enter a valid configuration name.")); + } else if (configurations [ConfigName] != null) { + MessageService.ShowWarning (GettextCatalog.GetString ("A configuration with the name '{0}' already exists.", ConfigName)); + } else + Respond (Gtk.ResponseType.Ok); + } + } +} diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/SelectReferenceDialog.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/SelectReferenceDialog.cs new file mode 100644 index 0000000000..816e98acfc --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/SelectReferenceDialog.cs @@ -0,0 +1,260 @@ +// SelectReferenceDialog.cs +// +// Author: +// Todd Berman <tberman@sevenl.net> +// Lluis Sanchez Gual <lluis@novell.com> +// +// Copyright (c) 2004 Todd Berman +// Copyright (c) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; + +using MonoDevelop.Projects; +using MonoDevelop.Core; +using MonoDevelop.Core.Assemblies; + +using Gtk; + +namespace MonoDevelop.Ide.Projects +{ + internal interface IReferencePanel + { + } + + internal partial class SelectReferenceDialog: Gtk.Dialog + { + ListStore refTreeStore; + + GacReferencePanel gacRefPanel; + ProjectReferencePanel projectRefPanel; + AssemblyReferencePanel assemblyRefPanel; + DotNetProject configureProject; + + const int NameColumn = 0; + const int TypeNameColumn = 1; + const int LocationColumn = 2; + const int ProjectReferenceColumn = 3; + const int IconColumn = 4; + + public ProjectReferenceCollection ReferenceInformations { + get { + ProjectReferenceCollection referenceInformations = new ProjectReferenceCollection(); + Gtk.TreeIter looping_iter; + if (!refTreeStore.GetIterFirst (out looping_iter)) { + return referenceInformations; + } + do { + referenceInformations.Add ((ProjectReference) refTreeStore.GetValue(looping_iter, ProjectReferenceColumn)); + } while (refTreeStore.IterNext (ref looping_iter)); + return referenceInformations; + } + } + + public void SetProject (DotNetProject configureProject) + { + this.configureProject = configureProject; + ((ListStore) ReferencesTreeView.Model).Clear (); + + projectRefPanel.SetProject (configureProject); + projectRefPanel.Show (); + + DotNetProject netProject = configureProject as DotNetProject; + if (netProject != null) + gacRefPanel.SetTargetFramework (netProject.AssemblyContext, netProject.TargetFramework); + gacRefPanel.Reset (); + assemblyRefPanel.SetBasePath (configureProject.BaseDirectory); + + foreach (ProjectReference refInfo in configureProject.References) + AppendReference (refInfo); + + OnChanged (null, null); + } + + public void SetReferenceCollection (ProjectReferenceCollection references, AssemblyContext runtime, TargetFramework targetVersion) + { + ((ListStore) ReferencesTreeView.Model).Clear (); + + projectRefPanel.Hide (); + + gacRefPanel.SetTargetFramework (runtime, targetVersion); + gacRefPanel.Reset (); + assemblyRefPanel.SetBasePath (Environment.GetFolderPath (Environment.SpecialFolder.Personal)); + + foreach (ProjectReference refInfo in references) + AppendReference (refInfo); + + OnChanged (null, null); + } + + TreeIter AppendReference (ProjectReference refInfo) + { + switch (refInfo.ReferenceType) { + case ReferenceType.Assembly: + return AddAssemplyReference (refInfo); + case ReferenceType.Project: + return AddProjectReference (refInfo); + case ReferenceType.Gac: + return AddGacReference (refInfo); + default: + return TreeIter.Zero; + } + } + + TreeIter AddAssemplyReference (ProjectReference refInfo) + { + return refTreeStore.AppendValues (System.IO.Path.GetFileName (refInfo.Reference), GetTypeText (refInfo), System.IO.Path.GetFullPath (refInfo.Reference), refInfo, "md-closed-folder"); + } + + TreeIter AddProjectReference (ProjectReference refInfo) + { + Solution c = configureProject.ParentSolution; + if (c == null) return TreeIter.Zero; + + Project p = c.FindProjectByName (refInfo.Reference); + if (p == null) return TreeIter.Zero; + + string iconName = p.StockIcon; + projectRefPanel.SignalRefChange (refInfo.Reference, true); + return refTreeStore.AppendValues (System.IO.Path.GetFileName (refInfo.Reference), GetTypeText (refInfo), p.BaseDirectory.ToString (), refInfo, iconName); + } + + TreeIter AddGacReference (ProjectReference refInfo) + { + gacRefPanel.SignalRefChange (refInfo, true); + return refTreeStore.AppendValues (System.IO.Path.GetFileNameWithoutExtension (refInfo.Reference), GetTypeText (refInfo), refInfo.Reference, refInfo, "md-package"); + } + + public SelectReferenceDialog () + { + Build (); + + refTreeStore = new ListStore (typeof (string), typeof(string), typeof(string), typeof(ProjectReference), typeof(string)); + ReferencesTreeView.Model = refTreeStore; + + TreeViewColumn col = new TreeViewColumn (); + col.Title = GettextCatalog.GetString("Reference"); + CellRendererPixbuf crp = new CellRendererPixbuf (); + col.PackStart (crp, false); + col.AddAttribute (crp, "stock-id", IconColumn); + CellRendererText text_render = new CellRendererText (); + col.PackStart (text_render, true); + col.AddAttribute (text_render, "text", NameColumn); + + ReferencesTreeView.AppendColumn (col); + ReferencesTreeView.AppendColumn (GettextCatalog.GetString ("Type"), new CellRendererText (), "text", TypeNameColumn); + ReferencesTreeView.AppendColumn (GettextCatalog.GetString ("Location"), new CellRendererText (), "text", LocationColumn); + + projectRefPanel = new ProjectReferencePanel (this); + gacRefPanel = new GacReferencePanel (this); + assemblyRefPanel = new AssemblyReferencePanel (this); + + mainBook.RemovePage (mainBook.CurrentPage); + mainBook.AppendPage (gacRefPanel, new Label (GettextCatalog.GetString ("Packages"))); + mainBook.AppendPage (projectRefPanel, new Label (GettextCatalog.GetString ("Projects"))); + mainBook.AppendPage (assemblyRefPanel, new Label (GettextCatalog.GetString (".Net Assembly"))); + mainBook.Page = 0; + ReferencesTreeView.Selection.Changed += new EventHandler (OnChanged); + ShowAll (); + OnChanged (null, null); + } + + void OnChanged (object o, EventArgs e) + { + if (ReferencesTreeView.Selection.CountSelectedRows () > 0) + RemoveReferenceButton.Sensitive = true; + else + RemoveReferenceButton.Sensitive = false; + } + + string GetTypeText (ProjectReference pref) + { + switch (pref.ReferenceType) { + case ReferenceType.Gac: return GettextCatalog.GetString ("Package"); + case ReferenceType.Assembly: return GettextCatalog.GetString ("Assembly"); + case ReferenceType.Project: return GettextCatalog.GetString ("Project"); + default: return ""; + } + } + + public void RemoveReference (ReferenceType referenceType, string reference) + { + TreeIter iter = FindReference (referenceType, reference); + if (iter.Equals (TreeIter.Zero)) + return; + refTreeStore.Remove (ref iter); + } + + public void AddReference (ProjectReference pref) + { + TreeIter iter = FindReference (pref.ReferenceType, pref.Reference); + if (!iter.Equals (TreeIter.Zero)) + return; + + TreeIter ni = AppendReference (pref); + if (!ni.Equals (TreeIter.Zero)) + ReferencesTreeView.ScrollToCell (refTreeStore.GetPath (ni), null, false, 0, 0); + } + + TreeIter FindReference (ReferenceType referenceType, string reference) + { + TreeIter looping_iter; + if (refTreeStore.GetIterFirst (out looping_iter)) { + do { + ProjectReference pref = (ProjectReference) refTreeStore.GetValue (looping_iter, ProjectReferenceColumn); + if (pref.Reference == reference && pref.ReferenceType == referenceType) { + return looping_iter; + } + } while (refTreeStore.IterNext (ref looping_iter)); + } + return TreeIter.Zero; + } + + protected void RemoveReference (object sender, EventArgs e) + { + TreeIter iter; + TreeModel mdl; + if (ReferencesTreeView.Selection.GetSelected (out mdl, out iter)) { + switch (((ProjectReference)refTreeStore.GetValue (iter, ProjectReferenceColumn)).ReferenceType) { + case ReferenceType.Gac: + gacRefPanel.SignalRefChange ((ProjectReference)refTreeStore.GetValue (iter, ProjectReferenceColumn), false); + break; + case ReferenceType.Project: + projectRefPanel.SignalRefChange ((string)refTreeStore.GetValue (iter, NameColumn), false); + break; + } + TreeIter newIter = iter; + if (refTreeStore.IterNext (ref newIter)) { + ReferencesTreeView.Selection.SelectIter (newIter); + refTreeStore.Remove (ref iter); + } else { + TreePath path = refTreeStore.GetPath (iter); + if (path.Prev ()) { + ReferencesTreeView.Selection.SelectPath (path); + refTreeStore.Remove (ref iter); + } else { + refTreeStore.Remove (ref iter); + } + } + } + } + } +} + |