Logo Search packages:      
Sourcecode: ugene version File versions

ProjectViewImpl.cpp

/*****************************************************************
* Unipro UGENE - Integrated Bioinformatics Suite
* Copyright (C) 2008 Unipro, Russia (http://ugene.unipro.ru)
* All Rights Reserved
* 
*     This source code is distributed under the terms of the
*     GNU General Public License. See the files COPYING and LICENSE
*     for details.
*****************************************************************/

#include "ProjectViewImpl.h"

#include "../AppContextImpl.h"

#include <core_api/ProjectModel.h>
#include <core_api/Settings.h>
#include <core_api/ObjectViewModel.h>
#include <core_api/IOAdapter.h>
#include <core_api/Log.h>
#include <core_api/GObject.h>

#include <gobjects/GObjectTypes.h>

#include <util_tasks/SaveDocumentTask.h>
#include <util_tasks/LoadDocumentTask.h>
#include <util_tasks/MultiTask.h>
#include <util_tasks/CopyDataTask.h>
#include <util_tasks/AddDocumentTask.h>

#include <util_gui/AddNewDocumentDialogImpl.h>
#include <util_gui/AddExistingDocumentDialogImpl.h>
#include <util_gui/GUIUtils.h>
#include <selection/SelectionUtils.h>

#include <QtGui/QtGui>
#include <memory>

namespace GB2 {


/* TRANSLATOR GB2::ProjectViewImpl */
/* TRANSLATOR GB2::ProjectTreeController */

static LogCategory log(ULOG_CAT_CORE_SERVICES);


#define SETTINGS_ROOT QString("projecview/")

ProjectViewWidget::ProjectViewWidget() {
    setupUi(this);
    setObjectName(DOCK_PROJECT_VIEW);
    setWindowTitle(tr("Project"));
    setWindowIcon(QIcon(":ugene/images/project.png"));
}

//////////////////////////////////////////////////////////////////////////
// ProjectViewImpl
ProjectViewImpl::ProjectViewImpl(Plugin* p)
: ProjectView(p, tr("projectview_sname"), tr("projectview_sdesc"))
{
    w = NULL;
    projectTreeController = NULL;
    objectViewController = NULL;
    addExistingDocumentAction = NULL;
//    addNewDocumentAction = NULL;
    saveSelectedDocsAction = NULL;

    //todo: move it somewhere else -> object views could be openend without project view service active
    registerBuiltInObjectViews();
}

ProjectViewImpl::~ProjectViewImpl() {
    unregisterBuiltInObjectViews();
}

/// returns NULL if no actions are required to enable service
Task* ProjectViewImpl::createServiceEnablingTask() {
    return new EnableProjectViewTask(this);
}

/// returns NULL if no actions are required to disable service
Task* ProjectViewImpl::createServiceDisablingTask() {
    return new DisableProjectViewTask(this);
}


void ProjectViewImpl::enable() {
    Project* pr = AppContext::getProject();
    connect(pr, SIGNAL(si_documentAdded(Document*)), SLOT(sl_onDocumentAdded(Document*)));
    connect(pr, SIGNAL(si_documentRemoved(Document*)), SLOT(sl_onDocumentRemoved(Document*)));
    connect(pr, SIGNAL(si_modifiedStateChanged()), SLOT(sl_onProjectModifiedStateChanged()));
    
    MWMDIManager* mdi = AppContext::getMainWindow()->getMDIManager();
    connect(mdi, SIGNAL(si_windowAdded(MWMDIWindow*)), SLOT(sl_onMDIWindowAdded(MWMDIWindow*)));

    
    assert(w == NULL);
    w = new ProjectViewWidget();
    
    assert(addExistingDocumentAction == NULL);
    addExistingDocumentAction = new QAction(QIcon(":ugene/images/advanced_open.png"), tr("open_as"), w);
    addExistingDocumentAction->setShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_O));
    addExistingDocumentAction->setShortcutContext(Qt::ApplicationShortcut);

    //addNewDocumentAction = new QAction(QIcon(":ugene/images/add_new_document.png"), tr("add_new_document_action"), w);
    saveSelectedDocsAction = new QAction(QIcon(":ugene/images/save_selected_documents.png"), tr("save_selected_modified_docs_action"), w);
    connect(addExistingDocumentAction, SIGNAL(triggered()), SLOT(sl_onAddExistingDocument()));
    //connect(addNewDocumentAction, SIGNAL(triggered()), SLOT(sl_onAddNewDocument()));
    connect(saveSelectedDocsAction, SIGNAL(triggered()), SLOT(sl_onSaveSelectedDocs()));

    initView();

    MainWindow* mw = AppContext::getMainWindow();
    MWDockManager* dm = mw->getDockManager();
    w->setObjectName("project_view");
    dm->registerDock(MWDockArea_Left, w, QKeySequence(Qt::ALT | Qt::Key_1));
    if (AppContext::getSettings()->getValue(SETTINGS_ROOT + "firstShow", true).toBool()) {
        dm->activateDock(w->objectName());
        AppContext::getSettings()->setValue(SETTINGS_ROOT + "firstShow", false);
    }
    
    MWMenuManager* mm = mw->getMenuManager();
    QMenu* fm = mm->getTopLevelMenu(MWMENU_FILE);
    fm->insertAction(GUIUtils::findActionAfter(fm->actions(), ACTION_PROJECTSUPPORT__OPEN_PROJECT), addExistingDocumentAction);

    //QToolBar* tb = mw->getToolBarManager()->getToolbar(MWTOOLBAR_MAIN);
    //tb->addAction(addNewDocumentAction);
    //tb->addAction(addExistingDocumentAction);


    AppContextImpl::getApplicationContext()->setProjectView(this);

    updateMWTitle();
    const QList<Document*>& docs = AppContext::getProject()->getDocuments();
    foreach(Document* d, docs) {
        sl_onDocumentAdded(d);
    }
    foreach (MWMDIWindow* w, mdi->getWindows()) {
        sl_onMDIWindowAdded(w);
    }
}

