mirror of
https://github.com/levinsv/pgadmin3.git
synced 2026-05-15 14:15:49 -06:00
300 lines
9.3 KiB
C++
300 lines
9.3 KiB
C++
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// pgAdmin III - PostgreSQL Tools
|
|
//
|
|
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
|
// This software is released under the PostgreSQL Licence
|
|
//
|
|
// hdDrawingEditor.cpp - Main class that manages all other classes
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "pgAdmin3.h"
|
|
|
|
// wxWindows headers
|
|
#include <wx/wx.h>
|
|
#include <wx/dcbuffer.h>
|
|
|
|
// App headers
|
|
#include "dd/ddmodel/ddDrawingEditor.h"
|
|
#include "dd/dditems/utilities/ddTableNameDialog.h"
|
|
#include "dd/ddmodel/ddDatabaseDesign.h"
|
|
#include "dd/ddmodel/ddDrawingView.h"
|
|
#include "hotdraw/utilities/hdRemoveDeleteDialog.h"
|
|
#include "dd/dditems/figures/ddRelationshipFigure.h"
|
|
#include "frm/frmDatabaseDesigner.h"
|
|
|
|
|
|
ddDrawingEditor::ddDrawingEditor(wxWindow *owner, wxWindow *frmOwner, ddDatabaseDesign *design)
|
|
: hdDrawingEditor(owner, true)
|
|
{
|
|
databaseDesign = design;
|
|
frm = (frmDatabaseDesigner *) frmOwner;
|
|
}
|
|
|
|
hdDrawing *ddDrawingEditor::createDiagram(wxWindow *owner, bool fromXml)
|
|
{
|
|
|
|
hdDrawing *_tmpModel = new hdDrawing(this);
|
|
|
|
ddDrawingView *_viewTmp = new ddDrawingView(_diagrams->count(), owner, this, wxSize(1200, 1200), _tmpModel);
|
|
|
|
// Set Scroll Bar & split
|
|
_viewTmp->SetScrollbars( 10, 10, 127, 80 );
|
|
_viewTmp->EnableScrolling(true, true);
|
|
_viewTmp->AdjustScrollbars();
|
|
|
|
_tmpModel->registerView(_viewTmp);
|
|
|
|
_viewTmp->SetDropTarget(new ddDropTarget(databaseDesign, _tmpModel));
|
|
|
|
if(!fromXml)
|
|
{
|
|
//Add a new position inside each figure to allow use of this new diagram existing figures.
|
|
int i;
|
|
hdIFigure *tmp;
|
|
for(i = 0; i < _model->count(); i++)
|
|
{
|
|
tmp = (hdIFigure *) _model->getItemAt(i);
|
|
tmp->AddPosForNewDiagram();
|
|
}
|
|
}
|
|
//Add Diagram
|
|
_diagrams->addItem((hdObject *) _tmpModel);
|
|
modelChanged = true;
|
|
return _tmpModel;
|
|
}
|
|
|
|
|
|
void ddDrawingEditor::remOrDelSelFigures(int diagramIndex)
|
|
{
|
|
hdIFigure *tmp;
|
|
ddTableFigure *table;
|
|
ddRelationshipFigure *relation;
|
|
hdIteratorBase *iterator;
|
|
hdCollection *tmpSelection;
|
|
int answer;
|
|
int numbTables = 0;
|
|
int numbRelationships = 0;
|
|
|
|
if (getExistingDiagram(diagramIndex)->countSelectedFigures() == 1)
|
|
{
|
|
tmp = (hdIFigure *) getExistingDiagram(diagramIndex)->selectedFigures()->getItemAt(0);
|
|
if(tmp->getKindId() == DDTABLEFIGURE)
|
|
{
|
|
numbTables = 1;
|
|
table = (ddTableFigure *)tmp;
|
|
hdRemoveDeleteDialog dialog(_("Are you sure you wish to delete table ") + table->getTableName() + wxT("?"), _("Delete table?"), getExistingView(diagramIndex));
|
|
answer = dialog.ShowModal();
|
|
}
|
|
if(tmp->getKindId() == DDRELATIONSHIPFIGURE)
|
|
{
|
|
numbRelationships = 1;
|
|
relation = (ddRelationshipFigure *)tmp;
|
|
//Relationship can be delete only NOT REMOVED
|
|
hdRemoveDeleteDialog dialog2(_("Are you sure you wish to delete relationship ") + relation->getConstraintName() + wxT("?"), _("Delete relationship?"), getExistingView(diagramIndex), false);
|
|
answer = dialog2.ShowModal();
|
|
}
|
|
}
|
|
else if (getExistingDiagram(diagramIndex)->countSelectedFigures() > 1)
|
|
{
|
|
numbTables = 0;
|
|
iterator = getExistingDiagram(diagramIndex)->selectionFigures();
|
|
while(iterator->HasNext())
|
|
{
|
|
tmp = (hdIFigure *)iterator->Next();
|
|
if(tmp->getKindId() == DDTABLEFIGURE)
|
|
numbTables++;
|
|
}
|
|
delete iterator;
|
|
|
|
|
|
//Improve messages to display about relationships and tables and only relationship
|
|
hdRemoveDeleteDialog dialog3(
|
|
wxString::Format(_("Are you sure you wish to delete %d tables, removing from model related relationships?"), numbTables),
|
|
_("Delete tables?"), getExistingView(diagramIndex));
|
|
answer = dialog3.ShowModal();
|
|
}
|
|
|
|
if (answer == DD_DELETE || answer == DD_REMOVE)
|
|
{
|
|
modelChanged = true;
|
|
tmpSelection = new hdCollection(new hdArrayCollection());
|
|
|
|
//Preprocess relationships counting and storing at temporary collection
|
|
numbRelationships = 0;
|
|
iterator = getExistingDiagram(diagramIndex)->selectionFigures();
|
|
while(iterator->HasNext())
|
|
{
|
|
tmp = (hdIFigure *)iterator->Next();
|
|
if(tmp->getKindId() == DDRELATIONSHIPFIGURE)
|
|
{
|
|
numbRelationships++;
|
|
tmpSelection->addItem(tmp);
|
|
}
|
|
}
|
|
delete iterator;
|
|
|
|
while(numbTables > 0)
|
|
{
|
|
tmp = (hdIFigure *) getExistingDiagram(diagramIndex)->selectedFigures()->getItemAt(0);
|
|
if(tmp->getKindId() == DDTABLEFIGURE)
|
|
{
|
|
table = (ddTableFigure *)tmp;
|
|
if(table && answer == DD_REMOVE)
|
|
{
|
|
getExistingDiagram(diagramIndex)->removeFromSelection(table);
|
|
getExistingDiagram(diagramIndex)->remove(table);
|
|
}
|
|
//if table is going to be delete all others diagrams should be alerted about it
|
|
if(table && answer == DD_DELETE)
|
|
{
|
|
removeFromAllSelections(table);
|
|
table->processDeleteAlert(getExistingDiagram(diagramIndex));
|
|
deleteModelFigure(table);
|
|
databaseDesign->refreshBrowser();
|
|
}
|
|
numbTables--;
|
|
}
|
|
else if(tmp->getKindId() == DDRELATIONSHIPFIGURE)
|
|
{
|
|
getExistingDiagram(diagramIndex)->removeFromSelection(tmp); //isn't a tables is probably a relationship
|
|
}
|
|
else
|
|
{
|
|
wxMessageBox(_("Invalid figure kind found"), _("Error while deleting tables"), wxCENTRE | wxICON_ERROR, getExistingView(diagramIndex));
|
|
}
|
|
}
|
|
|
|
if( numbRelationships > 0 )
|
|
{
|
|
|
|
//check again: Are there relationships selected that wasn't delete (only selected relationship not source/destination table)
|
|
numbRelationships = 0;
|
|
iterator = tmpSelection->createIterator(); //getExistingDiagram(diagramIndex)->selectionFigures();
|
|
while(iterator->HasNext())
|
|
{
|
|
tmp = (hdIFigure *)iterator->Next();
|
|
//only way a relationship don't exists at diagram is
|
|
//it had been deleted before by deleting source/destination table that owns it
|
|
if(getExistingDiagram(diagramIndex)->includes(tmp))
|
|
{
|
|
if(tmp->getKindId() == DDRELATIONSHIPFIGURE)
|
|
{
|
|
numbRelationships++;
|
|
}
|
|
else
|
|
{
|
|
wxMessageBox(_("Invalid figure kind found"), _("Error while deleting table"), wxCENTRE | wxICON_ERROR, getExistingView(diagramIndex));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
tmpSelection->removeItem(tmp);
|
|
}
|
|
}
|
|
delete iterator;
|
|
|
|
while(numbRelationships > 0 && tmpSelection->count() == numbRelationships)
|
|
{
|
|
tmp = (hdIFigure *) tmpSelection->getItemAt(0);
|
|
if(tmp->getKindId() == DDRELATIONSHIPFIGURE)
|
|
{
|
|
relation = (ddRelationshipFigure *)tmp;
|
|
if(relation && answer == DD_REMOVE)
|
|
{
|
|
getExistingDiagram(diagramIndex)->removeFromSelection(relation);
|
|
getExistingDiagram(diagramIndex)->remove(relation);
|
|
}
|
|
//if relation is going to be delete all others diagrams should be alerted about it
|
|
if(relation && answer == DD_DELETE)
|
|
{
|
|
removeFromAllSelections(relation);
|
|
relation->removeForeignKeys();
|
|
relation->disconnectEnd();
|
|
relation->disconnectStart();
|
|
deleteModelFigure(relation);
|
|
databaseDesign->refreshBrowser();
|
|
}
|
|
numbRelationships--;
|
|
}
|
|
else
|
|
{
|
|
wxMessageBox(_("Invalid figure kind found"), _("Error while deleting realtionships"), wxCENTRE | wxICON_ERROR, getExistingView(diagramIndex));
|
|
// getExistingDiagram(diagramIndex)->removeFromSelection(tmp); //isn't neither a table or relationship
|
|
}
|
|
}
|
|
}
|
|
getExistingDiagram(diagramIndex)->clearSelection(); //after delete all items all relationships remains at selection and should be removed
|
|
tmpSelection->removeAll();
|
|
delete tmpSelection;
|
|
}
|
|
}
|
|
|
|
void ddDrawingEditor::checkRelationshipsConsistency(int diagramIndex)
|
|
{
|
|
hdIFigure *tmp;
|
|
ddRelationshipFigure *relation;
|
|
hdDrawing *diagram = getExistingDiagram(diagramIndex);
|
|
|
|
// First Step Removel all orphan [relations without source or destination] relationships
|
|
// from DIAGRAM but NOT from MODEL
|
|
hdIteratorBase *iterator = diagram->figuresEnumerator();
|
|
while(iterator->HasNext())
|
|
{
|
|
tmp = (hdIFigure *)iterator->Next();
|
|
if(tmp->getKindId() == DDRELATIONSHIPFIGURE)
|
|
{
|
|
relation = (ddRelationshipFigure *)tmp;
|
|
//test if all tables of a relationship are included if this is not the case then remove relationship from this diagram
|
|
bool sourceExists = diagram->getFiguresCollection()->existsObject(relation->getStartTable());
|
|
bool destinationExists = diagram->getFiguresCollection()->existsObject(relation->getEndTable());
|
|
if(!sourceExists || !destinationExists)
|
|
{
|
|
diagram->remove(relation);
|
|
}
|
|
|
|
}
|
|
}
|
|
delete iterator;
|
|
|
|
// Now add all existing relationships in MODEL to DIAGRAM if both source and destination
|
|
// tables exists at DIAGRAM
|
|
iterator = _model->createIterator();
|
|
while(iterator->HasNext())
|
|
{
|
|
tmp = (hdIFigure *)iterator->Next();
|
|
if(tmp->getKindId() == DDRELATIONSHIPFIGURE)
|
|
{
|
|
relation = (ddRelationshipFigure *)tmp;
|
|
|
|
//test if all tables of a relationship are included if this is the case then include relationship at this diagram
|
|
bool sourceExists = diagram->getFiguresCollection()->existsObject(relation->getStartTable());
|
|
bool destinationExists = diagram->getFiguresCollection()->existsObject(relation->getEndTable());
|
|
bool relationExists = diagram->getFiguresCollection()->existsObject(relation);
|
|
if(sourceExists && destinationExists && !relationExists)
|
|
{
|
|
diagram->add(relation);
|
|
relation->updateConnection(diagramIndex);
|
|
}
|
|
}
|
|
}
|
|
delete iterator;
|
|
}
|
|
|
|
void ddDrawingEditor::checkAllDigramsRelConsistency()
|
|
{
|
|
int i, size = modelCount();
|
|
|
|
for(i = 0; i < size ; i++)
|
|
{
|
|
checkRelationshipsConsistency(i);
|
|
}
|
|
}
|
|
|
|
void ddDrawingEditor::notifyChanged()
|
|
{
|
|
if(frm)
|
|
frm->setModelChanged(true);
|
|
modelChanged = true;
|
|
}
|