///
/// 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.Collections;
using System.Windows.Forms;
using JetBrains.Omea.Containers;
using JetBrains.Omea.GUIControls;
using JetBrains.Omea.OpenAPI;
using JetBrains.Omea.ResourceTools;
namespace JetBrains.Omea
{
///
/// Common functionality of LinksBar and LinksPane.
///
internal abstract class LinksPaneBase : UserControl
{
///
/// Required designer variable.
///
private System.ComponentModel.Container components = null;
protected ILinksPaneFilter _filter;
protected IResourceStore _store;
protected IResourceList _resourceList;
private static readonly AnchoredList _linksPaneGroups = new AnchoredList(); // string -> IntArrayList
protected ColorScheme _colorScheme;
private IResourceList _customProperties;
public LinksPaneBase()
{
// This call is required by the Windows.Forms Form Designer.
InitializeComponent();
}
///
/// Clean up any resources being used.
///
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
if ( _customProperties != null )
{
_customProperties.ResourceAdded -= HandleCustomPropertyListChanged;
_customProperties.ResourceDeleting -= HandleCustomPropertyListChanged;
_customProperties.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()
{
components = new System.ComponentModel.Container();
}
#endregion
public static void RegisterLinksGroup( string groupId, int[] propTypes, ListAnchor anchor )
{
IntArrayList existingList = (IntArrayList) _linksPaneGroups.FindByKey( groupId );
if ( existingList != null )
{
foreach( int propType in propTypes )
{
if ( existingList.IndexOf( propType ) < 0 )
{
existingList.Add( propType );
}
}
}
else
{
_linksPaneGroups.Add( groupId, new IntArrayList( propTypes ), anchor );
}
}
public ColorScheme ColorScheme
{
get { return _colorScheme; }
set
{
if ( _colorScheme != value )
{
_colorScheme = value;
OnColorSchemeChanged();
Invalidate();
}
}
}
protected virtual void OnColorSchemeChanged()
{
}
/**
* Sets the list of resources for which the links are displayed.
*/
protected void SetResourceList( IResourceList resList, ILinksPaneFilter filter )
{
_filter = filter;
if ( _store == null )
{
_store = Core.ResourceStore;
_store.ResourceSaved += OnResourceSaved;
_customProperties = Core.ResourceStore.FindResourcesLive( "PropType", "Custom", 1 );
_customProperties.ResourceAdded += HandleCustomPropertyListChanged;
_customProperties.ResourceDeleting += HandleCustomPropertyListChanged;
}
_resourceList = resList;
}
private void OnResourceSaved( object sender, ResourcePropEventArgs e )
{
IResourceList resList = _resourceList;
if ( resList != null && resList.Count == 1 && e.Resource.Id == resList.ResourceIds [0] )
{
int[] changedPropIDs = e.ChangeSet.GetChangedProperties();
for( int i=0; i= 0 )
{
lastSection = BuildLinksForType( lastSection, propId, res );
linkTypes.RemoveAt( idx );
}
}
if ( groupStartSection != lastSection )
{
lastSection.Separator = true;
}
}
groupStartSection = lastSection;
foreach( int linkType in linkTypes )
{
if ( _store.PropTypes [linkType].HasFlag( PropTypeFlags.Internal ) )
continue;
lastSection = BuildLinksForType( lastSection, linkType, res );
}
if ( lastSection != groupStartSection )
{
lastSection.Separator = true;
}
if ( lastSection != null )
{
while( lastSection.PrevSection != null )
{
lastSection = lastSection.PrevSection;
}
}
return lastSection;
}
private LinkSection BuildLinksForType( LinkSection lastSection, int linkType, IResource res )
{
if ( _store.PropTypes [linkType].HasFlag( PropTypeFlags.DirectedLink ) )
{
lastSection = BuildLinkSection( lastSection, res, linkType, 1 );
lastSection = BuildLinkSection( lastSection, res, linkType, -1 );
}
else
{
lastSection = BuildLinkSection( lastSection, res, linkType, 0 );
}
return lastSection;
}
/**
* Shows the link type labels for the specified resource.
*/
private LinkSection BuildLinkSection( LinkSection lastSection, IResource res, int linkType, int direction )
{
IResourceList resList;
switch( direction )
{
case 0: resList = res.GetLinksOfType( null, linkType ); break;
case 1: resList = res.GetLinksFrom( null, linkType ); break;
case -1: resList = res.GetLinksTo( null, linkType ); break;
default: throw new System.ArgumentException( "Invalid direction parameter" );
}
if ( resList.Count == 0 )
return lastSection;
int propId = (direction == -1 ) ? -linkType : linkType;
string linkTypeName = Core.ResourceStore.PropTypes.GetPropDisplayName( propId );
if ( _filter != null )
{
if ( !_filter.AcceptLinkType( res, propId, ref linkTypeName ) )
{
return lastSection;
}
}
foreach( IResource linkRes in resList.ValidResources )
{
string linkToolTip = null;
if ( !CheckLinkVisible( res, propId, linkRes, ref linkToolTip ) )
{
continue;
}
if ( lastSection == null || lastSection.Name != linkTypeName )
{
lastSection = new LinkSection( linkTypeName, lastSection );
}
lastSection.AddResource( linkRes, propId, linkToolTip );
}
return lastSection;
}
private bool CheckLinkVisible( IResource baseResource, int propId, IResource linkRes, ref string linkTooltip )
{
if ( linkRes.HasProp( Core.Props.IsDeleted ) )
return false;
if ( !Core.ResourceStore.ResourceTypes [linkRes.Type].OwnerPluginLoaded )
{
return false;
}
foreach( IPropType propType in Core.ResourceStore.PropTypes )
{
if ( propType.HasFlag( PropTypeFlags.SourceLink ) && !propType.OwnerPluginLoaded &&
linkRes.HasProp( propType.Id ) )
{
return false;
}
}
if ( _filter != null && !_filter.AcceptLink( baseResource, propId, linkRes, ref linkTooltip ) )
{
return false;
}
return true;
}
protected void ShowLinkContextMenu( ResourceLinkLabel linkLabel, ResourceLinkLabelEventArgs e )
{
ActionContext context = new ActionContext( ActionContextKind.ContextMenu, this,
e.Resource.ToResourceList() );
context.SetLinkTarget( linkLabel.LinkType, _resourceList [0] );
Core.ActionManager.ShowResourceContextMenu( context, linkLabel, e.Point.X, e.Point.Y );
}
protected static string GetCustomPropText( IResource res, int propID )
{
string propText;
PropDataType dataType = Core.ResourceStore.PropTypes [propID].DataType;
if ( dataType == PropDataType.Bool )
{
propText = res.HasProp( propID ) ? "Yes" : "";
}
else if ( dataType == PropDataType.Date )
{
propText = res.GetDateProp( propID ).ToShortDateString();
}
else
{
propText = res.GetPropText( propID );
}
return propText;
}
internal class LinkItem
{
private readonly IResource _resource;
private readonly int _propId;
private readonly string _toolTip;
public LinkItem( IResource resource, int propId, string toolTip )
{
_resource = resource;
_propId = propId;
_toolTip = toolTip;
}
public IResource Resource
{
get { return _resource; }
}
public int PropId
{
get { return _propId; }
}
public string ToolTip
{
get { return _toolTip; }
}
}
internal class LinkSection
{
private readonly string _name;
private readonly ArrayList _linkItems = new ArrayList() ;
private bool _separator = false; // whether a group separator is displayed after the group name
private LinkSection _nextSection;
private LinkSection _prevSection;
public LinkSection( string name, LinkSection prevSection )
{
_name = name;
if ( prevSection != null )
{
prevSection._nextSection = this;
_prevSection = prevSection;
}
}
public string Name
{
get { return _name; }
}
public bool Separator
{
get { return _separator; }
set { _separator = value; }
}
public LinkSection NextSection
{
get { return _nextSection; }
}
public LinkSection PrevSection
{
get { return _prevSection; }
}
public ArrayList LinkItems
{
get { return _linkItems; }
}
internal void AddResource( IResource res, int propId, string toolTip )
{
_linkItems.Add( new LinkItem( res, propId, toolTip ) );
}
}
}
}