/**************************************************************************** ** ** This file is part of the LibreCAD project, a 2D CAD program ** ** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl) ** Copyright (C) 2001-2003 RibbonSoft. All rights reserved. ** ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file gpl-2.0.txt included in the ** packaging of this file. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ** ** This copyright notice MUST APPEAR in all copies of the script! ** **********************************************************************/ #include "rs_actionpolylineappend.h" #include #include "rs_dialogfactory.h" #include "rs_graphicview.h" #include "rs_commands.h" RS_ActionPolylineAppend::RS_ActionPolylineAppend(RS_EntityContainer& container, RS_GraphicView& graphicView) :RS_ActionDrawPolyline(container, graphicView) {} QAction* RS_ActionPolylineAppend::createGUIAction(RS2::ActionType /*type*/, QObject* /*parent*/) { QAction* action = new QAction(tr("A&ppend node"), NULL); action->setShortcut(QKeySequence()); action->setIcon(QIcon(":/extui/polylineappend.png")); action->setStatusTip(tr("Append polyline's node")); return action; } void RS_ActionPolylineAppend::trigger() { RS_DEBUG->print("RS_ActionPolylineAppend::trigger()"); RS_PreviewActionInterface::trigger(); if (polyline==NULL) { return; } // add the entity //RS_Polyline* polyline = new RS_Polyline(container, data); polyline->setLayerToActive(); polyline->setPenToActive(); // upd. undo list: if (document!=NULL) { document->startUndoCycle(); // RVT_PORT need to decide on how to handle undo cycles originalPolyline->setUndoState(true); document->addUndoable(originalPolyline); document->addUndoable(polyline); document->endUndoCycle(); } // upd view deleteSnapper(); graphicView->moveRelativeZero(RS_Vector(0.0,0.0)); graphicView->deleteEntity(originalPolyline); graphicView->drawEntity(polyline); graphicView->moveRelativeZero(polyline->getEndpoint()); drawSnapper(); RS_DEBUG->print("RS_ActionDrawPolyline::trigger(): polyline added: %d", polyline->getId()); polyline = NULL; } void RS_ActionPolylineAppend::mouseReleaseEvent(QMouseEvent* e) { if (e->button()==Qt::LeftButton) { if (getStatus()==SetStartpoint) { originalPolyline = (RS_Polyline*)catchEntity(e); if (originalPolyline==NULL) { RS_DIALOGFACTORY->commandMessage(tr("No Entity found.")); return; } else if (originalPolyline->rtti()!=RS2::EntityPolyline) { RS_DIALOGFACTORY->commandMessage( tr("Entity must be a polyline.")); return; } else if (originalPolyline->isClosed()) { RS_DIALOGFACTORY->commandMessage( tr("Can not append nodes in a closed polyline.")); return; } else { RS_Vector clickCoord = snapPoint(e); RS_Entity* entFirst = ((RS_Polyline*)originalPolyline)->firstEntity(); RS_Entity* entLast = ((RS_Polyline*)originalPolyline)->lastEntity(); double dist = graphicView->toGraphDX(snapRange)*0.9; RS_Entity* nearestSegment = originalPolyline->getNearestEntity( RS_Vector(graphicView->toGraphX(e->x()), graphicView->toGraphY(e->y())), &dist, RS2::ResolveNone); polyline = (RS_Polyline*)originalPolyline->clone(); container->addEntity(polyline); prepend = false; if (nearestSegment == entFirst){ prepend = true; point = originalPolyline->getStartpoint(); }else if (nearestSegment == entLast){ point = originalPolyline->getEndpoint(); }else{ RS_DIALOGFACTORY->commandMessage( tr("Click somewhere near the beginning or end of existing polyline.")); } } } RS_CoordinateEvent ce(snapPoint(e)); coordinateEvent(&ce); } else if (e->button()==Qt::RightButton) { if (getStatus()==SetNextPoint) { trigger(); } // deletePreview(); //clearPreview(); deleteSnapper(); init(getStatus()-1); } } void RS_ActionPolylineAppend::coordinateEvent(RS_CoordinateEvent* e) { if (e==NULL) { return; } RS_Vector mouse = e->getCoordinate(); switch (getStatus()) { case SetStartpoint: history.clear(); history.append(point); bHistory.clear(); bHistory.append(0.0); start = point; setStatus(SetNextPoint); graphicView->moveRelativeZero(point); updateMouseButtonHints(); break; case SetNextPoint: graphicView->moveRelativeZero(mouse); point = mouse; history.append(mouse); bHistory.append(0.0); if (polyline==NULL) { polyline = new RS_Polyline(container, data); polyline->addVertex(start, 0.0, prepend); } if (polyline!=NULL) { polyline->addVertex(mouse, 0.0, prepend); // polyline->setEndpoint(mouse); if (polyline->count()==1) { polyline->setLayerToActive(); polyline->setPenToActive(); } // RVT_PORT (can be deleted) deletePreview(); //clearPreview(); deleteSnapper(); graphicView->drawEntity(polyline); drawSnapper(); } //trigger(); //data.startpoint = data.endpoint; updateMouseButtonHints(); //graphicView->moveRelativeZero(mouse); break; default: break; } } void RS_ActionPolylineAppend::updateMouseButtonHints() { switch (getStatus()) { case SetStartpoint: RS_DIALOGFACTORY->updateMouseWidget(tr("Specify the polyline somewhere near the beginning or end point"), tr("Cancel")); break; case SetNextPoint: { QString msg = ""; if (history.size()>=3) { msg += RS_COMMANDS->command("close"); msg += "/"; } if (history.size()>=2) { msg += RS_COMMANDS->command("undo"); } if (history.size()>=2) { RS_DIALOGFACTORY->updateMouseWidget( tr("Specify next point or [%1]").arg(msg), tr("Back")); } else { RS_DIALOGFACTORY->updateMouseWidget( tr("Specify next point"), tr("Back")); } } break; default: RS_DIALOGFACTORY->updateMouseWidget("", ""); break; } } void RS_ActionPolylineAppend::undo() { if (history.size()>1) { history.removeLast(); bHistory.removeLast(); deletePreview(); point = history.last(); } else { RS_DIALOGFACTORY->commandMessage( tr("Cannot undo: " "Not enough entities defined yet.")); } } // EOF