umleditor.cpp
来自「uml编辑器很牛」· C++ 代码 · 共 1,677 行 · 第 1/4 页
CPP
1,677 行
/* ==========================================================================
Class : CUMLEditor
Author : Johan Rosengren, Abstrakt Mekanik AB
Date : 2004-06-28
Purpose : "CUMLEditor" is the main editor class of the UML-editor,
derived from "CDiagramEditor".
Description : "CUMLEditor" manages the drawing and contains the
interface to the application (together with
"CUMLEntityContainer"). In addition to the features of
"CDiagramEditor", it manages line-drawing with links
(the "CUMLLineSegment" class). It also handles the
display and navigation of packages.
Usage : Use as a "CDiagramEditor".
========================================================================
Changes : 4/8 2004 Added "Export only header files" support
(ikolev)
4/8 2004 Setting package to current when pasting
items (ikolev)
4/8 2004 Saving the destination between exports
(ikolev)
4/8 2004 Added initialization list from class
attributes to ctors.
5/8 2004 Corrected jog-drawing when zoomed.
========================================================================*/
#include "stdafx.h"
#include "UMLEditor.h"
#include "UMLEntityContainer.h"
#include "UMLMenu.h"
#include "UMLLineSegment.h"
#include "UMLEntityPackage.h"
#include "TextFile/TextFile.h"
#include "DiskObject/DiskObject.h"
#include <math.h>
#include <shlobj.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#pragma warning( disable : 4706 )
int CALLBACK BFFCallbackProc( HWND hwnd, UINT uMsg, LPARAM /*lParam*/, LPARAM lpData )
{
if( uMsg == BFFM_INITIALIZED )
::SendMessage( hwnd, BFFM_SETSELECTION, TRUE, lpData );
return 0;
}
/////////////////////////////////////////////////////////////////////////////
// CUMLEditor
CUMLEditor::CUMLEditor()
/* ============================================================
Function : CUMLEditor::CUMLEditor
Description : Constructor
Access : Public
Return : void
Parameters : none
Usage :
============================================================*/
{
SetBackgroundColor( RGB( 250, 250, 230 ) );
SetSnapToGrid( TRUE );
ShowGrid( FALSE );
SetRestraints( RESTRAINT_MARGIN );
SetMarginColor( RGB( 128, 128, 128 ) );
SetPopupMenu( new CUMLMenu );
m_drawingLine = FALSE;
m_curDrawLine = ::LoadCursor( AfxGetResourceHandle(), MAKEINTRESOURCE( IDC_UML_CURSOR_DRAW ) );
m_curAttach = ::LoadCursor( AfxGetResourceHandle(), MAKEINTRESOURCE( IDC_UML_CURSOR_ATTACH ) );
m_curUp = ::LoadCursor( AfxGetResourceHandle(), MAKEINTRESOURCE( IDC_UML_CURSOR_UP ) );
m_currentCursor = NULL;
}
CUMLEditor::~CUMLEditor()
/* ============================================================
Function : CUMLEditor::~CUMLEditor
Description : Destructor
Access : Public
Return : void
Parameters : none
Usage :
============================================================*/
{
delete m_data;
}
/////////////////////////////////////////////////////////////////////////////
// CUMLEditor overrides
BOOL CUMLEditor::Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, CDiagramEntityContainer* data )
/* ============================================================
Function : CUMLEditor::Create
Description : Creates the editor.
Access : Public
Return : BOOL - "TRUE" if created ok.
Parameters : DWORD dwStyle - Style of editor
const RECT& rect - Position of editor
CWnd* pParentWnd - Parent of editor
CDiagramEntityContainer* data - Data container
Usage : Call to create an editor.
============================================================*/
{
m_data = NULL;
if( data == NULL )
{
m_data = new CUMLEntityContainer;
data = m_data;
}
return CDiagramEditor::Create( dwStyle, rect, pParentWnd, data );
}
void CUMLEditor::DrawObjects( CDC* dc, double zoom ) const
/* ============================================================
Function : CUMLEditor::DrawObjects
Description : Draws the objects in the editor
Access : Protected
Return : void
Parameters : CDC* dc - "CDC" to draw to
double zoom - Zoom factor. Might not be
the same as the editor zoom
(for print previews, for
example)
Usage : Call to draw the objects of the editor.
Also draws package information and jogs.
============================================================*/
{
CString package = GetPackage();
if( package.GetLength() )
{
int place = round( 4 * zoom );
int size = round( 32 * zoom );
if( !dc->IsPrinting() )
{
HICON icon = ( HICON ) ::LoadImage( AfxGetResourceHandle(), MAKEINTRESOURCE( IDI_UML_ICON_UP ), IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR );
if( icon )
::DrawIconEx( dc->m_hDC, place, place, icon, size, size, 0, NULL, DI_NORMAL );
}
CString path;
CString level( package );
while( level.GetLength() )
{
CUMLEntity* obj = GetAllNamedObject( level );
if( obj )
{
path = obj->GetTitle() + _T( ":" ) + path;
level = obj->GetPackage();
}
else
level = _T( "" );
}
if( path.GetLength() )
path = path.Left( path.GetLength() - 1 );
CFont font;
font.CreateFont( -round( 12 * zoom ), 0, 0, 0, FW_NORMAL, 0, 0, 0, 0, 0, 0, 0, 0, _T( "Arial" ) );
dc->SelectObject( &font );
dc->TextOut( 7 * place, place, path );
dc->SelectStockObject( ANSI_VAR_FONT );
}
int count = GetObjectCount();
for( int i = 0 ; i < count ; i++ )
{
CUMLEntity* obj = GetObjectAt( i );
if( obj && package == obj->GetPackage() )
obj->DrawObject( dc, zoom );
}
CPen gridPen;
gridPen.CreatePen( PS_SOLID, 0, GetGridColor() );
CPen bgPen;
bgPen.CreatePen( PS_SOLID, 0, GetBackgroundColor() );
double x = static_cast< double >( GetMarkerSize().cx ) * GetZoom();
double y = static_cast< double >( GetMarkerSize().cy ) * GetZoom();
for( i = 0 ; i < count ; i++ )
{
CUMLLineSegment* obj = dynamic_cast< CUMLLineSegment* >( GetObjectAt( i ) );
if( obj && package == obj->GetPackage() )
{
// Drawing tunnels
BOOL horz = obj->IsHorizontal();
for( int t = i + 1 ; t < count ; t++ )
{
CUMLLineSegment* line = dynamic_cast< CUMLLineSegment* >( GetObjectAt( t ) );
if( line )
{
dc->SelectStockObject( NULL_BRUSH );
if( horz && !line->IsHorizontal() )
{
if( min( obj->GetLeft(), obj->GetRight() ) < line->GetLeft() &&
max( obj->GetLeft(), obj->GetRight() ) > line->GetLeft() &&
min( line->GetTop(), line->GetBottom() ) < obj->GetTop() &&
max( line->GetTop(), line->GetBottom() ) > obj->GetTop() )
{
CRect rect( round( line->GetLeft() - x ),
round( obj->GetTop() - y ),
round( line->GetLeft() + x ),
round( obj->GetTop() + y ) );
rect.InflateRect( -1, -1 );
if( IsGridVisible() )
dc->SelectObject( &gridPen );
else
dc->SelectObject( &bgPen );
CRect seg( rect );
seg.top = round( (double)seg.top * GetZoom() );
seg.bottom = round( (double)seg.bottom * GetZoom() );
seg.left = round( (double)seg.left * GetZoom() );
seg.right = round( (double)seg.right * GetZoom() );
int left = round( line->GetLeft() * GetZoom() );
dc->MoveTo( left, seg.top );
dc->LineTo( left, seg.top + seg.Height() / 2 );
dc->MoveTo( left, seg.top + seg.Height() / 2 + 1 );
dc->LineTo( left, seg.bottom );
CRgn rgn;
CRect rgnrect( rect );
VirtualToScreen( rgnrect );
rgn.CreateRectRgn( rgnrect.left, rgnrect.top, rgnrect.left + rgnrect.Width() / 2, rgnrect.bottom );
dc->SelectClipRgn( &rgn, RGN_AND );
dc->SelectStockObject( BLACK_PEN );
dc->Ellipse( rgnrect );
dc->SelectClipRgn( NULL );
}
}
else if( !horz && ( line->IsHorizontal() ) )
{
if( min( line->GetLeft(), line->GetRight() ) < obj->GetLeft() &&
max( line->GetLeft(), line->GetRight() ) > obj->GetLeft() &&
min( obj->GetTop(), obj->GetBottom() ) < line->GetTop() &&
max( obj->GetTop(), obj->GetBottom() ) > line->GetTop() )
{
CRect rect( round( obj->GetLeft() - x ),
round( line->GetTop() - y ),
round( obj->GetLeft() + x ),
round( line->GetTop() + y ) );
rect.InflateRect( -1, -1 );
if( IsGridVisible() )
dc->SelectObject( &gridPen );
else
dc->SelectObject( &bgPen );
CRect seg( rect );
seg.top = round( (double)seg.top * GetZoom() );
seg.bottom = round( (double)seg.bottom * GetZoom() );
seg.left = round( (double)seg.left * GetZoom() );
seg.right = round( (double)seg.right * GetZoom() );
int top = round( (double) line->GetTop() * GetZoom() );
dc->MoveTo( seg.left, top );
dc->LineTo( seg.left + seg.Width() / 2, top );
dc->MoveTo( seg.left + seg.Width() / 2 + 1, top );
dc->LineTo( seg.right, top );
CRgn rgn;
CRect rgnrect( rect );
VirtualToScreen( rgnrect );
rgn.CreateRectRgn( rgnrect.left, rgnrect.top, rgnrect.right, rgnrect.top + rgnrect.Height() / 2 );
dc->SelectClipRgn( &rgn, RGN_AND );
dc->SelectStockObject( BLACK_PEN );
dc->Ellipse( rgnrect );
dc->SelectClipRgn( NULL );
}
}
}
}
}
}
dc->SelectStockObject( WHITE_BRUSH );
dc->SelectStockObject( BLACK_PEN );
}
void CUMLEditor::StartDrawingObject( CDiagramEntity* obj )
/* ============================================================
Function : CUMLEditor::StartDrawingObject
Description : Starts drawing an object in the editor
Access : Public
Return : void
Parameters : CDiagramEntity* obj - Object to draw
Usage : Call to start drawing an object. The editor
takes ownership of the object.
============================================================*/
{
UnselectAll();
CUMLEntity* uml = static_cast< CUMLEntity* >( obj );
uml->SetPackage( GetPackage() );
uml->SetDisplayOptions( GetDisplayOptions() );
CDiagramEditor::StartDrawingObject( obj );
}
void CUMLEditor::OnObjectCommand( UINT nID )
/* ============================================================
Function : CUMLEditor::OnObjectCommand
Description : Command handler for the commands issued
from an object popup menu.
Access : Protected
Return : void
Parameters : UINT nID - ID of command
Usage : Called from MFC. We check and execute the
package Open command here.
============================================================*/
{
CUMLEntityPackage* package = dynamic_cast< CUMLEntityPackage* >( GetSelectedObject() );
if( package && nID == CMD_OPEN )
{
UnselectAll();
SetPackage( package->GetName() );
RedrawWindow();
}
else
CDiagramEditor::OnObjectCommand( nID );
}
void CUMLEditor::SelectAll()
/* ============================================================
Function : CUMLEditor::SelectAll
Description : Selects all objects in the current package.
Access : Public
Return : void
Parameters : none
Usage : Call to select all objects.
============================================================*/
{
int count = 0;
CUMLEntity* obj;
while( ( obj = GetObjectAt( count++ ) ) )
if( obj->GetPackage() == GetPackage() )
obj->Select( TRUE );
RedrawWindow();
}
/////////////////////////////////////////////////////////////////////////////
// CUMLEditor message handlers
//
void CUMLEditor::OnLButtonDown( UINT nFlags, CPoint point )
/* ============================================================
Function : CUMLEditor::OnLButtonDown
Description : Command handler for the "WM_LBUTTONDOWN"
message.
Access : Protected
Return : void
Parameters : UINT nFlags - Not used
CPoint point - Mouse position
Usage : Called from MFC. Extra processing is made
here regarding links and packages.
============================================================*/
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?