void ProjectViewImpl::disable() {
    MainWindow* mw = AppContext::getMainWindow();
    if (w!=NULL) {
        saveWidgetState(w);
    } 
    delete w;
    w = NULL;

    Project* pr = AppContext::getProject();
    pr->disconnect(this);

    //All these QObjects are autodeleted when 'w' is deleted;
    projectTreeController = NULL;
    objectViewController = NULL;
    addExistingDocumentAction = NULL;
//    addNewDocumentAction = NULL;

    AppContextImpl::getApplicationContext()->setProjectView(NULL);

    // close all views;
    MWMDIManager* mdiManager = mw->getMDIManager();
    const QList<GObjectViewWindow*> views = GObjectViewUtils::getAllActiveViews();
    foreach(GObjectViewWindow* view, views) {
        mdiManager->closeMDIWindow(view);
    }
    mw->setWindowTitle("");
}

void ProjectViewImpl::saveWidgetState(ProjectViewWidget* w) {
    QByteArray splitState = w->splitter->saveState();
    AppContext::getSettings()->setValue(SETTINGS_ROOT + "splitterState", splitState);
}

void ProjectViewImpl::restoreWidgetState(ProjectViewWidget* w) {
    QByteArray splitState = AppContext::getSettings()->getValue(SETTINGS_ROOT + "splitterState", QByteArray()).toByteArray();
    if (!splitState.isEmpty()) {
        w->splitter->restoreState(splitState);
    }
}

void ProjectViewImpl::initView() {
    w->documentLabel->setText(tr("documents_label"));
    w->viewLabel->setText(tr("bookmarks_label"));
    
    assert(projectTreeController == NULL);
    ProjectTreeControllerModeSettings s;
    s.loadTaskProvider = this;
    projectTreeController = new ProjectTreeController(w, w->documentTreeWidget, s);
    connect(projectTreeController, SIGNAL(si_onPopupMenuRequested(QMenu&)), SLOT(sl_onDocTreePopupMenuRequested(QMenu&)));
    connect(projectTreeController, SIGNAL(si_doubleClicked(GObject*)), SLOT(sl_onDoubleClicked(GObject*)));

    assert(objectViewController == NULL);
    objectViewController = new ObjectViewTreeController(w->viewTreeWidget);

    restoreWidgetState(w);    
}

bool ProjectViewImpl::eventFilter(QObject *obj, QEvent *event) {
    if (event->type() == QEvent::Close) {
        GObjectViewWindow* ov = qobject_cast<GObjectViewWindow*>(obj);
        assert(ov);
        if (ov->isPersistent()) {
            saveViewState(ov, GObjectViewState::APP_CLOSING_STATE_NAME);
        }
    }
    return QObject::eventFilter(obj, event);
}

