kivio

kivioconnectortool/tool_connector.cpp
1/*
2 * Kivio - Visual Modelling and Flowcharting
3 * Copyright (C) 2000-2001 theKompany.com & Dave Marotti
4 * Copyright (C) 2003-2005 Peter Simonsson <psn@linux.se>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20#include "tool_connector.h"
21
22#include <tqcursor.h>
23#include <kdebug.h>
24#include <kiconloader.h>
25#include <kstandarddirs.h>
26#include <KoPoint.h>
27#include <KoZoomHandler.h>
28#include <tdelocale.h>
29#include <KoGuides.h>
30
31#include "kivio_view.h"
32#include "kivio_canvas.h"
33#include "kivio_page.h"
34#include "kivio_doc.h"
35#include "kivio_factory.h"
36
37#include "kivio_stencil_spawner_set.h"
38#include "kivio_stencil_spawner.h"
39#include "kivio_custom_drag_data.h"
40#include "kivio_layer.h"
41#include "kivio_point.h"
42#include "kivio_stencil.h"
43#include "straight_connector.h"
44#include "kivio_pluginmanager.h"
45#include "kivio_1d_stencil.h"
46#include "kiviopolylineconnector.h"
47#include "polylineconnectorspawner.h"
48#include "mousetoolaction.h"
49
50ConnectorTool::ConnectorTool( KivioView* parent ) : Kivio::MouseTool(parent, "Connector Mouse Tool")
51{
52 m_connectorAction = new Kivio::MouseToolAction(i18n("Straight Connector"), "kivio_connector", 0,
53 actionCollection(), "connector");
54 connect(m_connectorAction, TQ_SIGNAL(toggled(bool)), this, TQ_SLOT(setActivated(bool)));
55 connect(m_connectorAction, TQ_SIGNAL(activated()), this, TQ_SLOT(activateStraight()));
56 connect(m_connectorAction, TQ_SIGNAL(doubleClicked()), this, TQ_SLOT(makePermanent()));
57 m_connectorAction->setExclusiveGroup("ConnectorTool");
58
59 m_polyLineAction = new Kivio::MouseToolAction(i18n("Polyline Connector"), "kivio_connector", 0,
60 actionCollection(), "polyLineConnector");
61 connect(m_polyLineAction, TQ_SIGNAL(toggled(bool)), this, TQ_SLOT(setActivated(bool)));
62 connect(m_polyLineAction, TQ_SIGNAL(activated()), this, TQ_SLOT(activatePolyline()));
63 connect(m_connectorAction, TQ_SIGNAL(doubleClicked()), this, TQ_SLOT(makePermanent()));
64 m_polyLineAction->setExclusiveGroup("ConnectorTool");
65
66 m_permanent = false;
67
68 m_type = StraightConnector;
69 m_mode = stmNone;
70 m_pDragData = 0;
71
72 m_pConnectorCursor1 = new TQCursor(BarIcon("kivio_connector_cursor1",KivioFactory::global()),2,2);
73 m_pConnectorCursor2 = new TQCursor(BarIcon("kivio_connector_cursor2",KivioFactory::global()),2,2);
74}
75
76ConnectorTool::~ConnectorTool()
77{
78 delete m_pConnectorCursor1;
79 delete m_pConnectorCursor2;
80 delete m_pDragData;
81 m_pDragData = 0;
82}
83
84
91bool ConnectorTool::processEvent(TQEvent* e)
92{
93 switch (e->type())
94 {
95 case TQEvent::MouseButtonPress:
96 mousePress( static_cast<TQMouseEvent*>(e) );
97 return true;
98 break;
99
100 case TQEvent::MouseButtonRelease:
101 mouseRelease( static_cast<TQMouseEvent*>(e) );
102 return true;
103 break;
104
105 case TQEvent::MouseMove:
106 mouseMove( static_cast<TQMouseEvent*>(e) );
107 return true;
108 break;
109
110 default:
111 break;
112 }
113
114 return false;
115}
116
117void ConnectorTool::setActivated(bool a)
118{
119 if(a) {
120 view()->canvasWidget()->setCursor(*m_pConnectorCursor1);
121 m_mode = stmNone;
122 m_pStencil = 0;
123 m_pDragData = 0;
124 view()->canvasWidget()->setShowConnectorTargets(true);
125 view()->canvasWidget()->repaint();
126 emit activated(this);
127 } else {
128 if(m_pStencil && (m_mode == stmDrawRubber) && (m_type == PolyLineConnector)) {
129 Kivio::PolyLineConnector* polyconnector = static_cast<Kivio::PolyLineConnector*>(m_pStencil);
130 polyconnector->removeLastPoint();
131
132 if(polyconnector->pointCount() > 1) {
133 connector(view()->canvasWidget()->rect());
134 } else {
135 view()->activePage()->unselectStencil(polyconnector);
136 view()->activePage()->curLayer()->takeStencil(polyconnector);
137 delete polyconnector;
138 polyconnector = 0;
139 }
140
141 view()->canvasWidget()->guideLines().repaintAfterSnapping();
142 }
143
144 m_pStencil = 0;
145 delete m_pDragData;
146 m_pDragData = 0;
147 m_type = StraightConnector;
148 m_connectorAction->setChecked(false);
149 m_polyLineAction->setChecked(false);
150 m_permanent = false;
151 view()->setStatusBarInfo("");
152 view()->canvasWidget()->setShowConnectorTargets(false);
153 view()->canvasWidget()->repaint();
154 }
155}
156
157void ConnectorTool::connector(TQRect)
158{
159 if (!m_pStencil)
160 return;
161
162 delete m_pDragData;
163 m_pDragData = 0;
164
165 KivioDoc* doc = view()->doc();
166 KivioPage* page = view()->activePage();
167
168 m_pStencil->searchForConnections(page, view()->zoomHandler()->unzoomItY(4));
169 doc->updateView(page);
170}
171
172void ConnectorTool::mousePress( TQMouseEvent *e )
173{
174 if(e->button() == TQt::LeftButton) {
175 bool ok = true;
176 if(!m_pStencil || (m_type == StraightConnector)) {
177 ok = startRubberBanding(e);
178 } else {
179 if(m_pStencil) {
180 Kivio::PolyLineConnector* connector = static_cast<Kivio::PolyLineConnector*>(m_pStencil);
181 KivioCanvas* canvas = view()->canvasWidget();
182 KivioPage* pPage = canvas->activePage();
183 bool hit = false;
184 KoPoint point = pPage->snapToTarget(canvas->mapFromScreen(e->pos()), 8.0, hit);
185
186 if(!hit) {
187 point = canvas->snapToGrid(startPoint);
188 }
189
190 if((m_mode == stmDrawRubber) && hit) {
191 endRubberBanding(e);
192 } else {
193 connector->addPoint(point);
194 }
195 }
196 }
197
198 if(ok) {
199 m_mode = stmDrawRubber;
200 } else {
201 m_mode = stmNone;
202 }
203 } else if(e->button() == TQt::RightButton) {
204 if(m_type == PolyLineConnector) {
205 if(m_mode == stmDrawRubber) {
206 endRubberBanding(e);
207 }
208
209 view()->canvasWidget()->setCursor(*m_pConnectorCursor1);
210 m_mode = stmNone;
211 }
212 }
213}
214
215
219bool ConnectorTool::startRubberBanding( TQMouseEvent *e )
220{
221 KivioCanvas* canvas = view()->canvasWidget();
222 KivioDoc* doc = view()->doc();
223 KivioPage* pPage = canvas->activePage();
224 TQString spawnerId;
225
226 if(m_type == StraightConnector) {
227 spawnerId = "Dave Marotti - Straight Connector";
228 } else {
229 spawnerId = "Internal - PolyLine Connector";
230 }
231
232 KivioStencilSpawner* ss = doc->findInternalStencilSpawner(spawnerId);
233
234 if(!ss) {
235 kdDebug(43000) << "ConnectorTool: Failed to find StencilSpawner!" << endl;
236 return false;
237 }
238
239 // Create the stencil
240 m_pStencil = static_cast<Kivio1DStencil*>(ss->newStencil());
241
242 bool hit = false;
243 startPoint = pPage->snapToTarget(canvas->mapFromScreen(e->pos()), 8.0, hit);
244
245 if(!hit) {
246 startPoint = canvas->snapToGrid(startPoint);
247 }
248
249
250 if(!m_pStencil) {
251 return false;
252 }
253
254 m_pStencil->setTextFont(doc->defaultFont());
255
256 // Unselect everything, add the stencil to the page, and select it
257 pPage->unselectAllStencils();
258 pPage->addStencil(m_pStencil);
259 pPage->selectStencil(m_pStencil);
260 // Get drag info ready
261 m_pDragData = new KivioCustomDragData();
262 m_pDragData->page = pPage;
263 m_pDragData->x = startPoint.x();
264 m_pDragData->y = startPoint.y();
265
266 if(m_type == StraightConnector) {
267 KivioStraightConnector* connector = static_cast<KivioStraightConnector*>(m_pStencil);
268 m_pDragData->id = kctCustom + 2;
269
270 connector->setStartPoint(startPoint.x(), startPoint.y());
271 connector->setEndPoint(startPoint.x() + 10.0, startPoint.y() + 10.0);
272 } else {
273 Kivio::PolyLineConnector* connector = static_cast<Kivio::PolyLineConnector*>(m_pStencil);
274 m_pDragData->id = kctCustom + 1;
275 connector->addPoint(startPoint);
276 connector->addPoint(startPoint);
277 }
278
279 m_pStencil->customDrag(m_pDragData);
280
281 canvas->repaint();
282 canvas->setCursor(*m_pConnectorCursor2);
283 return true;
284}
285
286void ConnectorTool::mouseMove( TQMouseEvent * e )
287{
288 switch( m_mode )
289 {
290 case stmDrawRubber:
291 continueRubberBanding(e);
292 break;
293
294 default:
295 break;
296 }
297}
298
299void ConnectorTool::continueRubberBanding( TQMouseEvent *e )
300{
301 KivioCanvas* canvas = view()->canvasWidget();
302 KivioPage* pPage = view()->activePage();
303 bool hit = false;
304 KoPoint endPoint = pPage->snapToTarget(canvas->mapFromScreen(e->pos()), 8.0, hit);
305
306 if(!hit) {
307 endPoint = canvas->snapToGridAndGuides(endPoint);
308 }
309
310 m_pDragData->x = endPoint.x();
311 m_pDragData->y = endPoint.y();
312
313 if(m_type == StraightConnector) {
314 KivioStraightConnector* connector = static_cast<KivioStraightConnector*>(m_pStencil);
315 connector->setEndPoint(endPoint.x(), endPoint.y());
316
317 m_pDragData->id = kctCustom + 2;
318 } else {
319 Kivio::PolyLineConnector* connector = static_cast<Kivio::PolyLineConnector*>(m_pStencil);
320 m_pDragData->id = kctCustom + connector->pointCount();
321 }
322
323 m_pStencil->customDrag(m_pDragData);
324 m_pStencil->updateGeometry();
325 canvas->repaint();
326}
327
328void ConnectorTool::mouseRelease( TQMouseEvent *e )
329{
330 if(m_type == StraightConnector) {
331 switch( m_mode )
332 {
333 case stmDrawRubber:
334 endRubberBanding(e);
335 break;
336 }
337
338 view()->canvasWidget()->setCursor(*m_pConnectorCursor1);
339 m_mode = stmNone;
340 }
341}
342
343void ConnectorTool::endRubberBanding(TQMouseEvent *)
344{
345 connector(view()->canvasWidget()->rect());
346 m_pStencil = 0;
347 m_mode = stmNone;
348 view()->canvasWidget()->guideLines().repaintAfterSnapping();
349
350 if(!m_permanent) {
351 view()->pluginManager()->activateDefaultTool();
352 }
353}
354
355void ConnectorTool::activateStraight()
356{
357 m_type = StraightConnector;
358 m_connectorAction->setChecked(true);
359 m_polyLineAction->setChecked(false);
360}
361
362void ConnectorTool::activatePolyline()
363{
364 m_type = PolyLineConnector;
365 m_connectorAction->setChecked(false);
366 m_polyLineAction->setChecked(true);
367 view()->setStatusBarInfo(i18n("Left mouse button to start drawing, right to end drawing."));
368}
369
370void ConnectorTool::makePermanent()
371{
372 m_permanent = true;
373}
374
375#include "tool_connector.moc"
Baseclass for mouse tools (like eg the select tool).
void activated(Kivio::MouseTool *)
this should be emited when the tool wants to be active