nodeeditor_doxy
|
00001 //dw 00002 //#include <QtGui> 00003 00004 #include "NodeItem.h" 00005 //#include "arrow.h" 00006 //dw 00007 //#include "nodeconnector.h" 00008 00009 00010 /*//dw FIXME:only proxified 00011 void NodeItem::hide() { 00012 this->widget()->close(); 00013 } 00014 //dw slot 00015 void NodeItem::deleted() { 00016 this->widget()->close(); 00017 //delete this; 00018 } 00019 void NodeItem::deleted(int result) { 00020 this->widget()->close(); 00021 } 00022 */ 00023 00024 NodeItem::~NodeItem() { 00025 removeWigetFromConnectors(); 00026 //deleteConnections(); 00027 //dw new 00028 if (scene() != NULL) { 00029 this->scene()->removeItem(this); 00030 } 00031 } 00032 00034 NodeItem::NodeItem(QMenu *contextMenu, 00035 QGraphicsItem *parent, /*//dw can we really assume our scene type*/ QGraphicsScene /*DiagramScene*/ *scene, Qt::WindowFlags wFlags) 00036 : /*QGraphicsPolygonItem(parent, scene) //dw*/ /*QFrame(parent->parentWidget(), 0)*/ 00037 QGraphicsObject(parent/*, /* //dw668: did this cause decorations now in 4.7 but no in 4.5.2?: Qt::Window*/ /*//dw FIXME:only proxifiedwFlags*/), mMaxRadius(1) 00038 { 00039 //dw new4: is this a problem? check it 00040 setCacheMode(DeviceCoordinateCache); 00041 00042 mContextMenu = contextMenu; 00043 isMoving = false; 00044 00045 //dw new: 00046 setZValue(1); 00047 //param 00048 mNoResize = true; 00049 if (mNoResize) { 00050 mControlResizeHandles = true; 00051 } 00052 else { 00053 //param 00054 mControlResizeHandles = false; 00055 } 00056 00057 00058 /* 00059 QPainterPath path; 00060 00061 //dw 00062 //QGroupBox *groupBox = new QGroupBox("GrBox"); 00063 //QLabel *numberLabel = new QLabel("Telephone number"); 00064 //QLineEdit *numberEdit = new QLineEdit; 00065 //QFormLayout *layout = new QFormLayout; 00066 //layout->addRow(numberLabel, numberEdit); 00067 //groupBox->setLayout(layout); 00068 QFormLayout *layout2 = new QFormLayout; 00069 //layout2->addRow(groupBox); 00070 00071 QLabel* out0 = new QLabel("out0"); 00072 out0->setAlignment(Qt::AlignRight); 00073 QLabel* in0 = new QLabel("in0"); 00074 layout2->addRow(in0, out0); 00075 QLabel* in1 = new QLabel("in1"); 00076 layout2->addRow(in1); 00077 QLabel* in2 = new QLabel("in2"); 00078 layout2->addRow(in2); 00079 QLabel* inout0 = new QLabel("inOut0"); 00080 inout0->setAlignment(Qt::AlignRight); 00081 layout2->addRow(inout0); 00082 00083 //QSpinBox ( int minValue, int maxValue, int step = 1, QWidget * parent = 0, const char * name = 0 ) 00084 QSpinBox* spinBox = new QSpinBox(); 00085 spinBox->setMinimum(0); 00086 spinBox->setMaximum(9); 00087 layout2->addRow(spinBox); 00088 00089 QDialog *dialog1 = new QDialog(); 00090 //QFrame *dialog1 = new QFrame(); 00091 //QGroupBox* dialog1 = new QGroupBox("A QGroupBox"); 00092 dialog1->setLayout(layout2); 00093 //dialog1->setLayout(groupBox); 00094 //this->setWidget(groupBox); 00095 //dw will this fix deletion not called on close? 00096 dialog1->setAttribute(Qt::WA_DeleteOnClose); 00097 this->setWidget(dialog1); 00098 00099 addConnector(new NodeConnector(this, scene, out0, NodeConnector::Out, true)); 00100 addConnector(new NodeConnector(this, scene, in0, NodeConnector::In)); 00101 addConnector(new NodeConnector(this, scene, in1, NodeConnector::In)); 00102 addConnector(new NodeConnector(this, scene, in2, NodeConnector::In)); 00103 addConnector(new NodeConnector(this, scene, inout0, NodeConnector::InOut, true)); 00104 00105 addConnector(new NodeConnector(this, scene, spinBox, NodeConnector::InOut)); 00106 00107 //QGraphicsScene scene; 00108 //QGraphicsObject *proxy = scene->addWidget(groupBox); 00109 //QGraphicsView view(&scene); 00110 //view.show(); 00111 */ 00112 00113 /* setPolygon(mPolygon);*/ 00114 setFlag(QGraphicsObject::ItemIsMovable, true); 00115 setFlag(QGraphicsObject::ItemIsSelectable, true); 00116 setFlag(QGraphicsObject::ItemIsFocusable, true); 00117 00118 00119 //dw why is that needed 00120 //dialog1->setWindowFlags(Qt::WindowMov); 00121 //widget()->setWindowFlags(Qt::WindowFlags); 00122 00123 //dw new 00124 if (scene != NULL){ 00125 scene->addItem(this); 00126 } 00127 00128 00129 /* 00130 QDialog signals: 00131 void accepted () 00132 void finished ( int result ) 00133 void rejected () 00134 */ 00135 /* 00136 connect(dialog1, SIGNAL(accepted()), this, SLOT(deleted())); 00137 connect(dialog1, SIGNAL(finished(int)), this, SLOT(deleted(int))); 00138 connect(dialog1, SIGNAL(rejected()), this, SLOT(deleted())); 00139 */ 00140 00141 /* 00142 QWidget signals: 00143 void customContextMenuRequested ( const QPoint & pos ) 00144 */ 00145 /* 00146 QObject signals: 00147 void destroyed ( QObject * obj = 0 ) 00148 */ 00149 00150 //dw big problem: we do not have dialog1 here with new design, but when to do it? ==> override setWidget() 00151 //connect(dialog1, SIGNAL(destroyed()), this, SLOT(deleted())); 00152 } 00154 00155 00156 QRectF NodeItem::boundingRect() const 00157 { 00158 /* 00159 qreal adjust = 5; 00160 return QRectF(-radius - adjust, -radius - adjust, 00161 2*(radius + adjust), 2*(radius + adjust)); 00162 */ 00163 00164 //dw new 00165 QRectF rec(QGraphicsObject::boundingRect()); 00166 //order matters!!! 00167 //rec.setX(rec.x() - 2 * (mMaxRadius)); 00168 //rec.setWidth(rec.width() + 2 * (mMaxRadius)); 00169 qreal extra = 3;//2 * (mMaxRadius) ; 00170 rec = rec.normalized().adjusted(-extra, 0, extra, 0); 00171 00172 //rec.setWidth(rec.width() - 2 * (mMaxRadius + 1)); 00173 //rec.setX(rec.x() + (mMaxRadius + 1)); 00174 //rec.setWidth(rec.width() - 4); 00175 //rec.setX(rec.x() + 2); 00176 return rec; 00177 } 00178 00179 QPainterPath NodeItem::shape() const { 00180 00181 QPainterPath p;// = QGraphicsObject::shape(); 00182 QRectF rec(QGraphicsObject::boundingRect()); 00183 //rec.setWidth(rec.width() - 2 * (mMaxRadius + 1)); 00184 //rec.setX(rec.x() + (mMaxRadius + 1)); 00185 p.addRect(rec); 00186 00187 /*//exclude children 00188 foreach (NodeConnector *c, connectors) { 00189 //dw problem: label already deleted but connector tries to enable it? 00190 //c->deleteConnections(); 00191 p = p.subtracted(c->shape()); 00192 }*/ 00193 00194 /*//add children 00195 foreach (NodeConnector *c, connectors) { 00196 p.addPath(this->mapFromItem(c, c->shape())); 00197 }*/ 00198 00199 return p; 00200 } 00201 00202 00203 /* // 00204 void NodeItem::setWidget(QWidget *widget) { 00205 //does this work for all possible wiget types 00206 QGraphicsObject::setWidget(widget); 00207 connect(widget, SIGNAL(destroyed()), this, SLOT(deleted())); 00208 }*/ 00209 00210 void NodeItem::addConnector(NodeConnector* nc) { 00211 connectors.append(nc); 00212 if (nc->mRadius > mMaxRadius) { 00213 mMaxRadius = nc->mRadius; 00214 } 00215 00216 updateConnectorsPos(); 00217 prepareGeometryChange(); 00218 } 00219 00220 00222 void NodeItem::deleteConnections() 00223 { 00224 foreach (NodeConnector *c, connectors) { 00225 //dw problem: label already deleted but connector tries to enable it? 00226 c->deleteConnections(); 00227 } 00228 00229 //dw good location?, needed? 00230 //this->scene()->removeItem(this); 00231 } 00233 00234 void NodeItem::removeWigetFromConnectors() { 00235 foreach (NodeConnector *c, connectors) { 00236 //dw problem: label already deleted but connector tries to enable it? 00237 c->removeWidget(); 00238 } 00239 } 00240 00242 void NodeItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) 00243 { 00244 scene()->clearSelection(); 00245 setSelected(true); 00246 //dw new3 00247 //mContextMenu->exec(event->screenPos()); 00248 if (mContextMenu != NULL) { 00249 mContextMenu->exec(event->screenPos()); 00250 } 00251 } 00253 00255 QVariant NodeItem::itemChange(GraphicsItemChange change, //dw FIXME: needs much cleanup 00256 const QVariant &value) 00257 { 00258 00259 //dw now in paint, check if this is a good idea (e.g. when is it called) 00260 //dw667 backmerge: was commented, but is shotgun approach!!! 00261 if (change == QGraphicsObject::ItemPositionChange) { 00262 updateConnectorsPos(); 00263 } 00264 //does this create loop on selection? 00265 00266 00267 /*//dw FIXME:only proxified 00268 //dw if visibilty changes to false, kill wiget (TODO: make configurable, usfull for Dialogs and such) 00269 if (change == QGraphicsObject::ItemVisibleHasChanged && !value.value<bool>()) { 00270 deleted(); 00271 return value; 00272 } 00273 */ 00274 00275 00276 00277 /* 00278 //dw 669: turn back on resize handle controlling 00279 //dw new3: do not allow cursor changes, better only over connector! 00280 */ 00281 if (mControlResizeHandles && change == QGraphicsObject::ItemCursorChange) { 00282 QCursor cur = qVariantValue<QCursor>(value); 00283 //FIXME: do we really have to do this by hand? 00284 //suppress all resizes 00285 if (cur.shape() == Qt::SizeVerCursor || cur.shape() == Qt::SizeHorCursor || cur.shape() == Qt::SizeBDiagCursor || cur.shape() == Qt::SizeFDiagCursor) { 00286 if (mNoResize) { 00287 return Qt::ArrowCursor; 00288 } 00289 else { 00290 foreach (NodeConnector *con, connectors) { 00291 if (con->isUnderMouse()) { 00292 return Qt::ArrowCursor; 00293 } 00294 } 00295 } 00296 } 00297 } 00298 00299 00300 //dw 669: turn back on resize handle controlling 00301 //dw ugly hack, find better way 00302 //dw deselecting proxy item dialog will cause error sometimes, has size of bounding rect, will not redraw connections 00303 if (change == QGraphicsObject::ItemSelectedChange || change == QGraphicsObject::ItemTransformChange || change == QGraphicsObject::ItemScaleChange 00304 || change == QGraphicsObject::ItemSendsGeometryChanges || change == QGraphicsObject::ItemMatrixChange) { 00305 /* 00306 foreach (NodeConnector *con, connectors) { 00307 con->updatePositionGeometry(); 00308 } 00309 */ 00310 updateConnectorsPos(); 00311 } 00312 if (change == QGraphicsObject::ItemPositionHasChanged || change == QGraphicsObject::ItemSelectedChange) { 00313 /* 00314 foreach (NodeConnector *con, connectors) { 00315 con->updatePositionGeometry(); 00316 } 00317 */ 00318 updateConnectorsPos(); 00319 } 00320 00321 00322 /*//dw debug help 00323 if (change == QGraphicsObject::ItemSelectedChange || change == QGraphicsObject::ItemEnabledChange || change == QGraphicsObject::ItemVisibleHasChanged || change == QGraphicsObject::ItemPositionChange 00324 || change == QGraphicsObject::ItemZValueChange || change == QGraphicsObject::ItemZValueHasChanged) { 00325 //scene()->clearSelection(); 00326 //setSelected(true); 00327 //return true; 00328 return QGraphicsObject::itemChange(change, value); 00329 }*/ 00330 00331 00332 return QGraphicsObject::itemChange(change, value); 00333 //return value; 00334 } 00336 00337 /*//dw FIXME:only proxified 00338 //dw669: new, fixes connector position on resizing, why can it not be done in itemChange? 00339 void NodeItem::resizeEvent ( QGraphicsSceneResizeEvent * event ) { 00340 QGraphicsObject::resizeEvent(event); 00341 updateConnectorsPos(); 00342 } 00343 */ 00344 00345 //dw new4: remove again 00346 void NodeItem::hoverMoveEvent ( QGraphicsSceneHoverEvent * event ) { 00347 event->ignore(); 00348 return; 00349 } 00350 00351 void NodeItem::updateConnectorsPos() { 00352 foreach (NodeConnector *con, connectors) { 00353 //dw667 backmerge: was active 00354 //con->updatePositionGeometry(); 00355 //dw new 00356 con->updatePosition(); 00357 } 00358 //dw667: was active 00359 //update(); 00360 } 00361 00362 00363 void NodeItem::debugPaint(QPainter *painter) { 00364 //dw debug 00365 static int i = 0, j=0, k=0; 00366 painter->fillRect(boundingRect(), /*Qt::green*/ QColor(i=(i+19)%256 , j=(j+51)%256, k=(k+11)%256)); // to see item. 00367 //painter->fillPath(shape(), QColor(i=(i+19)%256 , j=(j+51)%256, k=(k+11)%256)); 00368 } 00369 00370 00371 //dw 00372 void NodeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *w) 00373 { 00374 if (static_cast<DiagramScene*>(scene())->isDebugDraw()) { 00375 debugPaint(painter); 00376 } 00377 //dw new 00378 //dw667: was active 00379 //updateConnectorsPos(); 00380 00381 QGraphicsObject::paint(painter, option, w); 00382 //dw new2 00383 //QGraphicsObject::paint(painter, option, w); 00384 00385 //dw new3: why do we have to call paint of children??? 00386 //dw667: was active 00387 /* 00388 foreach (NodeConnector *c, connectors) { 00389 //dw problem: label already deleted but connector tries to enable it? 00390 c->paint(painter, option, w); 00391 c->update(); 00392 } 00393 */ 00394 } 00395 00396 /* 00397 //dw new3 00398 void NodeItem::update(const QRectF & rect) { 00399 00400 //dw new3: why do ourself 00401 foreach (NodeConnector *c, connectors) { 00402 //dw problem: label already deleted but connector tries to enable it? 00403 //c->paint(painter, option, w); 00404 c->update(rect); 00405 } 00406 00407 QGraphicsObject::update(rect); 00408 } 00409 */ 00410 00411 00412 /*//dw FIXME:only proxified 00413 00414 //dw TODO: move to good visible location, check which types should be included 00415 //const char* NodeItem::shouldNotMoveTypes[] = {"QLineEdit", "foo", "bar"}; 00416 const char* NodeItem::shouldMoveOnClickTypes[] = {"QDialog", "QFrame", "QGroupBox"}; 00417 00418 bool NodeItem::shouldMoveNode(QGraphicsSceneMouseEvent *mouseEvent) { 00419 QPointF pos = mouseEvent->pos(); 00420 QPointer<QWidget> hitWidget = widget()->childAt(pos.toPoint()); 00421 if (hitWidget == NULL) { 00422 return true; 00423 } 00424 //foreach(QString t, shouldNotMoveTypes) { 00425 // if (alienWidget->inherits(t.toStdString().c_str())) { 00426 const size_t len = sizeof(shouldMoveOnClickTypes) / sizeof(shouldMoveOnClickTypes[0]); 00427 for (size_t i = 0; i < len; ++i) { 00428 if (hitWidget->inherits(shouldMoveOnClickTypes[i])) { 00429 return true; 00430 } 00431 } 00432 return false; 00433 } 00434 00435 void NodeItem::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) { 00436 if (shouldMoveNode(mouseEvent)) { 00437 QGraphicsObject::mousePressEvent(mouseEvent); 00438 isMoving = true; 00439 // what if we have to remove that? 00440 scene()->clearSelection(); 00441 scene()->clearFocus(); 00442 setSelected(true); 00443 } 00444 else { 00445 QGraphicsObject::mousePressEvent(mouseEvent); 00446 } 00447 } 00448 00449 void NodeItem::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) { 00450 if (isMoving) { 00451 QGraphicsObject::mouseMoveEvent(mouseEvent); 00452 00453 //dw667 backmerge: was active 00454 /* 00455 //dw new5 00456 foreach (NodeConnector *con, connectors) { 00457 //dw667 backmerge: was active 00458 //con->updatePositionGeometry(); 00459 //dw667 backmerge: new 00460 con->updatePosition(); 00461 } 00462 */ 00463 /* 00464 } 00465 else { 00466 QGraphicsObject::mouseMoveEvent(mouseEvent); 00467 } 00468 00469 //scene()->clearSelection(); 00470 //setSelected(true); 00471 00472 //dw667 backmerge: was active 00473 //updateConnectorsPos(); 00474 } 00475 00476 void NodeItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) { 00477 if (isMoving) { 00478 isMoving = false; 00479 } 00480 //call both always to lose no events and to not have to do the same shit for clicks too 00481 QGraphicsObject::mouseReleaseEvent(mouseEvent); 00482 QGraphicsObject::mouseReleaseEvent(mouseEvent); 00483 scene()->clearSelection(); 00484 setSelected(true); 00485 00486 //updateConnectorsPos(); 00487 } 00488 */ 00489