|
|
|
/* This file is part of the KDE project
|
|
|
|
Copyright (C) 2002 Lucijan Busch <lucijan@gmx.at>
|
|
|
|
Copyright (C) 2003 Jaroslaw Staniek <js@iidea.pl>
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU Library General Public
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
Library General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
|
|
along with this program; see the file COPYING. If not, write to
|
|
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
* Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <kdebug.h>
|
|
|
|
|
|
|
|
#include <tqstringlist.h>
|
|
|
|
#include <tqlayout.h>
|
|
|
|
#include <tqlabel.h>
|
|
|
|
#include <tqheader.h>
|
|
|
|
#include <tqevent.h>
|
|
|
|
#include <tqpainter.h>
|
|
|
|
#include <tqstyle.h>
|
|
|
|
#include <tqlineedit.h>
|
|
|
|
#include <tqpopupmenu.h>
|
|
|
|
|
|
|
|
#include <klocale.h>
|
|
|
|
#include <kaction.h>
|
|
|
|
#include <kpopupmenu.h>
|
|
|
|
#include <kglobalsettings.h>
|
|
|
|
#include <kmessagebox.h>
|
|
|
|
|
|
|
|
#include <kexidb/tableschema.h>
|
|
|
|
#include <kexidb/indexschema.h>
|
|
|
|
#include <kexidb/utils.h>
|
|
|
|
|
|
|
|
#include "kexirelationview.h"
|
|
|
|
#include "kexirelationviewtable.h"
|
|
|
|
#include "kexirelationviewconnection.h"
|
|
|
|
#include <kexi.h>
|
|
|
|
|
|
|
|
KexiRelationView::KexiRelationView(TQWidget *parent, const char *name)
|
|
|
|
: TQScrollView(parent, name, WStaticContents)
|
|
|
|
{
|
|
|
|
// m_relation=relation;
|
|
|
|
// m_relation->incUsageCount();
|
|
|
|
m_selectedConnection = 0;
|
|
|
|
m_readOnly=false;
|
|
|
|
m_focusedTableView = 0;
|
|
|
|
setFrameStyle(TQFrame::WinPanel | TQFrame::Sunken);
|
|
|
|
|
|
|
|
// connect(relation, TQT_SIGNAL(relationListUpdated(TQObject *)), this, TQT_SLOT(slotListUpdate(TQObject *)));
|
|
|
|
|
|
|
|
viewport()->setPaletteBackgroundColor(colorGroup().mid());
|
|
|
|
setFocusPolicy(TQ_WheelFocus);
|
|
|
|
setResizePolicy(Manual);
|
|
|
|
/*MOVED TO KexiRelationDialog
|
|
|
|
//actions
|
|
|
|
m_tableQueryPopup = new KPopupMenu(this, "m_popup");
|
|
|
|
m_tableQueryPopup->insertTitle(i18n("Table"));
|
|
|
|
m_connectionPopup = new KPopupMenu(this, "m_connectionPopup");
|
|
|
|
m_connectionPopup->insertTitle(i18n("Relation"));
|
|
|
|
m_areaPopup = new KPopupMenu(this, "m_areaPopup");
|
|
|
|
|
|
|
|
plugSharedAction("edit_delete", i18n("Hide Table"), m_tableQueryPopup);
|
|
|
|
plugSharedAction("edit_delete",m_connectionPopup);
|
|
|
|
plugSharedAction("edit_delete",this, TQT_SLOT(removeSelectedObject()));
|
|
|
|
*/
|
|
|
|
#if 0
|
|
|
|
m_removeSelectedTableQueryAction = new KAction(i18n("&Hide Selected Table/Query"), "editdelete", "",
|
|
|
|
this, TQT_SLOT(removeSelectedTableQuery()), parent->actionCollection(), "relationsview_removeSelectedTableQuery");
|
|
|
|
m_removeSelectedConnectionAction = new KAction(i18n("&Remove Selected Relationship"), "button_cancel", "",
|
|
|
|
this, TQT_SLOT(removeSelectedConnection()), parent->actionCollection(), "relationsview_removeSelectedConnection");
|
|
|
|
m_openSelectedTableQueryAction = new KAction(i18n("&Open Selected Table/Query"), "", "",
|
|
|
|
this, TQT_SLOT(openSelectedTableQuery()), 0/*parent->actionCollection()*/, "relationsview_openSelectedTableQuery");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// invalidateActions();
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
|
|
|
|
|
|
|
m_popup = new KPopupMenu(this, "m_popup");
|
|
|
|
m_openSelectedTableQueryAction->plug( m_popup );
|
|
|
|
m_removeSelectedTableQueryAction->plug( m_popup );
|
|
|
|
m_removeSelectedConnectionAction->plug( m_popup );
|
|
|
|
|
|
|
|
invalidateActions();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
setSizePolicy(TQSizePolicy::Expanding, TQSizePolicy::Expanding, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
KexiRelationView::~KexiRelationView()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
/*KexiRelationViewTableContainer*
|
|
|
|
KexiRelationView::containerForTable(KexiDB::TableSchema* tableSchema)
|
|
|
|
{
|
|
|
|
if (!tableSchema)
|
|
|
|
return 0;
|
|
|
|
for (TablesDictIterator it(m_tables); it.current(); ++it) {
|
|
|
|
if (it.current()->schema()->table()==tableSchema)
|
|
|
|
return it.current();
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}*/
|
|
|
|
|
|
|
|
KexiRelationViewTableContainer *
|
|
|
|
KexiRelationView::tableContainer(KexiDB::TableSchema *t) const
|
|
|
|
{
|
|
|
|
return t ? m_tables.find(t->name()) : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
KexiRelationViewTableContainer*
|
|
|
|
KexiRelationView::addTableContainer(KexiDB::TableSchema *t, const TQRect &rect)
|
|
|
|
{
|
|
|
|
if(!t)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
kdDebug() << "KexiRelationView::addTable(): " << t->name() << ", " << viewport() << endl;
|
|
|
|
|
|
|
|
KexiRelationViewTableContainer* c = tableContainer(t);
|
|
|
|
if (c) {
|
|
|
|
kdWarning() << "KexiRelationView::addTable(): table already added" << endl;
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
c = new KexiRelationViewTableContainer(this,
|
|
|
|
/*! @todo what about query? */
|
|
|
|
new KexiDB::TableOrQuerySchema(t)
|
|
|
|
);
|
|
|
|
connect(c, TQT_SIGNAL(endDrag()), this, TQT_SLOT(slotTableViewEndDrag()));
|
|
|
|
connect(c, TQT_SIGNAL(gotFocus()), this, TQT_SLOT(slotTableViewGotFocus()));
|
|
|
|
// connect(c, TQT_SIGNAL(headerContextMenuRequest(const TQPoint&)),
|
|
|
|
// this, TQT_SLOT(tableHeaderContextMenuRequest(const TQPoint&)));
|
|
|
|
connect(c, TQT_SIGNAL(contextMenuRequest(const TQPoint&)),
|
|
|
|
this, TQT_SIGNAL(tableContextMenuRequest(const TQPoint&)));
|
|
|
|
|
|
|
|
addChild(c, 100,100);
|
|
|
|
if (rect.isValid()) {//predefined size
|
|
|
|
TQSize finalSize = c->size().expandedTo( c->sizeHint() );
|
|
|
|
TQRect r = rect;
|
|
|
|
r.setSize( finalSize + TQSize(0,10) );
|
|
|
|
moveChild( c, rect.left(), rect.top() );
|
|
|
|
//we're doing this instead of setGeometry(rect)
|
|
|
|
//because the geomenty might be saved on other system with bigger fonts :)
|
|
|
|
c->resize(c->sizeHint());
|
|
|
|
// c->setGeometry(r);
|
|
|
|
//TODO
|
|
|
|
|
|
|
|
// moveChild( c, rect.left(), rect.top() ); // setGeometry(rect);
|
|
|
|
// c->resize( finalSize );
|
|
|
|
// c->updateGeometry();
|
|
|
|
}
|
|
|
|
c->show();
|
|
|
|
updateGeometry();
|
|
|
|
if (!rect.isValid()) {
|
|
|
|
c->updateGeometry();
|
|
|
|
c->resize(c->sizeHint());
|
|
|
|
}
|
|
|
|
int x, y;
|
|
|
|
|
|
|
|
if(m_tables.count() > 0)
|
|
|
|
{
|
|
|
|
int place = -10;
|
|
|
|
TQDictIterator<KexiRelationViewTableContainer> it(m_tables);
|
|
|
|
for(; it.current(); ++it)
|
|
|
|
{
|
|
|
|
int right = (*it)->x() + (*it)->width();
|
|
|
|
if(right > place)
|
|
|
|
place = right;
|
|
|
|
}
|
|
|
|
|
|
|
|
x = place + 30;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
x = 5;
|
|
|
|
}
|
|
|
|
|
|
|
|
y = 5;
|
|
|
|
TQPoint p = viewportToContents(TQPoint(x, y));
|
|
|
|
recalculateSize(p.x() + c->width(), p.y() + c->height());
|
|
|
|
if (!rect.isValid()) {
|
|
|
|
moveChild(c, x, y);
|
|
|
|
}
|
|
|
|
|
|
|
|
m_tables.insert(t->name(), c);
|
|
|
|
|
|
|
|
connect(c, TQT_SIGNAL(moved(KexiRelationViewTableContainer *)), this,
|
|
|
|
TQT_SLOT(containerMoved(KexiRelationViewTableContainer *)));
|
|
|
|
|
|
|
|
if (hasFocus()) //ok?
|
|
|
|
c->setFocus();
|
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
KexiRelationView::addConnection(const SourceConnection& _conn)
|
|
|
|
{
|
|
|
|
SourceConnection conn = _conn;
|
|
|
|
kdDebug() << "KexiRelationView::addConnection()" << endl;
|
|
|
|
|
|
|
|
KexiRelationViewTableContainer *master = m_tables[conn.masterTable];
|
|
|
|
KexiRelationViewTableContainer *details = m_tables[conn.detailsTable];
|
|
|
|
if (!master || !details)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/*! @todo what about query? */
|
|
|
|
KexiDB::TableSchema *masterTable = master->schema()->table();
|
|
|
|
/*! @todo what about query? */
|
|
|
|
KexiDB::TableSchema *detailsTable = details->schema()->table();
|
|
|
|
if (!masterTable || !detailsTable)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// ok, but we need to know where is the 'master' and where is the 'details' side:
|
|
|
|
KexiDB::Field *masterFld = masterTable->field(conn.masterField);
|
|
|
|
KexiDB::Field *detailsFld = detailsTable->field(conn.detailsField);
|
|
|
|
if (!masterFld || !detailsFld)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!masterFld->isUniqueKey()) {
|
|
|
|
if (detailsFld->isUniqueKey()) {
|
|
|
|
//SWAP:
|
|
|
|
KexiDB::Field *tmpFld = masterFld;
|
|
|
|
masterFld = detailsFld;
|
|
|
|
detailsFld = tmpFld;
|
|
|
|
KexiDB::TableSchema *tmpTable = masterTable;
|
|
|
|
masterTable = detailsTable;
|
|
|
|
detailsTable = tmpTable;
|
|
|
|
KexiRelationViewTableContainer *tmp = master;
|
|
|
|
master = details;
|
|
|
|
details = tmp;
|
|
|
|
TQString tmp_masterTable = conn.masterTable;
|
|
|
|
conn.masterTable = conn.detailsTable;
|
|
|
|
conn.detailsTable = tmp_masterTable;
|
|
|
|
TQString tmp_masterField = conn.masterField;
|
|
|
|
conn.masterField = conn.detailsField;
|
|
|
|
conn.detailsField = tmp_masterField;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// kdDebug() << "KexiRelationView::addConnection(): finalSRC = " << m_tables[conn.srcTable] << endl;
|
|
|
|
|
|
|
|
KexiRelationViewConnection *connView = new KexiRelationViewConnection(master, details, conn, this);
|
|
|
|
m_connectionViews.append(connView);
|
|
|
|
updateContents(connView->connectionRect());
|
|
|
|
|
|
|
|
/*js: will be moved up to relation/query part as this is only visual class
|
|
|
|
KexiDB::TableSchema *mtable = m_conn->tableSchema(conn.srcTable);
|
|
|
|
KexiDB::TableSchema *ftable = m_conn->tableSchema(conn.rcvTable);
|
|
|
|
KexiDB::IndexSchema *forign = new KexiDB::IndexSchema(ftable);
|
|
|
|
|
|
|
|
forign->addField(mtable->field(conn.srcField));
|
|
|
|
new KexiDB::Reference(forign, mtable->primaryKey());
|
|
|
|
*/
|
|
|
|
#if 0
|
|
|
|
if(!interactive)
|
|
|
|
{
|
|
|
|
kdDebug() << "KexiRelationView::addConnection: adding self" << endl;
|
|
|
|
RelationList l = m_relation->projectRelations();
|
|
|
|
l.append(conn);
|
|
|
|
m_relation->updateRelationList(this, l);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
KexiRelationView::drawContents(TQPainter *p, int cx, int cy, int cw, int ch)
|
|
|
|
{
|
|
|
|
KexiRelationViewConnection *cview;
|
|
|
|
// p->translate(0, (double)contentsY());
|
|
|
|
|
|
|
|
TQRect clipping(cx, cy, cw, ch);
|
|
|
|
for(cview = m_connectionViews.first(); cview; cview = m_connectionViews.next())
|
|
|
|
{
|
|
|
|
if(clipping.intersects(cview->oldRect() | cview->connectionRect()))
|
|
|
|
cview->drawConnection(p);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
KexiRelationView::slotTableScrolling(const TQString& table)
|
|
|
|
{
|
|
|
|
KexiRelationViewTableContainer *c = m_tables[table];
|
|
|
|
|
|
|
|
if(c)
|
|
|
|
containerMoved(c);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
KexiRelationView::containerMoved(KexiRelationViewTableContainer *c)
|
|
|
|
{
|
|
|
|
KexiRelationViewConnection *cview;
|
|
|
|
TQRect r;
|
|
|
|
for (ConnectionListIterator it(m_connectionViews); ((cview=it.current())); ++it) {
|
|
|
|
//! @todo optimize
|
|
|
|
if(cview->masterTable() == c || cview->detailsTable() == c
|
|
|
|
|| cview->connectionRect().intersects(r))
|
|
|
|
{
|
|
|
|
r |= cview->oldRect();
|
|
|
|
kdDebug() << r << endl;
|
|
|
|
r |= cview->connectionRect();
|
|
|
|
kdDebug() << r << endl;
|
|
|
|
}
|
|
|
|
// updateContents(cview->oldRect());
|
|
|
|
// updateContents(cview->connectionRect());
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
//! @todo optimize!
|
|
|
|
//didn't work well: updateContents(r);
|
|
|
|
updateContents();
|
|
|
|
|
|
|
|
// TQRect w(c->x() - 5, c->y() - 5, c->width() + 5, c->height() + 5);
|
|
|
|
// updateContents(w);
|
|
|
|
|
|
|
|
TQPoint p = viewportToContents(TQPoint(c->x(), c->y()));
|
|
|
|
recalculateSize(p.x() + c->width(), p.y() + c->height());
|
|
|
|
|
|
|
|
emit tablePositionChanged(c);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
KexiRelationView::setReadOnly(bool b)
|
|
|
|
{
|
|
|
|
m_readOnly=b;
|
|
|
|
//TODO
|
|
|
|
// invalidateActions();
|
|
|
|
/* TableList::Iterator it, end( m_tables.end() );
|
|
|
|
for ( it=m_tables.begin(); it != end; ++it)
|
|
|
|
{
|
|
|
|
// (*it)->setReadOnly(b);
|
|
|
|
#ifndef TQ_WS_WIN
|
|
|
|
#warning readonly needed
|
|
|
|
#endif
|
|
|
|
}*/
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
KexiRelationView::slotListUpdate(TQObject *)
|
|
|
|
{
|
|
|
|
#if 0
|
|
|
|
if(s != this)
|
|
|
|
{
|
|
|
|
m_connectionViews.clear();
|
|
|
|
RelationList rl = m_relation->projectRelations();
|
|
|
|
if(!rl.isEmpty())
|
|
|
|
{
|
|
|
|
RelationList::ConstIterator it, end( rl.constEnd() );
|
|
|
|
for( it = rl.begin(); it != end; ++it)
|
|
|
|
{
|
|
|
|
addConnection((*it), true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
updateContents();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
KexiRelationView::contentsMousePressEvent(TQMouseEvent *ev)
|
|
|
|
{
|
|
|
|
KexiRelationViewConnection *cview;
|
|
|
|
for(cview = m_connectionViews.first(); cview; cview = m_connectionViews.next())
|
|
|
|
{
|
|
|
|
if(!cview->matchesPoint(ev->pos(), 3))
|
|
|
|
continue;
|
|
|
|
clearSelection();
|
|
|
|
setFocus();
|
|
|
|
cview->setSelected(true);
|
|
|
|
updateContents(cview->connectionRect());
|
|
|
|
m_selectedConnection = cview;
|
|
|
|
emit connectionViewGotFocus();
|
|
|
|
// invalidateActions();
|
|
|
|
|
|
|
|
if(ev->button() == Qt::RightButton) {//show popup
|
|
|
|
kdDebug() << "KexiRelationView::contentsMousePressEvent(): context" << endl;
|
|
|
|
// TQPopupMenu m;
|
|
|
|
// m_removeSelectedTableQueryAction->plug( &m );
|
|
|
|
// m_removeSelectedConnectionAction->plug( &m );
|
|
|
|
emit connectionContextMenuRequest( ev->globalPos() );
|
|
|
|
// executePopup( ev->globalPos() );
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
//connection not found
|
|
|
|
clearSelection();
|
|
|
|
// invalidateActions();
|
|
|
|
if(ev->button() == Qt::RightButton) {//show popup on view background area
|
|
|
|
// TQPopupMenu m;
|
|
|
|
// m_removeSelectedConnectionAction->plug( &m );
|
|
|
|
emit emptyAreaContextMenuRequest( ev->globalPos() );
|
|
|
|
// executePopup(ev->globalPos());
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
emit emptyAreaGotFocus();
|
|
|
|
}
|
|
|
|
setFocus();
|
|
|
|
// TQScrollView::contentsMousePressEvent(ev);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KexiRelationView::clearSelection()
|
|
|
|
{
|
|
|
|
if (m_focusedTableView) {
|
|
|
|
m_focusedTableView->unsetFocus();
|
|
|
|
m_focusedTableView = 0;
|
|
|
|
// setFocus();
|
|
|
|
// invalidateActions();
|
|
|
|
}
|
|
|
|
if (m_selectedConnection) {
|
|
|
|
m_selectedConnection->setSelected(false);
|
|
|
|
updateContents(m_selectedConnection->connectionRect());
|
|
|
|
m_selectedConnection = 0;
|
|
|
|
// invalidateActions();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
KexiRelationView::keyPressEvent(TQKeyEvent *ev)
|
|
|
|
{
|
|
|
|
kdDebug() << "KexiRelationView::keyPressEvent()" << endl;
|
|
|
|
|
|
|
|
if (ev->key()==KGlobalSettings::contextMenuKey()) {
|
|
|
|
if (m_selectedConnection) {
|
|
|
|
emit connectionContextMenuRequest(
|
|
|
|
mapToGlobal(m_selectedConnection->connectionRect().center()) );
|
|
|
|
}
|
|
|
|
// m_popup->exec( mapToGlobal( m_focusedTableView ? m_focusedTableView->pos() + m_focusedTableView->rect().center() : rect().center() ) );
|
|
|
|
// executePopup();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if(ev->key() == Key_Delete)
|
|
|
|
removeSelectedObject();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
KexiRelationView::recalculateSize(int width, int height)
|
|
|
|
{
|
|
|
|
kdDebug() << "recalculateSize(" << width << ", " << height << ")" << endl;
|
|
|
|
int newW = contentsWidth(), newH = contentsHeight();
|
|
|
|
kdDebug() << "contentsSize(" << newW << ", " << newH << ")" << endl;
|
|
|
|
|
|
|
|
if(newW < width)
|
|
|
|
newW = width;
|
|
|
|
|
|
|
|
if(newH < height)
|
|
|
|
newH = height;
|
|
|
|
|
|
|
|
resizeContents(newW, newH);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*! Resizes contents to size exactly enough to fit tableViews.
|
|
|
|
Executed on every tableView's drop event.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
KexiRelationView::stretchExpandSize()
|
|
|
|
{
|
|
|
|
int max_x=-1, max_y=-1;
|
|
|
|
TQDictIterator<KexiRelationViewTableContainer> it(m_tables);
|
|
|
|
for (;it.current(); ++it) {
|
|
|
|
if (it.current()->right()>max_x)
|
|
|
|
max_x = it.current()->right();
|
|
|
|
if (it.current()->bottom()>max_y)
|
|
|
|
max_y = it.current()->bottom();
|
|
|
|
}
|
|
|
|
TQPoint p = viewportToContents(TQPoint(max_x, max_y) + TQPoint(3,3)); //3 pixels margin
|
|
|
|
resizeContents(p.x(), p.y());
|
|
|
|
}
|
|
|
|
|
|
|
|
void KexiRelationView::slotTableViewEndDrag()
|
|
|
|
{
|
|
|
|
kdDebug() << "END DRAG!" <<endl;
|
|
|
|
stretchExpandSize();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
KexiRelationView::removeSelectedObject()
|
|
|
|
{
|
|
|
|
if (m_selectedConnection) {
|
|
|
|
removeConnection(m_selectedConnection);
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
RelationList l = m_relation->projectRelations();
|
|
|
|
RelationList nl;
|
|
|
|
for(RelationList::Iterator it = l.begin(); it != l.end(); ++it)
|
|
|
|
{
|
|
|
|
if((*it).srcTable == m_selectedConnection->connection().srcTable
|
|
|
|
&& (*it).rcvTable == m_selectedConnection->connection().rcvTable
|
|
|
|
&& (*it).srcField == m_selectedConnection->connection().srcField
|
|
|
|
&& (*it).rcvField == m_selectedConnection->connection().rcvField)
|
|
|
|
{
|
|
|
|
kdDebug() << "KexiRelationView::removeSelectedConnection(): matching found!" << endl;
|
|
|
|
// l.remove(it);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nl.append(*it);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
kdDebug() << "KexiRelationView::removeSelectedConnection(): d2" << endl;
|
|
|
|
m_relation->updateRelationList(this, nl);
|
|
|
|
kdDebug() << "KexiRelationView::removeSelectedConnection(): d3" << endl;
|
|
|
|
#endif
|
|
|
|
delete m_selectedConnection;
|
|
|
|
m_selectedConnection = 0;
|
|
|
|
// invalidateActions();
|
|
|
|
}
|
|
|
|
else if (m_focusedTableView) {
|
|
|
|
KexiRelationViewTableContainer *tmp = m_focusedTableView;
|
|
|
|
m_focusedTableView = 0;
|
|
|
|
hideTable(tmp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
KexiRelationView::hideTable(KexiRelationViewTableContainer* tableView)
|
|
|
|
{
|
|
|
|
/*! @todo what about query? */
|
|
|
|
KexiDB::TableSchema *ts = tableView->schema()->table();
|
|
|
|
//for all connections: find and remove all connected with this table
|
|
|
|
TQPtrListIterator<KexiRelationViewConnection> it(m_connectionViews);
|
|
|
|
for (;it.current();) {
|
|
|
|
if (it.current()->masterTable() == tableView
|
|
|
|
|| it.current()->detailsTable() == tableView)
|
|
|
|
{
|
|
|
|
//remove this
|
|
|
|
removeConnection(it.current());
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
m_tables.take(tableView->schema()->name());
|
|
|
|
delete tableView;
|
|
|
|
emit tableHidden( *ts );
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
KexiRelationView::hideAllTablesExcept( KexiDB::TableSchema::List* tables )
|
|
|
|
{
|
|
|
|
//! @todo what about queries?
|
|
|
|
for (TablesDictIterator it(m_tables); it.current();) {
|
|
|
|
KexiDB::TableSchema *table = it.current()->schema()->table();
|
|
|
|
if (!table || tables->findRef( table )!=-1) {
|
|
|
|
++it;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
hideTable(it.current());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
KexiRelationView::removeConnection(KexiRelationViewConnection *conn)
|
|
|
|
{
|
|
|
|
emit aboutConnectionRemove(conn);
|
|
|
|
m_connectionViews.remove(conn);
|
|
|
|
updateContents(conn->connectionRect());
|
|
|
|
kdDebug() << "KexiRelationView::removeConnection()" << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KexiRelationView::slotTableViewGotFocus()
|
|
|
|
{
|
|
|
|
if (m_focusedTableView == sender())
|
|
|
|
return;
|
|
|
|
kdDebug() << "GOT FOCUS!" <<endl;
|
|
|
|
clearSelection();
|
|
|
|
// if (m_focusedTableView)
|
|
|
|
// m_focusedTableView->unsetFocus();
|
|
|
|
m_focusedTableView = (KexiRelationViewTableContainer*)sender();
|
|
|
|
// invalidateActions();
|
|
|
|
emit tableViewGotFocus();
|
|
|
|
}
|
|
|
|
|
|
|
|
TQSize KexiRelationView::sizeHint() const
|
|
|
|
{
|
|
|
|
return TQSize(TQScrollView::sizeHint());//.width(), 600);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KexiRelationView::clear()
|
|
|
|
{
|
|
|
|
removeAllConnections();
|
|
|
|
m_tables.setAutoDelete(true);
|
|
|
|
m_tables.clear();
|
|
|
|
m_tables.setAutoDelete(false);
|
|
|
|
updateContents();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KexiRelationView::removeAllConnections()
|
|
|
|
{
|
|
|
|
clearSelection(); //sanity
|
|
|
|
m_connectionViews.setAutoDelete(true);
|
|
|
|
m_connectionViews.clear();
|
|
|
|
m_connectionViews.setAutoDelete(false);
|
|
|
|
updateContents();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
void KexiRelationView::tableHeaderContextMenuRequest(const TQPoint& pos)
|
|
|
|
{
|
|
|
|
if (m_focusedTableView != sender())
|
|
|
|
return;
|
|
|
|
kdDebug() << "HEADER CTXT MENU!" <<endl;
|
|
|
|
invalidateActions();
|
|
|
|
m_tableQueryPopup->exec(pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Invalidates all actions availability
|
|
|
|
void KexiRelationView::invalidateActions()
|
|
|
|
{
|
|
|
|
setAvailable("edit_delete", m_selectedConnection || m_focusedTableView);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KexiRelationView::executePopup( TQPoint pos )
|
|
|
|
{
|
|
|
|
if (pos==TQPoint(-1,-1)) {
|
|
|
|
pos = mapToGlobal( m_focusedTableView ? m_focusedTableView->pos() + m_focusedTableView->rect().center() : rect().center() );
|
|
|
|
}
|
|
|
|
if (m_focusedTableView)
|
|
|
|
m_tableQueryPopup->exec(pos);
|
|
|
|
else if (m_selectedConnection)
|
|
|
|
m_connectionPopup->exec(pos);
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "kexirelationview.moc"
|