/// /// 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.Collections; using System.ComponentModel; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Reflection; using System.Text; using System.Windows.Forms; using ContactsPlugin.ContactBlocks; using JetBrains.Omea.Base; using JetBrains.Omea.Contacts; using JetBrains.Omea.GUIControls; using JetBrains.Omea.OpenAPI; namespace JetBrains.Omea.ContactsPlugin { /// /// Block for editing contact names. /// internal class NameBlock : AbstractContactViewBlock { private const int _MaxContactNameList = 7; private const int _cThumbnailDim = 40; private const string _cDefaultPictureIcon = "ContactsPlugin.Icons.contact48.png"; private Button _btnPicture; private Button _btnClearPicture; private Button _btnFullName; private PropertyEditor _boxFullName; private Button _btnShowAllNames; private CheckBox _checkShowOrigNames; private JetLinkLabel _lblSeeAll; private CategoriesSelector _selector; /// /// Required designer variable. /// private Container components = null; private IResource _resource; private bool _isNewContact; private bool _hasChanged; private string _originalName; public NameBlock() { InitializeComponent(); } public static AbstractContactViewBlock CreateBlock() { return new NameBlock(); } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Component Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { _btnPicture = new Button(); _btnClearPicture = new Button(); _btnFullName = new Button(); _boxFullName = new PropertyEditor(); _btnShowAllNames = new System.Windows.Forms.Button(); _lblSeeAll = new JetBrains.Omea.GUIControls.JetLinkLabel(); _checkShowOrigNames = new CheckBox(); _selector = new CategoriesSelector(); this.SuspendLayout(); // // _btnPicture // _btnPicture.FlatStyle = System.Windows.Forms.FlatStyle.Flat; _btnPicture.Location = new System.Drawing.Point(2, 4); _btnPicture.Name = "_btnPicture"; _btnPicture.Size = new System.Drawing.Size(64, 64); _btnPicture.TabIndex = 1; // // _btnClearPicture // _btnClearPicture.FlatStyle = FlatStyle.System; _btnClearPicture.Location = new System.Drawing.Point(9, 74); _btnClearPicture.Name = "_btnClearPicture"; _btnClearPicture.Size = new System.Drawing.Size(50, 16); _btnClearPicture.Text = "Clear"; _btnClearPicture.TabIndex = 2; _btnClearPicture.Click += new EventHandler(_btnClearPicture_Click); // // _btnFullName // _btnFullName.FlatStyle = System.Windows.Forms.FlatStyle.System; _btnFullName.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(204))); _btnFullName.Location = new System.Drawing.Point(70, 5); _btnFullName.Name = "_btnFullName"; _btnFullName.Size = new System.Drawing.Size(92, 26); _btnFullName.TabIndex = 3; _btnFullName.Text = "Full &Name..."; _btnFullName.Click += new EventHandler(_btnFullName_Click); // // _boxFullName // _boxFullName.Anchor = (AnchorStyles.Top | AnchorStyles.Left| AnchorStyles.Right); _boxFullName.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(204))); _boxFullName.Location = new System.Drawing.Point(170, 7); _boxFullName.Multiline = false; _boxFullName.Name = "_boxFullName"; _boxFullName.ReadOnly = false; _boxFullName.Size = new System.Drawing.Size(114, 24); _boxFullName.TabIndex = 4; // // _btnShowAllNames // this._btnShowAllNames.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this._btnShowAllNames.FlatStyle = System.Windows.Forms.FlatStyle.System; this._btnShowAllNames.Location = new System.Drawing.Point(180, 75); this._btnShowAllNames.Name = "_btnShowAllNames"; this._btnShowAllNames.Size = new System.Drawing.Size(84, 23); this._btnShowAllNames.TabIndex = 5; this._btnShowAllNames.Text = "Show All Names"; this._btnShowAllNames.Click += new System.EventHandler(this.buttonShowAllNames_Click); // // _lblSeeAll // this._lblSeeAll.ClickableLink = true; this._lblSeeAll.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this._lblSeeAll.Cursor = System.Windows.Forms.Cursors.Default; this._lblSeeAll.Enabled = false; this._lblSeeAll.Location = new System.Drawing.Point(140, 75); this._lblSeeAll.Name = "_lblSeeAll"; this._lblSeeAll.Size = new System.Drawing.Size(0, 0); this._lblSeeAll.TabIndex = 6; this._lblSeeAll.Visible = false; this._lblSeeAll.Click += new EventHandler(labelSeeAll_Click); // // _checkShowOrigNames // this._checkShowOrigNames.Location = new Point( 70, 75 ); this._checkShowOrigNames.Size = new Size( 140, 20 ); this._checkShowOrigNames.Name = "_checkShowOrigNames"; this._checkShowOrigNames.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(204))); this._checkShowOrigNames.TabIndex = 7; this._checkShowOrigNames.Text = "Show Original Names"; this._checkShowOrigNames.Anchor = (AnchorStyles.Top | AnchorStyles.Left); this._checkShowOrigNames.FlatStyle = System.Windows.Forms.FlatStyle.System; // // __selector // _selector.Name = "_selector"; _selector.TabIndex = 8; _selector.Size = new Size(214, 40); _selector.Location = new Point(70, 32); _selector.Anchor = (AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right); // // NameBlock // Controls.Add( _selector ); Controls.Add( _checkShowOrigNames ); Controls.Add( _lblSeeAll ); Controls.Add( _btnShowAllNames ); Controls.Add( _boxFullName ); Controls.Add( _btnFullName ); Controls.Add( _btnClearPicture ); Controls.Add( _btnPicture ); Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(204))); Name = "NameBlock"; Size = new System.Drawing.Size(288, 120); ResumeLayout(false); } #endregion public override void EditResource( IResource res ) { EditResource( res, false ); } private void EditResource( IResource res, bool showAllNames ) { _resource = res; _isNewContact = res.IsTransient; InitializeContactControls( res ); InitializeContactNamesControls( res, showAllNames ); InitializeContactPicture( res ); int currentSize = CurrentBlockLowerBorder; int heightDiff = Size.Height - currentSize; if( heightDiff != 0 ) { Size = new Size( Width, currentSize ); } UpdateValidState(); } private void InitializeContactControls( IResource res ) { _boxFullName.Text = Core.ContactManager.GetFullName( res ); _boxFullName.TextChanged += OnNameTextChanged; _selector.Resource = res; _hasChanged = false; _originalName = Core.ContactManager.GetFullName( res ); } private void InitializeContactNamesControls( IResource res, bool showAllNames ) { _checkShowOrigNames.Checked = res.HasProp( Core.ContactManager.Props.ShowOriginalNames ); _checkShowOrigNames.Visible = _checkShowOrigNames.Enabled = (_checkShowOrigNames.Checked || (res.GetLinksOfType( "ContactName", Core.ContactManager.Props.LinkBaseContact ).Count > 1)); ArrayList uniqueNames = CollectUniqueContactNames( res, showAllNames ); _btnShowAllNames.Visible = _btnShowAllNames.Enabled = !_isNewContact && (uniqueNames.Count > 1); } private void InitializeContactPicture( IResource res ) { Image image; if (res.HasProp( Core.ContactManager.Props.Picture )) { Stream stream = res.GetBlobProp( Core.ContactManager.Props.Picture ); image = Image.FromStream( stream ); } else { image = Utils.TryGetEmbeddedResourceImageFromAssembly( Assembly.GetExecutingAssembly(), _cDefaultPictureIcon ); } _btnPicture.Image = image; _btnPicture.Click += _btnPicture_Click; } private static ArrayList CollectUniqueContactNames( IResource res, bool showAllNames ) { ArrayList uniqueNames = new ArrayList(); IResourceList names = res.GetLinksOfType( "ContactName", Core.ContactManager.Props.LinkBaseContact ); int maxNames = names.Count; if( !showAllNames ) maxNames = Math.Min( maxNames, _MaxContactNameList ); for( int i = 0; i < maxNames; i++ ) { string name = names[ i ].GetStringProp( Core.Props.Name ); if( uniqueNames.IndexOf( name ) == -1 ) uniqueNames.Add( name ); } return uniqueNames; } public override void Save() { if( _hasChanged ) { string title, fn, mn, ln, suffix, addspec; ContactResolver.ResolveName( _boxFullName.Text, null, out title, out fn, out mn, out ln, out suffix, out addspec); SaveProp( ContactManager._propTitle, title ); SaveProp( ContactManager._propFirstName, fn ); SaveProp( ContactManager._propMiddleName, mn ); SaveProp( ContactManager._propLastName, ln ); SaveProp( ContactManager._propSuffix, suffix ); } if( IsOptionDiffer() ) { if( _checkShowOrigNames.Checked ) _resource.SetProp( Core.ContactManager.Props.ShowOriginalNames, true ); else _resource.DeleteProp( Core.ContactManager.Props.ShowOriginalNames ); } } private void SaveProp( int propId, string valueText ) { string currVal = _resource.GetStringProp( propId ); // perform assignment only if values differ. if(( isValid( valueText ) && isValid( currVal ) && valueText != currVal ) || ( isValid( valueText ) && !isValid( currVal ) )) _resource.SetProp( propId, valueText ); else if( !isValid( valueText ) && isValid( currVal ) ) _resource.DeleteProp( propId ); } private static bool isValid( string text ) { return !String.IsNullOrEmpty( text ); } public override bool IsChanged() { return _hasChanged || IsOptionDiffer(); } public override bool OwnsProperty( int propId ) { return propId == ContactManager._propTitle || propId == ContactManager._propFirstName || propId == ContactManager._propMiddleName || propId == ContactManager._propLastName || propId == ContactManager._propSuffix || propId == ContactManager._propSpecificator || propId == Core.ContactManager.Props.ShowOriginalNames; } private void UpdateValidState() { bool isWarning = false; string message = null; if( String.IsNullOrEmpty( _boxFullName.Text )) { message = "Please enter a name for the contact"; } else if( _isNewContact && Core.ContactManager.FindContact( _boxFullName.Text ) != null ) { isWarning = true; message = "A contact with such name already exists"; } OnValidStateChanged(new ValidStateEventArgs( message == null, isWarning, message )); } private bool IsOptionDiffer() { return _checkShowOrigNames.Checked != _resource.HasProp( Core.ContactManager.Props.ShowOriginalNames ); } #region Move/Resize private int CurrentBlockLowerBorder { get { int lowerBound = 0; foreach( Control ctrl in Controls ) { if( ctrl.Enabled ) lowerBound = Math.Max( ctrl.Location.Y + ctrl.Size.Height, lowerBound ); } lowerBound += 8; return lowerBound; } } #endregion Move/Resize #region Name private void OnNameTextChanged( object sender, EventArgs e ) { UpdateValidState(); _hasChanged = _boxFullName.Text.Equals( _originalName ); } private void buttonShowAllNames_Click(object sender, EventArgs e) { AllFullNamesForm form = new AllFullNamesForm( _resource ); form.ShowDialog(); } private void labelSeeAll_Click(object sender, EventArgs e) { EditResource( _resource, true ); } void _btnFullName_Click(object sender, EventArgs e) { FullNameEditForm form = new FullNameEditForm(_resource, _boxFullName.Text); if (form.ShowDialog(this) == DialogResult.OK) { _boxFullName.Text = form.FullName; _hasChanged = false; } } #endregion Name #region Picture Handling private delegate void SetPropDelegate( int prop, Stream stream ); void _btnPicture_Click( object sender, EventArgs e ) { bool ctrlPressed = (ModifierKeys == Keys.Control); if( !ctrlPressed ) { using (OpenFileDialog dlg = new OpenFileDialog()) { dlg.CheckFileExists = true; dlg.Multiselect = false; dlg.Title = "Select Image File"; dlg.Filter = "Image files|*.ico;*.png;*.bmp;*jpg|All files|*.*"; if( dlg.ShowDialog( this ) == DialogResult.OK ) { String file = dlg.FileName; JetMemoryStream origStream = null, thumbStream = null; try { Image image = Image.FromFile( file ); origStream = new JetMemoryStream(); image.Save( origStream, ImageFormat.Png ); Image thumb = GraphicalUtils.GenerateImageThumbnail( image, _cThumbnailDim, _cThumbnailDim ); thumbStream = new JetMemoryStream(); ImageCodecInfo[] iciInfo = ImageCodecInfo.GetImageEncoders(); EncoderParameters encParams = new EncoderParameters( 1 ); encParams.Param[ 0 ] = new EncoderParameter( System.Drawing.Imaging.Encoder.Quality, 100L ); thumb.Save( thumbStream, iciInfo[ 1 ], encParams ); Core.ResourceAP.RunJob( new SetPropDelegate( SetStreamProp ), Core.ContactManager.Props.PictureOriginal, origStream ); Core.ResourceAP.RunJob( new SetPropDelegate( SetStreamProp ), Core.ContactManager.Props.Picture, thumbStream ); InitializeContactPicture( _resource ); Invalidate( true ); } catch( Exception ex ) { Core.UIManager.ShowSimpleMessageBox( "Error Format", ex.Message ); Core.ResourceAP.RunJob( new SetPropDelegate(SetStreamProp), Core.ContactManager.Props.PictureOriginal, null ); Core.ResourceAP.RunJob( new SetPropDelegate(SetStreamProp), Core.ContactManager.Props.Picture, null ); } finally { if( origStream != null ) origStream.Dispose(); if( thumbStream != null) thumbStream.Dispose(); } } } } else { // If there is a reference to a full-scaled picture, show it // in the associated application. Stream stream = _resource.GetBlobProp( Core.ContactManager.Props.PictureOriginal ); if( stream != null ) { string fileName = Path.GetTempFileName() + ".png"; using (Image image = Image.FromStream(stream)) { image.Save( fileName, ImageFormat.Png ); Utils.RunAssociatedApplicationOnFile( fileName ); } } } } void _btnClearPicture_Click(object sender, EventArgs e) { Core.ResourceAP.RunJob( new SetPropDelegate( SetStreamProp ), Core.ContactManager.Props.PictureOriginal, null ); Core.ResourceAP.RunJob( new SetPropDelegate( SetStreamProp ), Core.ContactManager.Props.Picture, null ); InitializeContactPicture(_resource); Invalidate(true); } private void SetStreamProp(int prop, Stream stream) { if( stream != null ) _resource.SetProp( prop, stream ); else _resource.DeleteProp( prop ); } #endregion Picture Handling #region Html Content public override string HtmlContent( IResource contact ) { StringBuilder result = StringBuilderPool.Alloc(); try { if (contact.GetPropText(ContactManager._propTitle).Length > 0) { result.Append( OptionalTag(contact, "Title:", ContactManager._propTitle) ); } result.Append( ObligatoryTag(contact, "First Name:", ContactManager._propFirstName) ); result.Append( ObligatoryTag(contact, "Mid Name:", ContactManager._propMiddleName) ); result.Append( ObligatoryTag(contact, "Last Name:", ContactManager._propLastName) ); if (contact.GetPropText(ContactManager._propSuffix).Length > 0) { result.Append( OptionalTag(contact, "Suffix:", ContactManager._propSuffix) ); } bool showAllNames = contact.HasProp( Core.ContactManager.Props.ShowOriginalNames ); if( showAllNames ) { ArrayList uniqueNames = CollectUniqueContactNames( contact, showAllNames ); if (((uniqueNames.Count > 1) || (uniqueNames.Count == 1 && (string)uniqueNames[ 0 ] != contact.DisplayName))) { result.Append("\tAvailable Names:"); foreach( string name in uniqueNames ) { result.Append( name ).Append("
"); } result.Append(""); } } return result.ToString(); } finally { StringBuilderPool.Dispose( result ); } } #endregion Html Content } }