void AbstractBoxItem::addInterface(InterfaceItem *i, bool resetPosition) {
interfaces.append(i);
if (resetPosition) resetInterfacesPosition();
- updateGeometry();
+ updateGeometry(InterfaceMove);
update();
}
delete i;
//resetInterfacesPosition();
- updateGeometry();
+ updateGeometry(InterfaceMove);
update();
}
}
}
-void AbstractBoxItem::deplaceInterface(QPointF pos) {
+void AbstractBoxItem::moveInterfaceTo(QPointF pos) {
double positionRatio;
if(currentInterface->getOrientation() == Parameters::North || currentInterface->getOrientation() == Parameters::South){
if(pos.x() < 0){
foreach(InterfaceItem *item, interfaces){
item->updatePosition();
}
+ // NB: dunno the utility of this test !!
if (getScene() != NULL) {
// update all connections from/to this block
foreach(ConnectionItem *item, getScene()->getConnectionItems()){
if ((item->getFromInterfaceItem()->getOwner() == this) || (item->getToInterfaceItem()->getOwner() == this)) {
- item->setPathes();
+ item->setPath();
}
}
}
void addInterface(InterfaceItem* i, bool resetPosition = false);
void removeInterface(InterfaceItem* i);
void resetInterfacesPosition();
- void deplaceInterface(QPointF pos);
+ /*!
+ * \brief moveInterfaceTo
+ * \param pos the new position (in scene) of the interface
+ *
+ * This method is called when user moves an InterfaceItem.
+ * see BoxItem::mouseMoveEvent() and GroupItem::mouseMoveEvent()
+ */
+ void moveInterfaceTo(QPointF pos);
+ /*!
+ * \brief updateInterfacesAndConnections
+ *
+ * This method allows to recompute the absolute position of the interfaces of this box
+ * taking into account their relative position (see positionRatio atribute) in the width/height
+ * of the box border they are located on. It allows update the shape of all ConnectionItem
+ * connected to this box.
+ *
+ * CAUTION: this method supposes that before its call, a call to prepareGeometryChange() hase been
+ * done for the BoxItem that owns this InterfaceItem, so that the scene will readraw automatically
+ * the BoxItem. For the connections, the call to prepareGeometryChange() is done within setPath()
+ * that is called in this method. Thus, there is no need to call update() after the termination of
+ * this method.
+ */
void updateInterfacesAndConnections();
InterfaceItem *searchInterfaceByName(QString name);
params = _params;
// creating the widget : tree, buttons, ...
- layout = new QBoxLayout(QBoxLayout::TopToBottom, this);
+ QBoxLayout* layout = new QBoxLayout(QBoxLayout::TopToBottom, this);
tree = new QTreeWidget(this);
- buttonAdd = new QPushButton("add", this);
+
+ buttonAdd = new QPushButton("add to", this);
buttonAdd->setEnabled(false);
+ comboScenes = new QComboBox();
+
+ QHBoxLayout* layBottom = new QHBoxLayout;
+ layBottom->addWidget(buttonAdd);
+ layBottom->addWidget(comboScenes);
connect(tree, SIGNAL(itemClicked(QTreeWidgetItem*,int)), this, SLOT(clicked()));
connect(tree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), this, SLOT(doubleClicked()));
QTreeWidgetItem* item = tree->invisibleRootItem();
tree->setHeaderLabel("Blocks list");
-
addChild(cat,item);
layout->addWidget(tree);
- layout->addWidget(buttonAdd);
+ layout->addLayout(layBottom);
this->setLayout(layout);
this->setFixedSize(300,230);
if(item->data(1,Qt::DisplayRole).isValid() && item->data(2,Qt::DisplayRole).isValid()){
int idParent = item->data(1,Qt::DisplayRole).toInt();
int idBlock = item->data(2,Qt::DisplayRole).toInt();
- dispatcher->addBlock(idParent, idBlock);
+ QVariant v = comboScenes->currentData();
+ cout << "adding block to scene " << v.toInt() << endl;
+ dispatcher->addBlock(idParent, idBlock, v.toInt());
}
// only take the first selected
// calling dispatcher addBlock() method.
}
-
-void BlockLibraryWidget::clicked()
-{
+void BlockLibraryWidget::clicked() {
if(tree->selectedItems().length() > 0){
QTreeWidgetItem *item = tree->selectedItems().at(0);
if(item->data(1,Qt::DisplayRole).isValid())
}
}
-void BlockLibraryWidget::doubleClicked()
-{
+void BlockLibraryWidget::doubleClicked() {
addClicked();
}
+
+void BlockLibraryWidget::updateComboScene() {
+ comboScenes->clear();
+ QMap<int,QString> list = dispatcher->getAllGroupNames();
+ QMapIterator<int,QString> iter(list);
+ while (iter.hasNext()) {
+ iter.next();
+ comboScenes->addItem(iter.value(),QVariant(iter.key()));
+ }
+}
explicit BlockLibraryWidget(Dispatcher* _dispatcher, Parameters* _params, QWidget *parent = 0);
~BlockLibraryWidget();
+public slots:
+ void updateComboScene();
+
private slots:
void addClicked();
void clicked();
Dispatcher* dispatcher;
QTreeWidget* tree;
QPushButton* buttonAdd;
- QBoxLayout *layout;
+ QComboBox* comboScenes;
// other attributes
void addChild(BlockCategory *catParent, QTreeWidgetItem* itemParent);
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges);
initInterfaces();
- updateGeometry();
+ updateGeometry(InterfaceMove);
resetInterfacesPosition();
QPointF initPos = QPointF(0.0,0.0) - originPoint;
setPos(initPos);
bool boxSizeChanged = false;
- if ((type == Resize) || (type == InterfaceMove)) {
- updateMinimumSize();
- }
+ // whatever the change, the minimum size may ahve changed
+ updateMinimumSize();
if (type == Resize) {
- prepareGeometryChange();
- updateInterfacesAndConnections();
+ // resize implies to move interfaces and to update connections
boxSizeChanged = true;
}
- if (boxWidth < minimumBoxWidth) {
- boxWidth = minimumBoxWidth;
- boxSizeChanged = true;
- }
- if (boxHeight < minimumBoxHeight) {
- boxHeight = minimumBoxHeight;
- boxSizeChanged = true;
+ else if (type == InterfaceMove) {
+ // if an interface moves, it may change the box size
+ if (boxWidth < minimumBoxWidth) {
+ boxWidth = minimumBoxWidth;
+ boxSizeChanged = true;
+ }
+ if (boxHeight < minimumBoxHeight) {
+ boxHeight = minimumBoxHeight;
+ boxSizeChanged = true;
+ }
}
if (boxSizeChanged) {
updateInterfacesAndConnections();
}
+
double x = 0.0;
double y = 0.0;
totalWidth = boxWidth;
// update all connections from/to this block
foreach(ConnectionItem *item, getScene()->getConnectionItems()){
if ((item->getFromInterfaceItem()->getOwner() == this) || (item->getToInterfaceItem()->getOwner() == this)) {
- item->setPathes();
+ item->setPath();
}
}
cursorPosition = event->scenePos();
break;
}
// recompute the geometry of the block and possibly the group item
- if (updateGeometry()) {
+ if (updateGeometry(Resize)) {
(getScene()->getGroupItem())->updateShape();
}
}
else if(params->editState == Parameters::EditInterfaceMove) {
prepareGeometryChange();
- deplaceInterface(event->pos());
+ moveInterfaceTo(event->pos());
// recompute the geometry of the block
- if (updateGeometry()) {
+ if (updateGeometry(InterfaceMove)) {
cout << "must recompute group item geometry" << endl;
(getScene()->getGroupItem())->updateShape();
}
// update connection from/to the selected interface
foreach(ConnectionItem *item, getScene()->getConnectionItems()){
if ((item->getFromInterfaceItem() == currentInterface) || (item->getToInterfaceItem() == currentInterface)) {
- item->setPathes();
+ item->setPath();
}
}
}
showProperties = menu.addAction("Show properties");
ConnectedInterface* iface = ifaceItem->refInter;
+ ConnectedInterface* ifaceGroup = NULL;
+
+
if ((iface->getDirection() == AbstractInterface::Input) && (iface->getConnectedFrom() == NULL)) {
connectToGroup = menu.addAction("Connect to group input");
}
else if ((iface->getDirection() == AbstractInterface::Output) && (!iface->isConnectedTo())) {
connectToGroup = menu.addAction("Connect to group output");
}
- else if ((iface->getConnectionFromParentGroup() != NULL) || (iface->getConnectionToParentGroup() != NULL)) {
- disconnectFromGroup = menu.addAction("Disconnect from group");
+ else if (iface->getConnectionFromParentGroup() != NULL) {
+ ifaceGroup = iface->getConnectionFromParentGroup();
+ if ((!ifaceGroup->isConnectedFrom()) || (!ifaceGroup->isConnectedTo())) {
+ disconnectFromGroup = menu.addAction("Disconnect from group");
+ }
+ }
+ else if (iface->getConnectionToParentGroup() != NULL) {
+ ifaceGroup = iface->getConnectionToParentGroup();
+ if ((!ifaceGroup->isConnectedFrom()) || (!ifaceGroup->isConnectedTo())) {
+ disconnectFromGroup = menu.addAction("Disconnect from group");
+ }
}
if (iface->isFunctionalInterface()) {
setCursor(Qt::PointingHandCursor);
setZValue(0);
- setPathes();
+ setPath();
}
}
-void ConnectionItem::setPathes() {
+void ConnectionItem::setPath() {
+ // signals to the scene that this connection is going to change of shape.
prepareGeometryChange();
pointFrom = fromInterfaceItem->getEndPointInGroup();
using namespace std;
using namespace Qt;
-/* NOTES :
+/*! \brief ConnectionItem class
- A connection item represent a graphical link between two interface items.
+ A ConnectionItem represents a graphical link between two interface items.
Even if it links two in/out interfaces, it is always oriented.
The orientation depends on the type and direction of linked interfaces :
void setSelected(bool selected);
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
- void setPathes();
+
+ /*!
+ * \brief setPath
+ * setPath() allows to compute the graphical shape of the ConnectionItem
+ * taking into account the position/direction of from and to interface items.
+ * Depending on their vlaue, it calls on of the dedicated methods.
+ *
+ * CAUTION: this method calls prepareGeometryChange() so that the scene
+ * can automatically updates and redraw the ConnectionItem. Thus, there is
+ * no need to call update() after the termination of this method.
+ *
+ */
+ void setPath();
void addInterPoint(QPointF point);
static int counter;
#include "InterfacePropertiesWindow.h"
+int Dispatcher::sceneCounter = 0;
Dispatcher::Dispatcher(Parameters* _params, MainWindow* _window) {
params = _params;
currentGroup = topGroup;
// getting the newly created scene
GroupScene *scene = topGroup->getScene();
+
params->setTopScene(scene);
params->setCurrentScene(scene);
return NULL;
}
+ groupList.append(topGroup);
return topGroup;
}
currentGroup->setWindowTitle("blast - "+text);
}
}
+
+ mainWindow->getLibrary()->updateComboScene();
}
else {
QMessageBox::warning(NULL,"Error in given name",
item->refInter->setName(text);
}
item->setName(text);
+
}
else {
QMessageBox::warning(NULL,"Error in given name",
}
-void Dispatcher::addBlock(int idCategory, int idBlock) {
+void Dispatcher::addBlock(int idCategory, int idBlock, int idScene) {
- GroupScene *scene = params->getCurrentScene();
+ GroupScene *scene = searchSceneById(idScene);
FunctionalBlock* newOne = params->addFunctionalBlock(idCategory, idBlock);
scene->createBlockItem(newOne);
}
currentGroup = topGroup;
// getting the newly created scene
GroupScene *scene = topGroup->getScene();
+ scene->setId(sceneCounter++);
params->setTopScene(scene);
params->setCurrentScene(scene);
// creating the view part of the group
scene->setGroupItem(group);
+ groupList.append(topGroup);
return topGroup;
}
GroupWidget *Dispatcher::createChildScene(GroupWidget* parentWidget, BoxItem *upperItemOfGroupItem) {
- GroupBlock* parentBlock = NULL;
+ // getting back the goup block already created
+ GroupBlock* groupBlock = NULL;
if (upperItemOfGroupItem != NULL) {
- parentBlock = AB_TO_GRP(upperItemOfGroupItem->getRefBlock());
- }
- // creating the model part of the group
- GroupBlock *groupBlock = new GroupBlock(parentBlock);
- groupBlock->setName("no name");
+ groupBlock = AB_TO_GRP(upperItemOfGroupItem->getRefBlock());
+ }
// creating the view part of the group
GroupItem *groupItem = new GroupItem(upperItemOfGroupItem,groupBlock,this,params);
// creating the group widget
GroupWidget* group = new GroupWidget(parentWidget, this, params);
// getting the newly created scene
GroupScene *scene = group->getScene();
+ scene->setId(sceneCounter++);
// affecting group item to the scene
scene->setGroupItem(groupItem);
+ groupList.append(group);
+
+ mainWindow->getLibrary()->updateComboScene();
return group;
}
// getting the GroupBlock and GroupItem that are parent of the block that owns item
ConnectedInterface *refInter = item->refInter;
+ cout << "owner of iface = " << qPrintable(refInter->getOwner()->getName()) << endl;
GroupBlock* parentBlock = AB_TO_GRP(refInter->getOwner()->getParent());
+ cout << "create iface for parent group = " << qPrintable(parentBlock->getName()) << endl;
GroupItem *parentItem = item->getOwner()->getScene()->getGroupItem();
// creating/adding the group interface in the graph model
}
}
+QMap<int, QString> Dispatcher::getAllGroupNames() {
+
+ QMap<int, QString> list;
+ foreach(GroupWidget *group, groupList) {
+ list.insert(group->getScene()->getId(), group->getScene()->getGroupItem()->getRefBlock()->getName());
+ }
+ return list;
+}
+
GroupScene* Dispatcher::searchSceneById(int id) {
foreach(GroupWidget *group, groupList){
if(group->getScene()->getId() == id)
GroupWidget* createChildScene(GroupWidget* parentWidget, BoxItem* upperItemOfGroupItem = NULL);
void showRaiseWindow(AbstractBoxItem *item);
void showRstClkInter(AbstractBoxItem *item);
+ void addNewEmptyGroup();
void addNewFullGroup();
inline GroupWidget* getCurrentGroup() { return currentGroup; }
bool isCurrentProject;
public slots:
-
+ QMap<int, QString> getAllGroupNames();
GroupScene* searchSceneById(int id);
+ GroupScene* searchSceneByName(QString name);
BoxItem* searchBlockItemById(int id);
GroupItem* searchGroupItemById(int id);
InterfaceItem* searchInterfaceItemById(int id);
void removeBlock(AbstractBoxItem* item);
void duplicateBlock(BoxItem* item);
void duplicateInterface(InterfaceItem* item);
- void addBlock(int idCategory, int idBlock);
+ void addBlock(int idCategory, int idBlock, int idScene);
ConnectionItem *addConnection(InterfaceItem *input, InterfaceItem *output);
void removeAllBlockConnections(AbstractBoxItem *block);
void removeConnection(ConnectionItem *conn);
QList<GroupWidget*> groupList;
GroupWidget* currentGroup;
GroupWidget *topGroup;
+
+ static int sceneCounter;
};
#endif // __DISPATCHER_H__
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges);
- updateGeometry();
+
+ updateGeometry(InterfaceMove);
QPointF initPos = QPointF(0.0,0.0) - originPoint;
setPos(initPos);
cout << "total size of group: " << totalWidth << "," << totalHeight << endl;
}
void GroupItem::updateShape() {
- updateGeometry();
+ updateGeometry(InterfaceMove);
}
bool GroupItem::updateGeometry(ChangeType type) {
QPointF oldOrigin = originPoint;
QSize oldSize(totalWidth,totalHeight);
- updateMinimumSize();
bool boxSizeChanged = false;
+
+ // whatever the change, the minimum size may have changed
+ updateMinimumSize();
+
+ if (type == Resize) {
+ boxSizeChanged = true;
+ }
+ // if an internal block has moved, the actual box size may be inadequate
if (boxWidth < minimumBoxWidth) {
boxWidth = minimumBoxWidth;
boxSizeChanged = true;
}
if (boxHeight < minimumBoxHeight) {
boxHeight = minimumBoxHeight;
- boxSizeChanged = true;
+ boxSizeChanged = true;
}
+
if (boxSizeChanged) {
updateInterfacesAndConnections();
}
+
// compute the max. width of interfaces' name for 4 orientations.
int maxSouth = 0;
int maxNorth = 0;
originPoint.setY(y);
if ((boxSizeChanged) || (newSize != oldSize) || (originPoint != oldOrigin)) {
- //cout << "must change group item shape" << endl;
+ cout << "must change group item shape" << endl;
prepareGeometryChange();
return true;
}
cout << "abnormal case while resizing block" << endl;
break;
}
- updateGeometry();
+ updateGeometry(Resize);
/*
// recompute the geometry of the block
updateGeometry();
}
else if(params->editState == Parameters::EditInterfaceMove) {
prepareGeometryChange();
- deplaceInterface(event->pos());
+ moveInterfaceTo(event->pos());
// recompute the geometry of the block
- updateGeometry();
+ updateGeometry(InterfaceMove);
// update connection from/to the selected interface
foreach(ConnectionItem *item, getScene()->getConnectionItems()){
if ((item->getFromInterfaceItem() == currentInterface) || (item->getToInterfaceItem() == currentInterface)) {
- item->setPathes();
+ item->setPath();
}
}
- update();
+ //update();
}
}
return lst;
}
-void GroupScene::createBlockItem(AbstractBlock *block) {
+BoxItem *GroupScene::createBlockItem(AbstractBlock *block) {
BoxItem* blockItem = new BoxItem(block,dispatcher,params,groupItem);
blockItem->setZValue(1);
addBlockItem(blockItem);
+ return blockItem;
}
void GroupScene::addBlockItem(BoxItem* item) {
void GroupScene::updateConnectionItemsShape() {
foreach(ConnectionItem* conn, connectionItems){
- conn->setPathes();
+ conn->setPath();
}
}
// others
- void createBlockItem(AbstractBlock* block);
+ BoxItem* createBlockItem(AbstractBlock* block);
void addBlockItem(BoxItem* item);
void removeBlockItem(BoxItem* item);
void createConnectionItem(InterfaceItem* iface1, InterfaceItem* iface2);
void GroupWidget::slotNewEmptyGroup() {
// creating the GroupBlock in graph model
- GroupBlock* groupBlock = params->addGroupBlock();
- // creating the BlockItem in the inner scene
- BoxItem* block = new BoxItem(groupBlock, dispatcher, params, scene->getGroupItem());
-
- GroupWidget* child = dispatcher->createChildScene(this,block);
+ GroupBlock* parent = AB_TO_GRP(scene->getGroupItem()->getRefBlock());
+ cout << "new group : parent = "<< qPrintable(parent->getName()) << endl;
+ GroupBlock* groupBlock = params->getGraph()->createChildBlock(parent);
+ cout << "new group : child = "<< qPrintable(groupBlock->getName()) << ", child of " << qPrintable(groupBlock->getParent()->getName()) << endl;
+ // creating the BlockItem in the scene
+ BoxItem* newItem = scene->createBlockItem(groupBlock);
+
+ GroupWidget* child = dispatcher->createChildScene(this,newItem);
child->show();
}
// creating block library
library = new BlockLibraryWidget(dispatcher,params);
- isCurrentProject = false;
+ params->isCurrentProject = false;
QLabel* labDefault = new QLabel("BLAST: BLock ASsembler Tool");
stackedWidget = new QStackedWidget;
GroupWidget* topGroup = dispatcher->loadProject(absoluteFilename);
if (topGroup != NULL) {
addTopGroup(topGroup);
+ library->updateComboScene();
}
else {
QMessageBox msgBox;
enableProjectActions(true, PROJECT_CLOSE | PROJECT_SAVE | PROJECT_SAVEAS | PROJECT_LIB, OP_RAZ);
GroupWidget* topGroup = dispatcher->createTopScene();
addTopGroup(topGroup);
-
+ library->updateComboScene();
}
void MainWindow::slotCloseProject(){
dispatcher->closeCurrentProject();
- isCurrentProject = false;
+ params->isCurrentProject = false;
params->unsaveModif = false;
absoluteFilename = QString();
}
void MainWindow::slotSaveAsProject(){
- if(isCurrentProject){
+ if(params->isCurrentProject){
QFileDialog dial(0, "Select a file", "save/");
dial.setDefaultSuffix(".xml");
dial.setAcceptMode(QFileDialog::AcceptSave);
}
void MainWindow::closeEvent(QCloseEvent *event){
- if(isCurrentProject){
+ if(params->isCurrentProject){
QMessageBox msgBox;
msgBox.setText("The project has been modified.");
msgBox.setInformativeText("Do you want to save your changes?");
Parameters *params;
BlockLibraryWidget *library;
- bool isCurrentProject;
QString absoluteFilename;
QString checkNewVersion;
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
moc_%.cpp : %.h
- moc -qt=$(QTVER) $(DEFINES) $(INCPATH) $< -o $@
+ /usr/bin/moc -qt=$(QTVER) $(DEFINES) $(INCPATH) -o $@ $<
rcc_%.cpp : %.qrc
- rcc -qt=$(QTVER) $< -o $@ -name $*
+ /usr/bin/rcc -qt=$(QTVER) $< -o $@ -name $*
### DEPENDENCIES OF EACH SOURCE FILE (auto-added by configure) ###
/***************************************************\r
attributes that are specific for the current project\r
****************************************************/\r
+ bool isCurrentProject; // true if a projet is currently open\r
int sceneMode; // takes values from MODE_XXX\r
CursorState cursorState;\r
EditState editState; // takes values from EDIT_STATE_XXX\r
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
-<!-- Written by QtCreator 3.2.1, 2017-04-26T13:47:31. -->
+<!-- Written by QtCreator 3.2.1, 2017-04-26T18:51:42. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
- <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/sdomas/Projet/Blast/code/v0.2</value>
+ <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/sdomas/Projet/Blast/code/blast</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets">
$(BUILDPATH)/MainWindow.o \
$(BUILDPATH)/moc_MainWindow.o \
$(BUILDPATH)/ArithmeticEvaluator.o \
- $(BUILDPATH)/moc_ArithmeticEvaluator.o \
$(BUILDPATH)/BlockWidget.o \
$(BUILDPATH)/moc_BlockWidget.o \
$(BUILDPATH)/GroupWidget.o \