~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to src/addins/MonoDevelop.XmlEditor/MonoDevelop.XmlEditor/XmlCompletionListWindow.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// MonoDevelop XML Editor
 
3
//
 
4
// Copyright (C) 2004-2007 MonoDevelop Team
 
5
//
 
6
 
 
7
using System;
 
8
using System.Collections;
 
9
 
 
10
using Gtk;
 
11
using MonoDevelop.Projects;
 
12
using MonoDevelop.Core;
 
13
using MonoDevelop.Ide.CodeCompletion;
 
14
 
 
15
namespace MonoDevelop.XmlEditor
 
16
{
 
17
        public class XmlCompletionListWindow : XmlEditorListWindow, IListDataProvider
 
18
        {
 
19
                ICompletionWidget completionWidget;
 
20
                ICodeCompletionContext completionContext;
 
21
                ICompletionData[] completionData;
 
22
                DeclarationViewWindow declarationviewwindow = new DeclarationViewWindow ();
 
23
                ICompletionData currentData;
 
24
                ICompletionDataProvider provider;
 
25
                IMutableCompletionDataProvider mutableProvider;
 
26
                Widget parsingMessage;
 
27
                char firstChar;
 
28
                CompletionDelegate closedDelegate;
 
29
                
 
30
                const int declarationWindowMargin = 3;
 
31
                static DataComparer dataComparer = new DataComparer ();
 
32
                
 
33
                public static event EventHandler WindowClosed;
 
34
                
 
35
                class DataComparer: IComparer
 
36
                {
 
37
                        public int Compare (object x, object y)
 
38
                        {
 
39
                                ICompletionData d1 = x as ICompletionData;
 
40
                                ICompletionData d2 = y as ICompletionData;
 
41
                                return String.Compare (d1.Text[0], d2.Text[0], true);
 
42
                        }
 
43
                }
 
44
                
 
45
                static XmlCompletionListWindow wnd;
 
46
                
 
47
                static XmlCompletionListWindow ()
 
48
                {
 
49
                        wnd = new XmlCompletionListWindow ();
 
50
                }
 
51
                
 
52
                internal XmlCompletionListWindow ()
 
53
                {
 
54
                        SizeAllocated += new SizeAllocatedHandler (ListSizeChanged);
 
55
                }
 
56
                
 
57
                public static void ShowWindow (char firstChar, ICompletionDataProvider provider, ICompletionWidget completionWidget, ICodeCompletionContext completionContext, CompletionDelegate closedDelegate)
 
58
                {
 
59
                        try {
 
60
                                if (!wnd.ShowListWindow (firstChar, provider,  completionWidget, completionContext, closedDelegate)) {
 
61
                                        provider.Dispose ();
 
62
                                        return;
 
63
                                }
 
64
                                
 
65
                                // makes control-space in midle of words to work
 
66
                                string text = wnd.completionWidget.GetCompletionText (completionContext);
 
67
                                if (text.Length == 0) {
 
68
                                        text = provider.DefaultCompletionString;
 
69
                                        if (text != null && text.Length > 0)
 
70
                                                wnd.SelectEntry (text);
 
71
                                        return;
 
72
                                }
 
73
                                
 
74
                                wnd.PartialWord = text; 
 
75
                                //if there is only one matching result we take it by default
 
76
                                if (wnd.IsUniqueMatch && !wnd.IsChanging)
 
77
                                {       
 
78
                                        wnd.UpdateWord ();
 
79
                                        wnd.Hide ();
 
80
                                }
 
81
                                
 
82
                        } catch (Exception ex) {
 
83
                                Console.WriteLine (ex);
 
84
                        }
 
85
                }
 
86
                
 
87
                bool ShowListWindow (char firstChar, ICompletionDataProvider provider, ICompletionWidget completionWidget, ICodeCompletionContext completionContext, CompletionDelegate closedDelegate)
 
88
                {
 
89
                        if (mutableProvider != null) {
 
90
                                mutableProvider.CompletionDataChanging -= OnCompletionDataChanging;
 
91
                                mutableProvider.CompletionDataChanged -= OnCompletionDataChanged;
 
92
                        }
 
93
                        
 
94
                        this.provider = provider;
 
95
                        this.completionContext = completionContext;
 
96
                        this.closedDelegate = closedDelegate;
 
97
                        mutableProvider = provider as IMutableCompletionDataProvider;
 
98
                        
 
99
                        if (mutableProvider != null) {
 
100
                                mutableProvider.CompletionDataChanging += OnCompletionDataChanging;
 
101
                                mutableProvider.CompletionDataChanged += OnCompletionDataChanged;
 
102
                        
 
103
                                if (mutableProvider.IsChanging)
 
104
                                        OnCompletionDataChanging (null, null);
 
105
                        }
 
106
                        
 
107
                        this.completionWidget = completionWidget;
 
108
                        this.firstChar = firstChar;
 
109
 
 
110
                        return FillList ();
 
111
                }
 
112
                
 
113
                bool FillList ()
 
114
                {
 
115
                        completionData = provider.GenerateCompletionData (completionWidget, firstChar);
 
116
                        if ((completionData == null || completionData.Length == 0) && !IsChanging)
 
117
                                return false;
 
118
                        
 
119
                        this.Style = completionWidget.GtkStyle;
 
120
                        
 
121
                        if (completionData == null)
 
122
                                completionData = new ICompletionData [0];
 
123
                        else
 
124
                                Array.Sort (completionData, dataComparer);
 
125
                        
 
126
                        DataProvider = this;
 
127
 
 
128
                        int x = completionContext.TriggerXCoord;
 
129
                        int y = completionContext.TriggerYCoord;
 
130
                        
 
131
                        int w, h;
 
132
                        GetSize (out w, out h);
 
133
                        
 
134
                        if ((x + w) > Screen.Width)
 
135
                                x = Screen.Width - w;
 
136
                        
 
137
                        if ((y + h) > Screen.Height)
 
138
                        {
 
139
                                y = y - completionContext.TriggerTextHeight - h;
 
140
                        }
 
141
 
 
142
                        Move (x, y);
 
143
                        
 
144
                        Show ();
 
145
                        
 
146
                        // HACK - make window bigger for namespace completion.
 
147
                        // This should probably be handled by the ListWidget/ListWindow
 
148
                        // itself.
 
149
                        if (firstChar == '=') {
 
150
                                this.Resize(this.List.WidthRequest + 220, this.List.HeightRequest);
 
151
                        }
 
152
                        return true;
 
153
                }
 
154
                
 
155
                public static void HideWindow ()
 
156
                {
 
157
                        wnd.Hide ();
 
158
                }
 
159
                
 
160
                /// <summary>
 
161
                /// Modified this method so that punctuation characters
 
162
                /// will not close the completion window.
 
163
                /// </summary>
 
164
                public static bool ProcessKeyEvent (Gdk.EventKey e)
 
165
                {
 
166
                        if (!wnd.Visible) return false;
 
167
                        
 
168
                        XmlEditorListWindow.KeyAction ka = wnd.ProcessKey (e);
 
169
                        
 
170
                        if ((ka & XmlEditorListWindow.KeyAction.CloseWindow) != 0) {
 
171
                                if (e.Key == Gdk.Key.Escape || e.Key == Gdk.Key.BackSpace || !System.Char.IsPunctuation((char)e.KeyValue)) {
 
172
                                        wnd.Hide ();
 
173
                                } 
 
174
                        }
 
175
                        
 
176
                        if ((ka & XmlEditorListWindow.KeyAction.Complete) != 0) {
 
177
                                switch (e.Key) {
 
178
                                        case Gdk.Key.Tab:
 
179
                                        case Gdk.Key.Return:
 
180
                                        case Gdk.Key.ISO_Enter:
 
181
                                        case Gdk.Key.Key_3270_Enter:
 
182
                                        case Gdk.Key.KP_Enter:
 
183
                                                wnd.Hide ();
 
184
                                                wnd.UpdateWord ();
 
185
                                                break;
 
186
                                        default:
 
187
                                                break;
 
188
                                }
 
189
                        }
 
190
                        
 
191
                        if ((ka & XmlEditorListWindow.KeyAction.Ignore) != 0)
 
192
                                return true;
 
193
 
 
194
                        if ((ka & XmlEditorListWindow.KeyAction.Process) != 0) {
 
195
                                if (e.Key == Gdk.Key.Left) {
 
196
                                        if (wnd.declarationviewwindow.Multiple) {
 
197
                                                wnd.declarationviewwindow.OverloadLeft ();
 
198
                                                wnd.UpdateDeclarationView ();
 
199
                                        }
 
200
                                        return true;
 
201
                                } else if (e.Key == Gdk.Key.Right) {
 
202
                                        if (wnd.declarationviewwindow.Multiple) {
 
203
                                                wnd.declarationviewwindow.OverloadRight ();
 
204
                                                wnd.UpdateDeclarationView ();
 
205
                                        }
 
206
                                        return true;
 
207
                                }
 
208
                        }
 
209
 
 
210
                        return false;
 
211
                }
 
212
                
 
213
                /// <summary>
 
214
                /// HACK - Insert the completion string not the text displayed in the 
 
215
                /// completion list and move the cursor between the attribute 
 
216
                /// quotes when an attribute is inserted.
 
217
                /// This should really be done using methods in the 
 
218
                /// ICompletionWidget class.  Here I am cheating and using
 
219
                /// the XmlEditorView and XmlCompletionData directly (The
 
220
                /// XmlCompletionData.InsertAction is not used in MonoDevelop).
 
221
                /// </summary>
 
222
//              void UpdateWord ()
 
223
//              {
 
224
//                      XmlCompletionData data = (XmlCompletionData)completionData[List.Selection];
 
225
//
 
226
//                      string completeWord = data.CompletionString;
 
227
//                      completionWidget.SetCompletionText(completionContext, wnd.PartialWord, completeWord);
 
228
//                      if (data.XmlCompletionDataType == XmlCompletionData.DataType.XmlAttribute) {
 
229
//                              // Position cursor inside attribute value string.
 
230
//                              XmlEditorView view = (XmlEditorView)completionWidget;
 
231
//                              TextIter iter = view.Buffer.GetIterAtMark(view.Buffer.InsertMark);
 
232
//                              iter.Offset--;
 
233
//                              view.Buffer.PlaceCursor(iter);  
 
234
//                      }
 
235
//                      //completionWidget.SetCompletionText(wnd.PartialWord, wnd.CompleteWord);
 
236
//              }
 
237
                
 
238
                void UpdateWord ()
 
239
                {
 
240
                        string word = wnd.CompleteWord;
 
241
                        if (word != null) {
 
242
                                if (wnd.Selection != -1) {
 
243
                                        IActionCompletionData ac = completionData [wnd.Selection] as IActionCompletionData;
 
244
                                        if (ac != null) {
 
245
                                                ac.InsertAction (completionWidget, completionContext);
 
246
                                                return;
 
247
                                        }
 
248
                                }
 
249
                                completionWidget.SetCompletionText (completionContext, wnd.PartialWord, word);
 
250
                        }
 
251
                }
 
252
                
 
253
                public new void Hide ()
 
254
                {
 
255
                        base.Hide ();
 
256
                        declarationviewwindow.HideAll ();
 
257
                        if (provider != null) {
 
258
                                provider.Dispose ();
 
259
                                provider = null;
 
260
                        }
 
261
                        if (closedDelegate != null) {
 
262
                                closedDelegate ();
 
263
                                closedDelegate = null;
 
264
                        }
 
265
                }
 
266
                
 
267
                protected override bool IsValidCompletionChar (char c)
 
268
                {
 
269
                        return XmlParser.IsXmlNameChar(c);
 
270
                }
 
271
 
 
272
                void ListSizeChanged (object obj, SizeAllocatedArgs args)
 
273
                {
 
274
                        UpdateDeclarationView ();
 
275
                }
 
276
 
 
277
                protected override bool OnButtonPressEvent (Gdk.EventButton evnt)
 
278
                {
 
279
                        bool ret = base.OnButtonPressEvent (evnt);
 
280
                        if (evnt.Button == 1 && evnt.Type == Gdk.EventType.TwoButtonPress) {
 
281
                                wnd.UpdateWord ();
 
282
                                wnd.Hide ();
 
283
                        }
 
284
                        return ret;
 
285
                }
 
286
                
 
287
                protected override void OnSelectionChanged ()
 
288
                {
 
289
                        base.OnSelectionChanged ();
 
290
                        UpdateDeclarationView ();
 
291
                }
 
292
                
 
293
                void UpdateDeclarationView ()
 
294
                {
 
295
                        if (completionData == null || List.Selection >= completionData.Length || List.Selection == -1)
 
296
                                return;
 
297
 
 
298
                        if (List.GdkWindow == null) return;
 
299
                        Gdk.Rectangle rect = List.GetRowArea (List.Selection);
 
300
                        int listpos_x = 0, listpos_y = 0;
 
301
                        while (listpos_x == 0 || listpos_y == 0)
 
302
                                GetPosition (out listpos_x, out listpos_y);
 
303
                        int vert = listpos_y + rect.Y;
 
304
                        
 
305
                        int lvWidth = 0, lvHeight = 0;
 
306
                        while (lvWidth == 0)
 
307
                                this.GdkWindow.GetSize (out lvWidth, out lvHeight);
 
308
                        if (vert >= listpos_y + lvHeight - 2) {
 
309
                                vert = listpos_y + lvHeight - rect.Height;
 
310
                        } else if (vert < listpos_y) {
 
311
                                vert = listpos_y;
 
312
                        }
 
313
 
 
314
                        ICompletionData data = completionData[List.Selection];
 
315
                        ICompletionDataWithMarkup datawMarkup = data as ICompletionDataWithMarkup;
 
316
                        XmlCompletionData ccdata = (XmlCompletionData) data;
 
317
 
 
318
                        string descMarkup = datawMarkup != null ? datawMarkup.DescriptionPango : data.Description;
 
319
 
 
320
                        declarationviewwindow.Hide ();
 
321
                        
 
322
                        if (data != currentData) {
 
323
                                declarationviewwindow.Clear ();
 
324
                                declarationviewwindow.Realize ();
 
325
        
 
326
                                declarationviewwindow.AddOverload (descMarkup);
 
327
 
 
328
                                //foreach (CodeCompletionData odata in ccdata.GetOverloads ()) {
 
329
                                //      ICompletionDataWithMarkup odatawMarkup = odata as ICompletionDataWithMarkup;
 
330
                                //      declarationviewwindow.AddOverload (odatawMarkup == null ? odata.Description : odatawMarkup.DescriptionPango);
 
331
                                //}
 
332
                        }
 
333
                        
 
334
                        currentData = data;
 
335
                        
 
336
                        if (declarationviewwindow.DescriptionMarkup.Length == 0)
 
337
                                return;
 
338
 
 
339
                        int dvwWidth, dvwHeight;
 
340
 
 
341
                        declarationviewwindow.Move (this.Screen.Width+1, vert);
 
342
                        
 
343
                        declarationviewwindow.SetFixedWidth (-1);
 
344
                        declarationviewwindow.ReshowWithInitialSize ();
 
345
                        declarationviewwindow.ShowAll ();
 
346
                        //declarationviewwindow.Multiple = (ccdata.Overloads != 0);
 
347
 
 
348
                        declarationviewwindow.GdkWindow.GetSize (out dvwWidth, out dvwHeight);
 
349
 
 
350
                        int horiz = listpos_x + lvWidth + declarationWindowMargin;
 
351
                        if (this.Screen.Width - horiz >= lvWidth) {
 
352
                                if (this.Screen.Width - horiz < dvwWidth)
 
353
                                        declarationviewwindow.SetFixedWidth (this.Screen.Width - horiz);
 
354
                        } else {
 
355
                                if (listpos_x - dvwWidth - declarationWindowMargin < 0) {
 
356
                                        declarationviewwindow.SetFixedWidth (listpos_x - declarationWindowMargin);
 
357
                                        dvwWidth = declarationviewwindow.SizeRequest ().Width;
 
358
                                }
 
359
                                horiz = listpos_x - dvwWidth - declarationWindowMargin;
 
360
                        }
 
361
 
 
362
                        declarationviewwindow.Move (horiz, vert);
 
363
                }
 
364
                
 
365
                public int ItemCount 
 
366
                { 
 
367
                        get { return completionData.Length; } 
 
368
                }
 
369
                
 
370
                public string GetText (int n)
 
371
                {
 
372
                        return completionData[n].Text[0];
 
373
                }
 
374
                
 
375
                public string GetCompletionText (int n)
 
376
                {
 
377
                        return completionData[n].CompletionString;
 
378
                }
 
379
                
 
380
                public Gdk.Pixbuf GetIcon (int n)
 
381
                {
 
382
                        return RenderIcon (completionData[n].Image, Gtk.IconSize.Menu, "");
 
383
                }
 
384
                
 
385
                internal bool IsChanging {
 
386
                        get { return mutableProvider != null && mutableProvider.IsChanging; }
 
387
                }
 
388
                
 
389
                void OnCompletionDataChanging (object s, EventArgs args)
 
390
                {
 
391
                        if (parsingMessage == null) {
 
392
                                VBox box = new VBox ();
 
393
                                box.PackStart (new Gtk.HSeparator (), false, false, 0);
 
394
                                HBox hbox = new HBox ();
 
395
                                hbox.BorderWidth = 3;
 
396
                                hbox.PackStart (new Gtk.Image ("md-parser", Gtk.IconSize.Menu), false, false, 0);
 
397
                                Gtk.Label lab = new Gtk.Label (GettextCatalog.GetString ("Gathering class information..."));
 
398
                                lab.Xalign = 0;
 
399
                                hbox.PackStart (lab, true, true, 3);
 
400
                                hbox.ShowAll ();
 
401
                                parsingMessage = hbox;
 
402
                        }
 
403
                        wnd.ShowFooter (parsingMessage);
 
404
                }
 
405
                
 
406
                void OnCompletionDataChanged (object s, EventArgs args)
 
407
                {
 
408
                        wnd.HideFooter ();
 
409
                        if (Visible) {
 
410
                                Reset ();
 
411
                                FillList ();
 
412
                        }
 
413
                }
 
414
        }
 
415
        
 
416
        public delegate void CompletionDelegate ();
 
417
}
 
 
b'\\ No newline at end of file'