summaryrefslogtreecommitdiffstats
path: root/kexi/widget/relations/kexirelationviewconnection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kexi/widget/relations/kexirelationviewconnection.cpp')
-rw-r--r--kexi/widget/relations/kexirelationviewconnection.cpp298
1 files changed, 298 insertions, 0 deletions
diff --git a/kexi/widget/relations/kexirelationviewconnection.cpp b/kexi/widget/relations/kexirelationviewconnection.cpp
new file mode 100644
index 00000000..2c27de87
--- /dev/null
+++ b/kexi/widget/relations/kexirelationviewconnection.cpp
@@ -0,0 +1,298 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 Lucijan Busch <[email protected]>
+ Copyright (C) 2004-2005 Jaroslaw Staniek <[email protected]>
+
+ 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 <qpainter.h>
+#include <qpixmap.h>
+#include <qcolor.h>
+#include <qapplication.h>
+#include <qpointarray.h>
+
+#include <kdebug.h>
+
+#include <math.h>
+
+#include "kexirelationview.h"
+#include "kexirelationviewtable.h"
+#include "kexirelationviewconnection.h"
+#include <kexidb/tableschema.h>
+#include <kexidb/utils.h>
+#include <core/kexi.h>
+
+//#include "r1.xpm"
+//#include "rn.xpm"
+
+KexiRelationViewConnection::KexiRelationViewConnection(
+ KexiRelationViewTableContainer *masterTbl, KexiRelationViewTableContainer *detailsTbl,
+ SourceConnection &c, KexiRelationView *parent)
+{
+ m_parent = parent;
+// kdDebug() << "KexiRelationViewConnection::KexiRelationViewConnection()" << endl;
+
+ m_masterTable = masterTbl;
+ if(!masterTbl || !detailsTbl)
+ {
+ kdDebug() << "KexiRelationViewConnection::KexiRelationViewConnection(): expect sig11" << endl;
+ kdDebug() << "KexiRelationViewConnection::KexiRelationViewConnection()" << masterTbl << endl;
+ kdDebug() << "KexiRelationViewConnection::KexiRelationViewConnection()" << detailsTbl << endl;
+ }
+
+ m_detailsTable = detailsTbl;
+ m_masterField = c.masterField;
+ m_detailsField = c.detailsField;
+
+ m_selected = false;
+}
+
+KexiRelationViewConnection::~KexiRelationViewConnection()
+{
+}
+
+void
+KexiRelationViewConnection::drawConnection(QPainter *p)
+{
+ p->setPen(m_parent->palette().active().foreground());
+ int sx = m_masterTable->x() + m_masterTable->width() + m_parent->contentsX();
+ int sy = m_masterTable->globalY(m_masterField);
+ int rx = m_detailsTable->x() + m_parent->contentsX();
+ int ry = m_detailsTable->globalY(m_detailsField);
+
+ QFont f( Kexi::smallFont( m_parent ) );
+ QFontMetrics fm(f);
+ int side1x=0, side1y=sy - fm.height(),
+ sideNx=0, sideNy=ry - fm.height();
+//! @todo details char can be also just a '1' for some cases
+ QChar sideNChar(0x221E); //infinity char
+ uint sideNCharWidth = 2+2+ fm.width( sideNChar );
+ QChar side1Char('1');
+ uint side1CharWidth = 2+2+ fm.width( side1Char );
+ p->setBrush(p->pen().color());
+
+ if(m_masterTable->x() < m_detailsTable->x())
+ {
+ //det. side
+ p->drawLine(rx - sideNCharWidth, ry, rx, ry);
+ QPointArray pa(3);
+ pa.setPoint(0, rx - 4, ry - 3);
+ pa.setPoint(1, rx - 4, ry + 3);
+ pa.setPoint(2, rx - 1, ry);
+ p->drawPolygon(pa, true);
+
+ //master side
+ p->drawLine(sx, sy - 1, sx + side1CharWidth -1, sy - 1);
+ p->drawLine(sx, sy, sx + side1CharWidth -1, sy);
+ p->drawLine(sx, sy + 1, sx + side1CharWidth -1, sy + 1);
+
+ side1x = sx;
+// side1y = sy - 7;
+
+ sideNx = rx - sideNCharWidth - 1;
+// sideNy = ry - 6;
+
+ QPen pen(p->pen());
+ if(m_selected)
+ {
+ QPen pen(p->pen());
+ pen.setWidth(2);
+ p->setPen(pen);
+ }
+
+ p->drawLine(sx + side1CharWidth, sy, rx - sideNCharWidth, ry);
+
+ if(m_selected)
+ {
+ QPen pen(p->pen());
+ pen.setWidth(1);
+ p->setPen(pen);
+ }
+
+ }
+ else
+ {
+ int lx = rx + m_detailsTable->width();
+ int rx = sx - m_masterTable->width();
+
+ //det. side
+ p->drawLine(lx, ry, lx + sideNCharWidth, ry);
+ QPointArray pa(3);
+ pa.setPoint(0, lx + 3, ry - 3);
+ pa.setPoint(1, lx + 3, ry + 3);
+ pa.setPoint(2, lx, ry);
+ p->drawPolygon(pa, true);
+
+// p->drawLine(lx, ry, lx + 8, ry);
+// p->drawPoint(lx + 1, ry - 1);
+// p->drawPoint(lx + 1, ry + 1);
+// p->drawLine(lx + 2, ry - 2, lx + 2, ry + 2);
+
+ //master side
+ p->drawLine(rx - side1CharWidth +1, sy - 1, rx, sy - 1);
+ p->drawLine(rx - side1CharWidth +1, sy + 1, rx, sy + 1);
+ p->drawLine(rx - side1CharWidth +1, sy, rx, sy);
+
+ side1x = rx - side1CharWidth;
+// side1y = sy - 7;
+
+ sideNx = lx + 1;
+// sideNy = ry - 6;
+
+ if(m_selected)
+ {
+ QPen pen(p->pen());
+ pen.setWidth(2);
+ p->setPen(pen);
+ }
+
+ p->drawLine(lx + sideNCharWidth, ry, rx - side1CharWidth, sy);
+
+ if(m_selected)
+ {
+ QPen pen(p->pen());
+ pen.setWidth(1);
+ p->setPen(pen);
+ }
+ }
+
+ p->drawText(side1x, side1y, side1CharWidth, fm.height(), Qt::AlignCenter, side1Char);
+ p->drawText(sideNx, sideNy, sideNCharWidth, fm.height(), Qt::AlignCenter, sideNChar);
+ //p->drawRect(QRect(connectionRect().topLeft(), QSize(50,50)));
+// p->drawPixmap(side1, QPixmap(r1_xpm));
+// p->drawPixmap(sideN, QPixmap(rn_xpm));
+}
+
+const QRect
+KexiRelationViewConnection::connectionRect()
+{
+ int sx = m_masterTable->x() + m_parent->contentsX();
+ int rx = m_detailsTable->x() + m_parent->contentsX();
+ int ry = m_detailsTable->globalY(m_detailsField);
+ int sy = m_masterTable->globalY(m_masterField);
+
+ int width, leftX, rightX;
+
+ if(sx < rx)
+ {
+ leftX = sx;
+ rightX = rx;
+ width = m_masterTable->width();
+ }
+ else
+ {
+ leftX = rx;
+ rightX = sx;
+ width = m_detailsTable->width();
+ }
+
+
+ int dx = QABS((leftX + width) - rightX);
+ int dy = QABS(sy - ry) + 2;
+
+ int top = QMIN(sy, ry);
+ int left = leftX + width;
+
+
+// return QRect(sx - 1, sy - 1, (rx + m_detailsTable->width()) - sx + 1, ry - sy + 1);
+ QRect rect(left - 150, top - 150, dx + 150, dy + 150);
+// kdDebug() << "KexiRelationViewConnection::connectionRect():" << m_oldRect << "," << rect << endl;
+
+ m_oldRect = rect;
+
+ return rect;
+}
+
+bool
+KexiRelationViewConnection::matchesPoint(const QPoint &p, int tolerance)
+{
+ QRect we = connectionRect();
+
+ if(!we.contains(p))
+ return false;
+
+ /** get our coordinats
+ * you know what i mean the x1, y1 is the top point
+ * and the x2, y2 is the bottom point
+ * (quite tirvial :) although that was the entrace to the magic
+ * gate...
+ */
+
+ int sx = m_masterTable->x() + m_masterTable->width();
+ int sy = m_masterTable->globalY(m_masterField);
+ int rx = m_detailsTable->x();
+ int ry = m_detailsTable->globalY(m_detailsField);
+
+ int x1 = sx + 8;
+ int y1 = sy;
+ int x2 = rx - 8;
+ int y2 = ry;
+
+ if(sx > rx)
+ {
+ x1 = m_detailsTable->x() + m_detailsTable->width();
+ x2 = m_masterTable->x();
+ y2 = sy;
+ y1 = ry;
+ }
+
+ /*
+ here we call pythagoras (the greek math geek :p)
+ see: http://w1.480.telia.com/%7Eu48019406/geekporn.gif if you don't know
+ how these people have got sex :)
+ */
+ float mx = x2-x1;
+ float my = y2-y1;
+ float mag = sqrt(mx * mx + my * my);
+ float u = (((p.x() - x1)*(x2 - x1))+((p.y() - y1)*(y2 - y1)))/(mag * mag);
+ kdDebug() << "KexiRelationViewConnection::matchesPoint(): u: " << u << endl;
+
+ float iX = x1 + u * (x2 - x1);
+ float iY = y1 + u * (y2 - y1);
+ kdDebug() << "KexiRelationViewConnection::matchesPoint(): px: " << p.x() << endl;
+ kdDebug() << "KexiRelationViewConnection::matchesPoint(): py: " << p.y() << endl;
+ kdDebug() << "KexiRelationViewConnection::matchesPoint(): ix: " << iX << endl;
+ kdDebug() << "KexiRelationViewConnection::matchesPoint(): iy: " << iY << endl;
+
+ float dX = iX - p.x();
+ float dY = iY - p.y();
+
+ kdDebug() << "KexiRelationViewConnection::matchesPoint(): dx: " << dX << endl;
+ kdDebug() << "KexiRelationViewConnection::matchesPoint(): dy: " << dY << endl;
+
+ float distance = sqrt(dX * dX + dY * dY);
+ kdDebug() << "KexiRelationViewConnection::matchesPoint(): distance: " << distance << endl;
+
+ if(distance <= tolerance)
+ return true;
+
+ return false;
+}
+
+QString
+KexiRelationViewConnection::toString() const
+{
+ QString str;
+/*! @todo what about query? */
+ if (m_masterTable && m_masterTable->schema()->table()) {
+ str += (QString(m_masterTable->schema()->name()) + "." + m_masterField);
+ }
+ if (m_detailsTable && m_detailsTable->schema()->table()) {
+ str += " - ";
+ str += (QString(m_detailsTable->schema()->name()) + "." + m_detailsField);
+ }
+ return str;
+}