diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-20 01:29:50 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-20 01:29:50 +0000 |
commit | 8362bf63dea22bbf6736609b0f49c152f975eb63 (patch) | |
tree | 0eea3928e39e50fae91d4e68b21b1e6cbae25604 /kexi/widget/relations/kexirelationview.cpp | |
download | koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.tar.gz koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.zip |
Added old abandoned KDE3 version of koffice
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/koffice@1077364 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kexi/widget/relations/kexirelationview.cpp')
-rw-r--r-- | kexi/widget/relations/kexirelationview.cpp | 639 |
1 files changed, 639 insertions, 0 deletions
diff --git a/kexi/widget/relations/kexirelationview.cpp b/kexi/widget/relations/kexirelationview.cpp new file mode 100644 index 00000000..9d68a755 --- /dev/null +++ b/kexi/widget/relations/kexirelationview.cpp @@ -0,0 +1,639 @@ +/* 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 <qstringlist.h> +#include <qlayout.h> +#include <qlabel.h> +#include <qheader.h> +#include <qevent.h> +#include <qpainter.h> +#include <qstyle.h> +#include <qlineedit.h> +#include <qpopupmenu.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(QWidget *parent, const char *name) + : QScrollView(parent, name, WStaticContents) +{ +// m_relation=relation; +// m_relation->incUsageCount(); + m_selectedConnection = 0; + m_readOnly=false; + m_focusedTableView = 0; + setFrameStyle(QFrame::WinPanel | QFrame::Sunken); + +// connect(relation, SIGNAL(relationListUpdated(QObject *)), this, SLOT(slotListUpdate(QObject *))); + + viewport()->setPaletteBackgroundColor(colorGroup().mid()); + setFocusPolicy(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, SLOT(removeSelectedObject())); +*/ +#if 0 + m_removeSelectedTableQueryAction = new KAction(i18n("&Hide Selected Table/Query"), "editdelete", "", + this, SLOT(removeSelectedTableQuery()), parent->actionCollection(), "relationsview_removeSelectedTableQuery"); + m_removeSelectedConnectionAction = new KAction(i18n("&Remove Selected Relationship"), "button_cancel", "", + this, SLOT(removeSelectedConnection()), parent->actionCollection(), "relationsview_removeSelectedConnection"); + m_openSelectedTableQueryAction = new KAction(i18n("&Open Selected Table/Query"), "", "", + this, 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(QSizePolicy::Expanding, QSizePolicy::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 QRect &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, SIGNAL(endDrag()), this, SLOT(slotTableViewEndDrag())); + connect(c, SIGNAL(gotFocus()), this, SLOT(slotTableViewGotFocus())); +// connect(c, SIGNAL(headerContextMenuRequest(const QPoint&)), +// this, SLOT(tableHeaderContextMenuRequest(const QPoint&))); + connect(c, SIGNAL(contextMenuRequest(const QPoint&)), + this, SIGNAL(tableContextMenuRequest(const QPoint&))); + + addChild(c, 100,100); + if (rect.isValid()) {//predefined size + QSize finalSize = c->size().expandedTo( c->sizeHint() ); + QRect r = rect; + r.setSize( finalSize + QSize(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; + QDictIterator<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; + QPoint p = viewportToContents(QPoint(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, SIGNAL(moved(KexiRelationViewTableContainer *)), this, + 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; + QString tmp_masterTable = conn.masterTable; + conn.masterTable = conn.detailsTable; + conn.detailsTable = tmp_masterTable; + QString 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(QPainter *p, int cx, int cy, int cw, int ch) +{ + KexiRelationViewConnection *cview; +// p->translate(0, (double)contentsY()); + + QRect 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 QString& table) +{ + KexiRelationViewTableContainer *c = m_tables[table]; + + if(c) + containerMoved(c); +} + +void +KexiRelationView::containerMoved(KexiRelationViewTableContainer *c) +{ + KexiRelationViewConnection *cview; + QRect 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(); + +// QRect w(c->x() - 5, c->y() - 5, c->width() + 5, c->height() + 5); +// updateContents(w); + + QPoint p = viewportToContents(QPoint(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 Q_WS_WIN + #warning readonly needed +#endif + }*/ +} + +void +KexiRelationView::slotListUpdate(QObject *) +{ +#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(QMouseEvent *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() == RightButton) {//show popup + kdDebug() << "KexiRelationView::contentsMousePressEvent(): context" << endl; +// QPopupMenu 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() == RightButton) {//show popup on view background area +// QPopupMenu m; +// m_removeSelectedConnectionAction->plug( &m ); + emit emptyAreaContextMenuRequest( ev->globalPos() ); +// executePopup(ev->globalPos()); + } + else { + emit emptyAreaGotFocus(); + } + setFocus(); +// QScrollView::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(QKeyEvent *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; + QDictIterator<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(); + } + QPoint p = viewportToContents(QPoint(max_x, max_y) + QPoint(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 + QPtrListIterator<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(); +} + +QSize KexiRelationView::sizeHint() const +{ + return QSize(QScrollView::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 QPoint& 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( QPoint pos ) +{ + if (pos==QPoint(-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" |