added some development tools
[windows-sources.git] / developer / VSSDK / VisualStudioIntegration / Common / Source / CSharp / LanguageService100 / Preferences.cs
bloba560efe8610603131af921b07c8a923bee128c6d
1 using Microsoft.VisualStudio.OLE.Interop;
2 using Microsoft.VisualStudio.TextManager.Interop;
3 using Microsoft.VisualStudio.Shell.Interop;
4 using Microsoft.VisualStudio.Designer.Interfaces;
5 using Microsoft.VisualStudio.Shell;
6 using Microsoft.Win32;
7 using System;
8 using System.Collections;
9 using System.ComponentModel;
10 using System.Drawing;
11 using System.Data;
12 using System.Diagnostics;
13 using System.Runtime.InteropServices;
14 using System.Windows.Forms;
15 using Microsoft.VisualStudio;
16 using System.Globalization;
17 using IOleServiceProvider = Microsoft.VisualStudio.OLE.Interop.IServiceProvider;
18 using IServiceProvider = System.IServiceProvider;
19 using VSRegistry = Microsoft.VisualStudio.Shell.VSRegistry;
21 namespace Microsoft.VisualStudio.Package {
22 /// <include file='doc\Utilities.uex' path='docs/doc[@for="IndentingStyle"]/*' />
23 public enum IndentingStyle {
24 /// <include file='doc\Utilities.uex' path='docs/doc[@for="IndentingStyle.None"]/*' />
25 None,
26 /// <include file='doc\Utilities.uex' path='docs/doc[@for="IndentingStyle.Block"]/*' />
27 Block,
28 /// <include file='doc\Utilities.uex' path='docs/doc[@for="IndentingStyle.Smart"]/*' />
29 Smart
32 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences"]/*' />
33 /// <summary>
34 /// LanguagePreferences encapsulates the standard General and Tab settings for a language service
35 /// and provides a way of getting and setting the values. It is expected that you
36 /// will have one global LanguagePreferences created by your package. The General and Tabs
37 /// settings are automatically persisted in .vssettings files by the core editor package.
38 /// All you need to do is register your language under AutomationProperties/TextEditor
39 /// and specify:
40 /// <code>
41 /// YourLanguage = s '%YourLocalizedName%'
42 /// {
43 /// val Name = s 'YourLanguage'
44 /// val Package = s '{F5E7E720-1401-11D1-883B-0000F87579D2}'
45 /// val ProfileSave = d 1
46 /// val ResourcePackage = s '%YourPackage%'
47 /// }
48 /// </code>
49 /// Therefore this class hides all it's properties from user setting persistence using
50 /// DesignerSerializationVisibility.Hidden. This is so that if you give this object
51 /// to the Package.ExportSettings method as the AutomationObject then it will only
52 /// write out your new settings which is what you want, otherwise the General and Tab
53 /// settings will appear in two places in the .vsssettings file.
54 /// </summary>
55 [CLSCompliant(false),ComVisible(true), Guid("934a92fd-b63a-49c7-9284-11aec8c1e03f")]
56 public class LanguagePreferences : IVsTextManagerEvents2, IDisposable {
57 IServiceProvider site;
58 Guid langSvc;
59 LANGPREFERENCES2 prefs;
60 NativeMethods.ConnectionPointCookie connection;
61 bool enableCodeSense;
62 bool enableMatchBraces;
63 bool enableQuickInfo;
64 bool enableShowMatchingBrace;
65 bool enableMatchBracesAtCaret;
66 bool enableFormatSelection;
67 bool enableCommenting;
68 int maxErrorMessages;
69 int codeSenseDelay;
70 bool enableAsyncCompletion;
71 bool autoOutlining;
72 int maxRegionTime;
73 _HighlightMatchingBraceFlags braceFlags;
74 string name;
76 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.LanguagePreferences"]/*' />
77 /// <summary>
78 /// Gets the language preferences.
79 /// </summary>
80 public LanguagePreferences(IServiceProvider site, Guid langSvc, string name) {
81 this.site = site;
82 this.langSvc = langSvc;
83 this.name = name;
86 /// <include file='doc\Preferences.uex' path='docs/doc[@for="LanguagePreferences.LanguagePreferences1"]/*' />
87 public LanguagePreferences() { }
89 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.LanguageName;"]/*' />
90 protected string LanguageName {
91 get { return this.name; }
92 set { this.name = value; }
95 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.Site;"]/*' />
96 /// <summary>
97 /// This property is not public for a reason. If it were public it would
98 /// get called during LoadSettingsFromStorage which will break it.
99 /// Instead use GetSite().
100 /// </summary>
101 protected IServiceProvider Site {
102 get { return this.site; }
103 set { this.site = value; }
106 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.Site;"]/*' />
107 public IServiceProvider GetSite() {
108 return this.site;
111 // Our base language service perferences (from Babel originally)
112 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.EnableCodeSense;"]/*' />
113 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
114 public bool EnableCodeSense {
115 get { return this.enableCodeSense; }
116 set { this.enableCodeSense = value; }
119 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.EnableMatchBraces;"]/*' />
120 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
121 public bool EnableMatchBraces {
122 get {
123 return this.enableMatchBraces; }
124 set { this.enableMatchBraces = value; }
127 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.EnableQuickInfo;"]/*' />
128 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
129 public bool EnableQuickInfo {
130 get { return this.enableQuickInfo; }
131 set { this.enableQuickInfo = value; }
134 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.EnableShowMatchingBrace;"]/*' />
135 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
136 public bool EnableShowMatchingBrace {
137 get { return this.enableShowMatchingBrace; }
138 set { this.enableShowMatchingBrace = value; }
141 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.EnableMatchBracesAtCaret;"]/*' />
142 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
143 public bool EnableMatchBracesAtCaret {
144 get { return this.enableMatchBracesAtCaret; }
145 set { this.enableMatchBracesAtCaret = value; }
148 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.MaxErrorMessages;"]/*' />
149 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
150 public int MaxErrorMessages {
151 get { return this.maxErrorMessages; }
152 set { this.maxErrorMessages = value; }
155 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.CodeSenseDelay;"]/*' />
156 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
157 public int CodeSenseDelay {
158 get { return this.codeSenseDelay; }
159 set { this.codeSenseDelay = value; }
162 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.EnableAsyncCompletion;"]/*' />
163 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
164 public bool EnableAsyncCompletion {
165 get { return this.enableAsyncCompletion; }
166 set { this.enableAsyncCompletion = value; }
169 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.EnableFormatSelection;"]/*' />
170 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
171 public bool EnableFormatSelection {
172 get { return this.enableFormatSelection; }
173 set { this.enableFormatSelection = value; }
176 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.EnableCommenting;"]/*' />
177 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
178 public bool EnableCommenting {
179 get { return this.enableCommenting; }
180 set { this.enableCommenting = value; }
183 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.MaxRegionTime;"]/*' />
184 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
185 public int MaxRegionTime {
186 get { return this.maxRegionTime; }
187 set { this.maxRegionTime = value; }
190 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.HighlightMatchingBraceFlags;"]/*' />
191 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
192 public _HighlightMatchingBraceFlags HighlightMatchingBraceFlags {
193 get { return this.braceFlags; }
194 set { this.braceFlags = value; }
197 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.Init"]/*' />
198 public virtual void Init() {
199 using (RegistryKey key = VSRegistry.RegistryRoot(__VsLocalRegistryType.RegType_Configuration)) {
200 if (key != null) {
201 InitMachinePreferences(key, name);
204 using (RegistryKey key = VSRegistry.RegistryRoot(__VsLocalRegistryType.RegType_UserSettings)) {
205 if (key != null) {
206 InitUserPreferences(key, name);
209 Connect();
212 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.InitUserPreferences"]/*' />
213 public virtual void InitUserPreferences(RegistryKey key, string name) {
214 this.GetLanguagePreferences();
216 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.GetIntegerValue"]/*' />
217 public int GetIntegerValue(RegistryKey key, string name, int def) {
218 object o = key.GetValue(name);
219 if (o is int) return (int)o;
220 int result;
221 if (o is string && int.TryParse((string)o,NumberStyles.Integer, CultureInfo.InvariantCulture, out result))
222 return result;
223 return def;
225 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.GetBooleanValue"]/*' />
226 public bool GetBooleanValue(RegistryKey key, string name, bool def) {
227 object o = key.GetValue(name);
228 if (o is int) return ((int)o != 0);
229 bool result;
230 if (o is string && bool.TryParse((string)o,out result))
231 return result;
232 return def;
235 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.InitMachinePreferences"]/*' />
236 public virtual void InitMachinePreferences(RegistryKey key, string name)
238 using (RegistryKey keyLanguage = key.OpenSubKey("languages\\language services\\" + name, false))
240 if (keyLanguage != null) {
241 this.EnableCodeSense = GetBooleanValue(keyLanguage, "CodeSense", true);
242 this.EnableMatchBraces = GetBooleanValue(keyLanguage, "MatchBraces", true);
243 this.EnableQuickInfo = GetBooleanValue(keyLanguage, "QuickInfo", true);
244 this.EnableShowMatchingBrace = GetBooleanValue(keyLanguage, "ShowMatchingBrace", true);
245 this.EnableMatchBracesAtCaret = GetBooleanValue(keyLanguage, "MatchBracesAtCaret", true);
246 this.MaxErrorMessages = GetIntegerValue(keyLanguage, "MaxErrorMessages", 10);
247 this.CodeSenseDelay = GetIntegerValue(keyLanguage, "CodeSenseDelay", 1000);
248 this.EnableAsyncCompletion = GetBooleanValue(keyLanguage, "EnableAsyncCompletion", true);
249 this.EnableFormatSelection = GetBooleanValue(keyLanguage, "EnableFormatSelection", false);
250 this.EnableCommenting = GetBooleanValue(keyLanguage, "EnableCommenting", true);
251 this.AutoOutlining = GetBooleanValue(keyLanguage, "AutoOutlining", true);
252 this.MaxRegionTime = GetIntegerValue(keyLanguage, "MaxRegionTime", 2000); // 2 seconds
253 this.braceFlags = (_HighlightMatchingBraceFlags)GetIntegerValue(keyLanguage, "HighlightMatchingBraceFlags", (int)_HighlightMatchingBraceFlags.HMB_USERECTANGLEBRACES);
258 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.Dispose"]/*' />
259 public virtual void Dispose() {
260 Disconnect();
261 site = null;
264 // General tab
265 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.AutoListMembers"]/*' />
266 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
267 public bool AutoListMembers {
268 get { return prefs.fAutoListMembers != 0; }
269 set { prefs.fAutoListMembers = (uint)(value ? 1 : 0); }
272 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.HideAdvancedMembers"]/*' />
273 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
274 public bool HideAdvancedMembers {
275 get { return prefs.fHideAdvancedAutoListMembers != 0; }
276 set { prefs.fHideAdvancedAutoListMembers = (uint)(value ? 1 : 0); }
279 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.ParameterInformation"]/*' />
280 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
281 public bool ParameterInformation {
282 get { return prefs.fAutoListParams != 0; }
283 set { prefs.fAutoListParams = (uint)(value ? 1 : 0); }
286 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.VirtualSpace"]/*' />
287 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
288 public bool VirtualSpace {
289 get { return prefs.fVirtualSpace != 0; }
290 set { prefs.fVirtualSpace = (uint)(value ? 1 : 0); }
293 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.WordWrap"]/*' />
294 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
295 public bool WordWrap {
296 get { return prefs.fWordWrap != 0; }
297 set { prefs.fWordWrap = (uint)(value ? 1 : 0); }
300 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.WordWrapGlyphs"]/*' />
301 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
302 public bool WordWrapGlyphs {
303 get { return (int)prefs.fWordWrapGlyphs != 0; }
304 set { prefs.fWordWrapGlyphs = (uint)(value ? 1 : 0); }
307 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.CutCopyBlankLines"]/*' />
308 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
309 public bool CutCopyBlankLines {
310 get { return (int)prefs.fCutCopyBlanks != 0; }
311 set { prefs.fCutCopyBlanks = (uint)(value ? 1 : 0); }
314 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.LineNumbers"]/*' />
315 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
316 public bool LineNumbers {
317 get { return prefs.fLineNumbers != 0; }
318 set { prefs.fLineNumbers = (uint)(value ? 1 : 0); }
321 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.EnableLeftClickForURLs"]/*' />
322 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
323 public bool EnableLeftClickForURLs {
324 get { return prefs.fHotURLs != 0; }
325 set { prefs.fHotURLs = (uint)(value ? 1 : 0); }
328 // Tabs tab
329 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.Indenting"]/*' />
330 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
331 public IndentingStyle IndentStyle {
332 get { return (IndentingStyle)prefs.IndentStyle; }
333 set { prefs.IndentStyle = (vsIndentStyle)value; }
336 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.TabSize"]/*' />
337 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
338 public int TabSize {
339 get { return (int)prefs.uTabSize; }
340 set { prefs.uTabSize = (uint)value; }
343 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.IndentSize"]/*' />
344 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
345 public int IndentSize {
346 get { return (int)prefs.uIndentSize; }
347 set { prefs.uIndentSize = (uint)value; }
350 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.InsertSpaces"]/*' />
351 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
352 public bool InsertTabs {
353 get { return prefs.fInsertTabs != 0; }
354 set { prefs.fInsertTabs = (uint)(value ? 1 : 0); }
357 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.ShowNavigationBar"]/*' />
358 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
359 public bool ShowNavigationBar {
360 get { return (int)prefs.fDropdownBar != 0; }
361 set { prefs.fDropdownBar = (uint)(value ? 1 : 0); }
364 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.EnableAutoOutlining"]/*' />
365 public bool AutoOutlining {
366 get { return this.autoOutlining; }
367 set { this.autoOutlining = value; }
370 /// <include file='doc\Preferences.uex' path='docs/doc[@for="LanguagePreferences.GetLanguagePrefs"]/*' />
371 public virtual void GetLanguagePreferences() {
372 IVsTextManager textMgr = site.GetService(typeof(SVsTextManager)) as IVsTextManager;
373 if (textMgr != null) {
374 this.prefs.guidLang = langSvc;
375 IVsTextManager2 textMgr2 = site.GetService(typeof(SVsTextManager)) as IVsTextManager2;
376 if (textMgr != null) {
377 LANGPREFERENCES2[] langPrefs2 = new LANGPREFERENCES2[1];
378 langPrefs2[0] = this.prefs;
379 if (NativeMethods.Succeeded(textMgr2.GetUserPreferences2(null, null, langPrefs2, null))) {
380 this.prefs = langPrefs2[0];
381 } else {
382 Debug.Assert(false, "textMgr2.GetUserPreferences2");
388 /// <include file='doc\PropertySheet.uex' path='docs/doc[@for="LanguagePreferences.Apply"]/*' />
389 public virtual void Apply() {
390 IVsTextManager2 textMgr2 = site.GetService(typeof(SVsTextManager)) as IVsTextManager2;
391 if (textMgr2 != null) {
392 this.prefs.guidLang = langSvc;
393 LANGPREFERENCES2[] langPrefs2 = new LANGPREFERENCES2[1];
394 langPrefs2[0] = this.prefs;
395 if (!NativeMethods.Succeeded(textMgr2.SetUserPreferences2(null, null, langPrefs2, null))) {
396 Debug.Assert(false, "textMgr2.SetUserPreferences2");
401 private void Connect() {
402 if (this.connection == null && this.site != null) {
403 IVsTextManager2 textMgr2 = this.site.GetService(typeof(SVsTextManager)) as IVsTextManager2;
404 if (textMgr2 != null) {
405 this.connection = new NativeMethods.ConnectionPointCookie(textMgr2, (IVsTextManagerEvents2)this, typeof(IVsTextManagerEvents2));
410 private void Disconnect() {
411 if (this.connection != null) {
412 this.connection.Dispose();
413 this.connection = null;
417 #region IVsTextManagerEvents2 Members
419 /// <include file='doc\Preferences.uex' path='docs/doc[@for="LanguagePreferences.OnRegisterMarkerType"]/*' />
420 public virtual int OnRegisterMarkerType(int iMarkerType)
422 return NativeMethods.S_OK;
424 /// <include file='doc\Preferences.uex' path='docs/doc[@for="LanguagePreferences.OnRegisterView"]/*' />
425 public virtual int OnRegisterView(IVsTextView view)
427 return NativeMethods.S_OK;
429 /// <include file='doc\Preferences.uex' path='docs/doc[@for="LanguagePreferences.OnUnregisterView"]/*' />
430 public virtual int OnUnregisterView(IVsTextView view)
432 return NativeMethods.S_OK;
434 /// <include file='doc\Preferences.uex' path='docs/doc[@for="LanguagePreferences.OnReplaceAllInFilesBegin"]/*' />
435 public virtual int OnReplaceAllInFilesBegin()
437 return NativeMethods.S_OK;
439 /// <include file='doc\Preferences.uex' path='docs/doc[@for="LanguagePreferences.OnReplaceAllInFilesEnd"]/*' />
440 public virtual int OnReplaceAllInFilesEnd()
442 return NativeMethods.S_OK;
445 /// <include file='doc\Preferences.uex' path='docs/doc[@for="LanguagePreferences.OnUserPreferencesChanged2"]/*' />
446 public virtual int OnUserPreferencesChanged2(VIEWPREFERENCES2[] viewPrefs, FRAMEPREFERENCES2[] framePrefs, LANGPREFERENCES2[] langPrefs, FONTCOLORPREFERENCES2[] fontColorPrefs)
448 if (langPrefs != null && langPrefs.Length > 0 && langPrefs[0].guidLang == this.langSvc) {
449 this.prefs = langPrefs[0];
451 return NativeMethods.S_OK;
454 #endregion