kivio

kivio_py_stencil.cpp

00001 
00002 #include "kivio_py_stencil.h"
00003 #include "kivio_view.h"
00004 
00005 KivioPage *page;
00006 KivioView *view;
00007 #ifdef HAVE_PYTHON
00008 
00009 #include "kivioglobal.h"
00010 #include "kivio_common.h"
00011 #include "kivio_connector_point.h"
00012 #include "kivio_connector_target.h"
00013 #include "kivio_fill_style.h"
00014 #include "kivio_intra_stencil_data.h"
00015 #include "kivio_line_style.h"
00016 #include "kivio_painter.h"
00017 #include "kivio_point.h"
00018 #include "kivio_screen_painter.h"
00019 #include "kivio_stencil_spawner.h"
00020 #include "kivio_stencil_spawner_info.h"
00021 #include "kivio_stencil_spawner_set.h"
00022 
00023 #include "kivio_py_stencil_spawner.h"
00024 
00025 #include "kivio_page.h"
00026 
00027 #include <qpainter.h>
00028 #include <qbrush.h>
00029 #include <qcolor.h>
00030 #include <kdebug.h>
00031 #include <math.h>
00032 #include <KoZoomHandler.h>
00033 
00034 #include "py_kivio.h"
00035 
00036 extern "C" {
00037    void initkivioc(void);
00038 }
00039 
00040 KivioPyStencil::KivioPyStencil()
00041     : KivioStencil()
00042 {
00043    m_pConnectorTargets = new QPtrList<KivioConnectorTarget>;
00044    m_pConnectorTargets->setAutoDelete(true);
00045 
00046    static bool first_time = true;
00047    if ( first_time ) {
00048      Py_Initialize();  // initialize python only once
00049      //kdDebug(43000) << "init kivioc" << endl;
00050      initkivioc();
00051      first_time = false;
00052    }
00053 
00054    PyObject* mainmod = PyImport_AddModule("__main__");
00055    globals = PyModule_GetDict(mainmod);
00056 
00057    m_x = old_x = 0.0;
00058    m_y = old_y = 0.0;
00059    m_w = old_w = 72.0;
00060    m_h = old_h = 72.0;
00061    double x2 = m_x+m_w;
00062    double y2 = m_y+m_h;
00063 
00064 
00065    vars = Py_BuildValue( "{s:d,s:d,s:d,s:d,s:d,s:d,s:{},s:[],s:[],s:{}}",
00066                             "x", m_x, "y", m_y, "w", m_w, "h", m_h, "x2", x2, "y2", y2 , "style","connectors","connector_targets","shapes");
00067 
00068    resizeCode = "";
00069 }
00070 
00071 
00072 KivioPyStencil::~KivioPyStencil()
00073 {
00074 }
00075 
00076 
00077 int KivioPyStencil::init( QString initCode )
00078 {
00079   runPython(kivio_module);
00080   if ( !runPython( initCode ) )
00081     return 1;
00082 
00083   m_w = getDoubleFromDict( vars, "w");
00084   m_h = getDoubleFromDict( vars, "h");
00085   m_x = getDoubleFromDict( vars, "x");
00086   m_y = getDoubleFromDict( vars, "y");
00087 
00088   old_x = m_x;
00089   old_y = m_y;
00090   old_w = m_w;
00091   old_h = m_h;
00092   return 1;
00093 }
00094 
00095 
00096 bool KivioPyStencil::loadXML( const QDomElement &e )
00097 {
00098     QDomNode node;
00099     QDomElement ele;
00100 
00101 
00102     node = e.firstChild();
00103     while( !node.isNull() )
00104     {
00105         QString nodeName = node.nodeName();
00106 
00107         ele = node.toElement();
00108 
00109         if( nodeName == "PyData" )
00110         {
00111             resizeCode = XmlReadString( ele, "resizeCode", "" );
00112 
00113             QString sVars = XmlReadString( ele, "vars", "" );
00114 
00115             PyObject* mainmod = PyImport_AddModule("__main__");
00116             PyObject* gdic = PyModule_GetDict(mainmod);
00117             PyObject *ldic = Py_BuildValue("{s:s,s:{}}", "ldic", sVars.latin1() ,"res");
00118 
00119             if ( !PyRun_String("import pickle\nres = pickle.loads(ldic)", Py_file_input, gdic, ldic) ) {
00120                 PyErr_Print();
00121                 return false;
00122             }
00123 
00124             vars = PyDict_GetItemString( ldic, "res" );
00125             Py_INCREF(vars);
00126             runPython(kivio_module);
00127 
00128             m_w = getDoubleFromDict( vars, "w");
00129             m_h = getDoubleFromDict( vars, "h");
00130             m_x = getDoubleFromDict( vars, "x");
00131             m_y = getDoubleFromDict( vars, "y");
00132 
00133             old_x = m_x;
00134             old_y = m_y;
00135             old_w = m_w;
00136             old_h = m_h;
00137 
00138         }
00139         else if( nodeName == "KivioConnectorTargetList" )
00140         {
00141             loadConnectorTargetListXML( ele );
00142         }
00143 
00144         node = node.nextSibling();
00145     }
00146     return true;
00147 }
00148 
00149 
00153 void KivioPyStencil::loadConnectorTargetListXML( const QDomElement &e )
00154 {
00155     QDomNode node;
00156     QDomElement ele;
00157     QString nodeName;
00158     KivioConnectorTarget *pTarget;
00159 
00160     pTarget = m_pConnectorTargets->first();
00161     node = e.firstChild();
00162     while( !node.isNull() && pTarget)
00163     {
00164         nodeName = node.nodeName();
00165         ele = node.toElement();
00166 
00167         if( nodeName == "KivioConnectorTarget" )
00168         {
00169             pTarget->loadXML( ele );
00170         }
00171 
00172         pTarget = m_pConnectorTargets->next();
00173         node = node.nextSibling();
00174     }
00175 }
00176 
00177 
00178 QDomElement KivioPyStencil::saveXML( QDomDocument &doc )
00179 {
00180     QDomElement e = doc.createElement("KivioPyStencil");
00181 
00182     XmlWriteString( e, "id", m_pSpawner->info()->id() );
00183     XmlWriteString( e, "setId", m_pSpawner->set()->id() );
00184 
00185 
00186     QDomElement dE = doc.createElement("PyData");
00187 
00188     // The python variables
00189     PyObject* mainmod = PyImport_AddModule("__main__");
00190     PyObject* gdic = PyModule_GetDict(mainmod);
00191     PyObject *ldic = Py_BuildValue("{s:O,s:{}}", "ldic", vars ,"res");
00192 
00193     char *dump_code = "import copy\n"\
00194                       "import pickle\n"\
00195                       "cres = {}\n"\
00196                       "for key in ldic.keys():\n"\
00197                       "   try:\n"\
00198                       "      cres[key] = copy.deepcopy(ldic[key])\n"\
00199                       "   except:\n"\
00200                       "      ii=0\n"\
00201                       "res = pickle.dumps(cres)\n";
00202 
00203     if ( !PyRun_String(dump_code, Py_file_input, gdic, ldic) )
00204         PyErr_Print();
00205 
00206     QString sVars = PyString_AsString( PyDict_GetItemString( ldic, "res") );
00207 
00208     XmlWriteString( dE, "vars", sVars );
00209     XmlWriteString( dE, "resizeCode", resizeCode );
00210 
00211     e.appendChild( dE );
00212 
00213 
00214     // Save the target list
00215     QDomElement clE = doc.createElement("KivioConnectorTargetList");
00216     QDomElement targetE;
00217     KivioConnectorTarget *pTarget = m_pConnectorTargets->first();
00218     while( pTarget )
00219     {
00220         targetE = pTarget->saveXML( doc );
00221         clE.appendChild( targetE );
00222 
00223         pTarget = m_pConnectorTargets->next();
00224     }
00225     e.appendChild( clE );
00226 
00227     return e;
00228 
00229 }
00230 
00231 void KivioPyStencil::updateGeometry()
00232 {
00233 
00234    //rescale items :
00235 
00236    rescaleShapes(vars);
00237 
00238    old_x = m_x;
00239    old_y = m_y;
00240    old_w = m_w;
00241    old_h = m_h;
00242 
00243    if ( !resizeCode.isEmpty() )
00244        runPython(resizeCode);
00245 
00246    // stuff from KivioSMLStensil
00247 
00248     KivioConnectorTarget *pTarget, *pOriginal;
00249 
00250     QPtrList<KivioConnectorTarget> *pOriginalTargets = ((KivioPyStencilSpawner*)m_pSpawner)->targets();
00251 
00252     pTarget = m_pConnectorTargets->first();
00253     pOriginal = pOriginalTargets->first();
00254 
00255     PyObject *targets = PyDict_GetItemString(vars,"connector_targets");
00256     int size = PyList_Size( targets );
00257     int i=0;
00258 
00259     while( pTarget && pOriginal && i<size )
00260     {
00261         PyObject *target = PyList_GetItem( targets, i );
00262         double x = getDoubleFromDict( target,"x");
00263         double y = getDoubleFromDict( target,"y");
00264 
00265         pTarget  ->setPosition( x, y );
00266         pOriginal->setPosition( x, y );
00267 
00268         pTarget = m_pConnectorTargets->next();
00269         pOriginal = pOriginalTargets->next();
00270         i++;
00271     }
00272 
00273 }
00274 
00275 void KivioPyStencil::rescaleShapes( PyObject *o )
00276 {
00277   if ( PyDict_Check(o) ) {
00278 
00279     PyObject *o_x = PyDict_GetItemString(o,"x");
00280     if ( o_x ) {
00281         double x = getDoubleFromDict(o,"x");
00282         x = m_x+(x-old_x)*m_w/old_w;
00283         PyDict_SetItemString( o, "x", Py_BuildValue( "d", x ) );
00284     }
00285 
00286     PyObject *o_y = PyDict_GetItemString(o,"y");
00287     if ( o_y ) {
00288         double y = getDoubleFromDict(o,"y");
00289         y = m_y+(y-old_y)*m_h/old_h;
00290         PyDict_SetItemString( o, "y", Py_BuildValue( "d", y ) );
00291     }
00292 
00293     PyObject *o_x2 = PyDict_GetItemString(o,"x2");
00294     if ( o_x2 ) {
00295         double x = getDoubleFromDict(o,"x2");
00296         x = m_x+(x-old_x)*m_w/old_w;
00297         PyDict_SetItemString( o, "x2", Py_BuildValue( "d", x ) );
00298     }
00299 
00300     //PyObject *o_y2 = PyDict_GetItemString(o,"y2");
00301     if ( o_y ) {
00302         double y = getDoubleFromDict(o,"y2");
00303         y = m_y+(y-old_y)*m_h/old_h;
00304         PyDict_SetItemString( o, "y2", Py_BuildValue( "d", y ) );
00305     }
00306 
00307     PyObject *o_w = PyDict_GetItemString(o,"w");
00308     if ( o_w ) {
00309         double w = getDoubleFromDict(o,"w");
00310         w = w*m_w/old_w;
00311         PyDict_SetItemString( o, "w", Py_BuildValue( "d", w ) );
00312     }
00313 
00314     PyObject *o_h = PyDict_GetItemString(o,"h");
00315     if ( o_h ) {
00316         double h = getDoubleFromDict(o,"h");
00317         h = h*m_h/old_h;
00318         PyDict_SetItemString( o, "h", Py_BuildValue( "d", h ) );
00319     }
00320 
00321     PyObject *childs = PyDict_Values( o );
00322     int size = PyList_Size( childs );
00323     for ( int i=0; i<size; i++ )
00324         rescaleShapes(PyList_GetItem(childs,i) );
00325 
00326   } else
00327   if ( PyList_Check(o) ) {
00328 
00329     int size = PyList_Size( o );
00330     for ( int i=0; i<size; i++ )
00331         rescaleShapes( PyList_GetItem(o,i) );
00332   }
00333 }
00334 
00341 KivioStencil *KivioPyStencil::duplicate()
00342 {
00343     KivioPyStencil *pNewStencil = new KivioPyStencil();
00344     KivioStencil *pReturn;
00345 
00346     pNewStencil->m_x = m_x;
00347     pNewStencil->m_y = m_y;
00348     pNewStencil->m_w = m_w;
00349     pNewStencil->m_h = m_h;
00350 
00351     pNewStencil->old_x = old_x;
00352     pNewStencil->old_y = old_y;
00353     pNewStencil->old_w = old_w;
00354     pNewStencil->old_h = old_h;
00355 
00356     pNewStencil->m_pSpawner = m_pSpawner;
00357     pNewStencil->resizeCode = resizeCode;
00358 
00359     //make deep copy of vars:
00360     PyObject* mainmod = PyImport_AddModule("__main__");
00361     PyObject* gdic = PyModule_GetDict(mainmod);
00362     PyObject *ldic = Py_BuildValue("{s:O,s:{}}", "ldic", vars ,"res");
00363 
00364     char *copy_code = "import copy\n"\
00365                       "for key in ldic.keys():\n"\
00366                       "   try:\n"\
00367                       "      res[key] = copy.deepcopy(ldic[key])\n"\
00368                       "   except:\n"\
00369                       "      i=0\n";
00370     if ( !PyRun_String(copy_code, Py_file_input, gdic, ldic) )
00371         PyErr_Print();
00372 
00373     pNewStencil->vars = PyDict_GetItemString( ldic, "res");
00374     pNewStencil->runPython(kivio_module);
00375 
00376     // Copy the Connector Targets
00377     KivioConnectorTarget *pTarget = m_pConnectorTargets->first();
00378 
00379     while( pTarget )
00380     {
00381         pNewStencil->m_pConnectorTargets->append( pTarget->duplicate() );
00382         pTarget = m_pConnectorTargets->next();
00383     }
00384 
00385     *(pNewStencil->protection()) = *m_pProtection;
00386     *(pNewStencil->canProtect()) = *m_pCanProtect;
00387 
00388     pReturn = pNewStencil;
00389     return pReturn;
00390 }
00391 
00392 
00393 
00394 void KivioPyStencil::paint( KivioIntraStencilData *d )
00395 {
00396    paint(d,false);
00397 }
00398 
00399 void KivioPyStencil::paintOutline( KivioIntraStencilData *d )
00400 {
00401    paint(d,true);
00402 }
00403 
00404 
00405 void KivioPyStencil::paint( KivioIntraStencilData *d, bool outlined )
00406 {
00407   KoZoomHandler* zoomHandler = d->zoomHandler;
00408 
00409   PyObject *shapes = PyDict_Values( PyDict_GetItemString( vars, "shapes" ) );
00410 
00411   if ( !shapes ) {
00412     return;
00413   }
00414 
00415   int size = PyList_Size( shapes );
00416 
00417   for ( int i=0; i<size; i++ ) {
00418     PyObject *shape = PyList_GetItem( shapes, i );
00419     if ( !PyDict_Check(shape) )
00420       continue;
00421 
00422     int fill = KivioFillStyle::kcsNone;
00423 
00424     // if style dosn't defined for shape, applay default for stencil
00425     setStyle( d, PyDict_GetItemString( vars, "style" ) , fill );
00426     setStyle( d, shape, fill );
00427 
00428     if ( isSelected() )
00429       setStyle( d, PyDict_GetItemString( shape, "selected" ) , fill );
00430 
00431     if ( outlined )
00432         fill = KivioFillStyle::kcsNone;
00433 
00434     QString stype = getStringFromDict( shape, "type" );
00435     stype = stype.lower();
00436 
00437     double x = zoomHandler->zoomItX(getDoubleFromDict(shape,"x"));
00438     double y = zoomHandler->zoomItY(getDoubleFromDict(shape,"y"));
00439     double w = zoomHandler->zoomItX(getDoubleFromDict(shape,"w"));
00440     double h = zoomHandler->zoomItY(getDoubleFromDict(shape,"h"));
00441     //double x2 = zoomHandler->zoomItX(getDoubleFromDict(shape,"x2"));
00442     //double y2 = zoomHandler->zoomItY(getDoubleFromDict(shape,"y2"));
00443 
00444     // get points list
00445     QPtrList<KivioPoint> points;
00446     points.setAutoDelete(true);
00447     PyObject *pyPoints = PyDict_GetItemString( shape, "points" );
00448     if ( pyPoints && PyList_Check(pyPoints) ) {
00449       int size = PyList_Size(pyPoints);
00450       for ( int i=0; i<size; i++ ) {
00451         PyObject *pyPoint = PyList_GetItem(pyPoints,i);
00452         double x = zoomHandler->zoomItX(getDoubleFromDict(pyPoint,"x"));
00453         double y = zoomHandler->zoomItY(getDoubleFromDict(pyPoint,"y"));
00454         points.append( new KivioPoint( x, y, KivioPoint::kptNormal ) );
00455       }
00456     }
00457 
00458 
00459     if ( stype == "rectangle" ) {
00460       if (fill)
00461         d->painter->fillRect( x, y, w, h );
00462       else
00463         d->painter->drawRect( x, y, w, h );
00464     }
00465 
00466     if ( stype == "textbox" ) {
00467       int tf = vTextAlign() | hTextAlign();
00468 
00469       QFont f = textFont();
00470       f.setPointSizeFloat(f.pointSizeFloat() * (((float)zoomHandler->zoom()) / 100.0));
00471 
00472       d->painter->setFont( f );
00473       QString text = getStringFromDict(shape,"text");
00474 
00475       if ( !text.isEmpty() ) {
00476         d->painter->drawText( int( x ), int( y ), int( w ), int( h ), tf | Qt::WordBreak, text );
00477       }
00478     }
00479 
00480     if ( stype == "arc" ) {
00481       double a1 = getDoubleFromDict(shape,"a1");
00482       double a2 = getDoubleFromDict(shape,"a2");
00483       d->painter->drawArc(x,y,w,h,a1,a2);
00484     }
00485 
00486     if ( stype == "roundrect" ) {
00487       double rx = zoomHandler->zoomItX(getDoubleFromDict(shape,"rx"));
00488       double ry = zoomHandler->zoomItY(getDoubleFromDict(shape,"ry"));
00489 
00490       if (fill) {
00491         d->painter->fillRoundRect( x, y, w, h, rx, ry );
00492       } else {
00493         d->painter->drawRoundRect( x, y, w, h, rx, ry );
00494       }
00495     }
00496 
00497     if ( stype == "linearray" ) {
00498       d->painter->drawLineArray(&points);
00499     }
00500 
00501     if ( stype == "ellipse" ) {
00502       if (fill) {
00503         d->painter->fillEllipse( x, y, w, h );
00504       } else {
00505         d->painter->drawEllipse( x, y, w, h );
00506       }
00507     }
00508 
00509     if(stype == "polygon") {
00510       d->painter->drawPolygon(&points);
00511     }
00512 
00513     if(stype == "polyline") {
00514       d->painter->drawPolyline(&points);
00515     }
00516   }
00517 
00518   KivioConnectorTarget *pTarget = m_pConnectorTargets->first();
00519 
00520   while( pTarget )
00521   {
00522     pTarget->paintOutline( d );
00523     pTarget = m_pConnectorTargets->next();
00524   }
00525 }
00526 
00527 
00528 
00529 int KivioPyStencil::runPython(QString code)
00530 {
00531 
00532     view = dynamic_cast<KivioView*>(KoDocument::documentList()->first()->views().getFirst());
00533     if ( view ) {
00534         page = view->activePage();
00535     }
00536 
00537     //const char *ccode = code.local8Bit().data();
00538     const char *ccode = code.latin1();
00539 
00540     //kdDebug(43000) << "code to run:" << endl << ccode << endl;
00541 
00542     PyObject *v = PyRun_String( const_cast<char*>(ccode) , Py_file_input, globals, vars );
00543 
00544     if (v == NULL) {
00545         PyErr_Print();
00546         return 0;
00547     }
00548 
00549     if (Py_FlushLine())
00550         PyErr_Clear();
00551 
00552     Py_DECREF(v);
00553     return 1;
00554 }
00555 
00556 
00557 double KivioPyStencil::getDoubleFromDict( PyObject *dict, const char *key )
00558 {
00559     if (!PyDict_Check(dict)) return 0.0;
00560 
00561     PyObject *val = PyDict_GetItemString(dict,const_cast<char*>(key));
00562     if ( val ) {
00563         if ( PyFloat_Check(val) )
00564             return PyFloat_AsDouble( val );
00565 
00566         if ( PyInt_Check(val) )
00567             return PyInt_AsLong( val );
00568 
00569         if ( PyLong_Check(val) )
00570             return PyLong_AsDouble( val );
00571     }
00572     return 0.0;
00573 }
00574 
00575 QString KivioPyStencil::getStringFromDict( PyObject *dict, const char *key )
00576 {
00577     PyObject *val = PyDict_GetItemString(dict,const_cast<char*>(key));
00578     if ( val && PyString_Check(val) )
00579         return QString( PyString_AsString(val) );
00580 
00581     return QString("");
00582 }
00583 
00584 
00585 KivioCollisionType KivioPyStencil::checkForCollision( KoPoint *pPoint, double )
00586 {
00587     double px = pPoint->x();
00588     double py = pPoint->y();
00589 
00590     if( !(px < m_x + m_w &&
00591          px >= m_x &&
00592          py < m_y + m_h &&
00593          py >= m_y ) )
00594     {
00595         return kctNone;
00596     }
00597 
00598     return kctBody;
00599 
00600 }
00601 
00602 
00606 int KivioPyStencil::resizeHandlePositions()
00607 {
00608    // Calculate the resize handle positions
00609    int mask = KIVIO_RESIZE_HANDLE_POSITION_ALL;
00610 
00611    if( m_pProtection->at( kpWidth ) )
00612    {
00613       mask &= ~(krhpNE | krhpNW | krhpSW | krhpSE | krhpE | krhpW);
00614    }
00615 
00616    if( m_pProtection->at( kpHeight) )
00617    {
00618       mask &= ~(krhpNE | krhpNW | krhpSW | krhpSE | krhpN | krhpS);
00619    }
00620 
00621    return mask;
00622 }
00623 
00624 
00628 void KivioPyStencil::paintConnectorTargets( KivioIntraStencilData *pData )
00629 {
00630   QPixmap targetPic;
00631   KivioPainter *painter;
00632   double x, y;
00633 
00634   // We don't draw these if we are selected!!!
00635   if( isSelected() )
00636     return;
00637 
00638   // Obtain the graphic used for KivioConnectorTargets
00639   targetPic = Kivio::connectorTargetPixmap();
00640 
00641 
00642   KoZoomHandler* zoomHandler = pData->zoomHandler;
00643   painter = pData->painter;
00644 
00645   KivioConnectorTarget *pTarget;
00646   pTarget = m_pConnectorTargets->first();
00647   while( pTarget )
00648   {
00649     x = zoomHandler->zoomItX(pTarget->x());
00650     y = zoomHandler->zoomItY(pTarget->y());
00651 
00652     painter->drawPixmap( x-3, y-3, targetPic );
00653 
00654     pTarget = m_pConnectorTargets->next();
00655   }
00656 }
00657 
00665 KivioConnectorTarget *KivioPyStencil::connectToTarget( KivioConnectorPoint *p, double threshHold )
00666 {
00667     double px = p->x();
00668     double py = p->y();
00669 
00670     double tx, ty;
00671 
00672     KivioConnectorTarget *pTarget = m_pConnectorTargets->first();
00673     while( pTarget )
00674     {
00675         tx = pTarget->x();
00676         ty = pTarget->y();
00677 
00678 
00679         if( px >= tx - threshHold &&
00680             px <= tx + threshHold &&
00681             py >= ty - threshHold &&
00682             py <= ty + threshHold )
00683         {
00684             // setTarget calls pTarget->addConnectorPoint() and removes
00685             // any previous connections from p
00686             p->setTarget( pTarget );
00687             return pTarget;
00688         }
00689 
00690         pTarget = m_pConnectorTargets->next();
00691     }
00692 
00693     return NULL;
00694 }
00695 
00696 KivioConnectorTarget *KivioPyStencil::connectToTarget( KivioConnectorPoint *p, int /*targetID*/ )
00697 {
00698     int id = p->targetId();
00699 
00700     KivioConnectorTarget *pTarget = m_pConnectorTargets->first();
00701     while( pTarget )
00702     {
00703         if( pTarget->id() == id )
00704         {
00705             p->setTarget(pTarget);
00706 
00707             return pTarget;
00708         }
00709 
00710         pTarget = m_pConnectorTargets->next();
00711     }
00712 
00713     return NULL;
00714 }
00715 
00716 int KivioPyStencil::generateIds( int nextAvailable )
00717 {
00718     KivioConnectorTarget *pTarget = m_pConnectorTargets->first();
00719 
00720     // Iterate through all the targets
00721     while( pTarget )
00722     {
00723         // If this target has something connected to it
00724         if( pTarget->hasConnections() )
00725         {
00726             // Set it's id to the next available id
00727             pTarget->setId( nextAvailable );
00728 
00729             // Increment the next available id
00730             nextAvailable++;
00731         }
00732         else
00733         {
00734             // Otherwise mark it as unused (-1)
00735             pTarget->setId( -1 );
00736         }
00737 
00738         pTarget = m_pConnectorTargets->next();
00739     }
00740 
00741     // Return the next availabe id
00742     return nextAvailable;
00743 }
00744 
00745 void KivioPyStencil::setStyle( KivioIntraStencilData *d, PyObject *s, int &fillStyle )
00746 {
00747   if ( !s )
00748     return;
00749 
00750   if ( !PyDict_Check(s) )
00751     return;
00752 
00753   KivioPainter *p = d->painter;
00754   KoZoomHandler* zoomHandler = d->zoomHandler;
00755 
00756   PyObject *color = PyDict_GetItemString(s,"color");
00757 
00758   if ( color ) {
00759     QColor c = readColor(color);
00760 
00761     if ( c.isValid() ) {
00762       p->setFGColor(c);
00763     }
00764   }
00765 
00766   color = PyDict_GetItemString(s,"bgcolor");
00767 
00768   if ( color ) {
00769     QColor c = readColor(color);
00770 
00771     if ( c.isValid() ) {
00772       p->setBGColor(c);
00773     }
00774   }
00775 
00776   color = PyDict_GetItemString(s,"textcolor");
00777 
00778   if ( color ) {
00779     QColor c = readColor(color);
00780 
00781     if ( c.isValid() ) {
00782       p->setTextColor(c);
00783     }
00784   }
00785 
00786   PyObject *lineWidth = PyDict_GetItemString(s,"linewidth");
00787 
00788   if ( lineWidth ) {
00789     double lw = getDoubleFromDict(s,"linewidth");
00790     p->setLineWidth( zoomHandler->zoomItY(lw) );
00791   }
00792 
00793   PyObject *o_fillStyle = PyDict_GetItemString(s,"fillstyle");
00794 
00795   if ( o_fillStyle ) {
00796     QString sfill = getStringFromDict(s,"fillstyle");
00797 
00798     if ( sfill == "solid" ) {
00799       fillStyle = KivioFillStyle::kcsSolid;
00800     }
00801 
00802     if ( sfill == "none" ) {
00803       fillStyle = KivioFillStyle::kcsNone;
00804     }
00805   }
00806 
00807   QString  sfont = getStringFromDict(s,"font");
00808   QFont f;
00809   int fontSize = (int)getDoubleFromDict(s,"fontsize");
00810 
00811   if(!fontSize) {
00812     fontSize = 12; // FIXME: Should use some kind of global setting!!!
00813   }
00814 
00815   f.setPointSize(fontSize);
00816   f.setPointSizeFloat(f.pointSizeFloat() * (((float)zoomHandler->zoom()) / 100.0));
00817 
00818   if ( !sfont.isEmpty() ) {
00819     f.setFamily(sfont);
00820   } else {
00821     f.setFamily("times"); // FIXME: Should use some kind of global setting!!!
00822   }
00823 
00824   p->setFont(f);
00825 }
00826 
00827 QColor KivioPyStencil::readColor( PyObject *color )
00828 {
00829     if ( !color )
00830         return QColor();
00831 
00832     if ( PyString_Check(color) ) {
00833         return QColor( PyString_AsString(color) );
00834     }
00835 
00836     if ( PyList_Check(color) ) {
00837         if ( PyList_Size(color) == 3 ) {
00838             PyObject  *ro = PyList_GetItem(color,0);
00839             PyObject  *go = PyList_GetItem(color,1);
00840             PyObject  *bo = PyList_GetItem(color,2);
00841 
00842             int r=0, g=0, b=0;
00843             if ( PyNumber_Check(ro) )
00844                 r = PyInt_AsLong( PyNumber_Int(ro));
00845             if ( PyNumber_Check(go) )
00846                 g = PyInt_AsLong( PyNumber_Int(go));
00847             if ( PyNumber_Check(bo) )
00848                 b = PyInt_AsLong( PyNumber_Int(bo));
00849 
00850             return QColor(r,g,b);
00851 
00852         }
00853     }
00854 
00855     return QColor();
00856 
00857 }
00858 
00859 void KivioPyStencil::PyDebug( PyObject * o )
00860 {
00861     kdDebug(43000) << "py_debug: " <<  PyString_AsString(PyObject_Str(o)) << endl;
00862 }
00863 
00864 
00865 QColor KivioPyStencil::fgColor()
00866 {
00867     QColor color = readColor( PyDict_GetItemString( PyDict_GetItemString(vars,"style"), "color" ) );
00868     if ( color.isValid() )
00869         return color;
00870     else
00871         return QColor(0,0,0);
00872 }
00873 
00874 void KivioPyStencil::setFGColor( QColor c )
00875 {
00876     PyDict_SetItemString(  PyDict_GetItemString(vars,"style") , "color"  , Py_BuildValue("[i,i,i]", c.red(), c.green(), c.blue() ) ) ;
00877 }
00878 
00879 
00880 QColor KivioPyStencil::bgColor()
00881 {
00882     QColor color = readColor( PyDict_GetItemString( PyDict_GetItemString(vars,"style"), "bgcolor" ) );
00883     if ( color.isValid() )
00884         return color;
00885     else
00886         return QColor(0,0,0);
00887 }
00888 
00889 void KivioPyStencil::setBGColor( QColor c )
00890 {
00891     PyDict_SetItemString(  PyDict_GetItemString(vars,"style") , "bgcolor"  , Py_BuildValue("[i,i,i]", c.red(), c.green(), c.blue() ) ) ;
00892 }
00893 
00894 
00895 QColor KivioPyStencil::textColor()
00896 {
00897     QColor color = readColor( PyDict_GetItemString( PyDict_GetItemString(vars,"style"), "textcolor" ) );
00898     if ( color.isValid() )
00899         return color;
00900     else
00901         return QColor(0,0,0);
00902 }
00903 
00904 void KivioPyStencil::setTextColor( QColor c )
00905 {
00906     PyDict_SetItemString(  PyDict_GetItemString(vars,"style") , "textcolor"  , Py_BuildValue("[i,i,i]", c.red(), c.green(), c.blue() ) ) ;
00907 }
00908 
00909 
00910 double KivioPyStencil::lineWidth()
00911 {
00912     PyObject *lw = PyDict_GetItemString( PyDict_GetItemString(vars,"style"), "linewidth" );
00913     if ( lw )
00914         if ( PyNumber_Check(lw) )
00915             return ( PyInt_AsLong( PyNumber_Int(lw)) );
00916     return 1.0;
00917 }
00918 
00919 void KivioPyStencil::setLineWidth( double w )
00920 {
00921     PyDict_SetItemString(  PyDict_GetItemString(vars,"style") , "linewidth"  , Py_BuildValue("f",w ) ) ;
00922 }
00923 
00924 
00925 void KivioPyStencil::setText( const QString &s )
00926 {
00927    PyObject *to = PyDict_GetItemString( PyDict_GetItemString(vars,"shapes"), "text" );
00928    if ( to )
00929       PyDict_SetItemString(to, "text", Py_BuildValue("s", s.latin1() ));
00930 }
00931 
00932 
00933 QString KivioPyStencil::text()
00934 {
00935     PyObject *to = PyDict_GetItemString( PyDict_GetItemString(vars,"shapes"), "text" );
00936     if ( to ) {
00937         return getStringFromDict(to, "text");
00938     }
00939     return QString("");
00940 }
00941 
00942 void KivioPyStencil::setTextFont( const QFont &f )
00943 {
00944     double fs = f.pointSizeFloat();
00945     QString family = f.family();
00946 
00947     int bold     = f.bold();
00948     int italic   = f.italic();
00949     int underline= f.underline();
00950 
00951     PyDict_SetItemString(  PyDict_GetItemString(vars,"style") , "fontsize"  , Py_BuildValue("f",fs ) ) ;
00952     PyDict_SetItemString(  PyDict_GetItemString(vars,"style") , "font"  , Py_BuildValue("s",family.latin1() ) ) ;
00953     PyDict_SetItemString(  PyDict_GetItemString(vars,"style") , "bold"  , Py_BuildValue("i",bold ) ) ;
00954     PyDict_SetItemString(  PyDict_GetItemString(vars,"style") , "italic"  , Py_BuildValue("i",italic ) ) ;
00955     PyDict_SetItemString(  PyDict_GetItemString(vars,"style") , "underline"  , Py_BuildValue("i",underline ) ) ;
00956 }
00957 
00958 QFont KivioPyStencil::textFont()
00959 {
00960     PyObject *fn = PyDict_GetItemString( PyDict_GetItemString(vars,"style"), "font" );
00961     PyObject *fs = PyDict_GetItemString( PyDict_GetItemString(vars,"style"), "fontsize" );
00962     PyObject *bd = PyDict_GetItemString( PyDict_GetItemString(vars,"style"), "bold" );
00963     PyObject *it = PyDict_GetItemString( PyDict_GetItemString(vars,"style"), "italic" );
00964     PyObject *ul = PyDict_GetItemString( PyDict_GetItemString(vars,"style"), "underline" );
00965 
00966     QFont f;
00967 
00968     if ( fs )
00969         if ( PyNumber_Check(fs))
00970             f.setPointSize( PyInt_AsLong( PyNumber_Int(fs)));
00971 
00972     if ( bd )
00973         if ( PyNumber_Check(bd))
00974             f.setBold( PyInt_AsLong( PyNumber_Int(bd)));
00975 
00976     if ( it )
00977         if ( PyNumber_Check(it))
00978             f.setItalic( PyInt_AsLong( PyNumber_Int(it)));
00979 
00980     if ( ul )
00981         if ( PyNumber_Check(ul))
00982             f.setUnderline( PyInt_AsLong( PyNumber_Int(ul)));
00983 
00984     if ( fn )
00985         if ( PyString_Check(fn))
00986             f.setFamily( PyString_AsString(fn));
00987 
00988     return f;
00989 }
00990 
00991 int KivioPyStencil::hTextAlign()
00992 {
00993     PyObject *hta = PyDict_GetItemString( PyDict_GetItemString(vars,"style"), "htextalign" );
00994 
00995     if ( hta )
00996         if ( PyNumber_Check(hta) )
00997             return ( PyInt_AsLong( PyNumber_Int(hta)));
00998 
00999     return Qt::AlignHCenter;
01000 }
01001 
01002 int KivioPyStencil::vTextAlign()
01003 {
01004     PyObject *vta = PyDict_GetItemString( PyDict_GetItemString(vars,"style"), "vtextalign" );
01005 
01006     if ( vta )
01007         if ( PyNumber_Check(vta) )
01008             return ( PyInt_AsLong( PyNumber_Int(vta)));
01009 
01010     return Qt::AlignVCenter;
01011 }
01012 
01013 void KivioPyStencil::setHTextAlign(int hta)
01014 {
01015     PyDict_SetItemString(  PyDict_GetItemString(vars,"style") , "htextalign"  , Py_BuildValue("i",hta));
01016 }
01017 
01018 void KivioPyStencil::setVTextAlign(int vta)
01019 {
01020     PyDict_SetItemString(  PyDict_GetItemString(vars,"style") , "vtextalign"  , Py_BuildValue("i",vta));
01021 }
01022 
01023 #endif // HAVE_PYTHON
01024 
KDE Home | KDE Accessibility Home | Description of Access Keys