mirror of
https://github.com/levinsv/pgadmin3.git
synced 2026-05-15 14:15:49 -06:00
293 lines
6.4 KiB
C++
293 lines
6.4 KiB
C++
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// pgAdmin III - PostgreSQL Tools
|
|
//
|
|
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
|
// This software is released under the PostgreSQL Licence
|
|
//
|
|
// hdLineConnection.cpp - Base class for line connection figure
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "pgAdmin3.h"
|
|
|
|
// wxWindows headers
|
|
#include <wx/wx.h>
|
|
#include <wx/dcbuffer.h>
|
|
|
|
// App headers
|
|
#include "hotdraw/figures/hdLineConnection.h"
|
|
#include "hotdraw/handles/hdChangeConnectionStartHandle.h"
|
|
#include "hotdraw/handles/hdChangeConnectionEndHandle.h"
|
|
#include "hotdraw/handles/hdLineConnectionHandle.h"
|
|
#include "hotdraw/locators/hdPolyLineLocator.h"
|
|
#include "hotdraw/utilities/hdArrayCollection.h"
|
|
|
|
hdLineConnection::hdLineConnection():
|
|
hdPolyLineFigure()
|
|
{
|
|
startConnector = NULL;
|
|
endConnector = NULL;
|
|
changeConnStartHandle = NULL;
|
|
changeConnEndHandle = NULL;
|
|
}
|
|
|
|
hdLineConnection::hdLineConnection(int posIdx, hdIFigure *figure1, hdIFigure *figure2):
|
|
hdPolyLineFigure()
|
|
{
|
|
//Check figure available positions for diagrams, add at least needed to allow initialization of the class
|
|
int i, start;
|
|
start = basicDisplayBox.CountPositions();
|
|
for(i = start; i < (posIdx + 1); i++)
|
|
{
|
|
AddPosForNewDiagram();
|
|
}
|
|
|
|
startConnector = NULL;
|
|
endConnector = NULL;
|
|
|
|
if(figure1)
|
|
{
|
|
connectStart(figure1->connectorAt(posIdx, 0, 0));
|
|
}
|
|
|
|
if(figure2)
|
|
{
|
|
connectEnd(figure2->connectorAt(posIdx, 0, 0));
|
|
}
|
|
}
|
|
|
|
hdLineConnection::~hdLineConnection()
|
|
{
|
|
}
|
|
|
|
hdIConnector *hdLineConnection::getStartConnector()
|
|
{
|
|
return startConnector;
|
|
}
|
|
|
|
hdIConnector *hdLineConnection::getEndConnector()
|
|
{
|
|
return endConnector;
|
|
}
|
|
|
|
void hdLineConnection::setStartConnector(hdIConnector *connector)
|
|
{
|
|
startConnector = connector;
|
|
}
|
|
|
|
void hdLineConnection::setEndConnector(hdIConnector *connector)
|
|
{
|
|
endConnector = connector;
|
|
}
|
|
|
|
void hdLineConnection::connectStart(hdIConnector *start, hdDrawingView *view)
|
|
{
|
|
if(startConnector == start)
|
|
{
|
|
return;
|
|
}
|
|
|
|
disconnectStart();
|
|
startConnector = start;
|
|
connectFigure(startConnector);
|
|
}
|
|
|
|
void hdLineConnection::connectEnd(hdIConnector *end, hdDrawingView *view)
|
|
{
|
|
if(endConnector == end)
|
|
{
|
|
return;
|
|
}
|
|
|
|
disconnectEnd();
|
|
endConnector = end;
|
|
connectFigure(endConnector);
|
|
}
|
|
|
|
void hdLineConnection::disconnectStart(hdDrawingView *view)
|
|
{
|
|
disconnectFigure (startConnector);
|
|
startConnector = NULL;
|
|
}
|
|
|
|
void hdLineConnection::disconnectEnd(hdDrawingView *view)
|
|
{
|
|
disconnectFigure (endConnector);
|
|
endConnector = NULL;
|
|
}
|
|
|
|
bool hdLineConnection::canConnectStart(hdIFigure *figure)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
bool hdLineConnection::canConnectEnd(hdIFigure *figure)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
hdIFigure *hdLineConnection::getStartFigure()
|
|
{
|
|
if(startConnector)
|
|
{
|
|
return startConnector->getOwner();
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
hdIFigure *hdLineConnection::getEndFigure()
|
|
{
|
|
if(endConnector)
|
|
{
|
|
return endConnector->getOwner();
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void hdLineConnection::updateConnection(int posIdx)
|
|
{
|
|
if(startConnector)
|
|
{
|
|
setStartPoint(posIdx, startConnector->findStart(posIdx, this));
|
|
}
|
|
if(endConnector)
|
|
{
|
|
setEndPoint(posIdx, endConnector->findEnd(posIdx, this));
|
|
}
|
|
}
|
|
|
|
hdIHandle *hdLineConnection::getStartHandle()
|
|
{
|
|
if(!changeConnStartHandle)
|
|
{
|
|
changeConnStartHandle = new hdChangeConnectionStartHandle(this);
|
|
}
|
|
return changeConnStartHandle;
|
|
}
|
|
|
|
hdIHandle *hdLineConnection::getEndHandle()
|
|
{
|
|
if(!changeConnEndHandle)
|
|
{
|
|
changeConnEndHandle = new hdChangeConnectionEndHandle(this);
|
|
}
|
|
return changeConnEndHandle;
|
|
}
|
|
|
|
void hdLineConnection::basicMoveBy(int posIdx, int x, int y)
|
|
{
|
|
hdPolyLineFigure::basicMoveBy(posIdx, x, y);
|
|
updateConnection(posIdx);
|
|
}
|
|
|
|
bool hdLineConnection::canConnect()
|
|
{
|
|
return false;
|
|
}
|
|
|
|
void hdLineConnection::setPointAt (int posIdx, int index, int x, int y)
|
|
{
|
|
hdPolyLineFigure::setPointAt(posIdx, index, x, y);
|
|
updateConnection(posIdx);
|
|
}
|
|
|
|
hdCollection *hdLineConnection::handlesEnumerator()
|
|
{
|
|
return handles;
|
|
}
|
|
|
|
|
|
void hdLineConnection::connectFigure (hdIConnector *connector)
|
|
{
|
|
if(connector)
|
|
{
|
|
connector->getOwner()->addObserver(this);
|
|
}
|
|
}
|
|
|
|
void hdLineConnection::disconnectFigure (hdIConnector *connector)
|
|
{
|
|
if(connector)
|
|
{
|
|
connector->getOwner()->removeObserver(this);
|
|
}
|
|
}
|
|
|
|
void hdLineConnection::onFigureChanged(int posIdx, hdIFigure *figure)
|
|
{
|
|
updateConnection(posIdx);
|
|
}
|
|
|
|
void hdLineConnection::addPoint (int posIdx, int x, int y)
|
|
{
|
|
willChange();
|
|
points[posIdx]->addItem((hdObject *) new hdPoint(x, y) );
|
|
//Update handles
|
|
if(points[posIdx]->count() == 1)
|
|
{
|
|
//first point add start handle
|
|
if(handles->count() == 0)
|
|
handles->addItem(getStartHandle());
|
|
}
|
|
else if(points[posIdx]->count() == 2)
|
|
{
|
|
//second point add end handle
|
|
if(handles->count() == 1)
|
|
handles->addItem(getEndHandle());
|
|
}
|
|
else if(points[posIdx]->count() > 2)
|
|
{
|
|
//Locate maximum index if there is need for one new handle then added it
|
|
if( getMaximunIndex() > handles->count() )
|
|
{
|
|
//third and above point, add a polylinehandle before end handle
|
|
handles->insertAtIndex(new hdPolyLineHandle(this, new hdPolyLineLocator(0), 0), handles->count() - 1);
|
|
}
|
|
}
|
|
updateHandlesIndexes();
|
|
changed(posIdx);
|
|
}
|
|
|
|
void hdLineConnection::insertPointAt (int posIdx, int index, int x, int y)
|
|
{
|
|
willChange();
|
|
points[posIdx]->insertAtIndex((hdObject *) new hdPoint(x, y), index);
|
|
//Update handles
|
|
//Is there need of a new handle if is first point
|
|
if(index == 0 && handles->count() == 0 )
|
|
{
|
|
//add a new handle "normal" for a point in next position 0,1 in 1... in 0 startHandle is not moved
|
|
handles->insertAtIndex(new hdPolyLineHandle(this, new hdPolyLineLocator(index), index), 1);
|
|
}
|
|
else if(index == (points[posIdx]->count() - 1) && handles->count() < getMaximunIndex() ) //last point
|
|
{
|
|
//add a new handle "normal" for a point in before last item position
|
|
handles->insertAtIndex(new hdPolyLineHandle(this, new hdPolyLineLocator(index), index), (points[posIdx]->count() - 1));
|
|
}
|
|
else if(handles->count() < getMaximunIndex())
|
|
{
|
|
//add handle at index
|
|
handles->insertAtIndex(new hdPolyLineHandle(this, new hdPolyLineLocator(index), index), index);
|
|
}
|
|
updateHandlesIndexes();
|
|
changed(posIdx);
|
|
}
|
|
|
|
//Update points between start and end, because start and end don't have index (is other kind of handle)
|
|
void hdLineConnection::updateHandlesIndexes()
|
|
{
|
|
hdPolyLineHandle *h = NULL;
|
|
|
|
//Get maximun point position in a collection of points
|
|
int maxPosition = getMaximunIndex();
|
|
|
|
//Update Handles indexes
|
|
for(int i = 1; i < maxPosition - 1; i++)
|
|
{
|
|
h = (hdPolyLineHandle *) handles->getItemAt(i);
|
|
h->setIndex(i);
|
|
}
|
|
}
|