1 /****************************************************************************
3 ** Copyright (C) 2006-2007 Trolltech ASA. All rights reserved.
5 ** This file is part of the example classes of the Qt Toolkit.
7 ** Licensees holding a valid Qt License Agreement may use this file in
8 ** accordance with the rights, responsibilities and obligations
9 ** contained therein. Please consult your licensing agreement or
10 ** contact sales@trolltech.com if any conditions of this licensing
11 ** agreement are not clear to you.
13 ** Further information about Qt licensing is available at:
14 ** http://www.trolltech.com/products/qt/licensing.html or by
15 ** contacting info@trolltech.com.
17 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
18 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 ****************************************************************************/
22 #include "graphwidget.h"
27 #include <QGraphicsScene>
28 #include <QWheelEvent>
29 #include <QApplication>
33 #include <TFunction_Iterator.hxx>
34 #include <TFunction_IFunction.hxx>
35 #include <TFunction_GraphNode.hxx>
36 #include <TFunction_Scope.hxx>
37 #include <TFunction_DriverTable.hxx>
38 #include <TFunction_Driver.hxx>
39 #include <TFunction_Function.hxx>
41 #include <TDataStd_Name.hxx>
42 #include <TDF_ChildIterator.hxx>
43 #include <TDF_ListIteratorOfLabelList.hxx>
44 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
46 #include "SimpleDriver.h"
47 #include "PointDriver.h"
48 #include "CircleDriver.h"
49 #include "PrismDriver.h"
50 #include "ConeDriver.h"
51 #include "CylinderDriver.h"
52 #include "ShapeSaverDriver.h"
53 #include "SimpleDriver.h"
55 GraphWidget::GraphWidget(QWidget* parent):QGraphicsView(parent),
56 myThread1(0),myThread2(0),myThread3(0),myThread4(0)
58 QGraphicsScene *scene = new QGraphicsScene(this);
59 scene->setItemIndexMethod(QGraphicsScene::NoIndex);
60 scene->setSceneRect(1, 1, parent->width(), parent->height());
62 setCacheMode(CacheBackground);
63 setRenderHint(QPainter::Antialiasing);
64 setTransformationAnchor(AnchorUnderMouse);
65 setResizeAnchor(AnchorViewCenter);
68 setMinimumSize(400, 400);
69 setWindowTitle(tr("Function Mechanism"));
74 GraphWidget::~GraphWidget()
79 myThread1->deleteLater();
84 myThread2->deleteLater();
89 myThread3->deleteLater();
94 myThread4->deleteLater();
98 bool GraphWidget::createModel(const Handle(TDocStd_Document)& doc)
102 TFunction_Iterator fIterator(myDocument->Main());
103 fIterator.SetUsageOfExecutionStatus(false);
104 Handle(TFunction_Scope) scope = TFunction_Scope::Set(myDocument->Main());
106 // Find out the size of the grid: number of functions in X and Y directions
107 int nbx = 0, nby = 0;
108 while (!fIterator.Current().IsEmpty())
110 const TDF_LabelList& funcs = fIterator.Current();
111 if (funcs.Extent() > nbx)
112 nbx = funcs.Extent();
120 int dx = width() / nbx, dy = height() / nby;
121 int x0 = dx / 2, y0 = dy / 2; // start position
124 double x = x0, y = y0;
125 fIterator.Init(myDocument->Main());
126 while (!fIterator.Current().IsEmpty())
128 const TDF_LabelList& funcs = fIterator.Current();
129 TDF_ListIteratorOfLabelList itrl(funcs);
130 for (; itrl.More(); itrl.Next())
132 TDF_Label L = itrl.Value();
133 Node *node = new Node(this);
134 node->setFunction(L);
135 scene()->addItem(node);
148 fIterator.Init(myDocument->Main());
149 while (!fIterator.Current().IsEmpty())
151 const TDF_LabelList& funcs = fIterator.Current();
152 TDF_ListIteratorOfLabelList itrl(funcs);
153 for (; itrl.More(); itrl.Next())
155 TDF_Label L = itrl.Value();
156 Node* node = findNode(L);
160 // Find backward dependencies of the function
161 TFunction_IFunction iFunc(L);
162 Handle(TFunction_GraphNode) graphNode = iFunc.GetGraphNode();
163 const TColStd_MapOfInteger& prev = graphNode->GetPrevious();
164 TColStd_MapIteratorOfMapOfInteger itrm(prev);
165 for (; itrm.More(); itrm.Next())
167 const int argID = itrm.Key();
168 const TDF_Label& argL = scope->GetFunction(argID);
169 Node* n = findNode(argL);
172 scene()->addItem(new Edge(n, node));
178 return !myDocument.IsNull();
181 void GraphWidget::wheelEvent(QWheelEvent *event)
183 scaleView(pow((double)2, -event->delta() / 240.0));
186 void GraphWidget::drawBackground(QPainter *painter, const QRectF &rect)
191 QRectF sceneRect = this->sceneRect();
192 QRectF rightShadow(sceneRect.right(), sceneRect.top() + 5, 5, sceneRect.height());
193 QRectF bottomShadow(sceneRect.left() + 5, sceneRect.bottom(), sceneRect.width(), 5);
194 if (rightShadow.intersects(rect) || rightShadow.contains(rect))
195 painter->fillRect(rightShadow, Qt::darkGray);
196 if (bottomShadow.intersects(rect) || bottomShadow.contains(rect))
197 painter->fillRect(bottomShadow, Qt::darkGray);
200 QLinearGradient gradient(sceneRect.topLeft(), sceneRect.bottomRight());
201 gradient.setColorAt(0, Qt::white);
202 gradient.setColorAt(1, Qt::lightGray);
203 painter->fillRect(rect.intersect(sceneRect), gradient);
204 painter->setBrush(Qt::NoBrush);
205 painter->drawRect(sceneRect);
208 void GraphWidget::scaleView(qreal scaleFactor)
210 qreal factor = matrix().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width();
211 if (factor < 0.07 || factor > 100)
214 scale(scaleFactor, scaleFactor);
217 // Find node of the function
218 Node* GraphWidget::findNode(const TDF_Label& L)
221 for (int i = 0; i < scene()->items().size(); i++)
223 Node* n = qgraphicsitem_cast<Node *>(scene()->items().at(i));
224 if (n && n->getFunction() == L)
233 void GraphWidget::compute()
235 myNbFinishedThreads = 0;
237 TFunction_Iterator fIterator(myDocument->Main());
238 fIterator.SetUsageOfExecutionStatus(true);
240 myThread1 = new FThread();
242 myThread2 = new FThread();
244 myThread3 = new FThread();
246 myThread4 = new FThread();
249 Handle(TFunction_Logbook) log = TFunction_Scope::Set(myDocument->Main())->GetLogbook();
250 myThread1->setLogbook(log);
252 myThread2->setLogbook(log);
254 myThread3->setLogbook(log);
256 myThread4->setLogbook(log);
258 myThread1->setIterator(fIterator);
260 myThread2->setIterator(fIterator);
262 myThread3->setIterator(fIterator);
264 myThread4->setIterator(fIterator);
266 myThread1->setGraph(this);
268 myThread2->setGraph(this);
270 myThread3->setGraph(this);
272 myThread4->setGraph(this);
274 myThread1->setThreadIndex(1);
276 myThread2->setThreadIndex(2);
278 myThread3->setThreadIndex(3);
280 myThread4->setThreadIndex(4);
282 QThread::Priority priority = QThread::LowestPriority;
283 if (!myThread1->isRunning())
284 myThread1->start(priority);
285 if (myNbThreads > 1 && !myThread2->isRunning())
286 myThread2->start(priority);
287 if (myNbThreads > 2 && !myThread3->isRunning())
288 myThread3->start(priority);
289 if (myNbThreads > 3 && !myThread4->isRunning())
290 myThread4->start(priority);
293 void GraphWidget::setNbThreads(const int nb)
296 if (myNbThreads < 4 && myThread4)
299 myThread4->deleteLater();
302 if (myNbThreads < 3 && myThread3)
305 myThread3->deleteLater();
308 if (myNbThreads < 2 && myThread2)
311 myThread2->deleteLater();
315 for (int i = 1; i <= myNbThreads; i++)
317 TFunction_DriverTable::Get()->AddDriver(PointDriver::GetID(), new PointDriver(), i);
318 TFunction_DriverTable::Get()->AddDriver(CircleDriver::GetID(), new CircleDriver(), i);
319 TFunction_DriverTable::Get()->AddDriver(PrismDriver::GetID(), new PrismDriver(), i);
320 TFunction_DriverTable::Get()->AddDriver(ConeDriver::GetID(), new ConeDriver(), i);
321 TFunction_DriverTable::Get()->AddDriver(CylinderDriver::GetID(), new CylinderDriver(), i);
322 TFunction_DriverTable::Get()->AddDriver(ShapeSaverDriver::GetID(), new ShapeSaverDriver(), i);
323 TFunction_DriverTable::Get()->AddDriver(SimpleDriver::GetID(), new SimpleDriver(), i);
327 int GraphWidget::getNbThreads()
332 void GraphWidget::setFinished()
334 myNbFinishedThreads++;
337 bool GraphWidget::isFinished()
339 return myNbThreads == myNbFinishedThreads ;
342 void GraphWidget::accelerateThread(const int thread_index)
344 bool all_slow = true;
345 if (myThread1 && myThread1->priority() != QThread::LowPriority)
347 if (all_slow && myThread2 && myThread2->priority() != QThread::LowPriority)
349 if (all_slow && myThread3 && myThread3->priority() != QThread::LowPriority)
351 if (all_slow && myThread4 && myThread4->priority() != QThread::LowPriority)
356 QThread::Priority priority = QThread::NormalPriority;
357 switch (thread_index)
360 myThread1->setPriority(priority);
363 myThread2->setPriority(priority);
366 myThread3->setPriority(priority);
369 myThread4->setPriority(priority);
374 void GraphWidget::slowDownThread(const int thread_index)
376 QThread::Priority priority = QThread::LowPriority;
377 switch (thread_index)
380 myThread1->setPriority(priority);
383 myThread2->setPriority(priority);
386 myThread3->setPriority(priority);
389 myThread4->setPriority(priority);