void ProjectViewImpl::saveViewState(GObjectViewWindow* v, const QString& stateName) {
    Project* p = AppContext::getProject();
    GObjectViewFactoryId id = v->getViewFactoryId();
    GObjectViewState* state = GObjectViewUtils::findStateInList(v->getViewName(), stateName, p->getGObjectViewStates());
    QVariantMap stateData = v->getObjectView()->saveState();
    if (stateData.isEmpty()) {
        return;
    }
    if (state == NULL) {
        state = new GObjectViewState(id, v->getViewName(), stateName, stateData);
        p->addGObjectViewState(state);
    } else {
        assert(state->getViewFactoryId() == id); //TODO: handle this error;
        state->setStateData(stateData);
    }
}

void ProjectViewImpl::sl_onMDIWindowAdded(MWMDIWindow* m) {
    GObjectViewWindow* v = qobject_cast<GObjectViewWindow*>(m);
    if (v) {
        v->installEventFilter(this);
        connect(v, SIGNAL(si_persistentStateChanged(GObjectViewWindow*)), SLOT(sl_onViewPersistentStateChanged(GObjectViewWindow*)));
    }
}

void ProjectViewImpl::sl_onDocumentRemoved(Document* doc) {
    doc->disconnect(this);
}

void ProjectViewImpl::sl_onAddNewDocument() {
    AddNewDocumentDialogModel m;
    DocumentFormatConstraints c;
    c.supportedObjectTypes.append(GObjectTypes::ANNOTATION_TABLE); //TODO: we can't create other data types on the fly..
    c.mustSupportWrite = true;
    AddNewDocumentDialogImpl::run(NULL, m, c);
    if (m.successful) {
        DocumentFormat* format = AppContext::getDocumentFormatRegistry()->getFormatById(m.format);
        IOAdapterFactory* iof = AppContext::getIOAdapterRegistry()->getIOAdapterFactoryById(m.io);
        log.info(tr("creating_new_document_lm %1").arg(m.url));
        Document* doc = format->createNewDocument(iof, m.url);
        doc->setModified(true);
        AppContext::getProject()->addDocument(doc);
    }
}


void ProjectViewImpl::sl_onSaveSelectedDocs() {
    const DocumentSelection* docSelection = getDocumentSelection();
    QList<Document*> modifiedDocs;
    foreach(Document* doc, docSelection->getSelectedDocuments()) {
        if (doc->isTreeItemModified()) {
            modifiedDocs.append(doc);
        }
    }
    if (!modifiedDocs.isEmpty()) {
        AppContext::getTaskScheduler()->registerTopLevelTask(new SaveMiltipleDocuments(modifiedDocs, false));
    }

}


void ProjectViewImpl::updateMWTitle() {
    Project* p  = AppContext::getProject();
    QString title = p->getProjectName();
    if (title.isEmpty()) {
        title = tr("unnamed_project_name");
    }
    if (p->isTreeItemModified()) {
        title+="*";
    }
    AppContext::getMainWindow()->setWindowTitle(title);
}

void ProjectViewImpl::sl_onProjectModifiedStateChanged() {
    updateMWTitle();
}

void ProjectViewImpl::sl_onViewPersistentStateChanged(GObjectViewWindow* v) {
    if (v->isPersistent()) {
        //add last saved state
        saveViewState(v, GObjectViewState::APP_CLOSING_STATE_NAME);
    } else {
        //remove all states
        QList<GObjectViewState*> states = GObjectViewUtils::findStatesByViewName(v->getViewName());
        foreach(GObjectViewState* s, states) {
            AppContext::getProject()->removeGObjectViewState(s);
        }
    }
}

void ProjectViewImpl::sl_onAddExistingDocument() {
    AddExistingDocumentDialogModel m;
      AddExistingDocumentDialogImpl::run(NULL, m, false);
      if (!m.successful) {
        return;
    }

    DocumentFormat* format = AppContext::getDocumentFormatRegistry()->getFormatById(m.format);
    IOAdapterFactory* iof = AppContext::getIOAdapterRegistry()->getIOAdapterFactoryById(m.io);

    log.info(tr("adding_existing_document %1").arg(m.url));

    QList<Task *> tasks;
    Document * newdoc = 0;
    QString multiTaskName;
    if( !m.dwnldPath.isEmpty() ) {
        IOAdapterFactory * iow = AppContext::getIOAdapterRegistry()->getIOAdapterFactoryById("local_file");
        QString url_w = m.dwnldPath;
        tasks.push_back( new CopyDataTask(iof, m.url, iow, url_w) );
        multiTaskName += "download_";
        newdoc = new Document( format, iow, url_w, m.formatSettings );
    } else {
        newdoc = new Document( format, iof, m.url, m.formatSettings );
    }
    if (m.readOnly) {
        newdoc->setUserModLock(true);
    }
    tasks.push_back( new AddDocumentTask(newdoc) );
    tasks.push_back( new LoadUnloadedDocumentAndOpenViewTask(newdoc) );
    multiTaskName += "add_load_document_task";
    AppContext::getTaskScheduler()->registerTopLevelTask( new MultiTask(multiTaskName, tasks) );

}

void ProjectViewImpl::sl_onDocTreePopupMenuRequested(QMenu& m) {
    buildViewMenu(m);
    emit si_onDocTreePopupMenuRequested(m);
}


Task* ProjectViewImpl::createLoadDocumentTask(Document* doc) const {
    return new LoadUnloadedDocumentAndOpenViewTask(doc);
}

//TODO: selection could be modified before slot activation!
class OpenViewContext : public QObject {
public:
    OpenViewContext(){}
    OpenViewContext(QObject* p, const MultiGSelection& s, GObjectViewFactory* f) : QObject(p), selection(s), state(NULL), factory(f){}
    OpenViewContext(QObject* p, const GObjectViewState* s, GObjectViewFactory* f) : QObject(p), state(s), factory(f){}
    OpenViewContext(QObject* p, const QString& _viewName) : QObject(p), state(NULL), factory(NULL), viewName(_viewName){}

    MultiGSelection                 selection;
    const GObjectViewState* state;
    GObjectViewFactory*       factory;
    QString                         viewName;
};

class AddToViewContext : public QObject {
public:
    AddToViewContext(QObject* p, GObjectView* v, QList<GObject*> objs) : QObject(p), view(v) {
        foreach(GObject* o , objs) {
            objects.append(o);
        }
    }
    QPointer<GObjectView>           view;
    QList<QPointer<GObject> > objects;
};

void ProjectViewImpl::sl_onDoubleClicked(GObject* o) {
    assert(o!=NULL);
    GObjectSelection os; os.addToSelection(o);
    MultiGSelection ms; ms.addSelection(&os);

    QMenu activeViewsMenu(tr("active_views_menu"), NULL);
    QList<QAction*> openActions;
    QList<GObjectViewFactory*> fs = AppContext::getObjectViewFactoryRegistry()->getAllFactories();
    foreach(GObjectViewFactory* f, fs) {
        QList<QAction*> tmp = selectOpenViewActions(f, ms, &activeViewsMenu);
        openActions<<tmp;
    }
    if (openActions.isEmpty()) { 
        return;
    }
    if (openActions.size() == 1 ) {
        QAction* a = openActions.first();
        a->trigger();
        return;
    } 
    foreach(QAction* a, openActions) {
        activeViewsMenu.addAction(a);
    }
    activeViewsMenu.exec(QCursor::pos());
}


QList<QAction*> ProjectViewImpl::selectOpenViewActions(GObjectViewFactory* f, const MultiGSelection& ms, QObject* actionsParent) {
    QList<QAction*> res;

    //check if object is already displayed in some view.
    QList<GObjectViewWindow*> views;
    QList<MWMDIWindow*> windows = AppContext::getMainWindow()->getMDIManager()->getWindows();
    GObjectSelection* objectsSelection = (GObjectSelection*)ms.findSelectionByType(GSelectionTypes::GOBJECTS);
    if (objectsSelection!=NULL) {
        QSet<GObject*> objectsInSelection = objectsSelection->getSelectedObjects().toSet();
        foreach(MWMDIWindow* w, windows) {
            GObjectViewWindow* ov = qobject_cast<GObjectViewWindow*>(w);
            if (ov==NULL) {
                continue;
            }
            if (ov->getViewFactoryId() != f->getId()) {
                continue;
            }
            const QList<GObject*>& viewObjects = ov->getObjects();
            bool contains = false;
            foreach(GObject* o, viewObjects) {
                if (objectsInSelection.contains(o)) {
                    contains = true;
                    break;
                }
            }
            if (!contains) {
                continue;
            }
            QAction* action = new QAction(tr("activate_view_action_%1").arg(ov->getViewName()), actionsParent);         
            OpenViewContext* c = new OpenViewContext(action, ov->getViewName());
            action->setData(QVariant::fromValue((void*)c));
            connect(action, SIGNAL(triggered()), SLOT(sl_activateView()));
            res.append(action);
        }
    }

    //check if new view can be created
    if (f->canCreateView(ms)) {
        QAction* action = new QAction(tr("open_view_action_%1").arg(f->getName()), actionsParent);          
        OpenViewContext* c = new OpenViewContext(action, ms, f);
        action->setData(QVariant::fromValue((void*)c));
        connect(action, SIGNAL(triggered()), SLOT(sl_openNewView()));
        res.append(action);
    }
    //check saved state can be activated
    QList<GObjectViewState*> viewStates = GObjectViewUtils::selectStates(f, ms, AppContext::getProject()->getGObjectViewStates());
    foreach(GObjectViewState* s, viewStates) {
        QAction* action = new QAction(tr("open_state_%1_%2").arg(s->getViewName()).arg(s->getStateName()), actionsParent);          
        OpenViewContext* c = new OpenViewContext(action, s, f);
        action->setData(QVariant::fromValue((void*)c));
        connect(action, SIGNAL(triggered()), SLOT(sl_openStateView()));
        res.append(action);
    }

    return res;
}

void ProjectViewImpl::buildOpenViewMenu(const MultiGSelection& ms, QMenu* m) {
    QList<GObjectViewFactory*> fs = AppContext::getObjectViewFactoryRegistry()->getAllFactories();
    foreach(GObjectViewFactory* f, fs) {
        QList<QAction*> openActions = selectOpenViewActions(f, ms, m);
        if (openActions.isEmpty()) {
            continue;
        }
        if (openActions.size() == 1) {
            m->addAction(openActions.first());
            continue;
        }
        QMenu* submenu = new QMenu(tr("open_view_submenu_%1").arg(f->getName()),     m);
        foreach (QAction* a, openActions) {
            submenu->addAction(a);
        }
        m->addAction(submenu->menuAction());
    }
}

void ProjectViewImpl::buildAddToViewMenu(const MultiGSelection& ms, QMenu* m) {
    MWMDIWindow* w = AppContext::getMainWindow()->getMDIManager()->getActiveWindow();
    if (w == NULL) {
        return;
    }
    GObjectViewWindow* ow = qobject_cast<GObjectViewWindow*>(w);
    if (ow == NULL) {
        return;
    }
    QList<GObject*> objects = SelectionUtils::getSelectedObjects(ms);
    if (objects.isEmpty()) {
        return;
    }
    foreach(GObject* obj, objects) {
        bool canBeAdded = ow->getObjectView()->canAddObject(obj);
        if (!canBeAdded) {
            return;
        }
    }
    QAction* action = new QAction(tr("add_to_view_action_%1").arg(ow->getViewName()), m);       
    AddToViewContext* ac = new AddToViewContext(action, ow->getObjectView(), objects);
    action->setData(QVariant::fromValue((void*)ac));
    connect(action, SIGNAL(triggered()), SLOT(sl_addToView()));
    m->addAction(action);
}

void ProjectViewImpl::buildViewMenu(QMenu& m) {
    QMenu* openViewMenu = new QMenu(tr("open_view_menu"), &m);
    QMenu* addToViewMenu= new QMenu(tr("add_to_view_menu"), &m);

    const DocumentSelection* docSelection = getDocumentSelection();
    MultiGSelection multiSelection;
    if (!getGObjectSelection()->isEmpty()) {
        multiSelection.addSelection(getGObjectSelection());
    }
    if (!docSelection->isEmpty()) {
        multiSelection.addSelection(getDocumentSelection());
    }

    buildOpenViewMenu(multiSelection, openViewMenu);
    buildAddToViewMenu(multiSelection, addToViewMenu);

    addToViewMenu->setDisabled(addToViewMenu->isEmpty());
    m.insertMenu(m.actions().first(), addToViewMenu);

    openViewMenu->setDisabled(openViewMenu->isEmpty());
    m.insertMenu(m.actions().first(), openViewMenu);


    bool hasModifiedDocs = false;
    foreach(Document* doc, docSelection->getSelectedDocuments()) {
        if (doc->isTreeItemModified()) {
            hasModifiedDocs = true;
            break;
        }
    }
    saveSelectedDocsAction->setEnabled(hasModifiedDocs);
    m.addAction(saveSelectedDocsAction);
}

