kivio

tool_connector.cpp

00001 /*
00002  * Kivio - Visual Modelling and Flowcharting
00003  * Copyright (C) 2000-2001 theKompany.com & Dave Marotti
00004  * Copyright (C) 2003-2005 Peter Simonsson <psn@linux.se>
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00019  */
00020 #include "tool_connector.h"
00021 
00022 #include <qcursor.h>
00023 #include <kdebug.h>
00024 #include <kiconloader.h>
00025 #include <kstandarddirs.h>
00026 #include <KoPoint.h>
00027 #include <KoZoomHandler.h>
00028 #include <klocale.h>
00029 #include <KoGuides.h>
00030 
00031 #include "kivio_view.h"
00032 #include "kivio_canvas.h"
00033 #include "kivio_page.h"
00034 #include "kivio_doc.h"
00035 #include "kivio_factory.h"
00036 
00037 #include "kivio_stencil_spawner_set.h"
00038 #include "kivio_stencil_spawner.h"
00039 #include "kivio_custom_drag_data.h"
00040 #include "kivio_layer.h"
00041 #include "kivio_point.h"
00042 #include "kivio_stencil.h"
00043 #include "straight_connector.h"
00044 #include "kivio_pluginmanager.h"
00045 #include "kivio_1d_stencil.h"
00046 #include "kiviopolylineconnector.h"
00047 #include "polylineconnectorspawner.h"
00048 #include "mousetoolaction.h"
00049 
00050 ConnectorTool::ConnectorTool( KivioView* parent ) : Kivio::MouseTool(parent, "Connector Mouse Tool")
00051 {
00052   m_connectorAction = new Kivio::MouseToolAction(i18n("Straight Connector"), "kivio_connector", 0,
00053     actionCollection(), "connector");
00054   connect(m_connectorAction, SIGNAL(toggled(bool)), this, SLOT(setActivated(bool)));
00055   connect(m_connectorAction, SIGNAL(activated()), this, SLOT(activateStraight()));
00056   connect(m_connectorAction, SIGNAL(doubleClicked()), this, SLOT(makePermanent()));
00057   m_connectorAction->setExclusiveGroup("ConnectorTool");
00058 
00059   m_polyLineAction = new Kivio::MouseToolAction(i18n("Polyline Connector"), "kivio_connector", 0,
00060     actionCollection(), "polyLineConnector");
00061   connect(m_polyLineAction, SIGNAL(toggled(bool)), this, SLOT(setActivated(bool)));
00062   connect(m_polyLineAction, SIGNAL(activated()), this, SLOT(activatePolyline()));
00063   connect(m_connectorAction, SIGNAL(doubleClicked()), this, SLOT(makePermanent()));
00064   m_polyLineAction->setExclusiveGroup("ConnectorTool");
00065 
00066   m_permanent = false;
00067 
00068   m_type = StraightConnector;
00069   m_mode = stmNone;
00070   m_pDragData = 0;
00071 
00072   m_pConnectorCursor1 = new QCursor(BarIcon("kivio_connector_cursor1",KivioFactory::global()),2,2);
00073   m_pConnectorCursor2 = new QCursor(BarIcon("kivio_connector_cursor2",KivioFactory::global()),2,2);
00074 }
00075 
00076 ConnectorTool::~ConnectorTool()
00077 {
00078   delete m_pConnectorCursor1;
00079   delete m_pConnectorCursor2;
00080   delete m_pDragData;
00081   m_pDragData = 0;
00082 }
00083 
00084 
00091 bool ConnectorTool::processEvent(QEvent* e)
00092 {
00093   switch (e->type())
00094   {
00095   case QEvent::MouseButtonPress:
00096     mousePress( static_cast<QMouseEvent*>(e) );
00097     return true;
00098     break;
00099 
00100   case QEvent::MouseButtonRelease:
00101     mouseRelease( static_cast<QMouseEvent*>(e) );
00102     return true;
00103     break;
00104 
00105   case QEvent::MouseMove:
00106     mouseMove( static_cast<QMouseEvent*>(e) );
00107     return true;
00108     break;
00109 
00110   default:
00111     break;
00112   }
00113 
00114   return false;
00115 }
00116 
00117 void ConnectorTool::setActivated(bool a)
00118 {
00119   if(a) {
00120     view()->canvasWidget()->setCursor(*m_pConnectorCursor1);
00121     m_mode = stmNone;
00122     m_pStencil = 0;
00123     m_pDragData = 0;
00124     view()->canvasWidget()->setShowConnectorTargets(true);
00125     view()->canvasWidget()->repaint();
00126     emit activated(this);
00127   } else {
00128     if(m_pStencil && (m_mode == stmDrawRubber) && (m_type == PolyLineConnector)) {
00129       Kivio::PolyLineConnector* polyconnector = static_cast<Kivio::PolyLineConnector*>(m_pStencil);
00130       polyconnector->removeLastPoint();
00131 
00132       if(polyconnector->pointCount() > 1) {
00133         connector(view()->canvasWidget()->rect());
00134       } else {
00135         view()->activePage()->unselectStencil(polyconnector);
00136         view()->activePage()->curLayer()->takeStencil(polyconnector);
00137         delete polyconnector;
00138         polyconnector = 0;
00139       }
00140 
00141       view()->canvasWidget()->guideLines().repaintAfterSnapping();
00142     }
00143 
00144     m_pStencil = 0;
00145     delete m_pDragData;
00146     m_pDragData = 0;
00147     m_type = StraightConnector;
00148     m_connectorAction->setChecked(false);
00149     m_polyLineAction->setChecked(false);
00150     m_permanent = false;
00151     view()->setStatusBarInfo("");
00152     view()->canvasWidget()->setShowConnectorTargets(false);
00153     view()->canvasWidget()->repaint();
00154   }
00155 }
00156 
00157 void ConnectorTool::connector(QRect)
00158 {
00159   if (!m_pStencil)
00160     return;
00161 
00162   delete m_pDragData;
00163   m_pDragData = 0;
00164 
00165   KivioDoc* doc = view()->doc();
00166   KivioPage* page = view()->activePage();
00167 
00168   m_pStencil->searchForConnections(page, view()->zoomHandler()->unzoomItY(4));
00169   doc->updateView(page);
00170 }
00171 
00172 void ConnectorTool::mousePress( QMouseEvent *e )
00173 {
00174   if(e->button() == LeftButton) {
00175     bool ok = true;
00176     if(!m_pStencil || (m_type == StraightConnector)) {
00177       ok = startRubberBanding(e);
00178     } else {
00179       if(m_pStencil) {
00180         Kivio::PolyLineConnector* connector = static_cast<Kivio::PolyLineConnector*>(m_pStencil);
00181         KivioCanvas* canvas = view()->canvasWidget();
00182         KivioPage* pPage = canvas->activePage();
00183         bool hit = false;
00184         KoPoint point = pPage->snapToTarget(canvas->mapFromScreen(e->pos()), 8.0, hit);
00185       
00186         if(!hit) {
00187           point = canvas->snapToGrid(startPoint);
00188         }
00189         
00190         if((m_mode == stmDrawRubber) && hit) {
00191           endRubberBanding(e);
00192         } else {
00193           connector->addPoint(point);
00194         }
00195       }
00196     }
00197     
00198     if(ok) {
00199       m_mode = stmDrawRubber;
00200     } else {
00201       m_mode = stmNone;
00202     }
00203   } else if(e->button() == RightButton) {
00204     if(m_type == PolyLineConnector) {
00205       if(m_mode == stmDrawRubber) {
00206         endRubberBanding(e);
00207       }
00208       
00209       view()->canvasWidget()->setCursor(*m_pConnectorCursor1);
00210       m_mode = stmNone;
00211     }
00212   }
00213 }
00214 
00215 
00219 bool ConnectorTool::startRubberBanding( QMouseEvent *e )
00220 {
00221   KivioCanvas* canvas = view()->canvasWidget();
00222   KivioDoc* doc = view()->doc();
00223   KivioPage* pPage = canvas->activePage();
00224   QString spawnerId;
00225   
00226   if(m_type == StraightConnector) {
00227     spawnerId = "Dave Marotti - Straight Connector";
00228   } else {
00229     spawnerId = "Internal - PolyLine Connector";
00230   }
00231 
00232   KivioStencilSpawner* ss = doc->findInternalStencilSpawner(spawnerId);
00233     
00234   if(!ss) {
00235     kdDebug(43000) << "ConnectorTool: Failed to find StencilSpawner!" << endl;
00236     return false;
00237   }
00238     
00239     // Create the stencil
00240   m_pStencil = static_cast<Kivio1DStencil*>(ss->newStencil());
00241   
00242   bool hit = false;
00243   startPoint = pPage->snapToTarget(canvas->mapFromScreen(e->pos()), 8.0, hit);
00244 
00245   if(!hit) {
00246     startPoint = canvas->snapToGrid(startPoint);
00247   }
00248 
00249   
00250   if(!m_pStencil) {
00251     return false;
00252   }
00253   
00254   m_pStencil->setTextFont(doc->defaultFont());
00255 
00256   // Unselect everything, add the stencil to the page, and select it
00257   pPage->unselectAllStencils();
00258   pPage->addStencil(m_pStencil);
00259   pPage->selectStencil(m_pStencil);
00260   // Get drag info ready
00261   m_pDragData = new KivioCustomDragData();
00262   m_pDragData->page = pPage;
00263   m_pDragData->x = startPoint.x();
00264   m_pDragData->y = startPoint.y();
00265 
00266   if(m_type == StraightConnector) {
00267     KivioStraightConnector* connector = static_cast<KivioStraightConnector*>(m_pStencil);
00268     m_pDragData->id = kctCustom + 2;
00269   
00270     connector->setStartPoint(startPoint.x(), startPoint.y());
00271     connector->setEndPoint(startPoint.x() + 10.0, startPoint.y() + 10.0);
00272   } else {
00273     Kivio::PolyLineConnector* connector = static_cast<Kivio::PolyLineConnector*>(m_pStencil);
00274     m_pDragData->id = kctCustom + 1;
00275     connector->addPoint(startPoint);
00276     connector->addPoint(startPoint);
00277   }
00278 
00279   m_pStencil->customDrag(m_pDragData);
00280 
00281   canvas->repaint();
00282   canvas->setCursor(*m_pConnectorCursor2);
00283   return true;
00284 }
00285 
00286 void ConnectorTool::mouseMove( QMouseEvent * e )
00287 {
00288   switch( m_mode )
00289   {
00290     case stmDrawRubber:
00291       continueRubberBanding(e);
00292       break;
00293 
00294     default:
00295       break;
00296   }
00297 }
00298 
00299 void ConnectorTool::continueRubberBanding( QMouseEvent *e )
00300 {
00301   KivioCanvas* canvas = view()->canvasWidget();
00302   KivioPage* pPage = view()->activePage();
00303   bool hit = false;
00304   KoPoint endPoint = pPage->snapToTarget(canvas->mapFromScreen(e->pos()), 8.0, hit);
00305 
00306   if(!hit) {
00307     endPoint = canvas->snapToGridAndGuides(endPoint);
00308   }
00309 
00310   m_pDragData->x = endPoint.x();
00311   m_pDragData->y = endPoint.y();
00312   
00313   if(m_type == StraightConnector) {
00314     KivioStraightConnector* connector = static_cast<KivioStraightConnector*>(m_pStencil);
00315     connector->setEndPoint(endPoint.x(), endPoint.y());
00316   
00317     m_pDragData->id = kctCustom + 2;
00318   } else {
00319     Kivio::PolyLineConnector* connector = static_cast<Kivio::PolyLineConnector*>(m_pStencil);
00320     m_pDragData->id = kctCustom + connector->pointCount();
00321   }
00322 
00323   m_pStencil->customDrag(m_pDragData);
00324   m_pStencil->updateGeometry();
00325   canvas->repaint();
00326 }
00327 
00328 void ConnectorTool::mouseRelease( QMouseEvent *e )
00329 {
00330   if(m_type == StraightConnector) {
00331     switch( m_mode )
00332     {
00333       case stmDrawRubber:
00334         endRubberBanding(e);
00335         break;
00336     }
00337 
00338     view()->canvasWidget()->setCursor(*m_pConnectorCursor1);
00339     m_mode = stmNone;
00340   }
00341 }
00342 
00343 void ConnectorTool::endRubberBanding(QMouseEvent *)
00344 {
00345   connector(view()->canvasWidget()->rect());
00346   m_pStencil = 0;
00347   m_mode = stmNone;
00348   view()->canvasWidget()->guideLines().repaintAfterSnapping();
00349 
00350   if(!m_permanent) {
00351     view()->pluginManager()->activateDefaultTool();
00352   }
00353 }
00354 
00355 void ConnectorTool::activateStraight()
00356 {
00357   m_type = StraightConnector;
00358   m_connectorAction->setChecked(true);
00359   m_polyLineAction->setChecked(false);
00360 }
00361 
00362 void ConnectorTool::activatePolyline()
00363 {
00364   m_type = PolyLineConnector;
00365   m_connectorAction->setChecked(false);
00366   m_polyLineAction->setChecked(true);
00367   view()->setStatusBarInfo(i18n("Left mouse button to start drawing, right to end drawing."));
00368 }
00369 
00370 void ConnectorTool::makePermanent()
00371 {
00372   m_permanent = true;
00373 }
00374 
00375 #include "tool_connector.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys