/****************************************************************************
Copyright (C) 2010-2012 the Office National des Forêts (ONF), France
and the Association de Recherche Technologie et Sciences (ARTS), Ecole Nationale Suprieure d'Arts et Métiers (ENSAM), Cluny, France.
All rights reserved.
Contact : alexandre.piboule@onf.fr
Developers : Michaël KREBS (ARTS/ENSAM)
This file is part of Computree version 2.0.
Computree is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Computree is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Computree. If not, see .
*****************************************************************************/
#include "gstepmanager.h"
#include "dm_guimanager.h"
#include "cdm_configfile.h"
#include "gstepmanageroptions.h"
#include "ct_result/abstract/ct_abstractresult.h"
#include "ct_step/abstract/ct_abstractsteploadfile.h"
#include "ct_abstractstepplugin.h"
#include "gaboutstepdialog.h"
#include
#include
#include
#include
#include
#include
#include
#include
GStepManager::GStepManager(CDM_StepManager &stepManager,
QWidget *parent) : QWidget(parent)
{
_stepManager = &stepManager;
_delegate = new MyTreeDelegate(&m_treeView);
m_proxy = new DM_StepManagerTreeViewProxy(this);
m_proxy->setSourceModel(&_model);
m_treeView.setModel(m_proxy);
m_treeView.setItemDelegate(_delegate);
m_treeView.setIndentation(12);
QStringList header;
header << tr("Nom");
header << tr("Debug");
header << tr("Temps");
_model.setHorizontalHeaderLabels(header);
m_rootItem = new MyQStandardItem(NULL, NULL, MyQStandardItem::Text, tr("Flux d'étapes"));
m_rootItem->setEditable(false);
_model.invisibleRootItem()->appendRow(m_rootItem);
#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
m_treeView.header()->setResizeMode(0, QHeaderView::ResizeToContents);
#else
m_treeView.header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
#endif
m_treeView.setStyleSheet(QString("QTreeView::item:selected{"
"color: rgb(255, 255, 255);"
"background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #F3C870, stop: 1 #BDA757);"
"}"));
delete layout();
setLayout(new QVBoxLayout());
layout()->addWidget(&m_treeView);
_contextMenuStep = new GTreeStepContextMenu(*_stepManager, this);
m_treeView.setContextMenuPolicy(Qt::CustomContextMenu);
//m_treeView.setExpandsOnDoubleClick(true);
connect(_contextMenuStep, SIGNAL(executeSelectedStep(CT_VirtualAbstractStep*)), this, SLOT(executeStep(CT_VirtualAbstractStep*)), Qt::QueuedConnection);
connect(_contextMenuStep, SIGNAL(executeModifySelectedStep(CT_VirtualAbstractStep*)), this, SLOT(executeModifyStep(CT_VirtualAbstractStep*)), Qt::QueuedConnection);
connect(_contextMenuStep, SIGNAL(configureInputResultOfSelectedStep(CT_VirtualAbstractStep*)), this, SLOT(configureInputResultOfStep(CT_VirtualAbstractStep*)), Qt::QueuedConnection);
connect(_contextMenuStep, SIGNAL(configureSelectedStep(CT_VirtualAbstractStep*)), this, SLOT(configureStep(CT_VirtualAbstractStep*)), Qt::QueuedConnection);
connect(_contextMenuStep, SIGNAL(deleteSelectedStep(CT_VirtualAbstractStep*)), this, SLOT(removeStep(CT_VirtualAbstractStep*)), Qt::QueuedConnection);
connect(_contextMenuStep, SIGNAL(loadResultOfSelectedStep(CT_AbstractStepSerializable*)), this, SLOT(loadResultStep(CT_AbstractStepSerializable*)), Qt::QueuedConnection);
connect(_contextMenuStep, SIGNAL(expand()), this, SLOT(expandSelected()));
connect(_contextMenuStep, SIGNAL(expandAll()), this, SLOT(expandAllTypeOfSelected()));
connect(_contextMenuStep, SIGNAL(collapse()), this, SLOT(collapseSelected()));
connect(_contextMenuStep, SIGNAL(collapseAll()), this, SLOT(collapseAllTypeOfSelected()));
connect(_contextMenuStep, SIGNAL(locateSelectedStepInMenu(CT_VirtualAbstractStep*)), this, SIGNAL(locateStepInMenu(CT_VirtualAbstractStep*)));
connect(_stepManager, SIGNAL(stepAdded(CT_VirtualAbstractStep*)), this, SLOT(stepAdded(CT_VirtualAbstractStep*)), Qt::DirectConnection);
connect(_stepManager, SIGNAL(stepInserted(int,CT_VirtualAbstractStep*)), this, SLOT(stepInserted(int,CT_VirtualAbstractStep*)), Qt::DirectConnection);
connect(_stepManager, SIGNAL(stepToBeRemoved(CT_VirtualAbstractStep*)), this, SLOT(stepToBeRemoved(CT_VirtualAbstractStep*)), Qt::DirectConnection);
connect(_stepManager, SIGNAL(resultToBeSerialized(const CT_AbstractResult*)), this, SLOT(resultToBeSerialized(const CT_AbstractResult*)), Qt::DirectConnection);
connect(&m_treeView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showViewContextMenu(QPoint)), Qt::QueuedConnection);
connect(&m_treeView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(indexDoubleClicked(QModelIndex)), Qt::QueuedConnection);
connect(m_treeView.selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(selectionChanged(QItemSelection,QItemSelection)));
connect(this, SIGNAL(addResult(QStandardItem*,CT_AbstractResult*)), this, SLOT(resultToAdd(QStandardItem*,CT_AbstractResult*)), Qt::QueuedConnection);
connect(this, SIGNAL(removeResult(QStandardItem*,MyQStandardItem*)), this, SLOT(resultToRemove(QStandardItem*,MyQStandardItem*)), Qt::QueuedConnection);
connect(this, SIGNAL(removeItem(QStandardItem*)), this, SLOT(itemToRemove(QStandardItem*)), Qt::QueuedConnection);
m_treeView.expand(m_proxy->mapFromSource(_model.indexFromItem(getRootItem())));
}
GStepManager::~GStepManager()
{
}
CDM_StepManager* GStepManager::getStepManager() const
{
return _stepManager;
}
////////////////// PRIVATE /////////////////
QList GStepManager::createItemsForStep(CT_VirtualAbstractStep &step)
{
QList list;
// nom de l'tape
MyQStandardItem *item = new MyQStandardItem(&step, NULL, MyQStandardItem::StepName, QString());
item->setToolTip(step.getToolTip());
item->setEditable(false);
connect(item, SIGNAL(dataChanged(QStandardItem*)), this, SLOT(itemDataChanged(QStandardItem*)));
connect(&step, SIGNAL(inProgress(int)), item, SLOT(setIntDataInvisible(int)), Qt::QueuedConnection);
list.append(item);
// debug
item = new MyQStandardItem(&step, NULL, MyQStandardItem::StepDebug, QString(""));
item->setEditable(false);
item->setCheckable(true);
item->setBoolData(step.isDebugModeOn());
connect(item, SIGNAL(dataChanged(QStandardItem*)), this, SLOT(itemDataChanged(QStandardItem*)));
list.append(item);
// temps coul
item = new MyQStandardItem(&step, NULL, MyQStandardItem::StepElapsedTime, step.getExecuteTime());
item->setEditable(false);
connect(&step, SIGNAL(elapsed(int)), item, SLOT(setIntData(int)), Qt::QueuedConnection);
list.append(item);
setStepItemBackgroundColor(step, list);
return list;
}
QList GStepManager::createItemsForResult(CT_AbstractResult &res)
{
QList list;
// nom du rsultat
MyQStandardItem *item = new MyQStandardItem(NULL, &res, MyQStandardItem::ResultVisibility, res.getName());
item->setCheckable(true);
item->setEditable(false);
item->setEnabled(!res.isBusy());
connect(&res, SIGNAL(busyStateChanged(bool)), item, SLOT(slotSetDisabled(bool)));
connect(item, SIGNAL(dataChanged(QStandardItem*)), this, SLOT(itemDataChanged(QStandardItem*)));
item->setToolTip(QString("%1 (%2)").arg(res.getName()).arg(res.getToolTip()));
list.append(item);
item = new MyQStandardItem(NULL, &res, MyQStandardItem::ResultEmpty, QString(""));
item->setEditable(false);
list.append(item);
item = new MyQStandardItem(NULL, &res, MyQStandardItem::ResultEmpty, QString(""));
item->setEditable(false);
list.append(item);
setResultItemBackgroundColor(ResultInfo(res.getClearFromMemoryProgress() < 100, false), list);
return list;
}
void GStepManager::setStepItemBackgroundColor(CT_VirtualAbstractStep &step, QList &list)
{
Q_UNUSED(step)
QListIterator it(list);
while(it.hasNext())
{
QStandardItem *item = it.next();
item->setData(step.isManual() ? QColor(183, 225, 170) : QColor(170, 186, 225), Qt::BackgroundColorRole);
}
}
void GStepManager::setResultItemBackgroundColor(ResultInfo info, QList &list)
{
QListIterator it(list);
while(it.hasNext())
{
QStandardItem *item = it.next();
if(info._isClearedFromMemory)
{
item->setData(QColor(236, 208, 209), Qt::BackgroundColorRole);
}
else if(info._isSerialized)
{
item->setData(QColor(206, 238, 211), Qt::BackgroundColorRole);
}
else
{
item->setData(QColor(220, 220, 220), Qt::BackgroundColorRole);
}
}
}
MyQStandardItem* GStepManager::findItem(CT_VirtualAbstractStep *step)
{
MyQStandardItem *item = getSelectedItem();
if((item != NULL)
&& (item->step() == step))
{
return item;
}
return recursiveFindItem(step);
}
MyQStandardItem* GStepManager::findItem(CT_AbstractResult *res)
{
MyQStandardItem *item = getSelectedItem();
if((item != NULL)
&& (item->result() == res))
{
return item;
}
return recursiveFindItem(res);
}
MyQStandardItem* GStepManager::getSelectedItem()
{
QModelIndexList list = m_treeView.selectionModel()->selectedRows();
if(!list.isEmpty())
return dynamic_cast(_model.itemFromIndex(m_proxy->mapToSource(list.first())));
return NULL;
}
MyQStandardItem* GStepManager::recursiveFindItem(CT_VirtualAbstractStep *step)
{
CT_VirtualAbstractStep* parent = step->parentStep();
QStandardItem *parentItem = NULL;
if(parent != NULL)
{
// on recherche le parent
parentItem = recursiveFindItem(parent);
}
// on est arriver au dbut de l'arbre
else
{
// on recherche l'tape dans les enfants
// de l'item root
parentItem = getRootItem();
}
if(parentItem != NULL)
{
int n = parentItem->rowCount();
for(int i=0; ichild(i);
if(item->step() == step)
{
return item;
}
}
}
return NULL;
}
MyQStandardItem* GStepManager::recursiveFindItem(CT_AbstractResult *res)
{
CT_VirtualAbstractStep* parent = res->parentStep();
MyQStandardItem *stepItem = recursiveFindItem(parent);
if(stepItem != NULL)
{
return getItemForResult(stepItem, res);
}
return NULL;
}
MyQStandardItem* GStepManager::getItemForResult(QStandardItem *stepItem, CT_AbstractResult *res)
{
int n = stepItem->rowCount();
for(int i=0; ichild(i);
if(item->result() == res)
{
return item;
}
}
return NULL;
}
QList GStepManager::getItemsForResult(QStandardItem *stepItem, CT_AbstractResult *res)
{
QList list;
int n = stepItem->rowCount();
for(int i=0; ichild(i);
if(item->result() == res)
{
int nc = _model.columnCount();
for(int j=0; jchild(i, j);
list.append(item);
}
return list;
}
}
return list;
}
MyQStandardItem *GStepManager::recursiveFindItemThatRepresentAStepForChild(MyQStandardItem *child) const
{
if(child->step() != NULL)
return child;
MyQStandardItem *parent = dynamic_cast(child->parentItem());
if(parent == NULL)
return NULL;
return recursiveFindItemThatRepresentAStepForChild(parent);
}
QStandardItem *GStepManager::getRootItem() const
{
return m_rootItem;
}
void GStepManager::stepDataChanged(MyQStandardItem *item)
{
CT_VirtualAbstractStep *step = item->step();
if(step != NULL)
{
switch(item->columnType())
{
case MyQStandardItem::StepDebug : { bool debugOn = (item->checkState() == Qt::Checked);
if(debugOn && !step->isDebuggable())
{
item->setData(false, Qt::CheckStateRole);
showMessageStepNotDebuggable();
}
else if(step->isDebugModeOn() != debugOn)
{
getStepManager()->setStepDebugModeOn(step, debugOn);
}
break;
}
}
}
}
void GStepManager::resultDataChanged(MyQStandardItem *item)
{
_mutexItemRes.lock();
CT_AbstractResult *res = item->result();
_mutexItemRes.unlock();
if(res != NULL)
{
switch(item->columnType())
{
case MyQStandardItem::ResultVisibility : if(item->checkState() == Qt::Checked)
{
editItemDrawableModelOfResult(item->result());
}
else
{
removeEditItemDrawableModelOfResult(item->result());
removeItemDrawableOfResult(item->result());
}
break;
}
}
}
QString GStepManager::staticGetStepName(CT_VirtualAbstractStep &step)
{
CT_AbstractStepLoadFile *stepLF = dynamic_cast(&step);
if(stepLF != NULL)
{
QString filePath = stepLF->getFilePath();
QFileInfo info(filePath);
return QString("%1%2").arg(step.isSettingsModified() ? "*" : "").arg(((step.getStepCustomName() == step.getStepExtendedDisplayableName()) && !info.fileName().isEmpty()) ? info.fileName() : step.getStepCustomName());
}
return QString("%1%2").arg(step.isSettingsModified() ? "*" : "").arg(step.getStepCustomName() == step.getStepExtendedDisplayableName() ? step.getStepExtendedDisplayableName() : step.getStepCustomName());
}
void GStepManager::showMessageStepNotDebuggable()
{
QMessageBox::warning(this, tr("Debug"), tr("L'étape ne semble pas être débogable."));
}
bool GStepManager::checkExecuteStepAndShowWarningMessage(CT_VirtualAbstractStep *step, bool debugMode)
{
bool continueExecution = true;
if(_stepManager->getOptions().isAutoSaveEnable()
&& (step != NULL)
&& _stepManager->checkAutoSaveDisabledIfExecuteFromStep(*step))
{
continueExecution = false;
QMessageBox msg(QMessageBox::Warning, tr("Attention"), tr("La srialisation semble tre active, si vous executez"
" l'opration partir de cette tape elle sera dsactive."), QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, this);
msg.setInformativeText(tr("Voulez-vous quand même continuer ?"));
if(msg.clickedButton() == msg.button(QMessageBox::Yes))
{
continueExecution = true;
}
}
if(continueExecution)
{
bool oneStepInDebugMode = _stepManager->checkOneStepIsInDebugModeFromStep(step);
if(oneStepInDebugMode && !debugMode)
{
continueExecution = false;
QMessageBox msg(QMessageBox::Warning, tr("Attention"), tr("Une ou plusieurs étapes sont en mode debug or vous allez lancer"
" les traitements en mode normal."), QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, this);
msg.setInformativeText(tr("Voulez-vous quand même continuer ?"));
msg.exec();
if(msg.clickedButton() == msg.button(QMessageBox::Yes))
{
continueExecution = true;
}
}
else if(!oneStepInDebugMode && debugMode)
{
continueExecution = false;
QMessageBox msg(QMessageBox::Warning, tr("Attention"), tr("Aucune étape n'est en mode debug or vous allez lancer"
" les traitements dans ce mode."), QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, this);
msg.setInformativeText(tr("Voulez-vous quand même continuer ?"));
msg.exec();
if(msg.clickedButton() == msg.button(QMessageBox::Yes))
{
continueExecution = true;
}
}
}
return continueExecution;
}
bool GStepManager::configureStepAndAdd(CT_VirtualAbstractStep *stepToCopy, CT_VirtualAbstractStep *parentStep)
{
if((stepToCopy != NULL) && (stepToCopy->getPlugin() != NULL))
{
if(!stepToCopy->acceptAddAfterThisStep(parentStep)) {
QString error = tr("Impossible d'ajouter l'étape %1").arg(staticGetStepName(*stepToCopy));
if(parentStep != NULL)
error += tr(" après l'étape %2 car elles ne sont pas compatible !").arg(staticGetStepName(*parentStep));
else
error += tr(" à la racine !");
GUI_LOG->addErrorMessage(LogInterface::gui, error);
}
else {
CT_VirtualAbstractStep *stepCopied = stepToCopy->getPlugin()->createNewInstanceOfStep(*stepToCopy, parentStep);
if(stepCopied->showPreConfigurationDialog())
{
if(stepCopied->initInResultModelList())
{
if(stepCopied->showInputResultConfigurationDialog())
{
if(stepCopied->showPostConfigurationDialog())
{
if(stepCopied->initAfterConfiguration())
{
_stepManager->addStep(stepCopied, parentStep);
selectStep(stepCopied);
return true;
}
}
}
}
}
delete stepCopied;
}
}
return false;
}
void GStepManager::recursiveExpandCollapseItemOfStep(MyQStandardItem *item, bool expand)
{
if(item->step() != NULL)
{
if(expand)
m_treeView.expand(m_proxy->mapFromSource(_model.indexFromItem(item)));
else
m_treeView.collapse(m_proxy->mapFromSource(_model.indexFromItem(item)));
}
int size = item->rowCount();
for(int i=0; ichild(i), expand);
}
void GStepManager::recursiveExpandCollapseItemOfResultsGroup(MyQStandardItem *item, bool expand)
{
if((item->step() == NULL) && (item->result() == NULL))
{
if(expand)
m_treeView.expand(m_proxy->mapFromSource(_model.indexFromItem(item)));
else
m_treeView.collapse(m_proxy->mapFromSource(_model.indexFromItem(item)));
}
int size = item->rowCount();
for(int i=0; ichild(i), expand);
}
void GStepManager::selectStep(CT_VirtualAbstractStep *step)
{
MyQStandardItem *item = findItem(step);
if(item != NULL)
m_treeView.selectionModel()->select(m_proxy->mapFromSource(_model.indexFromItem(item)), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
}
void GStepManager::addStepToSelectedStepOrToRootAndConfigure(CT_VirtualAbstractStep *stepToCopy)
{
MyQStandardItem *item = getSelectedItem();
configureStepAndAdd(stepToCopy, (item == NULL) ? NULL : item->step());
}
////////////// PUBLIC SLOTS //////////////
void GStepManager::addOpenFileStep(QString filePath)
{
CDM_PluginManager *pluginManager = getStepManager()->getScriptManager()->getPluginManager();
if(pluginManager->isAPluginLoaded())
{
QList stepLfList;
CT_AbstractStepLoadFile *stepToCopy = NULL;
int count = pluginManager->countPluginLoaded();
for(int i =0; i steps = pluginManager->getPlugin(i)->getOpenFileStep(filePath);
if(!steps.isEmpty())
{
stepToCopy = steps.first();
stepLfList.append(steps);
}
}
if(stepLfList.size() > 1)
{
stepToCopy = NULL;
QDialog dialog(this);
dialog.setLayout(new QVBoxLayout());
QComboBox *cb = new QComboBox(&dialog);
QDialogButtonBox *dbb = new QDialogButtonBox(QDialogButtonBox::Ok
| QDialogButtonBox::Cancel,
Qt::Horizontal,
&dialog);
connect(dbb, SIGNAL(accepted()), &dialog, SLOT(accept()));
connect(dbb, SIGNAL(rejected()), &dialog, SLOT(reject()));
dialog.layout()->addWidget(cb);
dialog.layout()->addWidget(dbb);
QListIterator itLf(stepLfList);
while(itLf.hasNext())
{
CT_AbstractStepLoadFile *stepLf = itLf.next();
cb->addItem(GStepManager::staticGetStepName(*stepLf) + " (" + pluginManager->getPluginName(stepLf->getPlugin()) + ")");
}
if(dialog.exec() == 1)
{
stepToCopy = stepLfList.at(cb->currentIndex());
}
}
if(stepToCopy != NULL)
{
stepLfList.removeOne(stepToCopy);
CT_VirtualAbstractStep *newStep = stepToCopy->getPlugin()->createNewInstanceOfStep(*stepToCopy, NULL);
CT_AbstractStepLoadFile *newStepLF = dynamic_cast(newStep);
if(newStepLF != NULL)
{
if(newStepLF->setFilePath(filePath))
{
if(newStepLF->showPreConfigurationDialog())
{
if(newStepLF->initInResultModelList())
{
if(newStepLF->showInputResultConfigurationDialog())
{
if(newStepLF->initAfterConfiguration())
{
_stepManager->addStep(newStepLF);
selectStep(newStepLF);
return;
}
}
}
}
}
}
delete newStep;
}
}
}
bool GStepManager::executeStep(CT_VirtualAbstractStep *step)
{
if(!_stepManager->isRunning())
{
if(checkExecuteStepAndShowWarningMessage(step, false))
return _stepManager->executeStep(step);
else
return false;
}
return _stepManager->executeStep(step);
}
bool GStepManager::executeModifyStep(CT_VirtualAbstractStep *step)
{
if(!_stepManager->isRunning())
return _stepManager->executeModifyStep(step);
return _stepManager->executeModifyStep(step);
}
bool GStepManager::executeOrForwardStepInDebugMode(CT_VirtualAbstractStep *step)
{
if(!_stepManager->isRunning())
{
if(checkExecuteStepAndShowWarningMessage(step, true))
return _stepManager->executeOrForwardStepInDebugMode(step);
else
return false;
}
return _stepManager->executeOrForwardStepInDebugMode(step);
}
bool GStepManager::executeOrForwardStepFastInDebugMode(CT_VirtualAbstractStep *step)
{
if(!_stepManager->isRunning())
{
if(checkExecuteStepAndShowWarningMessage(step, true))
return _stepManager->executeOrForwardStepFastInDebugMode(step);
else
return false;
}
return _stepManager->executeOrForwardStepFastInDebugMode(step);
}
bool GStepManager::executeOrForwardStepAutoInDebugMode(CT_VirtualAbstractStep *step)
{
if(!_stepManager->isRunning())
{
if(checkExecuteStepAndShowWarningMessage(step, true))
return _stepManager->executeOrForwardStepAutoInDebugMode(step);
else
return false;
}
return _stepManager->executeOrForwardStepAutoInDebugMode(step);
}
bool GStepManager::configureInputResultOfStep(CT_VirtualAbstractStep *step)
{
if((step != NULL)
&& (!_stepManager->isRunning()))
{
if(step->showInputResultConfigurationDialog())
{
return step->initAfterConfiguration();
}
}
return false;
}
bool GStepManager::configureStep(CT_VirtualAbstractStep *step)
{
if((step != NULL)
&& (!_stepManager->isRunning()))
{
if(step->showPostConfigurationDialog())
{
return step->initAfterConfiguration();
}
}
return false;
}
bool GStepManager::removeStep(CT_VirtualAbstractStep *step)
{
if(step != NULL)
{
return GUI_MANAGER->asyncRemoveStep(*step, NULL);
}
return false;
}
bool GStepManager::loadResultStep(CT_AbstractStepSerializable *step)
{
if(step != NULL)
{
return GUI_MANAGER->asyncLoadResultStep(*step, NULL);
}
return false;
}
bool GStepManager::editItemDrawableModelOfResult(CT_AbstractResult *res)
{
if(res != NULL)
{
return GUI_MANAGER->editItemDrawableModelOfResult(*res);
}
return false;
}
bool GStepManager::removeEditItemDrawableModelOfResult(CT_AbstractResult *res)
{
if(res != NULL)
{
return GUI_MANAGER->removeEditItemDrawableModelOfResult(*res);
}
return false;
}
bool GStepManager::removeItemDrawableOfResult(CT_AbstractResult *res)
{
if(res != NULL)
{
return GUI_MANAGER->asyncRemoveAllItemDrawableOfResultFromView(*res, NULL);
}
return false;
}
void GStepManager::showStepManagerOptions()
{
QDialog dialog(this);
dialog.setWindowTitle(tr("Configuration"));
QVBoxLayout *layout = new QVBoxLayout();
GStepManagerOptions *widget = new GStepManagerOptions(&dialog);
widget->setOptions(_stepManager->getOptions());
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
Qt::Horizontal,
&dialog);
layout->addWidget(widget);
layout->addWidget(buttonBox);
delete dialog.layout();
dialog.setLayout(layout);
connect(buttonBox, SIGNAL(accepted()), &dialog, SLOT(accept()));
connect(buttonBox, SIGNAL(rejected()), &dialog, SLOT(reject()));
if(dialog.exec())
{
_stepManager->setOptions(widget->getOptions());
}
}
void GStepManager::setStepNameConfiguration(GStepViewDefault::DisplayNameConfigs config)
{
m_proxy->setStepNameConfig(config);
}
////////////// PRIVATE SLOTS //////////////
void GStepManager::stepAdded(CT_VirtualAbstractStep *step)
{
CT_VirtualAbstractStep *parentStep = step->parentStep();
QStandardItem *item = NULL;
if(parentStep == NULL)
{
item = getRootItem();
}
else
{
item = findItem(parentStep);
}
if(item != NULL)
{
connect(step, SIGNAL(resultAdded(const CT_AbstractResult*)), this, SLOT(resultAdded(const CT_AbstractResult*)), Qt::DirectConnection);
connect(step, SIGNAL(resultToBeClearedFromMemory(const CT_AbstractResult*)), this, SLOT(resultToBeClearedFromMemory(const CT_AbstractResult*)), Qt::DirectConnection);
connect(step, SIGNAL(resultToBeRemoved(const CT_AbstractResult*)), this, SLOT(resultToBeRemoved(const CT_AbstractResult*)), Qt::DirectConnection);
connect(step, SIGNAL(settingsModified()), this, SLOT(stepSettingsModified()), Qt::QueuedConnection);
QList newItems = createItemsForStep(*step);
item->appendRow(newItems);
QModelIndex index = m_proxy->mapFromSource(_model.indexFromItem(newItems.first()));
m_treeView.expand(index);
m_treeView.selectionModel()->select(index, QItemSelectionModel::Rows | QItemSelectionModel::ClearAndSelect);
}
}
void GStepManager::stepInserted(int row, CT_VirtualAbstractStep *step)
{
CT_VirtualAbstractStep *parentStep = step->parentStep();
QStandardItem *item = NULL;
if(parentStep == NULL)
{
item = getRootItem();
}
else
{
item = findItem(parentStep);
}
if(item != NULL)
{
connect(step, SIGNAL(resultAdded(CT_AbstractResult*)), this, SLOT(resultAdded(CT_AbstractResult*)), Qt::DirectConnection);
connect(step, SIGNAL(resultToBeClearedFromMemory(CT_AbstractResult*)), this, SLOT(resultToBeClearedFromMemory(CT_AbstractResult*)), Qt::DirectConnection);
connect(step, SIGNAL(resultToBeRemoved(CT_AbstractResult*)), this, SLOT(resultToBeRemoved(CT_AbstractResult*)), Qt::DirectConnection);
connect(step, SIGNAL(settingsModified()), this, SLOT(stepSettingsModified()), Qt::QueuedConnection);
QList list = createItemsForStep(*step);
if(row > 0)
{
item->insertRow(row, list);
}
else
{
QStandardItem *newItem = list.first();
int nResult = ((MyQStandardItem*)item)->step()->nResult();
while(item->rowCount() > nResult)
{
QList tmpList = item->takeRow(item->rowCount()-1);
newItem->insertRow(0, tmpList);
}
item->insertRow(item->rowCount(), list);
}
m_treeView.expandAll();
}
}
void GStepManager::stepToBeRemoved(CT_VirtualAbstractStep *step)
{
QStandardItem *item = findItem(step);
if(item != NULL)
{
// on emet un signal pour qu'on supprime
// l'item dans une boucle d'vnement. Que se passerai-t-il
// si on ne faisait pas a : lorsqu'un thread supprime une tape
// du step manager et qu'on reoit directement le signal,
// on n'est pas dans la boucle d'vnement donc la vue est peut tre
// en train d'tre mis jour, donc si on supprime l'item pendant la
// mise jour du qteeview il peut y avoir un plantage.
emit removeItem(item);
}
}
void GStepManager::stepSettingsModified()
{
CT_VirtualAbstractStep *step = dynamic_cast(sender());
if(step != NULL)
{
MyQStandardItem *item = findItem(step);
if(item != NULL)
{
item->setDataWithoutSignal(GStepManager::staticGetStepName(*step), Qt::DisplayRole);
item->setToolTip(step->getToolTip());
}
}
}
void GStepManager::resultAdded(const CT_AbstractResult *res)
{
QStandardItem *item = findItem(res->parentStep());
if(item != NULL)
{
_mutexResList.lock();
_resToBeAddedList.append((CT_AbstractResult*)res);
_mutexResList.unlock();
// on emet un signal pour les mmes raisons que
// lors de la suppression d'tape
emit addResult(item, (CT_AbstractResult*)res);
}
}
void GStepManager::resultToBeClearedFromMemory(const CT_AbstractResult *res)
{
QStandardItem *item = findItem((CT_AbstractResult*)res);
if(item != NULL)
{
QStandardItem *parent = item->parent();
int row = item->row();
int col = parent->columnCount();
QList list;
for(int i=0; ichild(row, i));
}
setResultItemBackgroundColor(ResultInfo(true, false), list);
}
}
void GStepManager::resultToBeRemoved(const CT_AbstractResult *res)
{
// Dans un cas bien particulier il peut y avoir une
// erreur d'accs au rsultat, ce cas est le suivant :
//
// Si on a reu un signal qu'on doit ajouter un rsultat,
// on emet un signal d'ajout du rsultat. Si juste aprs on reoit
// un signal qu'un rsultat va tre supprim on emet un signal pour
// supprimer le rsultat. SI avant de recevoir NOTRE signal d'ajout
// du rsultat le rsultat est supprimer alors on aura une erreur
// d'accs mmoire si on essaye de crer des items pour ce rsultat.
//
// C'est pourquoi j'ai cr cette liste qui permet de vrifier si on
// a reu aussi un signal de suppression du rsultat aprs le signal d'ajout
// comme a on ne cre pas le rsultat.
//
//
// Je rapelle qu'on reoit un signal de l'tape quelle va ajouter un rsultat
// en Qt::DirectConnection et qu'on met un signal en Qt::QueuedConnection
// pour ce remettre dans l'event loop de Qt et ne pas avoir d'erreur si la vue
// est en train de ce mettre jour.
_mutexResList.lock();
_resToBeAddedList.removeOne((CT_AbstractResult*)res);
_mutexResList.unlock();
QStandardItem *item = findItem(res->parentStep());
MyQStandardItem *itemRes = NULL;
QList itemResList = getItemsForResult(item, (CT_AbstractResult*)res);
QListIterator it(itemResList);
if(it.hasNext())
{
itemRes = it.next();
it.toFront();
while(it.hasNext())
{
_mutexItemRes.lock();
it.next()->removeResult();
_mutexItemRes.unlock();
}
}
if((item != NULL)
&& (itemRes != NULL))
{
// on emet un signal pour les mmes raisons que
// lors de la suppression d'tape
emit removeResult(item, itemRes);
}
}
void GStepManager::resultToBeSerialized(const CT_AbstractResult *res)
{
QStandardItem *item = findItem((CT_AbstractResult*)res);
if(item != NULL)
{
QStandardItem *parent = item->parent();
int row = item->row();
int col = parent->columnCount();
QList list;
for(int i=0; ichild(row, i));
}
setResultItemBackgroundColor(ResultInfo(false, true), list);
}
}
void GStepManager::itemDataChanged(QStandardItem *item)
{
MyQStandardItem *myItem = (MyQStandardItem*)item;
if(myItem->step() != NULL)
{
stepDataChanged(myItem);
}
else if(myItem->result() != NULL)
{
resultDataChanged(myItem);
}
}
void GStepManager::indexDoubleClicked(QModelIndex index)
{
MyQStandardItem *myItem = dynamic_cast(_model.itemFromIndex(m_proxy->mapToSource(index)));
if((myItem != NULL)
&& (myItem->result() != NULL))
{
QStandardItem *it = ((QStandardItem*)myItem)->parent()->child(myItem->row(), MyQStandardItem::ResultVisibility-MyQStandardItem::BeginIndexForResult);
if(it->isEnabled())
it->setCheckState(it->checkState() == Qt::Checked ? Qt::Unchecked : Qt::Checked);
}
else if((myItem != NULL)
&& (myItem->step() != NULL)
&& (myItem->columnType() != MyQStandardItem::StepName))
{
GAboutStepDialog dialog(myItem->step());
dialog.exec();
}
}
void GStepManager::resultToAdd(QStandardItem *parentItem, CT_AbstractResult *res)
{
_mutexResList.lock();
int index;
// si le rsultat est toujours dans la liste.
if((index = _resToBeAddedList.indexOf(res)) >= 0)
{
QList newItems = createItemsForResult(*res);
parentItem->insertRow(0, newItems);
_resToBeAddedList.removeAt(index);
m_treeView.expand(m_proxy->mapFromSource(_model.indexFromItem(newItems.first())));
}
_mutexResList.unlock();
}
void GStepManager::resultToRemove(QStandardItem *parentItem, MyQStandardItem *resItem)
{
if(resItem != NULL)
{
parentItem->removeRow(resItem->row());
}
}
void GStepManager::itemToRemove(QStandardItem *item)
{
if(item->parent() != NULL)
{
item->parent()->removeRow(item->row());
}
else
{
getRootItem()->removeRow(item->row());
}
}
void GStepManager::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
{
MyQStandardItem *item = getSelectedItem();
// if the item represent a step
if((item != NULL) && (item->step() != NULL))
emit stepSelected(item->step());
else if(item != NULL){
// if not we get the first parent that represent a step and select it if we find it
MyQStandardItem *itemOfAStep = recursiveFindItemThatRepresentAStepForChild(item);
if(itemOfAStep == NULL)
emit stepSelected(NULL);
else
selectStep(itemOfAStep->step());
} else {
emit stepSelected(NULL);
}
}
void GStepManager::expandSelected()
{
QModelIndexList list = m_treeView.selectionModel()->selectedRows();
if(!list.isEmpty())
m_treeView.expand(list.first());
}
void GStepManager::expandAllTypeOfSelected()
{
MyQStandardItem *item = getSelectedItem();
if(item != NULL)
{
if(item->step() != NULL)
{
QStandardItem *root = getRootItem();
int size = root->rowCount();
for(int i=0; ichild(i), true);
}
else if(item->result() == NULL)
{
QStandardItem *root = getRootItem();
int size = root->rowCount();
for(int i=0; ichild(i), true);
}
}
}
void GStepManager::collapseSelected()
{
QModelIndexList list = m_treeView.selectionModel()->selectedRows();
if(!list.isEmpty())
m_treeView.collapse(list.first());
}
void GStepManager::collapseAllTypeOfSelected()
{
MyQStandardItem *item = getSelectedItem();
if(item != NULL)
{
if(item->step() != NULL)
{
QStandardItem *root = getRootItem();
int size = root->rowCount();
for(int i=0; ichild(i), false);
}
else if(item->result() == NULL)
{
QStandardItem *root = getRootItem();
int size = root->rowCount();
for(int i=0; ichild(i), false);
}
}
}
void GStepManager::removeAllStepFromRoot()
{
GUI_MANAGER->asyncRemoveAllStep(NULL);
}
void GStepManager::showViewContextMenu(const QPoint &point)
{
MyQStandardItem *item = getSelectedItem();
if(item != NULL)
{
if(item->step() != NULL)
{
_contextMenuStep->setSelectedStep(item->step());
_contextMenuStep->exec(m_treeView.viewport()->mapToGlobal(point));
}
else if(item->result() == NULL)
{
QMenu menu(this);
menu.addAction(QIcon(":/Icones/Icones/delete.png"), tr("Supprimer toutes les étapes"), this, SLOT(removeAllStepFromRoot()));
menu.addAction(QIcon(":/Icones/Icones/expand.png"), tr("Déplier"), this, SLOT(expandSelected()));
menu.addAction(QIcon(":/Icones/Icones/collapse.png"), tr("Replier"), this, SLOT(collapseSelected()));
menu.exec(m_treeView.viewport()->mapToGlobal(point));
}
}
}