///
/// 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 System.Drawing;
using System.Collections;
using System.Text;
using System.Windows.Forms;
using JetBrains.Omea.GUIControls;
using JetBrains.Omea.OpenAPI;
using JetBrains.Omea.FiltersManagement;
namespace JetBrains.Omea
{
/**
* Dialog for configuring the notifications for the specified resource.
*/
public class NotifyMeDlg : DialogBase
{
private Button _btnOK;
private Button _btnCancel;
private Label label1;
private Panel _separator;
///
/// Required designer variable.
///
private System.ComponentModel.Container components = null;
private static int _propNotifyMeRule;
private IResource _targetResource;
private IResource[] _notifyMeConditionTemplates;
private Label _notifyMeConditionLabel;
private CheckBox[] _notifyMeConditionCheckboxes;
private const string _playSoundTemplateName = "Play sound from %file%";
private Panel _actionPanel;
private TextBox _edtMessage;
private TextBox _edtSoundName;
private CheckBox _chkShowMessage;
private Button _btnBrowse;
private CheckBox _chkPlaySound;
private CheckBox _chkShowDesktopAlert;
private OpenFileDialog _openFileDialog;
private const string _showMessageTemplateName = "Display message box with %text%";
private const int _ConditionCheckboxVerSize = 24;
public NotifyMeDlg()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
///
/// Clean up any resources being used.
///
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this._btnOK = new System.Windows.Forms.Button();
this._btnCancel = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label();
this._separator = new System.Windows.Forms.Panel();
this._actionPanel = new System.Windows.Forms.Panel();
this._edtMessage = new System.Windows.Forms.TextBox();
this._edtSoundName = new System.Windows.Forms.TextBox();
this._chkShowMessage = new System.Windows.Forms.CheckBox();
this._btnBrowse = new System.Windows.Forms.Button();
this._chkPlaySound = new System.Windows.Forms.CheckBox();
this._chkShowDesktopAlert = new System.Windows.Forms.CheckBox();
this._openFileDialog = new System.Windows.Forms.OpenFileDialog();
this._actionPanel.SuspendLayout();
this.SuspendLayout();
//
// _btnOK
//
this._btnOK.DialogResult = System.Windows.Forms.DialogResult.OK;
this._btnOK.FlatStyle = System.Windows.Forms.FlatStyle.System;
this._btnOK.Location = new System.Drawing.Point(220, 252);
this._btnOK.Name = "_btnOK";
this._btnOK.TabIndex = 0;
this._btnOK.Text = "OK";
//
// _btnCancel
//
this._btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this._btnCancel.FlatStyle = System.Windows.Forms.FlatStyle.System;
this._btnCancel.Location = new System.Drawing.Point(304, 252);
this._btnCancel.Name = "_btnCancel";
this._btnCancel.TabIndex = 1;
this._btnCancel.Text = "Cancel";
//
// label1
//
this.label1.FlatStyle = System.Windows.Forms.FlatStyle.System;
this.label1.Location = new System.Drawing.Point(4, 4);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(148, 16);
this.label1.TabIndex = 2;
this.label1.Text = "Notify when messages arrive:";
//
// _separator
//
this._separator.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
this._separator.Location = new System.Drawing.Point(4, 44);
this._separator.Name = "_separator";
this._separator.Size = new System.Drawing.Size(380, 4);
this._separator.TabIndex = 3;
//
// _actionPanel
//
this._actionPanel.Controls.Add(this._edtMessage);
this._actionPanel.Controls.Add(this._edtSoundName);
this._actionPanel.Controls.Add(this._chkShowMessage);
this._actionPanel.Controls.Add(this._btnBrowse);
this._actionPanel.Controls.Add(this._chkPlaySound);
this._actionPanel.Controls.Add(this._chkShowDesktopAlert);
this._actionPanel.Location = new System.Drawing.Point(0, 48);
this._actionPanel.Name = "_actionPanel";
this._actionPanel.Size = new System.Drawing.Size(384, 84);
this._actionPanel.TabIndex = 10;
//
// _edtMessage
//
this._edtMessage.Enabled = false;
this._edtMessage.Location = new System.Drawing.Point(128, 56);
this._edtMessage.Name = "_edtMessage";
this._edtMessage.Size = new System.Drawing.Size(250, 21);
this._edtMessage.TabIndex = 15;
this._edtMessage.Text = "";
this._edtMessage.TextChanged += new System.EventHandler(this._edtMessage_TextChanged);
//
// _edtSoundName
//
this._edtSoundName.Enabled = false;
this._edtSoundName.Location = new System.Drawing.Point(128, 28);
this._edtSoundName.Name = "_edtSoundName";
this._edtSoundName.Size = new System.Drawing.Size(172, 21);
this._edtSoundName.TabIndex = 12;
this._edtSoundName.Text = "";
this._edtSoundName.TextChanged += new System.EventHandler(this._edtSoundName_TextChanged);
//
// _chkShowMessage
//
this._chkShowMessage.FlatStyle = System.Windows.Forms.FlatStyle.System;
this._chkShowMessage.Location = new System.Drawing.Point(8, 60);
this._chkShowMessage.Name = "_chkShowMessage";
this._chkShowMessage.Size = new System.Drawing.Size(104, 20);
this._chkShowMessage.TabIndex = 14;
this._chkShowMessage.Text = "Show Message";
this._chkShowMessage.CheckedChanged += new System.EventHandler(this._chkShowMessage_CheckedChanged);
//
// _btnBrowse
//
this._btnBrowse.FlatStyle = System.Windows.Forms.FlatStyle.System;
this._btnBrowse.Location = new System.Drawing.Point(304, 28);
this._btnBrowse.Name = "_btnBrowse";
this._btnBrowse.TabIndex = 13;
this._btnBrowse.Text = "Browse...";
this._btnBrowse.Click += new System.EventHandler(this._btnBrowse_Click);
//
// _chkPlaySound
//
this._chkPlaySound.FlatStyle = System.Windows.Forms.FlatStyle.System;
this._chkPlaySound.Location = new System.Drawing.Point(8, 32);
this._chkPlaySound.Name = "_chkPlaySound";
this._chkPlaySound.Size = new System.Drawing.Size(104, 20);
this._chkPlaySound.TabIndex = 11;
this._chkPlaySound.Text = "Play Sound";
this._chkPlaySound.CheckedChanged += new System.EventHandler(this._chkPlaySound_CheckedChanged);
//
// _chkShowDesktopAlert
//
this._chkShowDesktopAlert.FlatStyle = System.Windows.Forms.FlatStyle.System;
this._chkShowDesktopAlert.Location = new System.Drawing.Point(8, 4);
this._chkShowDesktopAlert.Name = "_chkShowDesktopAlert";
this._chkShowDesktopAlert.Size = new System.Drawing.Size(172, 20);
this._chkShowDesktopAlert.TabIndex = 10;
this._chkShowDesktopAlert.Text = "Show Desktop Alert";
//
// _openFileDialog
//
this._openFileDialog.Filter = "Sound files (*.WAV)|*.WAV|All files|*.*";
//
// NotifyMeDlg
//
this.AcceptButton = this._btnOK;
this.AutoScaleBaseSize = new System.Drawing.Size(5, 14);
this.CancelButton = this._btnCancel;
this.ClientSize = new System.Drawing.Size(386, 285);
this.Controls.Add(this._actionPanel);
this.Controls.Add(this._separator);
this.Controls.Add(this.label1);
this.Controls.Add(this._btnCancel);
this.Controls.Add(this._btnOK);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.Name = "NotifyMeDlg";
this.Text = "Notify Me";
this._actionPanel.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
public static void RegisterTypes()
{
IResourceStore store = ICore.Instance.ResourceStore;
_propNotifyMeRule = store.PropTypes.Register( "NotifyMeRule", PropDataType.Link,
PropTypeFlags.Internal );
}
public void ShowNotifyMeDialog( IResource res )
{
_targetResource = res;
_notifyMeConditionTemplates = GetValidNotifyConditions();
if ( _notifyMeConditionTemplates.Length == 0 )
{
MessageBox.Show( Core.MainWindow,
"There are no valid notify conditions for '" + res.DisplayName + "'",
"Notify Me" );
return;
}
if ( _notifyMeConditionTemplates.Length > 1 )
{
ShowNotifyConditionCheckboxes();
}
else
{
string condName = GetNotifyConditionName( _notifyMeConditionTemplates [0] );
_notifyMeConditionLabel = new Label();
_notifyMeConditionLabel.FlatStyle = FlatStyle.System;
_notifyMeConditionLabel.Text = condName;
_notifyMeConditionLabel.AutoSize = true;
_notifyMeConditionLabel.Location = new Point( 4, 24 );
Controls.Add( _notifyMeConditionLabel );
}
_btnOK.Top = _actionPanel.Bottom + 4;
_btnCancel.Top = _btnOK.Top;
Height = (Height - ClientSize.Height) + _btnOK.Bottom + 8;
ShowExistingNotifyRule();
if ( ShowDialog() == DialogResult.OK )
{
ICore.Instance.ResourceAP.RunJob( new MethodInvoker( SaveNotifyRule ) );
}
}
/**
* Returns the list of notify conditions which have valid parameters
* for the specified resource.
*/
private IResource[] GetValidNotifyConditions()
{
ArrayList templateList = new ArrayList( Core.NotificationManager.GetNotifyMeConditions( _targetResource.Type ) );
for( int i=templateList.Count-1; i >= 0; i-- )
{
IResource conditionTemplate = (IResource) templateList [i];
if ( GetNotifyConditionName( conditionTemplate ) == null )
{
templateList.RemoveAt( i );
}
}
return (IResource[]) templateList.ToArray( typeof (IResource) );
}
/**
* Create checkboxes for the multiple available notify conditions and check them
* if they are already used in the existing rule.
*/
private void ShowNotifyConditionCheckboxes()
{
IResource rule = _targetResource.GetLinkProp( _propNotifyMeRule );
int y = _ConditionCheckboxVerSize;
_notifyMeConditionCheckboxes = new CheckBox[ _notifyMeConditionTemplates.Length ];
for( int i = 0; i < _notifyMeConditionTemplates.Length; i++ )
{
IResource condition = _notifyMeConditionTemplates [i];
CheckBox chkCondition = new CheckBox();
chkCondition.Location = new Point( 8, y );
chkCondition.FlatStyle = FlatStyle.System;
chkCondition.Text = GetNotifyConditionName( condition );
chkCondition.Size = new Size( Width - 12, _ConditionCheckboxVerSize );
chkCondition.CheckedChanged += new EventHandler( OnConditionCheckedChanged );
if ( rule != null )
{
chkCondition.Checked = IsConditionTemplateUsed( condition, rule );
}
Controls.Add( chkCondition );
_notifyMeConditionCheckboxes [i] = chkCondition;
y += _ConditionCheckboxVerSize;
}
UpdateButtonState();
_separator.Top = y;
_actionPanel.Top = y + 4;
}
private void OnConditionCheckedChanged( object sender, EventArgs e )
{
UpdateButtonState();
}
/**
* If all conditions are unchecked, disables the OK button
*/
private void UpdateButtonState()
{
bool anyChecked = true;
if ( _notifyMeConditionCheckboxes != null )
{
anyChecked = false;
foreach( CheckBox chk in _notifyMeConditionCheckboxes )
{
if ( chk != null && chk.Checked )
{
anyChecked = true;
break;
}
}
}
if ( !anyChecked )
{
_btnOK.Enabled = false;
}
else
{
if ( ( _chkPlaySound.Checked && _edtSoundName.Text.Length == 0 ) ||
( _chkShowMessage.Checked && _edtMessage.Text.Length == 0 ) )
{
_btnOK.Enabled = false;
}
else
{
_btnOK.Enabled = true;
}
}
}
/**
* Returns true if the specified condition template is used in the specified rule.
*/
private static bool IsConditionTemplateUsed( IResource conditionTemplate, IResource rule )
{
string templateName = conditionTemplate.GetStringProp( Core.Props.Name );
foreach( IResource condition in Core.FilterRegistry.GetConditions( rule ) )
{
IResource template = condition.GetLinkProp( "TemplateLink" );
if(( template != null ) && ( template.GetStringProp( Core.Props.Name ) == templateName ))
return true;
}
return false;
}
/**
* If a notify rule already exists for the target resource, show its parameters
* in the dialog.
*/
private void ShowExistingNotifyRule()
{
IResource rule = _targetResource.GetLinkProp( _propNotifyMeRule );
if ( rule != null )
{
IResourceList actions = Core.FilterRegistry.GetActions( rule );
foreach( IResource action in actions )
{
IResource template = action.GetLinkProp( "TemplateLink" );
string templateName = (template != null) ? template.GetStringProp( Core.Props.Name ) : string.Empty;
if( action.GetStringProp( Core.Props.Name ) == "Show desktop alert" )
{
_chkShowDesktopAlert.Checked = true;
}
else if( templateName == _playSoundTemplateName )
{
_chkPlaySound.Checked = true;
_edtSoundName.Text = action.GetStringProp( "ConditionVal" );
}
else if( templateName == _showMessageTemplateName )
{
_chkShowMessage.Checked = true;
_edtMessage.Text = action.GetStringProp( "ConditionVal" );
}
}
}
}
private void SaveNotifyRule()
{
IResource rule = _targetResource.GetLinkProp( _propNotifyMeRule );
if ( rule != null )
{
Core.FilterRegistry.DeleteRule( rule );
}
string ruleName;
IResource[] ruleConditions = BuildRuleConditions( out ruleName );
IResource[] ruleActions = BuildRuleActions();
if ( ruleActions.Length > 0 )
{
string ruleResType = Core.NotificationManager.GetRuleResourceType( _targetResource.Type );
rule = Core.FilterRegistry.RegisterRule( StandardEvents.ResourceReceived, ruleName,
( ruleResType == null )? null : new string[ 1 ]{ ruleResType },
ruleConditions, null, ruleActions );
_targetResource.AddLink( _propNotifyMeRule, rule );
}
}
/**
* Returns the array of conditions for the selected condition template
* or templates.
*/
private IResource[] BuildRuleConditions( out string ruleName )
{
StringBuilder ruleNameBuilder = new StringBuilder( "Notify Me: " );
ArrayList conditions = new ArrayList();
if ( _notifyMeConditionTemplates.Length == 1 )
{
ruleNameBuilder.Append( GetNotifyConditionName( _notifyMeConditionTemplates [0] ) );
conditions.Add( BuildRuleCondition( _notifyMeConditionTemplates [0] ) );
}
else
{
for( int i=0; i<_notifyMeConditionTemplates.Length; i++ )
{
if ( _notifyMeConditionCheckboxes [i].Checked )
{
if ( conditions.Count > 0 )
{
ruleNameBuilder.Append( ", " );
}
ruleNameBuilder.Append( GetNotifyConditionName( _notifyMeConditionTemplates [i] ) );
conditions.Add( BuildRuleCondition( _notifyMeConditionTemplates [i] ) );
}
}
}
ruleName = ruleNameBuilder.ToString();
return (IResource[]) conditions.ToArray( typeof(IResource) );
}
/**
* Creates a condition with an appropriate parameter from the specified template.
*/
private IResource BuildRuleCondition( IResource conditionTemplate )
{
IResource param = GetConditionParameter( conditionTemplate );
return FilterConvertors.InstantiateTemplate( conditionTemplate, param.ToResourceList(),
new string[ 1 ] { _targetResource.Type } );
}
/**
* Returns an array of rule actions currently checked in the dialog.
*/
private IResource[] BuildRuleActions()
{
ArrayList ruleActions = new ArrayList();
if ( _chkShowDesktopAlert.Checked )
{
ruleActions.Add( Core.ResourceStore.FindUniqueResource( FilterManagerProps.RuleActionResName,
"Name", "Show desktop alert" ) );
}
if ( _chkPlaySound.Checked && _edtSoundName.Text != "" )
{
IResource template = Core.ResourceStore.FindUniqueResource( FilterManagerProps.RuleActionTemplateResName,
"Name", _playSoundTemplateName );
ruleActions.Add( FilterConvertors.Template2Action( template, _edtSoundName.Text, null ) );
}
if ( _chkShowMessage.Checked && _edtMessage.Text != "" )
{
IResource template = Core.ResourceStore.FindUniqueResource( FilterManagerProps.RuleActionTemplateResName,
"Name", _showMessageTemplateName );
ruleActions.Add( FilterConvertors.Template2Action( template, _edtMessage.Text, null ) );
}
return (IResource[]) ruleActions.ToArray( typeof(IResource) );
}
/**
* Returns the name of the condition displayed in the dialog for the specified
* condition template.
*/
private string GetNotifyConditionName( IResource conditionTemplate )
{
IResource param = GetConditionParameter( conditionTemplate );
if ( param == null )
return null;
string visualName = conditionTemplate.GetStringProp( Core.Props.Name );
if ( param != null )
{
int startPercent = visualName.IndexOf( '%' );
if ( startPercent >= 0 )
{
int endPercent = visualName.IndexOf( '%', startPercent+1 );
if ( endPercent >= 0 )
{
return visualName.Substring( 0, startPercent ) + "'" + param.DisplayName +
"'" + visualName.Substring( endPercent+1 );
}
}
}
return visualName;
}
/**
* Returns either the target resource or the resource linked to it with the
* link type registered for the specified condition.
*/
private IResource GetConditionParameter( IResource conditionTemplate )
{
int linkType = Core.NotificationManager.GetConditionLinkType( _targetResource.Type, conditionTemplate );
IResource param = (linkType == 0)
? _targetResource
: _targetResource.GetLinkProp( linkType );
return param;
}
private void _chkPlaySound_CheckedChanged( object sender, EventArgs e )
{
_edtSoundName.Enabled = _chkPlaySound.Checked;
_btnBrowse.Enabled = _chkPlaySound.Checked;
UpdateButtonState();
}
private void _chkShowMessage_CheckedChanged(object sender, EventArgs e)
{
_edtMessage.Enabled = _chkShowMessage.Checked;
if ( _chkShowMessage.Checked && _edtMessage.Text == "" )
{
CreateDefaultNotificationMessage();
}
UpdateButtonState();
}
private void CreateDefaultNotificationMessage()
{
StringBuilder msgBuilder = new StringBuilder( "New item received: " );
if ( _notifyMeConditionLabel != null )
{
msgBuilder.Append( _notifyMeConditionLabel.Text );
}
else
{
bool firstItem = true;
for ( int i=0; i<_notifyMeConditionCheckboxes.Length; i++ )
{
if ( _notifyMeConditionCheckboxes [i].Checked )
{
if ( !firstItem )
{
msgBuilder.Append( ", " );
}
firstItem = false;
msgBuilder.Append( _notifyMeConditionCheckboxes [i].Text );
}
}
}
_edtMessage.Text = msgBuilder.ToString();
}
private void _btnBrowse_Click( object sender, EventArgs e )
{
_openFileDialog.FileName = _edtSoundName.Text;
if ( _openFileDialog.ShowDialog() == DialogResult.OK )
{
_edtSoundName.Text = _openFileDialog.FileName;
}
}
private void _edtSoundName_TextChanged(object sender, EventArgs e)
{
UpdateButtonState();
}
private void _edtMessage_TextChanged(object sender, EventArgs e)
{
UpdateButtonState();
}
}
public class NotifyMeAction: IAction
{
public void Execute( IActionContext context )
{
using( NotifyMeDlg dlg = new NotifyMeDlg() )
{
dlg.ShowNotifyMeDialog( context.SelectedResources [0] );
}
}
public void Update( IActionContext context, ref ActionPresentation presentation )
{
if ( context.SelectedResources.Count != 1 )
{
presentation.Visible = false;
}
else
{
string resType = context.SelectedResources [0].Type;
if ( ICore.Instance.NotificationManager.GetNotifyMeConditions( resType ).Length == 0 )
{
presentation.Visible = false;
}
}
if ( context.Kind == ActionContextKind.MainMenu && !presentation.Visible )
{
presentation.Visible = true;
presentation.Enabled = false;
}
}
}
public class NotifyMeOnContactNameAction: IAction
{
public void Execute( IActionContext context )
{
IResource res = context.SelectedResources[ 0 ].GetLinkProp( Core.ContactManager.Props.LinkBaseContact );
using( NotifyMeDlg dlg = new NotifyMeDlg() )
{
dlg.ShowNotifyMeDialog( res );
}
}
public void Update( IActionContext context, ref ActionPresentation presentation )
{
presentation.Visible = (context.SelectedResources.Count == 1) &&
(context.SelectedResources[ 0 ].Type == "ContactName") &&
(Core.NotificationManager.GetNotifyMeConditions( "Contact" ).Length > 0 );
}
}
}