void ProjectViewImpl::sl_activateView() {
    QAction* action  = (QAction*)sender();
    OpenViewContext* c = (OpenViewContext*)action->data().value<void*>();
    assert(!c->viewName.isEmpty());
    GObjectViewWindow* ov = GObjectViewUtils::findViewByName(c->viewName);
    if (ov!=NULL) {
        AppContext::getMainWindow()->getMDIManager()->activateWindow(ov);
    }
}


void ProjectViewImpl::sl_openNewView() {
    QAction* action  = (QAction*)sender();
    OpenViewContext* c = (OpenViewContext*)action->data().value<void*>();
    assert(c->factory->canCreateView(c->selection));
    AppContext::getTaskScheduler()->registerTopLevelTask(c->factory->createViewTask(c->selection));
}

void ProjectViewImpl::sl_addToView() {
    //TODO: create specialized action classes instead of using ->data().value<void*>() casts
    QAction* action  = (QAction*)sender();
    AddToViewContext* ac = (AddToViewContext*)action->data().value<void*>();
    GObjectView* view = ac->view;
    if (view == NULL) {
        return;
    }
    foreach(GObject* o, ac->objects) {
        if (o!=NULL) {
            QString err  = view->addObject(o);
            if (!err.isEmpty()) {
                QMessageBox::critical(NULL, tr("error_adding_object_to_view_title"), err);
            }
        }
    }
}

void ProjectViewImpl::sl_openStateView() {
    QAction* action  = (QAction*)sender();
    OpenViewContext* c = (OpenViewContext*)action->data().value<void*>();
    const GObjectViewState* state = c->state;
    assert(state);

    //todo: 70% of code duplication with ObjectViewTreeController::sl_activateView -> create util
    GObjectViewWindow* view = GObjectViewUtils::findViewByName(state->getViewName());
    if (view!=NULL) {
        assert(view->isPersistent());
        AppContext::getTaskScheduler()->registerTopLevelTask(view->getObjectView()->updateViewTask(state->getStateName(), state->getStateData()));
    } else {
        GObjectViewFactory* f = AppContext::getObjectViewFactoryRegistry()->getFactoryById(state->getViewFactoryId());
        assert(f!=NULL);
        AppContext::getTaskScheduler()->registerTopLevelTask(f->createViewTask(state->getViewName(), state->getStateData()));
    }
}

void ProjectViewImpl::sl_onDocumentAdded(Document* d) {
    connect(d, SIGNAL(si_loadedStateChanged()), SLOT(sl_onDocumentLoadedStateChanged()));
}

void ProjectViewImpl::sl_onDocumentLoadedStateChanged() {
    //do nothing..
}

//////////////////////////////////////////////////////////////////////////
// Tasks

//EnableProjectViewTask

EnableProjectViewTask::EnableProjectViewTask(ProjectViewImpl* _pvi) 
: Task(tr("enable_project_view"), TaskFlags_NR_DWF), pvi(_pvi)
{
}

Task::ReportResult EnableProjectViewTask::report() {
    assert(AppContext::getProject()!=NULL);
    pvi->enable();
    return ReportResult_Finished;
}


DisableProjectViewTask::DisableProjectViewTask(ProjectViewImpl* _pvi) 
: Task(tr("disable_project_view"), TaskFlags_NR_DWF_SSSOR), pvi(_pvi)
{
}

void DisableProjectViewTask::prepare() {
    if (AppContext::getProject()->isTreeItemModified()) {
        addSubTask(AppContext::getProjectService()->saveProjectTask(SaveProjectTaskKind_SaveProjectAndDocumentsAskEach));
    }
}


Task::ReportResult DisableProjectViewTask::report() {
    if (propagateSubtaskError()) {
        return ReportResult_Finished;
    }
    pvi->disable();
    return ReportResult_Finished;
}

}//namespace

Generated by  Doxygen 1.6.0   Back to index