1111using System ;
1212using System . ComponentModel ;
1313using System . ComponentModel . Composition ;
14+ using System . Windows ;
1415using Process = System . Diagnostics . Process ;
1516
1617namespace GtmExtension
@@ -21,7 +22,8 @@ namespace GtmExtension
2122 public sealed class GtmListener : IVsTextViewCreationListener
2223 {
2324 private bool initialized ;
24- private string gtmExe , prevPath , status ;
25+ private string gtmExe , prevPath , status , prevCaption ;
26+ private int index ;
2527 private DateTime lastUpdate ;
2628 private IVsEditorAdaptersFactoryService editor ;
2729 private DocumentEvents documentEvents ;
@@ -80,6 +82,8 @@ private static bool ExistsOnPath(string exeName)
8082
8183 private void ShowError ( string message )
8284 {
85+ ThreadHelper . ThrowIfNotOnUIThread ( ) ;
86+
8387 // Show message box.
8488 Guid clsid = Guid . Empty ;
8589 ErrorHandler . ThrowOnFailure ( uiShell . ShowMessageBox ( 0 , ref clsid , "GtmExtension" , message , string . Empty , 0 ,
@@ -100,6 +104,55 @@ private I GetService<S, I>()
100104 return ( I ) service ;
101105 }
102106
107+ private static readonly bool appendToStatusbar = true ;
108+ private static readonly bool prepend = true ;
109+ private string Title
110+ {
111+ get
112+ {
113+ ThreadHelper . ThrowIfNotOnUIThread ( ) ;
114+
115+ if ( appendToStatusbar )
116+ {
117+ statusbar . GetText ( out var text ) ;
118+ return text ;
119+ }
120+ return Application . Current . MainWindow . Title ;
121+ }
122+ set
123+ {
124+ ThreadHelper . ThrowIfNotOnUIThread ( ) ;
125+
126+ if ( appendToStatusbar )
127+ {
128+ statusbar . SetText ( value ) ;
129+ }
130+ else
131+ {
132+ Application . Current . MainWindow . Title = value ;
133+ }
134+ }
135+ }
136+ private void AppendToWindowTitle ( string title )
137+ {
138+ ThreadHelper . ThrowIfNotOnUIThread ( ) ;
139+
140+ var format = prepend ? "{1} {0}" : "{0} {1}" ;
141+ var caption = Title ;
142+ if ( caption == prevCaption )
143+ {
144+ if ( prepend ) { caption = caption . Substring ( prevCaption . Length - index ) ; }
145+ else { caption = caption . Substring ( 0 , index ) ; }
146+
147+ Title = prevCaption = string . Format ( format , caption , title ) ;
148+ }
149+ else
150+ {
151+ index = caption . Length ;
152+ Title = prevCaption = string . Format ( format , caption , title ) ;
153+ }
154+ }
155+
103156 #endregion
104157
105158 #region Event handlers
@@ -108,7 +161,7 @@ public void VsTextViewCreated(IVsTextView textView)
108161 {
109162 Initialize ( ) ;
110163
111- var wpfTextView = editor . GetWpfTextView ( textView ) ;
164+ IWpfTextView wpfTextView = editor . GetWpfTextView ( textView ) ;
112165 wpfTextView . LayoutChanged += WpfTextView_LayoutChanged ;
113166 wpfTextView . Caret . PositionChanged += Caret_PositionChanged ;
114167
@@ -124,6 +177,7 @@ private void Caret_PositionChanged(object sender, CaretPositionChangedEventArgs
124177 }
125178 private void DocumentEvents_DocumentSaved ( Document Document )
126179 {
180+ ThreadHelper . ThrowIfNotOnUIThread ( ) ;
127181 Update ( Document . FullName , force : true ) ;
128182 }
129183
@@ -134,6 +188,8 @@ private void Initialize()
134188 if ( initialized ) { return ; }
135189 initialized = true ;
136190
191+ ThreadHelper . ThrowIfNotOnUIThread ( ) ;
192+
137193 // Get services.
138194 GetService ( ref uiShell ) ;
139195 GetService ( ref statusbar ) ;
@@ -180,14 +236,14 @@ private void Update(string path, bool force = false)
180236 status = ExecuteForOutput ( gtmExe , $ "record --status \" { path } \" ") ;
181237 if ( ! string . IsNullOrWhiteSpace ( status ) )
182238 {
183- statusbar . SetText ( $ "GTM: { status } *") ;
239+ AppendToWindowTitle ( $ "[ GTM: { status } *] ") ;
184240 }
185241
186242 prevPath = path ;
187243 }
188244 else if ( ! string . IsNullOrWhiteSpace ( status ) )
189245 {
190- statusbar . SetText ( $ "GTM: { status } ") ;
246+ AppendToWindowTitle ( $ "[ GTM: { status } ] ") ;
191247 }
192248 lastUpdate = time ;
193249 }
0 commit comments