39#include "kivio_1d_stencil.h"
40#include "kivio_arrowhead.h"
41#include "kivio_common.h"
42#include "kivio_connector_point.h"
43#include "kivio_custom_drag_data.h"
44#include "kivio_fill_style.h"
45#include "kivio_intra_stencil_data.h"
46#include "kivio_layer.h"
47#include "kivio_line_style.h"
48#include "kivio_page.h"
49#include "kivio_painter.h"
50#include "kivio_point.h"
51#include "kivio_stencil.h"
52#include "kivio_stencil_spawner.h"
53#include "kivio_stencil_spawner_info.h"
54#include "kivio_stencil_spawner_set.h"
55#include "kivio_text_style.h"
56#include "kivio_connector_target.h"
60#include <KoZoomHandler.h>
71Kivio1DStencil::Kivio1DStencil()
74 m_pFillStyle =
new KivioFillStyle();
75 m_pLineStyle =
new KivioLineStyle();
76 m_pTextStyle =
new KivioTextStyle();
78 m_pConnectorPoints =
new TQPtrList<KivioConnectorPoint>;
79 m_pConnectorPoints->setAutoDelete(
true);
81 m_pStart =
new KivioConnectorPoint(
this,
true);
82 m_pStart->setPosition(72.0f, 18.0f,
false);
84 m_pEnd =
new KivioConnectorPoint(
this,
true);
85 m_pEnd->setPosition(0.0f, 18.0f,
false);
87 m_pLeft =
new KivioConnectorPoint(
this,
false);
88 m_pLeft->setPosition(36.0f, 36.0f,
false);
90 m_pRight =
new KivioConnectorPoint(
this,
false);
91 m_pRight->setPosition(36.0f, 0.0f,
false);
93 m_pTextConn =
new KivioConnectorPoint(
this,
false);
94 m_pTextConn->setPosition(36.0f, 18.0f,
false);
96 m_connectorWidth = 36.0f;
100 m_pConnectorPoints->append( m_pStart );
101 m_pConnectorPoints->append( m_pEnd );
102 m_pConnectorPoints->append( m_pLeft );
103 m_pConnectorPoints->append( m_pRight );
104 m_pConnectorPoints->append( m_pTextConn );
111Kivio1DStencil::~Kivio1DStencil()
116 delete m_pConnectorPoints;
119void Kivio1DStencil::setFGColor( TQColor c )
121 m_pLineStyle->setColor(c);
124TQColor Kivio1DStencil::fgColor()
126 return m_pLineStyle->color();
129void Kivio1DStencil::setLineWidth(
double f )
131 m_pLineStyle->setWidth(f);
134double Kivio1DStencil::lineWidth()
136 return m_pLineStyle->width();
139void Kivio1DStencil::setLinePattern(
int p)
141 m_pLineStyle->setStyle(p);
144int Kivio1DStencil::linePattern()
146 return m_pLineStyle->style();
149void Kivio1DStencil::setFillPattern(
int p)
151 m_pFillStyle->setBrushStyle(
static_cast<TQt::BrushStyle
>(p));
154int Kivio1DStencil::fillPattern()
156 return m_pFillStyle->brushStyle();
159void Kivio1DStencil::setBGColor( TQColor c )
161 m_pFillStyle->setColor(c);
164TQColor Kivio1DStencil::bgColor()
166 return m_pFillStyle->color();
173void Kivio1DStencil::setX(
double x )
176 KivioConnectorPoint *p = m_pConnectorPoints->first();
181 p->setX( p->x() + dx,
false );
182 p = m_pConnectorPoints->next();
188void Kivio1DStencil::setY(
double y )
191 KivioConnectorPoint *p = m_pConnectorPoints->first();
196 p->setY( p->y() + dy,
false );
197 p = m_pConnectorPoints->next();
203void Kivio1DStencil::setPosition(
double x,
double y )
211 KivioConnectorPoint *p = m_pConnectorPoints->first();
214 p->setPosition( p->x()+dx, p->y()+dy,
false );
217 p = m_pConnectorPoints->next();
230void Kivio1DStencil::setStartPoint(
double x,
double y )
232 double oldX = m_pStart->x();
233 double oldY = m_pStart->y();
235 m_pStart->setPosition(x, y,
false);
236 m_pStart->disconnect();
238 updateConnectorPoints(m_pStart, oldX, oldY);
242void Kivio1DStencil::setEndPoint(
double x,
double y )
244 double oldX = m_pEnd->x();
245 double oldY = m_pEnd->y();
247 m_pEnd->setPosition(x, y,
false);
248 m_pEnd->disconnect();
250 updateConnectorPoints(m_pEnd, oldX, oldY);
253void Kivio1DStencil::updateConnectorPoints( KivioConnectorPoint *p,
double ,
double )
256 if( p == m_pStart || p == m_pEnd )
258 double vx = m_pStart->x() - m_pEnd->x();
259 double vy = m_pStart->y() - m_pEnd->y();
260 double len = sqrt( vx*vx + vy*vy );
261 double midX = (m_pStart->x() + m_pEnd->x())/2.0f;
262 double midY = (m_pStart->y() + m_pEnd->y())/2.0f;
267 double d = m_connectorWidth/2.0f;
269 m_pLeft->setPosition( midX + d*vy, midY + d*(-vx),
false );
270 m_pRight->setPosition( midX + d*(-vy), midY + d*vx,
false );
277void Kivio1DStencil::paint( KivioIntraStencilData * )
282void Kivio1DStencil::paintOutline( KivioIntraStencilData *pData )
288void Kivio1DStencil::paintConnectorTargets( KivioIntraStencilData * )
292void Kivio1DStencil::paintSelectionHandles( KivioIntraStencilData *pData )
294 KivioPainter *painter = pData->painter;
298 KoZoomHandler* zoomHandler = pData->zoomHandler;
300 KivioConnectorPoint *p = m_pConnectorPoints->first();
305 x1 = zoomHandler->zoomItX(p->x());
306 y1 = zoomHandler->zoomItY(p->y());
308 flag = (p->target()) ? KivioPainter::cpfConnected : 0;
312 if( m_needsText==
true )
314 painter->drawHandle( x1, y1, 0 );
317 else if( p==m_pLeft || p==m_pRight )
319 if( m_needsWidth==
true )
321 painter->drawHandle( x1, y1, 0 );
324 else if( p==m_pStart )
326 painter->drawHandle( x1, y1, KivioPainter::cpfStart | flag );
330 painter->drawHandle( x1, y1, KivioPainter::cpfEnd | flag );
334 if( p->connectable() ) {
335 painter->drawHandle( x1, y1, KivioPainter::cpfConnectable | flag );
337 painter->drawHandle( x1, y1, flag );
341 p = m_pConnectorPoints->next();
350KivioCollisionType Kivio1DStencil::checkForCollision( KoPoint *,
double )
371void Kivio1DStencil::customDrag( KivioCustomDragData *pData )
373 setCustomIDPoint(pData->id, KoPoint(pData->x, pData->y), pData->page);
380void Kivio1DStencil::updateGeometry()
382 double minX, minY, maxX, maxY;
384 minX = 1000000000000.0f;
386 maxX = -100000000000.0f;
390 KivioConnectorPoint *p;
391 p = m_pConnectorPoints->first();
403 p = m_pConnectorPoints->next();
409 m_w = maxX - minX + 1.0f;
410 m_h = maxY - minY + 1.0f;
416bool Kivio1DStencil::loadXML(
const TQDomElement &e )
421 node = e.firstChild();
422 while( !node.isNull() )
424 name = node.nodeName();
426 if( name ==
"KivioStencilProperties" )
428 loadProperties(node.toElement() );
431 node = node.nextSibling();
440TQDomElement Kivio1DStencil::createRootElement( TQDomDocument &doc )
442 TQDomElement e = doc.createElement(
"KivioPluginStencil");
444 XmlWriteString( e,
"id", m_pSpawner->info()->id() );
445 XmlWriteString( e,
"setId", m_pSpawner->set()->id() );
451TQDomElement Kivio1DStencil::saveXML( TQDomDocument &doc )
453 TQDomElement e = createRootElement(doc);
455 e.appendChild( saveProperties(doc) );
462KivioStencil *Kivio1DStencil::duplicate()
469bool Kivio1DStencil::boolAllTrue(
bool *boolArray,
int count )
473 for( i=0; i<count; i++ )
475 if( boolArray[i]==
false )
482bool Kivio1DStencil::boolContainsFalse(
bool *boolArray,
int count )
486 for( i=0; i<count; i++ )
488 if( boolArray[i]==
false )
495void Kivio1DStencil::searchForConnections( KivioPage *pPage )
497 bool *done =
new bool[ m_pConnectorPoints->count()];
500 for(i = 0; i < m_pConnectorPoints->count(); i++) {
504 KivioConnectorPoint *p;
506 p = m_pConnectorPoints->first();
510 if( p->targetId() == -1 ) {
515 p = m_pConnectorPoints->next();
519 if( boolAllTrue( done, m_pConnectorPoints->count() ) )
525 KivioLayer *pLayer = pPage->firstLayer();
527 while( pLayer && ( boolContainsFalse(done, m_pConnectorPoints->count()) ) )
529 KivioStencil *pStencil = pLayer->firstStencil();
531 while( pStencil && ( boolContainsFalse(done, m_pConnectorPoints->count()) ) )
534 if((pStencil !=
this))
540 p = m_pConnectorPoints->first();
543 if( !done[i] && p->targetId() != -1 )
545 if(pStencil->connectToTarget( p, p->targetId()))
552 p = m_pConnectorPoints->next();
557 pStencil = pLayer->nextStencil();
560 pLayer = pPage->nextLayer();
566void Kivio1DStencil::searchForConnections( KivioPage *pPage,
double threshold )
568 bool *done =
new bool[ m_pConnectorPoints->count()];
571 for( i=0; i<(int)m_pConnectorPoints->count(); i++ ) {
575 KivioConnectorPoint *p;
577 p = m_pConnectorPoints->first();
581 if(p->target() != 0L) {
586 p = m_pConnectorPoints->next();
590 if( boolAllTrue( done, m_pConnectorPoints->count() ) )
596 KivioLayer *pLayer = pPage->firstLayer();
598 while( pLayer && ( boolContainsFalse(done, m_pConnectorPoints->count()) ) )
600 KivioStencil *pStencil = pLayer->firstStencil();
602 while( pStencil && ( boolContainsFalse(done, m_pConnectorPoints->count()) ) )
605 if( pStencil !=
this )
611 p = m_pConnectorPoints->first();
615 if( !done[i] && p->target() == 0 )
617 if( pStencil->connectToTarget( p, threshold ) )
624 p = m_pConnectorPoints->next();
629 pStencil = pLayer->nextStencil();
632 pLayer = pPage->nextLayer();
641int Kivio1DStencil::resizeHandlePositions()
643 return (
int)krhpNone;
646TQDomElement Kivio1DStencil::saveConnectors( TQDomDocument &doc )
648 TQDomElement eConns = doc.createElement(
"KivioConnectorList");
650 KivioConnectorPoint *p;
651 p = m_pConnectorPoints->first();
654 eConns.appendChild( p->saveXML(doc) );
656 p = m_pConnectorPoints->next();
662bool Kivio1DStencil::loadConnectors(
const TQDomElement &e )
664 m_pConnectorPoints->clear();
666 KivioConnectorPoint *p;
668 TQDomNode node = e.firstChild();
672 while( !node.isNull() )
674 e2 = node.toElement();
675 name = e2.nodeName();
677 if( name ==
"KivioConnectorPoint" )
679 p =
new KivioConnectorPoint();
683 m_pConnectorPoints->append( p );
687 node = node.nextSibling();
691 m_pStart = m_pConnectorPoints->first();
692 m_pEnd = m_pConnectorPoints->next();
693 m_pLeft = m_pConnectorPoints->next();
694 m_pRight = m_pConnectorPoints->next();
695 m_pTextConn = m_pConnectorPoints->next();
698 if( m_pStart == NULL ) {
699 m_pStart =
new KivioConnectorPoint(
this,
true);
701 if( m_pEnd == NULL ) {
702 m_pEnd =
new KivioConnectorPoint(
this,
true);
704 if( m_pLeft == NULL ) {
705 m_pLeft =
new KivioConnectorPoint(
this,
false);
707 if( m_pRight == NULL ) {
708 m_pRight =
new KivioConnectorPoint(
this,
false);
710 if( m_pTextConn == NULL ) {
711 m_pTextConn =
new KivioConnectorPoint(
this,
false);
718TQDomElement Kivio1DStencil::saveProperties( TQDomDocument &doc )
720 TQDomElement propE = doc.createElement(
"KivioStencilProperties");
722 TQDomElement connE = doc.createElement(
"Kivio1DProperties");
723 XmlWriteFloat( connE,
"connectorWidth", m_connectorWidth );
724 XmlWriteInt( connE,
"needsWidth", m_needsWidth );
725 propE.appendChild( connE );
727 propE.appendChild( m_pLineStyle->saveXML( doc ) );
729 propE.appendChild( m_pFillStyle->saveXML( doc ) );
731 propE.appendChild( m_pTextStyle->saveXML( doc ) );
733 propE.appendChild( saveConnectors(doc) );
735 TQDomElement customE = doc.createElement(
"CustomData");
736 if( saveCustom( customE, doc )==
true )
738 propE.appendChild( customE );
744bool Kivio1DStencil::loadProperties(
const TQDomElement &e )
750 node = e.firstChild();
751 while( !node.isNull() )
753 nodeE = node.toElement();
754 nodeName = node.nodeName();
756 if( nodeName ==
"KivioFillStyle" )
758 m_pFillStyle->loadXML( nodeE );
760 else if( nodeName ==
"KivioLineStyle" )
762 m_pLineStyle->loadXML( nodeE );
764 else if( nodeName ==
"KivioTextStyle" )
766 m_pTextStyle->loadXML( nodeE );
768 else if( nodeName ==
"KivioConnectorList" )
770 loadConnectors( nodeE );
772 else if( nodeName ==
"Kivio1DProperties" )
774 m_needsWidth = (bool)XmlReadInt( nodeE,
"needsWidth", (
int)
true );
775 m_connectorWidth = XmlReadFloat( nodeE,
"connectorWidth", 36.0f );
777 else if( nodeName ==
"CustomData" )
782 node = node.nextSibling();
788bool Kivio1DStencil::loadCustom(
const TQDomElement & )
793bool Kivio1DStencil::saveCustom( TQDomElement &, TQDomDocument & )
798void Kivio1DStencil::copyBasicInto( Kivio1DStencil *pStencil )
800 KivioConnectorPoint *pSrc, *pTg;
803 pStencil->setSpawner( m_pSpawner );
806 pSrc = m_pConnectorPoints->first();
807 pTg = pStencil->m_pConnectorPoints->first();
810 pTg->setPosition( pSrc->x(), pSrc->y(),
false );
812 pSrc = m_pConnectorPoints->next();
813 pTg = pStencil->m_pConnectorPoints->next();
823 pStencil->m_connectorWidth = m_connectorWidth;
824 pStencil->m_needsWidth = m_needsWidth;
827 m_pFillStyle->copyInto( pStencil->m_pFillStyle );
828 m_pLineStyle->copyInto( pStencil->m_pLineStyle );
829 m_pTextStyle->copyInto( pStencil->m_pTextStyle );
832 *(pStencil->m_pProtection) = *m_pProtection;
833 *(pStencil->m_pCanProtect) = *m_pCanProtect;
836void Kivio1DStencil::drawText( KivioIntraStencilData *pData )
838 if(m_pTextStyle->text().isEmpty()) {
842 KoZoomHandler* zoomHandler = pData->zoomHandler;
843 KivioPainter *painter = pData->painter;
847 _x = zoomHandler->zoomItX(m_pTextConn->x());
848 _y = zoomHandler->zoomItY(m_pTextConn->y());
852 TQFont f = m_pTextStyle->font();
853 int tf = m_pTextStyle->hTextAlign() | m_pTextStyle->vTextAlign();
855 f.setPointSizeFloat(f.pointSizeFloat() * (((
float)zoomHandler->zoom()) / 100.0));
857 TQRect boundRect = painter->boundingRect( _x, _y, _w, _h, tf, m_pTextStyle->text() );
858 TQPixmap pix(boundRect.width(), boundRect.height());
861 p.setPen(m_pTextStyle->color());
863 p.drawText( 0, 0, boundRect.width(), boundRect.height(), tf, m_pTextStyle->text() );
867 painter->drawPixmap(_x, _y, pix);
870bool Kivio1DStencil::connected()
872 KivioConnectorPoint *p;
873 p = m_pConnectorPoints->first();
877 if(p->target() != 0) {
881 p = m_pConnectorPoints->next();
887void Kivio1DStencil::disconnectFromTargets()
889 KivioConnectorPoint *p;
890 p = m_pConnectorPoints->first();
895 p = m_pConnectorPoints->next();
899KivioLineStyle Kivio1DStencil::lineStyle()
901 return *m_pLineStyle;
904void Kivio1DStencil::setLineStyle(KivioLineStyle ls)
906 ls.copyInto(m_pLineStyle);
909void Kivio1DStencil::setCustomIDPoint(
int customID,
const KoPoint& point, KivioPage* page)
912 KivioConnectorPoint *p;
915 p = m_pConnectorPoints->at( customID - (kctCustom+1));
919 kdDebug(43000) <<
"Kivio1DStencil::customDrag() - KivioConnectorPoint customID: " << (customID - (kctCustom+1)) <<
" not found\n" << endl;
925 p->setPosition(point.x(),point.y(),
true);
927 if( p->connectable()==
true )
930 KivioLayer *pCurLayer = page->curLayer();
931 KivioLayer *pLayer = page->firstLayer();
932 bool foundConnection =
false;
934 while( pLayer && !foundConnection )
937 if( pLayer!=pCurLayer )
939 if( pLayer->connectable()==
false || pLayer->visible()==
false )
941 pLayer = page->nextLayer();
947 if( pLayer->connectPointToTarget( p, 8.0f ) )
949 foundConnection =
true;
952 pLayer = page->nextLayer();
955 if( foundConnection ==
false )
962 if( customID == kctCustom+1 || customID == kctCustom+2 )
965 if( p==m_pEnd && m_needsText==
true )
967 m_pTextConn->setPosition( m_pTextConn->x() + (m_pEnd->x() - oldX),
968 m_pTextConn->y() + (m_pEnd->y() - oldY),
false );
971 updateConnectorPoints(p, oldX, oldY);
975 else if( (customID == kctCustom+3 || customID == kctCustom+4) && (m_needsWidth==
true) )
977 double vx = m_pStart->x() - m_pEnd->x();
978 double vy = m_pStart->y() - m_pEnd->y();
979 double len = sqrt( vx*vx + vy*vy );
980 double midX = (m_pStart->x() + m_pEnd->x())/2.0f;
981 double midY = (m_pStart->y() + m_pEnd->y())/2.0f;
986 double d = shortestDistance( m_pStart, m_pEnd, (customID==kctCustom+3) ? m_pLeft : m_pRight );
988 m_pLeft->setPosition( midX + d*vy, midY + d*(-vx),
false );
989 m_pRight->setPosition( midX + d*(-vy), midY + d*vx,
false );
991 m_connectorWidth = d*2.0f;
993 updateConnectorPoints(p, oldX, oldY);
997 else if( customID == kctCustom+5 )
999 updateConnectorPoints(p, oldX, oldY);
1003KoPoint Kivio1DStencil::customIDPoint(
int customID)
1005 KivioConnectorPoint *p;
1008 p = m_pConnectorPoints->at( customID - (kctCustom+1));
1010 return p->position();