kivio

stencilbardockmanager.cpp
1/*
2 * Kivio - Visual Modelling and Flowcharting
3 * Copyright (C) 2000-2001 theKompany.com & Dave Marotti
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * 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
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19#include "kivio_doc.h"
20#include "stencilbardockmanager.h"
21#include "stencilbarbutton.h"
22#include "kivio_stackbar.h"
23#include "kivio_view.h"
24
25#include <tqcursor.h>
26#include <tqvaluelist.h>
27#include <tqapplication.h>
28#include <tqwindowdefs.h>
29#include <tqtimer.h>
30#include <tqrect.h>
31#include <tqframe.h>
32#include <tqpainter.h>
33
34#include <tdelocale.h>
35#include <kdebug.h>
36
37StencilBarDockManager::StencilBarDockManager( KivioView* parent, const char* name )
38: TQWidget(parent,name)
39{
40 dragButton = 0L;
41 dragWidget = 0L;
42 m_pView = parent;
43 m_destinationBar = 0L;
44 dragPos = OnDesktop;
45
46 m_pBars.setAutoDelete(true);
47
48 m_pDoc = m_pView->doc();
49 connect(m_pDoc, TQ_SIGNAL(sig_deleteStencilSet(DragBarButton*, TQWidget*, KivioStackBar*)), this,
50 TQ_SLOT(slotDeleteStencilSet(DragBarButton*, TQWidget*, KivioStackBar*)));
51
52 moveManager = new KoToolDockMoveManager();
53 connect(moveManager,TQ_SIGNAL(positionChanged()),TQ_SLOT(slotMoving()));
54}
55
56StencilBarDockManager::~StencilBarDockManager()
57{
58 delete moveManager;
59}
60
61void StencilBarDockManager::insertStencilSet( TQWidget* w, const TQString& caption,
62 BarPos pos, TQRect /*r*/, KivioStackBar* destinationBar )
63{
64 KivioStackBar* bar = 0L;
65
66 if(destinationBar) {
67 bar = destinationBar;
68 } else {
69 TQt::Dock position = TQt::DockLeft;
70
71 if ( pos == AutoSelect ) {
72 pos = Left;
73 }
74
75 switch (pos) {
76 case OnDesktop:
77 position = TQt::DockTornOff;
78 break;
79 case Left:
80 {
81 TQPtrList<TQDockWindow> dockList = m_pView->mainWindow()->dockWindows(TQt::DockLeft);
82
83 for(TQDockWindow* dock = dockList.first(); dock; dock = dockList.next()) {
84 if(::tqt_cast<KivioStackBar*>(dock) && (static_cast<KivioStackBar*>(dock)->view() == m_pView)) {
85 bar = static_cast<KivioStackBar*>(dock);
86 break;
87 }
88 }
89
90 position = TQt::DockLeft;
91 break;
92 }
93 case Top:
94 {
95 TQPtrList<TQDockWindow> dockList = m_pView->mainWindow()->dockWindows(TQt::DockTop);
96
97 for(TQDockWindow* dock = dockList.first(); dock; dock = dockList.next()) {
98 if(::tqt_cast<KivioStackBar*>(dock) && (static_cast<KivioStackBar*>(dock)->view() == m_pView)) {
99 bar = static_cast<KivioStackBar*>(dock);
100 break;
101 }
102 }
103
104 position = TQt::DockTop;
105 break;
106 }
107 case Right:
108 {
109 TQPtrList<TQDockWindow> dockList = m_pView->mainWindow()->dockWindows(TQt::DockRight);
110
111 for(TQDockWindow* dock = dockList.first(); dock; dock = dockList.next()) {
112 if(::tqt_cast<KivioStackBar*>(dock) && (static_cast<KivioStackBar*>(dock)->view() == m_pView)) {
113 bar = static_cast<KivioStackBar*>(dock);
114 break;
115 }
116 }
117
118 position = TQt::DockRight;
119 break;
120 }
121 case Bottom:
122 {
123 TQPtrList<TQDockWindow> dockList = m_pView->mainWindow()->dockWindows(TQt::DockBottom);
124
125 for(TQDockWindow* dock = dockList.first(); dock; dock = dockList.next()) {
126 if(::tqt_cast<KivioStackBar*>(dock) && (static_cast<KivioStackBar*>(dock)->view() == m_pView)) {
127 bar = static_cast<KivioStackBar*>(dock);
128 break;
129 }
130 }
131
132 position = TQt::DockBottom;
133 break;
134 }
135 case OnTopLevelBar: // hmm this shouldn't happen :)
136 position = TQt::DockTornOff;
137 break;
138 default:
139 break;
140 }
141
142 if (!bar) {
143 bar = new KivioStackBar(m_pView, m_pView->mainWindow());
144 m_pView->mainWindow()->moveDockWindow(bar, position);
145 m_pBars.append(bar);
146 connect(bar,TQ_SIGNAL(beginDragPage(DragBarButton*)),TQ_SLOT(slotBeginDragPage(DragBarButton*)));
147 connect(bar,TQ_SIGNAL(finishDragPage(DragBarButton*)),TQ_SLOT(slotFinishDragPage(DragBarButton*)));
148 connect(bar,TQ_SIGNAL(deleteButton(DragBarButton*,TQWidget*,KivioStackBar*)),
149 m_pDoc, TQ_SLOT(slotDeleteStencilSet(DragBarButton*,TQWidget*,KivioStackBar*)));
150 }
151 }
152
153 bar->insertPage(w,caption);
154 bar->showPage(w);
155 bar->show();
156}
157
158void StencilBarDockManager::slotBeginDragPage( DragBarButton* w )
159{
160 m_destinationBar = 0L;
161 dragButton = w;
162 dragWidget = ((KivioStackBar*)sender())->findPage(dragButton);
163 dragButton->setUpdatesEnabled(false);
164 dragWidget->setUpdatesEnabled(false);
165 dragPos = OnDesktop;
166 moveManager->doMove(dragButton);
167}
168
169void StencilBarDockManager::slotFinishDragPage( DragBarButton* )
170{
171 moveManager->stop();
172 dragButton->setUpdatesEnabled(true);
173 dragButton->update();
174
175 dragWidget->setUpdatesEnabled(true);
176 dragWidget->update();
177
178 TQString caption(dragButton->text());
179 KivioStackBar* bar = (KivioStackBar*)sender();
180 bar->removePage(dragWidget);
181
182 insertStencilSet(dragWidget,caption,dragPos,moveManager->geometry(),m_destinationBar);
183
184 // remove KivioStackBar if no more pages
185 if (!bar->visiblePage()) {
186 int k = m_pBars.findRef(bar);
187
188 if ( k!= -1 ) {
189 m_pBars.remove(k);
190 m_pBars.insert(k,0L);
191 }
192 }
193
194 dragButton = 0L;
195 dragWidget = 0L;
196 m_destinationBar = 0L;
197}
198
199
200void StencilBarDockManager::slotMoving()
201{
202 m_destinationBar = 0L;
203 TQPoint p = TQCursor::pos();
204 TQPoint globalPos;
205
206 // check existing bars
207 for ( KivioStackBar* bar = m_pBars.first(); bar; bar = m_pBars.next() ) {
208 if ( bar->geometry().contains(p) ) {
209 if(bar->place() == TQDockWindow::OutsideDock) {
210 dragPos = OnTopLevelBar;
211 globalPos = bar->geometry().topLeft();
212 } else {
213 dragPos = AutoSelect;
214 globalPos = bar->mapToGlobal(bar->geometry().topLeft());
215 }
216
217 m_destinationBar = bar;
218 moveManager->movePause(true,false);
219 moveManager->setGeometry(globalPos.x(),
220 moveManager->y(),
221 bar->width(),
222 moveManager->getWidget()->sizeHint().height());
223 return;
224 }
225 }
226
227 // check "on mainView"
228 TQRect mr(m_pView->mapToGlobal(TQPoint(0,0)),m_pView->size());
229
230 if ( mr.contains(p) ) {
231 TQRect r(mr);
232 r.setWidth(r.width()/4);
233 if ( r.contains(p) && !m_pBars.at(Left) ) {
234 moveManager->movePause();
235 moveManager->setGeometry(r);
236 dragPos = Left;
237 return;
238 }
239
240 r.moveBy(r.width()*3,0);
241
242 if ( r.contains(p) && !m_pBars.at(Right) ) {
243 moveManager->movePause();
244 moveManager->setGeometry(r);
245 dragPos = Right;
246 return;
247 }
248
249 TQRect t(mr);
250
251 t.setHeight(t.height()/4);
252 if ( t.contains(p) && !m_pBars.at(Top) ) {
253 moveManager->movePause();
254 moveManager->setGeometry(t);
255 dragPos = Top;
256 return;
257 }
258
259 t.moveBy(0,t.height()*3);
260
261 if ( t.contains(p) && !m_pBars.at(Bottom) ) {
262 moveManager->movePause();
263 moveManager->setGeometry(t);
264 dragPos = Bottom;
265 return;
266 }
267 }
268
269 // on desktop
270 moveManager->resize(dragWidget->size());
271 moveManager->movePause(false,false);
272 dragPos = OnDesktop;
273}
274
275void StencilBarDockManager::slotDeleteStencilSet( DragBarButton* pBtn, TQWidget *, KivioStackBar *pBar )
276{
277 pBar->deletePageAndButton(pBtn);
278
279 // remove KivioStackBar if no more pages
280 if (!pBar->visiblePage()) {
281 int k = m_pBars.findRef(pBar);
282
283 if ( k!= -1 ) {
284 m_pBars.remove(k);
285 pBar = 0;
286 } else {
287 delete pBar;
288 pBar = 0;
289 }
290 }
291}
292
293void StencilBarDockManager::setAllStackBarsShown(bool shown)
294{
295 for(KivioStackBar* bar = m_pBars.first(); bar; bar = m_pBars.next()) {
296 if(shown) {
297 bar->show();
298 } else {
299 bar->hide();
300 }
301 }
302}
303
304//
305// KoToolDockMoveManager
306//
307
308KoToolDockMoveManager::KoToolDockMoveManager()
309 : TQObject()
310{
311#if defined TQ_WS_X11 && !defined K_WS_TQTONLY
312 XGCValues gv;
313#endif
314
315 working=false;
316 noLast=true;
317
318#if defined TQ_WS_X11 && !defined K_WS_TQTONLY
319 scr = tqt_xscreen();
320 root = tqt_xrootwin();
321
322 gv.function = GXxor;
323 gv.line_width = 2;
324 gv.foreground = WhitePixel(tqt_xdisplay(), scr)^BlackPixel(tqt_xdisplay(), scr);
325 gv.subwindow_mode = IncludeInferiors;
326 long mask = GCForeground | GCFunction | GCLineWidth | GCSubwindowMode;
327 rootgc = XCreateGC(tqt_xdisplay(), tqt_xrootwin(), mask, &gv);
328#endif
329
330 timer = new TQTimer(this);
331}
332
333KoToolDockMoveManager::~KoToolDockMoveManager()
334{
335 stop();
336 delete timer;
337}
338
339void KoToolDockMoveManager::doMove( TQWidget* _w )
340{
341 if (working)
342 return;
343
344 working=true;
345 isDoMove = true;
346 mirrorX=false;
347 mirrorY=false;
348
349 setWidget(_w);
350
351 offX = rx - p.x();
352 offY = ry - p.y();
353
354 orig_x = p.x();
355 orig_y = p.y();
356 orig_w = w;
357 orig_h = h;
358
359 TQApplication::setOverrideCursor(TQCursor(sizeAllCursor));
360
361 movePause(false,false);
362
363 drawRectangle(xp, yp, w, h);
364
365 timer->disconnect();
366 connect(timer,TQ_SIGNAL(timeout()),TQ_SLOT(doMoveInternal()));
367 timer->start(0);
368}
369
370void KoToolDockMoveManager::doMoveInternal()
371{
372 if ( !working )
373 return;
374
375 if (!pauseMoveX)
376 rx = TQCursor::pos().x();
377
378 if (!pauseMoveY)
379 ry = TQCursor::pos().y();
380
381 xp = rx - offX;
382 yp = ry - offY;
383
384 emit positionChanged();
385
386 if (check(xp, yp, w, h)) {
387 paintProcess(false,xp, yp, w, h);
388
389#if defined TQ_WS_X11 && !defined K_WS_TQTONLY
390 XFlush(tqt_xdisplay());
391 XSync(tqt_xdisplay(),false);
392#endif
393 }
394}
395
396void KoToolDockMoveManager::stop()
397{
398 if (!working)
399 return;
400
401 timer->stop();
402 TQApplication::restoreOverrideCursor();
403
404 paintProcess();
405#if defined TQ_WS_X11 && !defined K_WS_TQTONLY
406 XFlush(tqt_xdisplay());
407#endif
408
409 working = false;
410}
411
412void KoToolDockMoveManager::setGeometry( const TQRect& r )
413{
414 setGeometry(r.x(),r.y(),r.width(),r.height());
415}
416
417void KoToolDockMoveManager::setGeometry(int _x, int _y, int _w, int _h)
418{
419 xp=_x;
420 yp=_y;
421 w=_w;
422 h=_h;
423
424 check(_x, _y, _w, _h, true);
425 paintProcess(false,_x, _y, _w, _h);
426
427#if defined TQ_WS_X11 && !defined K_WS_TQTONLY
428 XFlush(tqt_xdisplay());
429 XSync(tqt_xdisplay(),false);
430#endif
431}
432
433void KoToolDockMoveManager::drawRectangle( int _x, int _y, int _w, int _h)
434{
435 if (!noLast)
436 return;
437
438 ox = _x;
439 oy = _y;
440 ow = _w;
441 oh = _h;
442
443#if defined TQ_WS_X11 && !defined K_WS_TQTONLY
444 XDrawRectangle(tqt_xdisplay(), root, rootgc, _x, _y, _w, _h);
445#endif
446 noLast = false;
447}
448
449void KoToolDockMoveManager::paintProcess( bool onlyDelete, int _x, int _y, int _w, int _h )
450{
451 if (noLast && onlyDelete)
452 return;
453
454 if ( ox == _x && oy == _y && ow ==_w && oh == _h )
455 return;
456
457#if defined TQ_WS_X11 && !defined K_WS_TQTONLY
458 XDrawRectangle(tqt_xdisplay(), root, rootgc, ox, oy, ow, oh);
459#endif
460 noLast = true;
461
462 drawRectangle(_x,_y,_w,_h);
463}
464
465void KoToolDockMoveManager::movePause( bool horizontal, bool vertical )
466{
467 pauseMoveX = horizontal;
468 pauseMoveY = vertical;
469}
470
471void KoToolDockMoveManager::moveContinue()
472{
473 pauseMoveX = false;
474 pauseMoveY = false;
475}
476
477void KoToolDockMoveManager::doXResize( TQWidget* w, bool mirror )
478{
479 if (working)
480 return;
481
482 mirrorX = mirror;
483 mirrorY = false;
484
485 yOnly = false;
486 xOnly = true;
487
488 doResize(w);
489}
490
491void KoToolDockMoveManager::doYResize( TQWidget* w, bool mirror )
492{
493 if (working)
494 return;
495
496 mirrorX = false;
497 mirrorY = mirror;
498
499 yOnly = true;
500 xOnly = false;
501
502 doResize(w);
503}
504
505void KoToolDockMoveManager::doXYResize( TQWidget* w, bool _mirrorX, bool _mirrorY )
506{
507 if (working)
508 return;
509
510 mirrorX = _mirrorX;
511 mirrorY = _mirrorY;
512
513 yOnly = false;
514 xOnly = false;
515
516 doResize(w);
517}
518
519void KoToolDockMoveManager::doResizeInternal()
520{
521 if (!yOnly)
522 rx = TQCursor::pos().x();
523
524 if (!xOnly)
525 ry = TQCursor::pos().y();
526
527 int dx = rx - sx;
528 int dy = ry - sy;
529
530 if ( mirrorX ){
531 w = rr.width() - dx;
532 xp = rr.x() + dx;
533 } else {
534 w = rr.width() + dx;
535 }
536
537 if ( mirrorY ){
538 h = rr.height() - dy;
539 yp = rr.y() + dy;
540 } else {
541 h = rr.height() + dy;
542 }
543
544 emit sizeChanged();
545
546 if (check(xp, yp, w, h)) {
547 paintProcess(false,xp, yp, w, h);
548
549#if defined TQ_WS_X11 && !defined K_WS_TQTONLY
550 XFlush(tqt_xdisplay());
551 XSync(tqt_xdisplay(),false);
552#endif
553 }
554}
555
556void KoToolDockMoveManager::setWidget( TQWidget* _w )
557{
558 widget = _w;
559 minSize = widget->minimumSize();
560 maxSize = widget->maximumSize();
561
562 rr = TQRect(widget->mapToGlobal(TQPoint(0,0)),widget->size());
563 p = rr.topLeft();
564
565 xp = rr.x();
566 yp = rr.y();
567 w = rr.width();
568 h = rr.height();
569
570 rx = TQCursor::pos().x();
571 ry = TQCursor::pos().y();
572}
573
574void KoToolDockMoveManager::doResize( TQWidget* _w )
575{
576 setWidget(_w);
577
578 working=true;
579 isDoMove = false;
580
581 TQPoint curPos = TQCursor::pos();
582 sx = curPos.x();
583 sy = curPos.y();
584
585 offX = sx - p.x();
586 offY = sy - p.y();
587
588 drawRectangle(xp, yp, w, h);
589
590 timer->disconnect();
591 connect(timer,TQ_SIGNAL(timeout()),TQ_SLOT(doResizeInternal()));
592 timer->start(0);
593}
594
595bool KoToolDockMoveManager::check(int& x, int& y, int& w, int& h, bool change)
596{
597
598 int w1 = TQMIN(TQMAX(minSize.width(), w), maxSize.width());
599 int h1 = TQMIN(TQMAX(minSize.height(), h), maxSize.height());
600
601 bool f1 = (w1-w)+(h1-h) == 0;
602
603 if (change) {
604 if (mirrorX)
605 x += w - w1;
606 w = w1;
607 if (mirrorY)
608 y += h - h1;
609 h = h1;
610 }
611
612 int x0 = x;
613 int y0 = y;
614 int w0 = w;
615 int h0 = h;
616
617 if (isDoMove)
618 emit fixPosition(x0,y0,w0,h0);
619 else
620 emit fixSize(x0,y0,w0,h0);
621
622 bool f2 = (x0==x)&&(y0==y)&&(w0==w)&&(h0==h);
623
624 if (change) {
625 x = x0;
626 y = y0;
627 w = w0;
628 h = h0;
629 }
630
631 return f1&&f2;
632}
633
634TQRect KoToolDockMoveManager::geometry()
635{
636 int x0 = xp;
637 int y0 = yp;
638 int w0 = w;
639 int h0 = h;
640 check(x0,y0,w0,h0,true);
641
642 return TQRect(x0,y0,w0,h0);
643}
644
645#include "stencilbardockmanager.moc"
The move manager handles moving tooldocks or other widgets that it can manage, such as the Kivio sten...