diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-20 01:29:50 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-20 01:29:50 +0000 |
commit | 8362bf63dea22bbf6736609b0f49c152f975eb63 (patch) | |
tree | 0eea3928e39e50fae91d4e68b21b1e6cbae25604 /kivio/kiviopart/kiviosdk/kiviopolylineconnector.cpp | |
download | koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.tar.gz koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.zip |
Added old abandoned KDE3 version of koffice
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/koffice@1077364 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kivio/kiviopart/kiviosdk/kiviopolylineconnector.cpp')
-rw-r--r-- | kivio/kiviopart/kiviosdk/kiviopolylineconnector.cpp | 497 |
1 files changed, 497 insertions, 0 deletions
diff --git a/kivio/kiviopart/kiviosdk/kiviopolylineconnector.cpp b/kivio/kiviopart/kiviosdk/kiviopolylineconnector.cpp new file mode 100644 index 00000000..9afe2f9e --- /dev/null +++ b/kivio/kiviopart/kiviosdk/kiviopolylineconnector.cpp @@ -0,0 +1,497 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Peter Simonsson <[email protected]>, + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "kiviopolylineconnector.h" + +#include <kdebug.h> + +#include <KoZoomHandler.h> +#include <KoSize.h> + +#include "kivio_line_style.h" +#include "kivio_painter.h" +#include "kivio_intra_stencil_data.h" +#include "kivio_connector_point.h" +#include "kivio_custom_drag_data.h" +#include "tkmath.h" +#include "kivio_page.h" +#include "kivio_layer.h" +#include "kivio_common.h" + + +namespace Kivio { + PolyLineConnector::PolyLineConnector() + : Kivio1DStencil() + { + m_startArrow = new KivioArrowHead(); + m_endArrow = new KivioArrowHead(); + + m_needsWidth = false; + m_needsText = false; // FIXME add text support + + m_pCanProtect->clearBit(kpAspect); + m_pCanProtect->clearBit(kpWidth); + m_pCanProtect->clearBit(kpHeight); + m_pCanProtect->clearBit(kpX); + m_pCanProtect->clearBit(kpY); + + // This is a stencil of type connector + setType(kstConnector); + } + + PolyLineConnector::~PolyLineConnector() + { + delete m_startArrow; + delete m_endArrow; + } + + KivioStencil* PolyLineConnector::duplicate() + { + PolyLineConnector* connector = new PolyLineConnector(); + copyBasicInto(connector); + connector->m_points = m_points; + + // Copy the arrow head information + connector->setStartAHType( m_startArrow->type() ); + connector->setStartAHWidth( m_startArrow->width() ); + connector->setStartAHLength( m_startArrow->length() ); + + connector->setEndAHType( m_endArrow->type() ); + connector->setEndAHWidth( m_endArrow->width() ); + connector->setEndAHLength( m_endArrow->length() ); + + return connector; + } + + bool PolyLineConnector::loadCustom(const QDomElement& e) + { + QDomNode node = e.firstChild(); + QString nodeName; + m_points.clear(); + + while(!node.isNull()) { + nodeName = node.nodeName(); + + if(nodeName == "KivioArrowHeads") { + loadArrowHeads(node.toElement()); + } else if(nodeName == "KivioGeometryPoints") { + QDomNode pointsNode = node.firstChild(); + QDomElement el; + + while(!pointsNode.isNull()) { + if(pointsNode.nodeName() == "KivioPoint") { + el = pointsNode.toElement(); + KoPoint p; + p.setX(XmlReadFloat(el, "x", 1.0f)); + p.setY(XmlReadFloat(el, "y", 1.0f)); + addPoint(p); + } + + pointsNode = pointsNode.nextSibling(); + } + } + + node = node.nextSibling(); + } + + return true; + } + + bool PolyLineConnector::saveCustom(QDomElement& e, QDomDocument& doc) + { + e.appendChild(saveArrowHeads(doc)); + QDomElement pointsElement = doc.createElement("KivioGeometryPoints"); + + for(QValueList<KoPoint>::iterator it = m_points.begin(); it != m_points.end(); ++it) { + KoPoint p = (*it); + QDomElement el = doc.createElement("KivioPoint"); + XmlWriteFloat(el, "x", p.x()); + XmlWriteFloat(el, "y", p.y()); + pointsElement.appendChild(el); + } + + e.appendChild(pointsElement); + + return true; + } + + KivioCollisionType PolyLineConnector::checkForCollision(KoPoint* p, double threshold) + { + unsigned int i = 0; + KoPoint point; + double px = p->x(); + double py = p->y(); + uint count = m_points.count(); + + while(i < count) { + point = m_points[i]; + + if(px >= point.x() - threshold && px <= point.x() + threshold && + py >= point.y() - threshold && py <= point.y() + threshold) + { + return static_cast<KivioCollisionType>(i + kctCustom + 1); + } + + i++; + } + + i = 0; + count--; // As we need current + 1; + + while(i < count) { + point = m_points[i]; + + if(collisionLine(point.x(), point.y(), + m_points[i + 1].x(), m_points[i + 1].y(), px, py, threshold)) + { + return kctBody; + } + + i++; + } + + return kctNone; + } + + void PolyLineConnector::paint(KivioIntraStencilData* data) + { + if(m_points.count() < 2) { + kdDebug(43000) << "ARGH! We're missing points in this connector!" << endl; + return; + } + + KoZoomHandler* zoom = data->zoomHandler; + KivioPainter* painter = data->painter; + + painter->setLineStyle(m_pLineStyle); + painter->setLineWidth(zoom->zoomItY(m_pLineStyle->width())); + + QPointArray pa(m_points.count()); + QValueList<KoPoint>::iterator it; + int i = 0; + + for(it = m_points.begin(); it != m_points.end(); ++it) { + pa.setPoint(i, zoom->zoomPoint(*it)); + i++; + } + + KoPoint startVec = m_points[1] - m_points[0]; + KoPoint endVec = m_points.last() - m_points[m_points.count() - 2]; + double startLen = startVec.manhattanLength(); + double endLen = endVec.manhattanLength(); + + if(startLen) { + startVec.setX(startVec.x() / startLen); + startVec.setY(startVec.y() / startLen); + QPoint p = pa[0]; + p.setX(p.x() + qRound(startVec.x() * zoom->zoomItX(m_startArrow->cut()))); + p.setY(p.y() + qRound(startVec.y() * zoom->zoomItY(m_startArrow->cut()))); + } + + if(endLen) { + endVec.setX(endVec.x() / endLen); + endVec.setY(endVec.y() / endLen); + QPoint p = pa[m_points.count() - 1]; + p.setX(p.x() + qRound(endVec.x() * zoom->zoomItX(m_endArrow->cut()))); + p.setY(p.y() + qRound(endVec.y() * zoom->zoomItY(m_endArrow->cut()))); + } + + painter->drawPolyline(pa); + painter->setBGColor(m_pFillStyle->color()); + + if(startLen) { + m_startArrow->paint(painter, m_points[0].x(), m_points[0].y(), -startVec.x(), -startVec.y(), zoom); + } + + if(endLen) { + m_endArrow->paint(painter, m_points.last().x(), m_points.last().y(), endVec.x(), endVec.y(), zoom); + } + } + + void PolyLineConnector::paintOutline(KivioIntraStencilData* data) + { + paint(data); + } + + void PolyLineConnector::paintSelectionHandles( KivioIntraStencilData* data ) + { + KivioPainter* painter = data->painter; + KoZoomHandler* zoomHandler = data->zoomHandler; + QValueList<KoPoint>::Iterator it; + int x, y, flag; + x = y = flag = 0; + + for(it = m_points.begin(); it != m_points.end(); ++it) { + x = zoomHandler->zoomItX((*it).x()); + y = zoomHandler->zoomItY((*it).y()); + + if((*it) == m_pEnd->position()) { + flag = ((m_pEnd->target()) ? KivioPainter::cpfConnected : 0) | KivioPainter::cpfEnd; + } else if((*it) == m_pStart->position()) { + flag = ((m_pStart->target()) ? KivioPainter::cpfConnected : 0) | KivioPainter::cpfStart; + } else { + flag = 0; + } + + painter->drawHandle(x, y, flag); + } + } + + void PolyLineConnector::addPoint(const KoPoint& p) + { + if(m_points.count() == 0) { + m_pStart->setPosition(p.x(), p.y(), false); + m_pStart->disconnect(); + } else { + m_pEnd->setPosition(p.x(), p.y(), false); + m_pEnd->disconnect(); + } + + m_points.append(p); + } + + void PolyLineConnector::movePoint(unsigned int index, double xOffset, double yOffset) + { + if(index >= m_points.count()) { + return; + } + + KoPoint p(xOffset, yOffset); + m_points[index] += p; + + if(index == (m_points.count() - 1)) { + m_pEnd->setPosition(m_points[index].x(), m_points[index].y(), false); + m_pEnd->disconnect(); + } else if(index == 0) { + m_pStart->setPosition(m_points[index].x(), m_points[index].y(), false); + m_pStart->disconnect(); + } + } + + void PolyLineConnector::movePointTo(unsigned int index, const KoPoint& p) + { + m_points[index] = p; + + if(index == (m_points.count() - 1)) { + m_pEnd->setPosition(p.x(), p.y(), false); + m_pEnd->disconnect(); + } else if(index == 0) { + m_pStart->setPosition(p.x(), p.y(), false); + m_pStart->disconnect(); + } + } + + void PolyLineConnector::moveLastPointTo(const KoPoint& p) + { + movePointTo(m_points.count() - 1, p); + } + + void PolyLineConnector::customDrag(KivioCustomDragData* data) + { + KoPoint pos(data->x, data->y); + setCustomIDPoint(data->id, pos, data->page); + } + + void PolyLineConnector::move(double xOffset, double yOffset) + { + for(unsigned int i = 0; i < m_points.count(); i++) { + movePoint(i, xOffset, yOffset); + } + } + + double PolyLineConnector::x() + { + if(m_points.count() == 0) { + return 0; + } + + return rect().x(); + } + + void PolyLineConnector::setX(double newX) + { + double dx = newX - x(); + move(dx, 0); + } + + double PolyLineConnector::y() + { + if(m_points.count() == 0) { + return 0; + } + + return rect().y(); + } + + void PolyLineConnector::setY(double newY) + { + double dy = newY - y(); + move(0, dy); + } + + void PolyLineConnector::checkForConnection(KivioConnectorPoint* cp, KivioPage* page) + { + if(cp->connectable()) { + KivioLayer* currentLayer = page->curLayer(); + KivioLayer* layer = page->firstLayer(); + bool found = false; + + while(layer && !found) { + if((layer != currentLayer) && (!layer->connectable() || !layer->visible())) { + layer = page->nextLayer(); + continue; + } + + if(layer->connectPointToTarget(cp, 8.0f)) { + found = true; + } + + layer = page->nextLayer(); + } + + if(!found) { + cp->disconnect(); + } + } + } + + void PolyLineConnector::updateConnectorPoints(KivioConnectorPoint* cp, double /*oldX*/, double /*oldY*/) + { + if(cp == m_pStart) { + m_points[0] = m_pStart->position(); + } else if(cp == m_pEnd) { + m_points[m_points.count() - 1] = m_pEnd->position(); + } + } + + KoRect PolyLineConnector::rect() + { + KoPoint p = m_points.first(); + KoPoint topLeft(p.x(), p.y()), bottomRight; + QValueList<KoPoint>::iterator it; + QValueList<KoPoint>::iterator itEnd = m_points.end(); + + for(it = m_points.begin(); it != itEnd; ++it) { + p = (*it); + topLeft.setX(QMIN(p.x(), topLeft.x())); + topLeft.setY(QMIN(p.y(), topLeft.y())); + bottomRight.setX(QMAX(p.x(), bottomRight.x())); + bottomRight.setY(QMAX(p.y(), bottomRight.y())); + } + + KoRect rect; + rect.moveTopLeft(topLeft); + rect.setWidth(bottomRight.x() - topLeft.x()); + rect.setHeight(bottomRight.y() - topLeft.y()); + return rect; + } + + bool PolyLineConnector::isInRect(const KoRect& rect) + { + QValueList<KoPoint>::Iterator it; + bool retVal = true; + + for(it = m_points.begin(); it != m_points.end(); ++it) { + retVal = retVal && rect.contains((*it)); + } + + return retVal; + } + + bool PolyLineConnector::loadArrowHeads(const QDomElement& e) + { + bool first = true; + QDomNode node = e.firstChild(); + + while(!node.isNull()) { + if(node.nodeName() == "KivioArrowHead") { + if(first) { + m_startArrow->loadXML(node.toElement()); + first = false; + } else { + m_endArrow->loadXML(node.toElement()); + } + } + + node = node.nextSibling(); + } + + return true; + } + + QDomElement PolyLineConnector::saveArrowHeads(QDomDocument& doc) + { + QDomElement e = doc.createElement("KivioArrowHeads"); + + e.appendChild( m_startArrow->saveXML(doc) ); + e.appendChild( m_endArrow->saveXML(doc) ); + + return e; + } + + void PolyLineConnector::removePoint(unsigned int index) + { + if(index >= m_points.count()) { + return; + } + + m_points.remove(m_points.at(index)); + } + + void PolyLineConnector::removeLastPoint() + { + removePoint(m_points.count() - 1); + } + + void PolyLineConnector::setCustomIDPoint(int customID, const KoPoint& point, KivioPage* page) + { + int index = customID - (kctCustom + 1); + + if((index < 0) || index >= (int)m_points.count()) { + kdDebug(43000) << "PolyLineConnector::setCustomIDPoint: Index out of range! Index = " << index << endl; + return; + } + + movePointTo(index, point); + KivioConnectorPoint* cp; + + if(index == 0) { + cp = m_pStart; + } else if(index == ((int)m_points.count() - 1)) { + cp = m_pEnd; + } else { + return; + } + + checkForConnection(cp, page); + } + + KoPoint PolyLineConnector::customIDPoint(int customID) + { + int index = customID - (kctCustom + 1); + + if((index < 0) || index >= (int)m_points.count()) { + kdDebug(43000) << "PolyLineConnector::customIDPoint: Index out of range! Index = " << index << endl; + return KoPoint(); + } + + return m_points[index]; + } + +} |