kexi

kexirelationviewconnection.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2004 Lucijan Busch <lucijan@kde.org>
3 Copyright (C) 2004-2005 Jaroslaw Staniek <js@iidea.pl>
4
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this program; see the file COPYING. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19*/
20
21#include <tqpainter.h>
22#include <tqpixmap.h>
23#include <tqcolor.h>
24#include <tqapplication.h>
25#include <tqpointarray.h>
26
27#include <kdebug.h>
28
29#include <math.h>
30
31#include "kexirelationview.h"
32#include "kexirelationviewtable.h"
33#include "kexirelationviewconnection.h"
34#include <kexidb/tableschema.h>
35#include <kexidb/utils.h>
36#include <core/kexi.h>
37
38//#include "r1.xpm"
39//#include "rn.xpm"
40
41KexiRelationViewConnection::KexiRelationViewConnection(
42 KexiRelationViewTableContainer *masterTbl, KexiRelationViewTableContainer *detailsTbl,
43 SourceConnection &c, KexiRelationView *parent)
44{
45 m_parent = parent;
46// kdDebug() << "KexiRelationViewConnection::KexiRelationViewConnection()" << endl;
47
48 m_masterTable = masterTbl;
49 if(!masterTbl || !detailsTbl)
50 {
51 kdDebug() << "KexiRelationViewConnection::KexiRelationViewConnection(): expect sig11" << endl;
52 kdDebug() << "KexiRelationViewConnection::KexiRelationViewConnection()" << masterTbl << endl;
53 kdDebug() << "KexiRelationViewConnection::KexiRelationViewConnection()" << detailsTbl << endl;
54 }
55
56 m_detailsTable = detailsTbl;
57 m_masterField = c.masterField;
58 m_detailsField = c.detailsField;
59
60 m_selected = false;
61}
62
63KexiRelationViewConnection::~KexiRelationViewConnection()
64{
65}
66
67void
68KexiRelationViewConnection::drawConnection(TQPainter *p)
69{
70 p->setPen(m_parent->palette().active().foreground());
71 int sx = m_masterTable->x() + m_masterTable->width() + m_parent->contentsX();
72 int sy = m_masterTable->globalY(m_masterField);
73 int rx = m_detailsTable->x() + m_parent->contentsX();
74 int ry = m_detailsTable->globalY(m_detailsField);
75
76 TQFont f( Kexi::smallFont( m_parent ) );
77 TQFontMetrics fm(f);
78 int side1x=0, side1y=sy - fm.height(),
79 sideNx=0, sideNy=ry - fm.height();
81 TQChar sideNChar(0x221E); //infinity char
82 uint sideNCharWidth = 2+2+ fm.width( sideNChar );
83 TQChar side1Char('1');
84 uint side1CharWidth = 2+2+ fm.width( side1Char );
85 p->setBrush(p->pen().color());
86
87 if(m_masterTable->x() < m_detailsTable->x())
88 {
89 //det. side
90 p->drawLine(rx - sideNCharWidth, ry, rx, ry);
91 TQPointArray pa(3);
92 pa.setPoint(0, rx - 4, ry - 3);
93 pa.setPoint(1, rx - 4, ry + 3);
94 pa.setPoint(2, rx - 1, ry);
95 p->drawPolygon(pa, true);
96
97 //master side
98 p->drawLine(sx, sy - 1, sx + side1CharWidth -1, sy - 1);
99 p->drawLine(sx, sy, sx + side1CharWidth -1, sy);
100 p->drawLine(sx, sy + 1, sx + side1CharWidth -1, sy + 1);
101
102 side1x = sx;
103// side1y = sy - 7;
104
105 sideNx = rx - sideNCharWidth - 1;
106// sideNy = ry - 6;
107
108 TQPen pen(p->pen());
109 if(m_selected)
110 {
111 TQPen pen(p->pen());
112 pen.setWidth(2);
113 p->setPen(pen);
114 }
115
116 p->drawLine(sx + side1CharWidth, sy, rx - sideNCharWidth, ry);
117
118 if(m_selected)
119 {
120 TQPen pen(p->pen());
121 pen.setWidth(1);
122 p->setPen(pen);
123 }
124
125 }
126 else
127 {
128 int lx = rx + m_detailsTable->width();
129 int rx = sx - m_masterTable->width();
130
131 //det. side
132 p->drawLine(lx, ry, lx + sideNCharWidth, ry);
133 TQPointArray pa(3);
134 pa.setPoint(0, lx + 3, ry - 3);
135 pa.setPoint(1, lx + 3, ry + 3);
136 pa.setPoint(2, lx, ry);
137 p->drawPolygon(pa, true);
138
139// p->drawLine(lx, ry, lx + 8, ry);
140// p->drawPoint(lx + 1, ry - 1);
141// p->drawPoint(lx + 1, ry + 1);
142// p->drawLine(lx + 2, ry - 2, lx + 2, ry + 2);
143
144 //master side
145 p->drawLine(rx - side1CharWidth +1, sy - 1, rx, sy - 1);
146 p->drawLine(rx - side1CharWidth +1, sy + 1, rx, sy + 1);
147 p->drawLine(rx - side1CharWidth +1, sy, rx, sy);
148
149 side1x = rx - side1CharWidth;
150// side1y = sy - 7;
151
152 sideNx = lx + 1;
153// sideNy = ry - 6;
154
155 if(m_selected)
156 {
157 TQPen pen(p->pen());
158 pen.setWidth(2);
159 p->setPen(pen);
160 }
161
162 p->drawLine(lx + sideNCharWidth, ry, rx - side1CharWidth, sy);
163
164 if(m_selected)
165 {
166 TQPen pen(p->pen());
167 pen.setWidth(1);
168 p->setPen(pen);
169 }
170 }
171
172 p->drawText(side1x, side1y, side1CharWidth, fm.height(), TQt::AlignCenter, side1Char);
173 p->drawText(sideNx, sideNy, sideNCharWidth, fm.height(), TQt::AlignCenter, sideNChar);
174 //p->drawRect(TQRect(connectionRect().topLeft(), TQSize(50,50)));
175// p->drawPixmap(side1, TQPixmap(r1_xpm));
176// p->drawPixmap(sideN, TQPixmap(rn_xpm));
177}
178
179const TQRect
180KexiRelationViewConnection::connectionRect()
181{
182 int sx = m_masterTable->x() + m_parent->contentsX();
183 int rx = m_detailsTable->x() + m_parent->contentsX();
184 int ry = m_detailsTable->globalY(m_detailsField);
185 int sy = m_masterTable->globalY(m_masterField);
186
187 int width, leftX, rightX;
188
189 if(sx < rx)
190 {
191 leftX = sx;
192 rightX = rx;
193 width = m_masterTable->width();
194 }
195 else
196 {
197 leftX = rx;
198 rightX = sx;
199 width = m_detailsTable->width();
200 }
201
202
203 int dx = TQABS((leftX + width) - rightX);
204 int dy = TQABS(sy - ry) + 2;
205
206 int top = TQMIN(sy, ry);
207 int left = leftX + width;
208
209
210// return TQRect(sx - 1, sy - 1, (rx + m_detailsTable->width()) - sx + 1, ry - sy + 1);
211 TQRect rect(left - 150, top - 150, dx + 150, dy + 150);
212// kdDebug() << "KexiRelationViewConnection::connectionRect():" << m_oldRect << "," << rect << endl;
213
214 m_oldRect = rect;
215
216 return rect;
217}
218
219bool
220KexiRelationViewConnection::matchesPoint(const TQPoint &p, int tolerance)
221{
222 TQRect we = connectionRect();
223
224 if(!we.contains(p))
225 return false;
226
233
234 int sx = m_masterTable->x() + m_masterTable->width();
235 int sy = m_masterTable->globalY(m_masterField);
236 int rx = m_detailsTable->x();
237 int ry = m_detailsTable->globalY(m_detailsField);
238
239 int x1 = sx + 8;
240 int y1 = sy;
241 int x2 = rx - 8;
242 int y2 = ry;
243
244 if(sx > rx)
245 {
246 x1 = m_detailsTable->x() + m_detailsTable->width();
247 x2 = m_masterTable->x();
248 y2 = sy;
249 y1 = ry;
250 }
251
252 /*
253 here we call pythagoras (the greek math geek :p)
254 see: http://w1.480.telia.com/%7Eu48019406/geekporn.gif if you don't know
255 how these people have got sex :)
256 */
257 float mx = x2-x1;
258 float my = y2-y1;
259 float mag = sqrt(mx * mx + my * my);
260 float u = (((p.x() - x1)*(x2 - x1))+((p.y() - y1)*(y2 - y1)))/(mag * mag);
261 kdDebug() << "KexiRelationViewConnection::matchesPoint(): u: " << u << endl;
262
263 float iX = x1 + u * (x2 - x1);
264 float iY = y1 + u * (y2 - y1);
265 kdDebug() << "KexiRelationViewConnection::matchesPoint(): px: " << p.x() << endl;
266 kdDebug() << "KexiRelationViewConnection::matchesPoint(): py: " << p.y() << endl;
267 kdDebug() << "KexiRelationViewConnection::matchesPoint(): ix: " << iX << endl;
268 kdDebug() << "KexiRelationViewConnection::matchesPoint(): iy: " << iY << endl;
269
270 float dX = iX - p.x();
271 float dY = iY - p.y();
272
273 kdDebug() << "KexiRelationViewConnection::matchesPoint(): dx: " << dX << endl;
274 kdDebug() << "KexiRelationViewConnection::matchesPoint(): dy: " << dY << endl;
275
276 float distance = sqrt(dX * dX + dY * dY);
277 kdDebug() << "KexiRelationViewConnection::matchesPoint(): distance: " << distance << endl;
278
279 if(distance <= tolerance)
280 return true;
281
282 return false;
283}
284
285TQString
286KexiRelationViewConnection::toString() const
287{
288 TQString str;
290 if (m_masterTable && m_masterTable->schema()->table()) {
291 str += (TQString(m_masterTable->schema()->name()) + "." + m_masterField);
292 }
293 if (m_detailsTable && m_detailsTable->schema()->table()) {
294 str += " - ";
295 str += (TQString(m_detailsTable->schema()->name()) + "." + m_detailsField);
296 }
297 return str;
298}
provides a view for displaying relations between database tables.
KEXICORE_EXPORT TQFont smallFont(TQWidget *init=0)
Definition kexi.cpp:143