?? flowchartentitycontainer.cpp
字號:
/* ==========================================================================
CFlowchartEntityContainer
Author : Johan Rosengren, Abstrakt Mekanik AB
Date : 2004-04-29
Purpose : CFlowchartEntityContainer is a CDiagramEntityContainer-
derived class, holding the data for a CFlowchartEditor.
In addition to CDiagramEntityContainer, this class keeps
and manages a list of links. This includes copy/paste
and undo-handling.
Description : The class uses a derived CDiagramClipboardHandler.
Usage : Use as a normal CDiagramEntityContainer class. The
editor class exposes functions for command enabling.
========================================================================*/
#include "stdafx.h"
#include "FlowchartEntityContainer.h"
#include <math.h>
CFlowchartEntityContainer::CFlowchartEntityContainer()
/* ============================================================
Function : CFlowchartEntityContainer::CFlowchartEntityContainer
Description : constructor
Return : void
Parameters : none
Usage :
============================================================*/
{
}
CFlowchartEntityContainer::~CFlowchartEntityContainer()
/* ============================================================
Function : CFlowchartEntityContainer::~CFlowchartEntityContainer
Description : destructor
Return : void
Parameters : none
Usage :
============================================================*/
{
ClearLinks();
ClearUndo();
}
BOOL CFlowchartEntityContainer::CreateLink( CFlowchartEntity* from, CFlowchartEntity* to, const CString& title )
/* ============================================================
Function : CFlowchartEntityContainer::CreateLink
Description : Creates a link between from and to and
puts it into the link-array.
Return : BOOL - TRUE if ok.
Parameters : CFlowchartEntity* from - From-object.
CFlowchartEntity* to - To-object.
const CString& title - Title of link.
Usage : Call to create a link between from and to.
============================================================*/
{
BOOL result = FALSE;
int fromtype = 0;
int totype = 0;
CPoint source;
CPoint target;
if( FindClosestLink( from, to, fromtype, totype ) )
{
CFlowchartLink* link = new CFlowchartLink;
link->from = from->GetName();
link->to = to->GetName();
link->fromtype = fromtype;
link->totype = totype;
link->title = title;
m_links.Add( link );
result = TRUE;
}
return result;
}
BOOL CFlowchartEntityContainer::HasLinks( CFlowchartEntity* obj1, CFlowchartEntity* obj2 )
/* ============================================================
Function : CFlowchartEntityContainer::HasLinks
Description : Returns TRUE if obj1 and obj2 are linked
to each other or another object using the
link-point closest between them..
Return : BOOL - TRUE if obj1 and
obj2 has a link
Parameters : CFlowchartEntity* obj1 - First object to
test
CFlowchartEntity* obj2 - Second object
to test
Usage : Call to see if it is possible to link two
objects, or they already have one or both
link-points attached.
============================================================*/
{
BOOL result = FALSE;
CString n1 = obj1->GetName();
CString n2 = obj2->GetName();
int fromtype = 0;
int totype = 0;
if( FindClosestLink( obj1, obj2, fromtype, totype ) )
{
if( fromtype & LINK_ALL && totype & LINK_ALL )
{
// Box-objects
int max = m_links.GetSize();
for( int t = 0; t < max ; t++ )
{
CFlowchartLink* link = static_cast< CFlowchartLink* >( m_links.GetAt( t ) );
if( ( link->fromtype == fromtype && link->from == n1 ) || ( link->totype == totype && link->to == n2 ) )
result = TRUE;
}
}
else
{
// Line-objects
int max = m_links.GetSize();
for( int t = 0; t < max ; t++ )
{
CFlowchartLink* link = static_cast< CFlowchartLink* >( m_links.GetAt( t ) );
if( ( ( link->fromtype == fromtype && link->from == n1 ) && ( link->totype == totype && link->to == n2 ) ) ||
( ( link->fromtype == totype && link->to == n1 ) && ( link->totype == fromtype && link->from == n2 ) ) )
result = TRUE;
}
}
}
return result;
}
BOOL CFlowchartEntityContainer::FindClosestLink( CFlowchartEntity* obj1, CFlowchartEntity* obj2, int& fromtype, int& totype )
/* ============================================================
Function : CFlowchartEntityContainer::FindClosestLink
Description : Finds the closet link types between two
objects.
Return : BOOL - TRUE if the
objects can be
linked.
Parameters : CFlowchartEntity* obj1 - First object
to link
CFlowchartEntity* obj2 - Second object
to link
int& fromtype - Type of link for the first object
int& totype - Type of link for the second object.
Usage : The link types can be:
LINK_TOP Top of the object.
LINK_BOTTOM Bottom of the object.
LINK_LEFT To the left of the object.
LINK_RIGHT To the right of the object.
LINK_START To the start of the line (normally
the top-left corner of
the non-normalized bounding
rect).
LINK_END To the end of the line
(normally the bottom-right
corner of the non-normalized
bounding rect).
============================================================*/
{
BOOL result = TRUE;
CPoint start;
CPoint end;
double diff2 = 0;
double diff1 = 0x7FFFFFFF;
// We go through all the allowed links for obj1, and get the
// distance between the inspected link point and the allowed
// link points of obj2. Shortest distance wins!
if( ( obj1->AllowLink() & LINK_LEFT ) )
{
start = obj1->GetLinkPosition( LINK_LEFT );
if( ( obj2->AllowLink() & LINK_START ) && ( obj2->AllowLink() & LINK_END ))
{
end = obj2->GetLinkPosition( LINK_START );
diff2 = Dist( start, end );
if( diff2 <= diff1 && start.x > end.x )
{
fromtype = LINK_LEFT;
totype = LINK_START;
diff1 = diff2;
}
end = obj2->GetLinkPosition( LINK_END );
diff2 = Dist( start, end );
if( diff2 <= diff1 && start.x > end.x )
{
fromtype = LINK_LEFT;
totype = LINK_END;
diff1 = diff2;
}
}
else
{
end = obj2->GetLinkPosition( LINK_RIGHT );
diff2 = Dist( start, end );
if( diff2 <= diff1 && start.x > end.x )
{
fromtype = LINK_LEFT;
totype = LINK_RIGHT;
diff1 = diff2;
}
}
}
if( ( obj1->AllowLink() & LINK_RIGHT ) )
{
start = obj1->GetLinkPosition( LINK_RIGHT );
if( ( obj2->AllowLink() & LINK_START ) && ( obj2->AllowLink() & LINK_END ))
{
end = obj2->GetLinkPosition( LINK_START );
diff2 = Dist( start, end );
if( diff2 <= diff1 && end.x > start.x )
{
fromtype = LINK_RIGHT;
totype = LINK_START;
diff1 = diff2;
}
end = obj2->GetLinkPosition( LINK_END );
diff2 = Dist( start, end );
if( diff2 <= diff1 && end.x > start.x )
{
fromtype = LINK_RIGHT;
totype = LINK_END;
diff1 = diff2;
}
}
else
{
end = obj2->GetLinkPosition( LINK_LEFT );
diff2 = Dist( start, end );
if( diff2 <= diff1 && end.x > start.x )
{
fromtype = LINK_RIGHT;
totype = LINK_LEFT;
diff1 = diff2;
}
}
}
if( ( obj1->AllowLink() & LINK_TOP ) )
{
start = obj1->GetLinkPosition( LINK_TOP );
if( ( obj2->AllowLink() & LINK_START ) && ( obj2->AllowLink() & LINK_END ))
{
end = obj2->GetLinkPosition( LINK_START );
diff2 = Dist( start, end );
if( diff2 < diff1 && start.y > end.y )
{
fromtype = LINK_TOP;
totype = LINK_START;
diff1 = diff2;
}
end = obj2->GetLinkPosition( LINK_END );
diff2 = Dist( start, end );
if( diff2 < diff1 && start.y > end.y )
{
fromtype = LINK_TOP;
totype = LINK_END;
diff1 = diff2;
}
}
else
{
end = obj2->GetLinkPosition( LINK_BOTTOM );
diff2 = Dist( start, end );
if( diff2 < diff1 && start.y > end.y )
{
fromtype = LINK_TOP;
totype = LINK_BOTTOM;
diff1 = diff2;
}
}
}
if( ( obj1->AllowLink() & LINK_BOTTOM ) )
{
start = obj1->GetLinkPosition( LINK_BOTTOM );
if( ( obj2->AllowLink() & LINK_START ) && ( obj2->AllowLink() & LINK_END ))
{
end = obj2->GetLinkPosition( LINK_START );
diff2 = Dist( start, end );
if( diff2 <= diff1 && end.y > start.y )
{
fromtype = LINK_BOTTOM;
totype = LINK_START;
diff1 = diff2;
}
end = obj2->GetLinkPosition( LINK_END );
diff2 = Dist( start, end );
if( diff2 <= diff1 && end.y > start.y )
{
fromtype = LINK_BOTTOM;
totype = LINK_END;
diff1 = diff2;
}
}
else
{
end = obj2->GetLinkPosition( LINK_TOP );
diff2 = Dist( start, end );
if( diff2 <= diff1 && end.y > start.y )
{
fromtype = LINK_BOTTOM;
totype = LINK_TOP;
diff1 = diff2;
}
}
}
int sum2 = 0;
if( ( obj1->AllowLink() & LINK_START ) )
{
start = obj1->GetLinkPosition( LINK_START );
if( obj2->AllowLink() & LINK_START )
{
end = obj2->GetLinkPosition( LINK_START );
diff2 = Dist( start, end );
if( diff2 < diff1 )
{
fromtype = LINK_START;
totype = LINK_START;
diff1 = diff2;
}
}
if( obj2->AllowLink() & LINK_END )
{
end = obj2->GetLinkPosition( LINK_END );
diff2 = Dist( start, end );
if( diff2 < diff1 )
{
fromtype = LINK_START;
totype = LINK_END;
diff1 = diff2;
}
}
if( obj2->AllowLink() & LINK_LEFT )
{
end = obj2->GetLinkPosition( LINK_LEFT );
diff2 = Dist( start, end );
if( diff2 < diff1 && start.x <= end.x)
{
fromtype = LINK_START;
totype = LINK_LEFT;
diff1 = diff2;
}
}
if( obj2->AllowLink() & LINK_RIGHT )
{
end = obj2->GetLinkPosition( LINK_RIGHT );
diff2 = Dist( start, end );
if( diff2 < diff1 && start.x >= end.x )
{
fromtype = LINK_START;
totype = LINK_RIGHT;
diff1 = diff2;
}
}
if( obj2->AllowLink() & LINK_TOP )
{
end = obj2->GetLinkPosition( LINK_TOP );
diff2 = Dist( start, end );
if( diff2 < diff1 && start.y <= end.y )
{
fromtype = LINK_START;
totype = LINK_TOP;
diff1 = diff2;
}
}
if( obj2->AllowLink() & LINK_BOTTOM )
{
end = obj2->GetLinkPosition( LINK_BOTTOM );
diff2 = Dist( start, end );
if( diff2 < diff1 && start.y >= end.y )
{
fromtype = LINK_START;
totype = LINK_BOTTOM;
diff1 = diff2;
}
}
}
if( ( obj1->AllowLink() & LINK_END ) )
{
start = obj1->GetLinkPosition( LINK_END );
if( obj2->AllowLink() & LINK_START )
{
end = obj2->GetLinkPosition( LINK_START );
diff2 = Dist( start, end );
if( diff2 < diff1 )
{
fromtype = LINK_END;
totype = LINK_START;
diff1 = diff2;
}
}
if( obj2->AllowLink() & LINK_END )
{
end = obj2->GetLinkPosition( LINK_END );
diff2 = Dist( start, end );
if( diff2 < diff1 )
{
fromtype = LINK_END;
totype = LINK_END;
diff1 = diff2;
}
}
if( obj2->AllowLink() & LINK_LEFT )
{
end = obj2->GetLinkPosition( LINK_LEFT );
diff2 = Dist( start, end );
if( diff2 < diff1 && start.x <= end.x )
{
fromtype = LINK_END;
totype = LINK_LEFT;
diff1 = diff2;
}
}
if( obj2->AllowLink() & LINK_RIGHT )
{
end = obj2->GetLinkPosition( LINK_RIGHT );
diff2 = Dist( start, end );
if( diff2 < diff1 && start.x >= end.x )
{
fromtype = LINK_END;
totype = LINK_RIGHT;
diff1 = diff2;
}
}
if( obj2->AllowLink() & LINK_TOP )
{
end = obj2->GetLinkPosition( LINK_TOP );
diff2 = Dist( start, end );
if( diff2 < diff1 && start.y <= end.y )
{
fromtype = LINK_END;
totype = LINK_TOP;
diff1 = diff2;
}
}
if( obj2->AllowLink() & LINK_BOTTOM )
{
end = obj2->GetLinkPosition( LINK_BOTTOM );
diff2 = Dist( start, end );
if( diff2 < diff1 && start.y >= end.y )
{
fromtype = LINK_END;
totype = LINK_BOTTOM;
diff1 = diff2;
}
}
}
// To be really, really sure
if( !( obj1->AllowLink() & fromtype ) )
{
result = FALSE;
fromtype = 0;
}
if( !( obj2->AllowLink() & totype ) )
{
result = FALSE;
totype = 0;
}
return result;
}
CFlowchartLink* CFlowchartEntityContainer::GetLinkAt( int index )
/* ============================================================
Function : CFlowchartEntityContainer::GetLinkAt
Description : Returns the CFlowchartLink object at
position index in the internal data array.
Return : CFlowchartLink* - Object at index. NULL
if not a CFlowchartLink
or out of bounds.
Parameters : int index - The index in the data
array.
Usage : Call to get the object at index, or to check
if the object is a CFlowchartLink-object.
============================================================*/
{
CFlowchartLink* result = NULL;
if( index < GetLinks() )
result = static_cast< CFlowchartLink* >( m_links[ index ] );
return result;
}
int CFlowchartEntityContainer::GetLinks()
/* ============================================================
Function : CFlowchartEntityContainer::GetLinks
Description : Returns the number of links in the link
array.
Return : int - The current number of links.
Parameters : none
Usage : Call to get the current number of links.
============================================================*/
{
return m_links.GetSize();
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -