~ubuntu-branches/ubuntu/oneiric/monodevelop/oneiric

« back to all changes in this revision

Viewing changes to src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring/ExtractMethod/ExtractMethodDialog.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2011-06-27 17:03:13 UTC
  • mto: (1.8.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 54.
  • Revision ID: james.westby@ubuntu.com-20110627170313-6cvz3s19x6e9hqe9
ImportĀ upstreamĀ versionĀ 2.5.92+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// 
 
2
// ExtractMethodDialog.cs
 
3
//  
 
4
// Author:
 
5
//       Mike KrĆ¼ger <mkrueger@novell.com>
 
6
// 
 
7
// Copyright (c) 2009 Novell, Inc (http://www.novell.com)
 
8
// 
 
9
// Permission is hereby granted, free of charge, to any person obtaining a copy
 
10
// of this software and associated documentation files (the "Software"), to deal
 
11
// in the Software without restriction, including without limitation the rights
 
12
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
13
// copies of the Software, and to permit persons to whom the Software is
 
14
// furnished to do so, subject to the following conditions:
 
15
// 
 
16
// The above copyright notice and this permission notice shall be included in
 
17
// all copies or substantial portions of the Software.
 
18
// 
 
19
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
20
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
21
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
22
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
23
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
24
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
25
// THE SOFTWARE.
 
26
 
 
27
using System;
 
28
 
 
29
using Gtk;
 
30
 
 
31
using MonoDevelop.Core;
 
32
using MonoDevelop.Projects.Dom;
 
33
using MonoDevelop.Projects.CodeGeneration;
 
34
using System.Collections.Generic;
 
35
using MonoDevelop.Ide;
 
36
using Mono.TextEditor;
 
37
using Mono.TextEditor.PopupWindow;
 
38
using MonoDevelop.Refactoring;
 
39
 
 
40
namespace MonoDevelop.CSharp.Refactoring.ExtractMethod
 
41
{
 
42
        public partial class ExtractMethodDialog : Gtk.Dialog
 
43
        {
 
44
                ExtractMethodRefactoring extractMethod;
 
45
                ExtractMethodRefactoring.ExtractMethodParameters properties;
 
46
                ListStore store;
 
47
                RefactoringOptions options;
 
48
                string methodName;
 
49
                int activeModifier;
 
50
                bool generateComments;
 
51
                
 
52
                public ExtractMethodDialog (RefactoringOptions options, ExtractMethodRefactoring extractMethod, ExtractMethodRefactoring.ExtractMethodParameters properties)
 
53
                {
 
54
                        this.Build ();
 
55
                        this.options = options;
 
56
                        this.properties = properties;
 
57
                        this.extractMethod = extractMethod;
 
58
                        
 
59
                        store = new ListStore (typeof (string), typeof (string));
 
60
                        treeviewParameters.Model = store;
 
61
                        treeviewParameters.AppendColumn ("Type", new CellRendererText (), "text", 0);
 
62
                        treeviewParameters.AppendColumn ("Name", new CellRendererText (), "text", 1);
 
63
                        FillStore ();
 
64
                        buttonPreview.Sensitive = buttonOk.Sensitive = false;
 
65
                        entry.Changed += delegate { buttonPreview.Sensitive = buttonOk.Sensitive = ValidateName (); };
 
66
                        ValidateName ();
 
67
                        
 
68
                        buttonOk.Clicked += OnOKClicked;
 
69
                        buttonCancel.Clicked += OnCancelClicked;
 
70
                        buttonPreview.Clicked += OnPreviewClicked;
 
71
                        
 
72
                        buttonUp.Clicked += delegate {
 
73
                                List<int> indices = new List<int> ();
 
74
                                foreach (TreePath path in treeviewParameters.Selection.GetSelectedRows ()) {
 
75
                                        int index = Int32.Parse (path.ToString ());
 
76
                                        if (index > 0) {
 
77
                                                VariableDescriptor tmp = properties.Parameters [index - 1];
 
78
                                                properties.Parameters [index - 1] = properties.Parameters [index];
 
79
                                                properties.Parameters [index] = tmp;
 
80
                                                indices.Add (index - 1);
 
81
                                        }
 
82
                                }
 
83
                                FillStore ();
 
84
                                treeviewParameters.Selection.SelectPath (new TreePath (indices.ToArray ()));
 
85
                        };
 
86
                        buttonDown.Clicked += delegate {
 
87
                                List<int> indices = new List<int> ();
 
88
                                foreach (TreePath path in treeviewParameters.Selection.GetSelectedRows ()) {
 
89
                                        int index = Int32.Parse (path.ToString ());
 
90
                                        if (index + 1 < properties.Parameters.Count) {
 
91
                                                VariableDescriptor tmp = properties.Parameters [index + 1];
 
92
                                                properties.Parameters [index + 1] = properties.Parameters [index];
 
93
                                                properties.Parameters [index] = tmp;
 
94
                                                indices.Add (index + 1);
 
95
                                        }
 
96
                                }
 
97
                                FillStore ();
 
98
                                treeviewParameters.Selection.SelectPath (new TreePath (indices.ToArray ()));
 
99
                        };
 
100
                        ListStore modifiers = new ListStore (typeof (string));
 
101
                        modifiers.AppendValues ("");
 
102
                        modifiers.AppendValues ("public");
 
103
                        modifiers.AppendValues ("private");
 
104
                        modifiers.AppendValues ("protected");
 
105
                        modifiers.AppendValues ("internal");
 
106
                        comboboxModifiers.Model = modifiers;
 
107
                        comboboxModifiers.Active = PropertyService.Get<int> ("MonoDevelop.Refactoring.ExtractMethod.ExtractMethodDialog.DefaultModifier");
 
108
                        entry.Activated += delegate {
 
109
                                if (buttonOk.Sensitive)
 
110
                                        buttonOk.Click ();
 
111
                        };
 
112
                }
 
113
                
 
114
                void FillStore ()
 
115
                {
 
116
                        store.Clear ();
 
117
                        foreach (VariableDescriptor var in properties.Parameters) {
 
118
                                store.AppendValues (var.ReturnType != null ? var.ReturnType.ToInvariantString () : "<null>" , var.Name);
 
119
                        }
 
120
                }
 
121
 
 
122
                bool ValidateName ()
 
123
                {
 
124
                        string fileName = properties.DeclaringMember.DeclaringType.CompilationUnit.FileName;
 
125
                        string methodName = entry.Text;
 
126
                        if (HasMember (methodName)) {
 
127
                                labelWarning.Text = GettextCatalog.GetString ("A member with the name '{0}' already exists.", methodName);
 
128
                                imageWarning.IconName = Gtk.Stock.DialogError;
 
129
                                return false;
 
130
                        }
 
131
 
 
132
                        INameValidator nameValidator = MonoDevelop.Projects.LanguageBindingService.GetRefactorerForFile (fileName ?? "default.cs");
 
133
                        if (nameValidator == null)
 
134
                                return true;
 
135
                        ValidationResult result = nameValidator.ValidateName (new DomMethod (), entry.Text);
 
136
                        if (!result.IsValid) {
 
137
                                imageWarning.IconName = Gtk.Stock.DialogError;
 
138
                        } else if (result.HasWarning) {
 
139
                                imageWarning.IconName = Gtk.Stock.DialogWarning;
 
140
                        } else {
 
141
                                imageWarning.IconName = Gtk.Stock.Apply;
 
142
                        }
 
143
                        labelWarning.Text = result.Message;
 
144
                        return result.IsValid;
 
145
                }
 
146
 
 
147
                bool HasMember (string name)
 
148
                {
 
149
                        foreach (var member in properties.DeclaringMember.DeclaringType.SearchMember (name, true)) {
 
150
                                var method = member as IMethod;
 
151
                                if (method == null)
 
152
                                        continue;
 
153
                                if (method.Parameters.Count != properties.Parameters.Count)
 
154
                                        continue;
 
155
                                bool equals = true;
 
156
                                for (int i = 0; i < method.Parameters.Count; i++) {
 
157
                                        if (properties.Parameters[i].ReturnType.ToInvariantString () != member.Parameters[i].ReturnType.ToInvariantString ()) {
 
158
                                                equals = false;
 
159
                                                break;
 
160
                                        }
 
161
                                }
 
162
                                if (equals) 
 
163
                                        return true;
 
164
                        }
 
165
                        return false;
 
166
                }
 
167
                
 
168
                void OnCancelClicked (object sender, EventArgs e)
 
169
                {
 
170
                        this.Destroy ();
 
171
                }
 
172
                
 
173
                void SetProperties ()
 
174
                {
 
175
                        properties.Name = methodName;
 
176
                        properties.GenerateComment = generateComments;
 
177
                        switch (activeModifier) {
 
178
                        case 0:
 
179
                                properties.Modifiers = Modifiers.None;
 
180
                                break;
 
181
                        case 1:
 
182
                                properties.Modifiers = Modifiers.Public;
 
183
                                break;
 
184
                        case 2:
 
185
                                properties.Modifiers = Modifiers.Private;
 
186
                                break;
 
187
                        case 3:
 
188
                                properties.Modifiers = Modifiers.Protected;
 
189
                                break;
 
190
                        case 4:
 
191
                                properties.Modifiers = Modifiers.Internal;
 
192
                                break;
 
193
                        }
 
194
                        PropertyService.Set ("MonoDevelop.Refactoring.ExtractMethod.ExtractMethodDialog.DefaultModifier", comboboxModifiers.Active);
 
195
                }
 
196
                
 
197
                void OnOKClicked (object sender, EventArgs e)
 
198
                {
 
199
                        TextEditorData data = options.GetTextEditorData ();
 
200
                        Mono.TextEditor.TextEditor editor = data.Parent;
 
201
// Insertion cursor mode test:
 
202
                        if (editor != null) {
 
203
                                IType type = properties.DeclaringMember.DeclaringType;
 
204
                                
 
205
                                InsertionCursorEditMode mode = new InsertionCursorEditMode (editor, CodeGenerationService.GetInsertionPoints (options.Document, type));
 
206
                                for (int i = 0; i < mode.InsertionPoints.Count; i++) {
 
207
                                        var point = mode.InsertionPoints[i];
 
208
                                        if (point.Location < editor.Caret.Location) {
 
209
                                                mode.CurIndex = i;
 
210
                                        } else {
 
211
                                                break;
 
212
                                        }
 
213
                                }
 
214
                                ModeHelpWindow helpWindow = new ModeHelpWindow ();
 
215
                                helpWindow.TransientFor = IdeApp.Workbench.RootWindow;
 
216
                                helpWindow.TitleText = GettextCatalog.GetString ("<b>Extract Method -- Targeting</b>");
 
217
                                helpWindow.Items.Add (new KeyValuePair<string, string> (GettextCatalog.GetString ("<b>Key</b>"), GettextCatalog.GetString ("<b>Behavior</b>")));
 
218
                                helpWindow.Items.Add (new KeyValuePair<string, string> (GettextCatalog.GetString ("<b>Up</b>"), GettextCatalog.GetString ("Move to <b>previous</b> target point.")));
 
219
                                helpWindow.Items.Add (new KeyValuePair<string, string> (GettextCatalog.GetString ("<b>Down</b>"), GettextCatalog.GetString ("Move to <b>next</b> target point.")));
 
220
                                helpWindow.Items.Add (new KeyValuePair<string, string> (GettextCatalog.GetString ("<b>Enter</b>"), GettextCatalog.GetString ("<b>Declare new method</b> at target point.")));
 
221
                                helpWindow.Items.Add (new KeyValuePair<string, string> (GettextCatalog.GetString ("<b>Esc</b>"), GettextCatalog.GetString ("<b>Cancel</b> this refactoring.")));
 
222
                                mode.HelpWindow = helpWindow;
 
223
                                mode.StartMode ();
 
224
                                methodName = entry.Text;
 
225
                                activeModifier = comboboxModifiers.Active;
 
226
                                generateComments = checkbuttonGenerateComment.Active;
 
227
                                
 
228
                                mode.Exited += delegate(object s, InsertionCursorEventArgs args) {
 
229
                                        if (args.Success) {
 
230
                                                SetProperties ();
 
231
                                                properties.InsertionPoint = args.InsertionPoint;
 
232
                                                List<Change> changes = extractMethod.PerformChanges (options, properties);
 
233
                                                IProgressMonitor monitor = IdeApp.Workbench.ProgressMonitors.GetBackgroundProgressMonitor (this.Title, null);
 
234
                                                RefactoringService.AcceptChanges (monitor, options.Dom, changes);
 
235
                                        }
 
236
                                };
 
237
                        }
 
238
                        
 
239
                        ((Widget)this).Destroy ();
 
240
                }
 
241
                
 
242
                void OnPreviewClicked (object sender, EventArgs e)
 
243
                {
 
244
                        methodName = entry.Text;
 
245
                        SetProperties ();
 
246
                        List<Change> changes = extractMethod.PerformChanges (options, properties);
 
247
                        ((Widget)this).Destroy ();
 
248
                        MessageService.ShowCustomDialog (new RefactoringPreviewDialog (options.Dom, changes));
 
249
                }
 
250
        }
 
251
}