///
/// Copyright © 2003-2008 JetBrains s.r.o.
/// You may distribute under the terms of the GNU General Public License, as published by the Free Software Foundation, version 2 (see License.txt in the repository root folder).
///
using System;
using JetBrains.Omea.OpenAPI;
using System.Windows.Forms;
using System.Collections;
namespace JetBrains.Omea
{
/**
* The class which manages output of status messages to a single status bar panel.
*/
public class StatusPaneManager
{
private StatusBar _statusBar;
private StatusBarPanel _panel;
private Hashtable _statusWriters = new Hashtable();
private ArrayList _activeStatusWriters = new ArrayList();
private bool _updatingStatusText = false;
private bool _recursiveUpdateStatusText = false;
private string _defaultText;
public StatusPaneManager( StatusBar statusBar, StatusBarPanel panel, string defaultText )
{
_statusBar = statusBar;
_panel = panel;
_defaultText = defaultText;
}
public IStatusWriter GetStatusWriter( object owner )
{
lock( _statusWriters )
{
IStatusWriter writer = (IStatusWriter) _statusWriters [owner];
if ( writer == null )
{
writer = new StatusWriter( this, owner );
_statusWriters [owner] = writer;
}
return writer;
}
}
public void RemoveStatusWriter( object owner )
{
lock( _statusWriters )
{
_statusWriters.Remove( owner );
}
}
internal void UpdateStatus( IStatusWriter writer, string message, bool doEvents )
{
lock( _activeStatusWriters )
{
_activeStatusWriters.Remove( writer );
if ( message != null )
_activeStatusWriters.Insert( 0, writer );
}
Core.UIManager.QueueUIJob( new UpdateStatusTextDelegate( UpdateStatusText ), new object[] { doEvents } );
}
internal void UpdateStatusText( bool doEvents )
{
if ( _statusBar.Panels.Count == 0 ) // do not crash when we are closing
return;
if ( _updatingStatusText )
{
_recursiveUpdateStatusText = true;
return;
}
_updatingStatusText = true;
do
{
string panelText;
lock( _activeStatusWriters )
{
if ( _activeStatusWriters.Count == 0 )
{
panelText = _defaultText;
}
else
{
StatusWriter statusWriter = (StatusWriter) _activeStatusWriters [0];
panelText = statusWriter.LastMessage;
}
}
_panel.Text = panelText;
if ( doEvents )
{
_recursiveUpdateStatusText = false;
_statusBar.Refresh();
}
} while( _recursiveUpdateStatusText );
_updatingStatusText = false;
_recursiveUpdateStatusText = false;
}
public bool NeedDoEvents
{
get { return _statusBar.InvokeRequired; }
}
}
internal class StatusWriter: IStatusWriter
{
private StatusPaneManager _manager;
private string _lastMessage;
private object _owner;
internal StatusWriter( StatusPaneManager manager, object owner )
{
_manager = manager;
_owner = owner;
}
public void ShowStatus( string message )
{
ShowStatus( message, 0, _manager.NeedDoEvents );
}
///
/// Shows a status bar message in the appropriate status bar pane and optionally forces it to redraw immediately.
///
public void ShowStatus( string message, bool repaint )
{
ShowStatus( message, 0, repaint );
}
public void ShowStatus( string message, int nShowForSeconds, bool doEvents )
{
// Save message
if ( message == "" )
_lastMessage = null;
else
_lastMessage = message;
// Show
_manager.UpdateStatus( this, _lastMessage, doEvents );
// Queue erasure
if(nShowForSeconds != 0)
Core.UserInterfaceAP.QueueJobAt( DateTime.Now.AddSeconds(nShowForSeconds), "Clear Expired Status Message.", new MethodInvoker(ClearStatus));
}
public void ClearStatus()
{
_lastMessage = null;
_manager.UpdateStatus( this, null, _manager.NeedDoEvents );
_manager.RemoveStatusWriter( _owner );
}
public string LastMessage
{
get { return _lastMessage; }
}
///
/// Shows a status bar message in the appropriate status bar pane and automatically removes it after a given time span.
///
public void ShowStatus( string message, int nSecondsToKeep )
{
ShowStatus(message, nSecondsToKeep, _manager.NeedDoEvents);
}
}
}