kexi

kexirelationviewconnection.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2004 Lucijan Busch <lucijan@kde.org>
00003    Copyright (C) 2004-2005 Jaroslaw Staniek <js@iidea.pl>
00004 
00005    This program is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this program; see the file COPYING.  If not, write to
00017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include <qpainter.h>
00022 #include <qpixmap.h>
00023 #include <qcolor.h>
00024 #include <qapplication.h>
00025 #include <qpointarray.h>
00026 
00027 #include <kdebug.h>
00028 
00029 #include <math.h>
00030 
00031 #include "kexirelationview.h"
00032 #include "kexirelationviewtable.h"
00033 #include "kexirelationviewconnection.h"
00034 #include <kexidb/tableschema.h>
00035 #include <kexidb/utils.h>
00036 #include <core/kexi.h>
00037 
00038 //#include "r1.xpm"
00039 //#include "rn.xpm"
00040 
00041 KexiRelationViewConnection::KexiRelationViewConnection(
00042     KexiRelationViewTableContainer *masterTbl, KexiRelationViewTableContainer *detailsTbl, 
00043     SourceConnection &c, KexiRelationView *parent)
00044 {
00045     m_parent = parent;
00046     kdDebug() << "KexiRelationViewConnection::KexiRelationViewConnection()" << endl;
00047 
00048     m_masterTable = masterTbl;
00049     if(!masterTbl || !detailsTbl)
00050     {
00051         kdDebug() << "KexiRelationViewConnection::KexiRelationViewConnection(): expect sig11" << endl;
00052         kdDebug() << "KexiRelationViewConnection::KexiRelationViewConnection()" << masterTbl << endl;
00053         kdDebug() << "KexiRelationViewConnection::KexiRelationViewConnection()" << detailsTbl << endl;
00054     }
00055 
00056     m_detailsTable = detailsTbl;
00057     m_masterField = c.masterField;
00058     m_detailsField = c.detailsField;
00059 
00060     m_selected = false;
00061 }
00062 
00063 KexiRelationViewConnection::~KexiRelationViewConnection()
00064 {
00065 }
00066 
00067 void
00068 KexiRelationViewConnection::drawConnection(QPainter *p)
00069 {
00070     p->setPen(m_parent->palette().active().foreground());
00071     int sx = m_masterTable->x() + m_masterTable->width() + m_parent->contentsX();
00072     int sy = m_masterTable->globalY(m_masterField);
00073     int rx = m_detailsTable->x() + m_parent->contentsX();
00074     int ry = m_detailsTable->globalY(m_detailsField);
00075 
00076     QFont f( Kexi::smallFont( m_parent ) );
00077     QFontMetrics fm(f);
00078     int side1x=0, side1y=sy - fm.height(), 
00079         sideNx=0, sideNy=ry - fm.height();
00081     QChar sideNChar(0x221E); //infinity char
00082     uint sideNCharWidth = 2+2+ fm.width( sideNChar );
00083     QChar side1Char('1');
00084     uint side1CharWidth = 2+2+ fm.width( side1Char );
00085     p->setBrush(p->pen().color());
00086 
00087     if(m_masterTable->x() < m_detailsTable->x())
00088     {
00089         //det. side
00090         p->drawLine(rx - sideNCharWidth, ry, rx, ry);
00091         QPointArray pa(3);
00092         pa.setPoint(0, rx - 4, ry - 3);
00093         pa.setPoint(1, rx - 4, ry + 3);
00094         pa.setPoint(2, rx - 1, ry);
00095         p->drawPolygon(pa, true);
00096         
00097         //master side
00098         p->drawLine(sx, sy - 1, sx + side1CharWidth -1, sy - 1);
00099         p->drawLine(sx, sy, sx + side1CharWidth -1, sy);
00100         p->drawLine(sx, sy + 1, sx + side1CharWidth -1, sy + 1);
00101 
00102         side1x = sx;
00103 //      side1y = sy - 7;
00104 
00105         sideNx = rx - sideNCharWidth - 1;
00106 //      sideNy = ry - 6;
00107 
00108         QPen pen(p->pen());
00109         if(m_selected)
00110         {
00111             QPen pen(p->pen());
00112             pen.setWidth(2);
00113             p->setPen(pen);
00114         }
00115 
00116         p->drawLine(sx + side1CharWidth, sy, rx - sideNCharWidth, ry);
00117 
00118         if(m_selected)
00119         {
00120             QPen pen(p->pen());
00121             pen.setWidth(1);
00122             p->setPen(pen);
00123         }
00124 
00125     }
00126     else
00127     {
00128         int lx = rx + m_detailsTable->width();
00129         int rx = sx - m_masterTable->width();
00130 
00131         //det. side
00132         p->drawLine(lx, ry, lx + sideNCharWidth, ry);
00133         QPointArray pa(3);
00134         pa.setPoint(0, lx + 3, ry - 3);
00135         pa.setPoint(1, lx + 3, ry + 3);
00136         pa.setPoint(2, lx, ry);
00137         p->drawPolygon(pa, true);
00138         
00139 //      p->drawLine(lx, ry, lx + 8, ry);
00140 //      p->drawPoint(lx + 1, ry - 1);
00141 //      p->drawPoint(lx + 1, ry + 1);
00142 //      p->drawLine(lx + 2, ry - 2, lx + 2, ry + 2);
00143 
00144         //master side
00145         p->drawLine(rx - side1CharWidth +1, sy - 1, rx, sy - 1);
00146         p->drawLine(rx - side1CharWidth +1, sy + 1, rx, sy + 1);
00147         p->drawLine(rx - side1CharWidth +1, sy, rx, sy);
00148 
00149         side1x = rx - side1CharWidth;
00150 //      side1y = sy - 7;
00151 
00152         sideNx = lx + 1;
00153 //      sideNy = ry - 6;
00154 
00155         if(m_selected)
00156         {
00157             QPen pen(p->pen());
00158             pen.setWidth(2);
00159             p->setPen(pen);
00160         }
00161 
00162         p->drawLine(lx + sideNCharWidth, ry, rx - side1CharWidth, sy);
00163 
00164         if(m_selected)
00165         {
00166             QPen pen(p->pen());
00167             pen.setWidth(1);
00168             p->setPen(pen);
00169         }
00170     }
00171 
00172     p->drawText(side1x, side1y, side1CharWidth, fm.height(), Qt::AlignCenter, side1Char);
00173     p->drawText(sideNx, sideNy, sideNCharWidth, fm.height(), Qt::AlignCenter, sideNChar);
00174     //p->drawRect(QRect(connectionRect().topLeft(), QSize(50,50)));
00175 //  p->drawPixmap(side1, QPixmap(r1_xpm));
00176 //  p->drawPixmap(sideN, QPixmap(rn_xpm));
00177 }
00178 
00179 const QRect
00180 KexiRelationViewConnection::connectionRect()
00181 {
00182     int sx = m_masterTable->x() + m_parent->contentsX();
00183     int rx = m_detailsTable->x() + m_parent->contentsX();
00184     int ry = m_detailsTable->globalY(m_detailsField);
00185     int sy = m_masterTable->globalY(m_masterField);
00186 
00187     int width, leftX, rightX;
00188 
00189     if(sx < rx)
00190     {
00191         leftX = sx;
00192         rightX = rx;
00193         width = m_masterTable->width();
00194     }
00195     else
00196     {
00197         leftX = rx;
00198         rightX = sx;
00199         width = m_detailsTable->width();
00200     }
00201 
00202 
00203     int dx = QABS((leftX + width) - rightX);
00204     int dy = QABS(sy - ry) + 2;
00205 
00206     int top = QMIN(sy, ry);
00207     int left = leftX + width;
00208 
00209 
00210 //  return QRect(sx - 1, sy - 1, (rx + m_detailsTable->width()) - sx + 1, ry - sy + 1);
00211     QRect rect(left - 150, top - 150, dx + 150, dy + 150);
00212     kdDebug() << "KexiRelationViewConnection::connectionRect():" << m_oldRect << "," << rect << endl;
00213     
00214     m_oldRect = rect;
00215 
00216     return rect;
00217 }
00218 
00219 bool
00220 KexiRelationViewConnection::matchesPoint(const QPoint &p, int tolerance)
00221 {
00222     QRect we = connectionRect();
00223 
00224     if(!we.contains(p))
00225         return false;
00226 
00234     int sx = m_masterTable->x() + m_masterTable->width();
00235     int sy = m_masterTable->globalY(m_masterField);
00236     int rx = m_detailsTable->x();
00237     int ry = m_detailsTable->globalY(m_detailsField);
00238 
00239     int x1 = sx + 8;
00240     int y1 = sy;
00241     int x2 = rx - 8;
00242     int y2 = ry;
00243 
00244     if(sx > rx)
00245     {
00246         x1 = m_detailsTable->x() + m_detailsTable->width();
00247         x2 = m_masterTable->x();
00248         y2 = sy;
00249         y1 = ry;
00250     }
00251 
00252     /*
00253       here we call pythagoras (the greek math geek :p)
00254       see: http://w1.480.telia.com/%7Eu48019406/geekporn.gif if you don't know
00255       how these people have got sex :)
00256      */
00257     float mx = x2-x1;
00258     float my = y2-y1;
00259     float mag = sqrt(mx * mx + my * my);
00260     float u = (((p.x() - x1)*(x2 - x1))+((p.y() - y1)*(y2 - y1)))/(mag * mag);
00261     kdDebug() << "KexiRelationViewConnection::matchesPoint(): u: " << u << endl;
00262 
00263     float iX = x1 + u * (x2 - x1);
00264     float iY = y1 + u * (y2 - y1);
00265     kdDebug() << "KexiRelationViewConnection::matchesPoint(): px: " << p.x() << endl;
00266     kdDebug() << "KexiRelationViewConnection::matchesPoint(): py: " << p.y() << endl;
00267     kdDebug() << "KexiRelationViewConnection::matchesPoint(): ix: " << iX << endl;
00268     kdDebug() << "KexiRelationViewConnection::matchesPoint(): iy: " << iY << endl;
00269 
00270     float dX = iX - p.x();
00271     float dY = iY - p.y();
00272 
00273     kdDebug() << "KexiRelationViewConnection::matchesPoint(): dx: " << dX << endl;
00274     kdDebug() << "KexiRelationViewConnection::matchesPoint(): dy: " << dY << endl;
00275 
00276     float distance = sqrt(dX * dX + dY * dY);
00277     kdDebug() << "KexiRelationViewConnection::matchesPoint(): distance: " << distance << endl;
00278 
00279     if(distance <= tolerance)
00280         return true;
00281 
00282     return false;
00283 }
00284 
00285 QString
00286 KexiRelationViewConnection::toString() const
00287 {
00288     QString str;
00290     if (m_masterTable && m_masterTable->schema()->table()) {
00291         str += (QString(m_masterTable->schema()->name()) + "." + m_masterField);
00292     }
00293     if (m_detailsTable && m_detailsTable->schema()->table()) {
00294         str += " - ";
00295         str += (QString(m_detailsTable->schema()->name()) + "." + m_detailsField);
00296     }
00297     return str;
00298 }
KDE Home | KDE Accessibility Home | Description of Access Keys