Logo Search packages:      
Sourcecode: ugene version File versions

ProjectTreeController.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 "ProjectTreeController.h"
#include "AddNewDocumentDialogImpl.h"

#include <core_api/ProjectModel.h>
#include <core_api/GObject.h>
#include <core_api/ProjectView.h>
#include <core_api/DocumentFormats.h>
#include <core_api/ResourceTracker.h>
#include <core_api/ObjectViewModel.h>

#include <util_tasks/RemoveDocumentTask.h>
#include <util_tasks/LoadDocumentTask.h>
#include <util_tasks/SaveDocumentTask.h>
#include <gobjects/GObjectTypes.h>

#include <QtCore/QMimeData>
#include <QtCore/QMap>
#include <QtGui/QDrag>
#include <QtGui/QMenu>
#include <QtGui/QMessageBox>

/* TRANSLATOR GB2::ProjectTreeController */

namespace GB2 {

ProjectTreeController::ProjectTreeController(QObject* parent, QTreeWidget* _tree, const ProjectTreeControllerModeSettings& m) 
: QObject(parent), mode(m) {

      tree = _tree;
    tree->setSelectionMode(mode.allowMultipleSelection ? QAbstractItemView::ExtendedSelection : QAbstractItemView::SingleSelection);
      tree->headerItem()->setHidden(true);
      tree->setContextMenuPolicy(Qt::CustomContextMenu);
    if (m.sorted) {
        tree->setSortingEnabled(true);
        tree->sortItems(0, Qt::AscendingOrder);
    }
    documentIcon.addFile(":/core/images/document.png");
    roDocumentIcon.addFile(":/core/images/ro_document.png");
    gobjectIcon.addFile(":/core/images/gobject.png");

    removeSelectedDocumentsAction = new QAction(QIcon(":core/images/remove_selected_documents.png"), tr("remove_selected_documents_action"), this);
      removeSelectedDocumentsAction->setShortcut(QKeySequence::Delete);
    removeSelectedDocumentsAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
    tree->addAction(removeSelectedDocumentsAction);
    connect(removeSelectedDocumentsAction, SIGNAL(triggered()), SLOT(sl_onRemoveSelectedDocuments()));

      loadSelectedDocumentsAction = new QAction(QIcon(":core/images/load_selected_documents.png"), tr("load_selected_documents_action"), this);
    loadSelectedDocumentsAction->setShortcuts(QList<QKeySequence>() << Qt::Key_Enter << Qt::Key_Return);
    loadSelectedDocumentsAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
    tree->addAction(loadSelectedDocumentsAction);
      connect(loadSelectedDocumentsAction, SIGNAL(triggered()), SLOT(sl_onLoadSelectedDocuments()));

    addReadonlyFlagAction = new QAction(tr("make_doc_readonly"), this);
    connect(addReadonlyFlagAction, SIGNAL(triggered()), SLOT(sl_onToggleReadonly()));

    removeReadonlyFlagAction = new QAction(tr("make_doc_not_readonly"), this);
    connect(removeReadonlyFlagAction, SIGNAL(triggered()), SLOT(sl_onToggleReadonly()));

    unloadSelectedDocumentsAction = new QAction(QIcon(":core/images/unload_document.png"), tr("unload_sel_doc"), this);
    connect(unloadSelectedDocumentsAction, SIGNAL(triggered()), SLOT(sl_onUnloadSelectedDocuments()));

      connect(tree, SIGNAL(itemSelectionChanged()), SLOT(sl_onTreeSelectionChanged()));
      connect(tree, SIGNAL(customContextMenuRequested(const QPoint &)), SLOT(sl_onContextMenuRequested(const QPoint &)));
      connect(tree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), SLOT(sl_onItemDoubleClicked(QTreeWidgetItem*, int )));

      Project* pr = AppContext::getProject();
      connect(pr, SIGNAL(si_documentAdded(Document*)), SLOT(sl_onDocumentAddedToProject(Document*)));
      connect(pr, SIGNAL(si_documentRemoved(Document*)), SLOT(sl_onDocumentRemovedFromProject(Document*)));

    connectModel();

      buildTree();

      updateActions();

    connectToResourceTracker();
}

void ProjectTreeController::connectToResourceTracker() {
    connect(AppContext::getResourceTracker(), 
        SIGNAL(si_resourceUserRegistered(const QString&, Task*)), 
        SLOT(sl_onResourceUserRegistered(const QString&, Task*)));

    connect(AppContext::getResourceTracker(), 
        SIGNAL(si_resourceUserUnregistered(const QString&, Task*)), 
        SLOT(sl_onResourceUserUnregistered(const QString&, Task*)));


    foreach(Document* d, AppContext::getProject()->getDocuments()) {
        const QString resName = LoadUnloadedDocumentTask::getResourceName(d);
        QList<Task*> users = AppContext::getResourceTracker()->getResourceUsers(resName);
        foreach(Task* t, users) {
            sl_onResourceUserRegistered(resName, t);
        }
    }
}

void ProjectTreeController::connectModel() {
      Project* p = AppContext::getProject();
      const QList<Document*>& docs = p->getDocuments();
      foreach(Document* d, docs) {
            connectDocument(d);
      }
}

void ProjectTreeController::connectDocument(Document* d) {
      connect(d, SIGNAL(si_modifiedStateChanged()), SLOT(sl_onDocumentModifiedStateChanged()));
      connect(d, SIGNAL(si_loadedStateChanged()), SLOT(sl_onDocumentLoadedStateChanged()));
      connect(d, SIGNAL(si_objectAdded(GObject*)), SLOT(sl_onObjectAdded(GObject*)));
      connect(d, SIGNAL(si_objectRemoved(GObject*)), SLOT(sl_onObjectRemoved(GObject*)));
    connect(d, SIGNAL(si_lockedStateChanged()), SLOT(sl_lockedStateChanged()));
      
      const QList<GObject*>& objects = d->getObjects();
      foreach(GObject* o, objects) {
            connectGObject(o);
      }
}

void ProjectTreeController::disconnectDocument(Document* d) {
      d->disconnect(this);
      const QList<GObject*>& objects = d->getObjects();
      foreach(GObject* o, objects) {
            o->disconnect(this);
      }
    Task* t = LoadUnloadedDocumentTask::findActiveLoadingTask(d);
    if (t) {
        t->disconnect(this);
        t->cancel();
    }
}

void ProjectTreeController::connectGObject(GObject* o) {
      connect(o, SIGNAL(si_modifiedStateChanged()), SLOT(sl_onObjectModifiedStateChanged()));
}

void ProjectTreeController::buildTree() {
      tree->clear();

      const QList<Document*>& docs = AppContext::getProject()->getDocuments();
      foreach(Document* d, docs) {
            buildDocumentTree(d);
      }
}

#define MAX_OBJECTS_TO_AUTOEXPAND 50

void ProjectTreeController::buildDocumentTree(Document* d) {
    ProjViewDocumentTreeItem* docItem =  NULL;
    
    if (mode.isDocumentShown(d)) {
        docItem = new ProjViewDocumentTreeItem(d, this);
    }
    
      const QList<GObject*>& objs = d->getObjects();
      foreach(GObject* obj, objs) {
        if (mode.isObjectShown(obj)) {
                ProjViewObjectTreeItem* oItem = new ProjViewObjectTreeItem(obj, docItem, this);
            if (docItem==NULL) {
                tree->addTopLevelItem(oItem);
            }
        }
      }
    if (docItem!=NULL) {
          tree->addTopLevelItem(docItem);
        
        if (d->getObjects().size() < MAX_OBJECTS_TO_AUTOEXPAND && d->isLoaded()) { //avoid system slowdown without user interaction
            docItem->setExpanded(true);
        }
    }
}


ProjViewDocumentTreeItem* ProjectTreeController::findDocumentItem(Document* d) const {
      for (int i=0;i<tree->topLevelItemCount(); i++) {
        ProjViewTreeItem* item = (ProjViewTreeItem*)tree->topLevelItem(i);
        if (!item->isDocumentItem()) {
            continue;
        }
            ProjViewDocumentTreeItem* docItem = (ProjViewDocumentTreeItem*)item;
            if (docItem->doc == d) {
                  return docItem;
            }
      }
      return NULL;
}

ProjViewObjectTreeItem* ProjectTreeController::findGObjectItem(Document* doc, GObject* obj) const {
    assert(doc == obj->getDocument() || obj->getDocument() == NULL);
    assert(doc != NULL);
      ProjViewDocumentTreeItem* docItem = findDocumentItem(doc);
    if (docItem!=NULL) {
        for (int i=0;i<docItem->childCount(); i++) {
            ProjViewObjectTreeItem* item = (ProjViewObjectTreeItem*)docItem->child(i);
            if (item->obj == obj) {
                return item;
            }
        }
    } else {
        for (int i=0; i < tree->topLevelItemCount(); i++) {
            ProjViewTreeItem* item = (ProjViewTreeItem*)tree->topLevelItem(i);
            if (!item->isObjectItem()) {
                continue;
            }
            ProjViewObjectTreeItem* objItem = (ProjViewObjectTreeItem*)item;
            if (objItem->obj == obj) {
                return objItem;
            }
        }
    }
    return NULL;
}

void ProjectTreeController::sl_onTreeSelectionChanged() {
      updateSelection();
      updateActions();
}

void ProjectTreeController::updateSelection() {
      QList<QTreeWidgetItem*> items = tree->selectedItems();
      if (items.isEmpty()) {
            objectSelection.clear();
            documentSelection.clear();
            return;
      } 
      QList<Document*> selectedDocs;
      QList<GObject*> selectedObjs;
      foreach(QTreeWidgetItem* item , items) {
            ProjViewTreeItem* pvi = (ProjViewTreeItem*)item;
            if (pvi->isDocumentItem()) {
                  ProjViewDocumentTreeItem* di = (ProjViewDocumentTreeItem*)pvi;
                  selectedDocs.push_back(di->doc);
            } else {
                  assert(pvi->isObjectItem());
                  ProjViewObjectTreeItem* oi = (ProjViewObjectTreeItem*)pvi;
                  selectedObjs.push_back(oi->obj);
            }
      }
      objectSelection.setSelection(selectedObjs);
      documentSelection.setSelection(selectedDocs);
}


void ProjectTreeController::sl_onItemDoubleClicked(QTreeWidgetItem * item, int column) {
    Q_UNUSED(column);
      ProjViewTreeItem* pvi = (ProjViewTreeItem*)item;
      if (pvi->isObjectItem()) {
            emit si_doubleClicked(((ProjViewObjectTreeItem*)pvi)->obj);
      } else {
            assert(pvi->isDocumentItem());
            Document* d = ((ProjViewDocumentTreeItem*)pvi)->doc;
            if (!d->isLoaded()) {
                  assert(loadSelectedDocumentsAction->isEnabled());
                  loadSelectedDocumentsAction->trigger();
            }
      }
}

void ProjectTreeController::sl_onContextMenuRequested(const QPoint & pos) {
    Q_UNUSED(pos);
      
    QMenu m;

      if (loadSelectedDocumentsAction->isEnabled()) {
            m.addAction(loadSelectedDocumentsAction);
      }
    if (unloadSelectedDocumentsAction->isEnabled()) {
        m.addAction(unloadSelectedDocumentsAction);
    }
    if (addReadonlyFlagAction->isEnabled()) {
        m.addAction(addReadonlyFlagAction);
    }
    if (removeReadonlyFlagAction->isEnabled()) {
        m.addAction(removeReadonlyFlagAction);
    }

    ProjectView* pv = AppContext::getProjectView();
      if (pv!=NULL) {
        //change original text, these actions removed when menu deleted
        //QAction* addNewDocumentAction = new QAction(pv->getAddNewDocumentAction()->icon(), tr("new_document"), &m);
        //connect(addNewDocumentAction, SIGNAL(triggered()), pv->getAddNewDocumentAction(), SLOT(trigger()));

        QAction* addExistingDocumentAction = new QAction(pv->getAddExistingDocumentAction()->icon(), tr("existing_document"), &m);
        connect(addExistingDocumentAction, SIGNAL(triggered()), pv->getAddExistingDocumentAction(), SLOT(trigger()));

        QMenu* addMenu = m.addMenu(tr("add_submenu"));
        addMenu->menuAction()->setObjectName(ACTION_PROJECT__ADD_MENU);
        addMenu->addAction(addExistingDocumentAction);
        //addMenu->addAction(addNewDocumentAction);
      }
    
    QMenu* removeMenu = m.addMenu(tr("remove_submenu"));
      removeMenu->addAction(removeSelectedDocumentsAction);
      removeMenu->setEnabled(removeSelectedDocumentsAction->isEnabled());

      emit si_onPopupMenuRequested(m);

      m.exec(QCursor::pos());
}

void ProjectTreeController::updateActions() {
      removeSelectedDocumentsAction->setEnabled(objectSelection.isEmpty() && !documentSelection.isEmpty());

      bool hasUnloadedDocumentInSelection = false;
    bool hasLoadedDocumentInSelection = false;
      foreach(Document* d, documentSelection.getSelectedDocuments()) {
            if (!d->isLoaded()) {
                  hasUnloadedDocumentInSelection = true;
                  break;
        } else {
            hasLoadedDocumentInSelection = true;
        }

      }
      loadSelectedDocumentsAction->setEnabled(hasUnloadedDocumentInSelection);
    unloadSelectedDocumentsAction->setEnabled(hasLoadedDocumentInSelection);
    
    const QList<Document*> selectedDocs = documentSelection.getSelectedDocuments();
    addReadonlyFlagAction->setEnabled(selectedDocs.size() == 1 && !selectedDocs[0]->hasUserModLock());
    removeReadonlyFlagAction->setEnabled(selectedDocs.size() == 1 && selectedDocs[0]->hasUserModLock());
}

void ProjectTreeController::sl_onRemoveSelectedDocuments() {
      Project* p = AppContext::getProject();
      QList<Document*> docs = documentSelection.getSelectedDocuments();
      if (!docs.isEmpty())
        AppContext::getTaskScheduler()->registerTopLevelTask(new RemoveMultipleDocumentsTask(p, docs, true, true));
}

void ProjectTreeController::sl_onLoadSelectedDocuments() {
    foreach(Document* d, documentSelection.getSelectedDocuments()) {
        if (!d->isLoaded() && LoadUnloadedDocumentTask::findActiveLoadingTask(d)==NULL) {
            runLoadDocumentTask(d);
        }
    }
}

void ProjectTreeController::sl_onUnloadSelectedDocuments() {
    QList<Document*> docsToUnload;
    foreach(Document* doc, documentSelection.getSelectedDocuments()) {
        if (doc->isLoaded()) {
            docsToUnload.append(doc);
        }
    }

    UnloadDocumentTask::runUnloadTaskHelper(docsToUnload, UnloadDocumentTask_SaveMode_Ask);
}


void ProjectTreeController::runLoadDocumentTask(Document* d) {
    Task* t = NULL;
    if (mode.loadTaskProvider!=NULL) {
        t = mode.loadTaskProvider->createLoadDocumentTask(d);
    } else {
        t = new LoadUnloadedDocumentTask(d);
    }
    AppContext::getTaskScheduler()->registerTopLevelTask(t);
}

void ProjectTreeController::sl_onDocumentAddedToProject(Document* d) {
      //todo: sort?
      buildDocumentTree(d);
      connectDocument(d);

      updateActions();
}

void ProjectTreeController::sl_onDocumentRemovedFromProject(Document* d) {
      ProjViewDocumentTreeItem* item = findDocumentItem(d);
      assert(item);
      disconnectDocument(d);
      delete item;

      updateSelection();
      updateActions();
}

void ProjectTreeController::sl_onToggleReadonly() {
    const QList<Document*> selectedDocs = documentSelection.getSelectedDocuments();
    if (selectedDocs.size()!=1) {
        return;
    }
    Document* doc = selectedDocs[0];
    if (doc->hasUserModLock()) {
        doc->setUserModLock(false);
    } else {
        doc->setUserModLock(true);
    }
}

void ProjectTreeController::sl_lockedStateChanged() {
    Document* doc = qobject_cast<Document*>(sender());
    assert(doc!=NULL);
    ProjViewDocumentTreeItem* di = findDocumentItem(doc);
    if (di!=NULL) {
        di->updateVisual(false);
    }
    updateActions();
}


void ProjectTreeController::flattenDocumentItem(ProjViewDocumentTreeItem* docItem) {
    while (docItem->childCount()!=0) {
        ProjViewTreeItem* item = (ProjViewTreeItem*)docItem->takeChild(0);
        assert(item->isObjectItem());
        ProjViewObjectTreeItem* objItem = (ProjViewObjectTreeItem*)item;
        if (mode.isObjectShown(objItem->obj)) {
            tree->addTopLevelItem(objItem);
            objItem->updateVisual();
        } else {
            delete objItem;
        }
    }
}

void ProjectTreeController::sl_onDocumentLoadedStateChanged() {
    Document* d = qobject_cast<Document*>(sender());
    ProjViewDocumentTreeItem* docItem = findDocumentItem(d);
    if (!mode.isDocumentShown(d)) { //document item can be automatically removed from the view after its loaded
        if (docItem!=NULL) {
            flattenDocumentItem(docItem);
            delete docItem;
            docItem = NULL;
        }
    }
    if (docItem!=NULL && d->getObjects().size() < MAX_OBJECTS_TO_AUTOEXPAND) {
        docItem->setExpanded(d->isLoaded());
    }
      updateActions();
}


void ProjectTreeController::sl_onDocumentModifiedStateChanged() {
    Document* d = qobject_cast<Document*>(sender());
    assert(d!=NULL);
    if (!mode.isDocumentShown(d)) {
        return;
    }
    updateActions();
      ProjViewDocumentTreeItem* item = findDocumentItem(d);
    assert(item);
      item->updateVisual();
}

void ProjectTreeController::sl_onObjectModifiedStateChanged() {
    updateActions();
      GObject* obj = qobject_cast<GObject*>(sender());
    assert(obj!=NULL);
    if (!mode.isObjectShown(obj)) {
        return;
    }
      ProjViewObjectTreeItem* item = findGObjectItem(obj->getDocument(), obj);
      assert(item);
      item->updateVisual();
}


void ProjectTreeController::sl_onObjectAdded(GObject* obj) {
    if (!mode.isObjectShown(obj)) {
        return;
    }
      Document* doc = obj->getDocument();
      assert(doc);
      ProjViewDocumentTreeItem* docItem = NULL;
    if (mode.isDocumentShown(doc)) {
        docItem = findDocumentItem(doc);
        assert(docItem);
    }
      ProjViewObjectTreeItem* objItem = new ProjViewObjectTreeItem(obj, docItem, this);
    if (docItem == NULL) {
        tree->addTopLevelItem(objItem);
    }
      updateActions();
}

void ProjectTreeController::sl_onObjectRemoved(GObject* obj) {
    if (!mode.isObjectShown(obj)) {
        return;
    }
    Document* doc = qobject_cast<Document*>(sender());
    assert(doc!=NULL);
      ProjViewObjectTreeItem* objItem = findGObjectItem(doc, obj);
      assert(objItem!=NULL);
      delete objItem;
      updateActions();
}

void ProjectTreeController::sl_onResourceUserRegistered(const QString& res, Task* t) {
    Q_UNUSED(res);
    LoadUnloadedDocumentTask* lut = qobject_cast<LoadUnloadedDocumentTask*>(t);
    if (lut == NULL) {
        return;
    }
    connect(lut, SIGNAL(si_progressChanged()), SLOT(sl_onLoadingDocumentProgressChanged()));
}

void ProjectTreeController::sl_onResourceUserUnregistered(const QString& res, Task* t) {
    Q_UNUSED(res);
    LoadUnloadedDocumentTask* lut = qobject_cast<LoadUnloadedDocumentTask*>(t);
    if (lut == NULL) {
        return;
    }
    lut->disconnect(this);

    Document* doc = lut->getDocument();
    ProjViewDocumentTreeItem* di = findDocumentItem(doc);
    if (di!=NULL) {
        di->updateVisual();
    }
}


void ProjectTreeController::sl_onLoadingDocumentProgressChanged() {
    LoadUnloadedDocumentTask* lut = qobject_cast<LoadUnloadedDocumentTask*>(sender());
    assert(lut!=NULL);
    Document* doc = lut->getDocument();
    if (!mode.isDocumentShown(doc)) {
        return;
    }
    ProjViewDocumentTreeItem* di = findDocumentItem(doc);
    if (di) {
        di->updateVisual();
    }
}

//////////////////////////////////////////////////////////////////////////
/// tree items
ProjViewDocumentTreeItem::ProjViewDocumentTreeItem(Document* _doc, ProjectTreeController* c) 
: ProjViewTreeItem(NULL, c), doc(_doc) 
{
      updateVisual();
}

void ProjViewDocumentTreeItem::updateVisual(bool recursive) {
      if (recursive) {
            for (int i = 0, n = childCount(); i < n ; i++ ) {
                  ProjViewObjectTreeItem* oi = (ProjViewObjectTreeItem*)child(i);
                  oi->updateVisual(recursive);
            }
      }

    //update text
      QString text;
      if (doc->isTreeItemModified()) {
            text+="[modified]"; //TODO: replace with * sign?
      } 
      if (!doc->isLoaded()) {
        LoadUnloadedDocumentTask* t = LoadUnloadedDocumentTask::findActiveLoadingTask(doc);
        if (t == NULL) {
            text+="[unloaded]";
        } else {
            text+=ProjectTreeController::tr("[loading %1%]").arg(t->getProgress());
        }
      }
      text+=doc->getName();
      setData(0, Qt::DisplayRole, text);
      
    //update icon
    bool showLockedIcon = doc->isStateLocked();
    if (!doc->isLoaded() && doc->getStateLocks().size() == 1 && doc->getDocumentModLock(DocumentModLock_UNLOADED_STATE)!=NULL) {
        showLockedIcon = false;
    }
    setIcon(0, showLockedIcon ? controller->roDocumentIcon : controller->documentIcon);

    //update tooltip
    QString tooltip = doc->getURL();
    if  (doc->isStateLocked()) {
        tooltip.append("<br><br>").append(ProjectTreeController::tr("locks:"));
        if (doc->getParentStateLockItem()->isStateLocked()) {
            tooltip.append("<br>&nbsp;*&nbsp;").append(ProjectTreeController::tr("project_is_locked"));
        } 
        foreach(StateLock* lock, doc->getStateLocks()) {
            if (!doc->isLoaded() && lock == doc->getDocumentModLock(DocumentModLock_FORMAT_AS_INSTANCE)) {
                continue; //do not visualize some locks for unloaded document
            }
            tooltip.append("<br>&nbsp;*&nbsp;").append(lock->getUserDesc());
        }
    }
    setData(0, Qt::ToolTipRole, tooltip);
}

ProjViewObjectTreeItem::ProjViewObjectTreeItem(GObject* _obj, ProjViewDocumentTreeItem* parent, ProjectTreeController* c) 
: ProjViewTreeItem(parent, c), obj(_obj) 
{
      updateVisual();
}

void ProjViewObjectTreeItem::updateVisual(bool recursive) {
    Q_UNUSED(recursive);
      QString text;
    GObjectType t = obj->getGObjectType();
    if (t == GObjectTypes::DNA_SEQUENCE) {
        text+="[s] ";
    } else if (t == GObjectTypes::ANNOTATION_TABLE) {
        text+="[a] ";
    } else if (t == GObjectTypes::TEXT) {
        text+="[t] ";
    } else if (t == GObjectTypes::DNA_CHROMATOGRAM) {
        text+="[c] ";
    } else  if (t == GObjectTypes::MULTIPLE_ALIGNMENT) {
        text+="[m] ";
    } else  if (t == GObjectTypes::BIOSTRUCTURE_3D) {
        text+="[3d] ";
    }

      if (obj->isTreeItemModified()) {
            text+="[modified]";
      }
      text+=obj->getGObjectName();
      setData(0, Qt::DisplayRole, text);
    setIcon(0, controller->gobjectIcon);


    QString tooltip;
    //todo: make tooltop for object items
   
    if (parent() == NULL) {
        tooltip.append(obj->getDocument()->getURL());
    }
    setToolTip(0, tooltip);
}

//////////////////////////////////////////////////////////////////////////
// settings

bool ProjectTreeControllerModeSettings::isDocumentShown(Document* doc) const {
    //filter by readonly state
    
    //TODO: revise readonly filters;
    //if the only lock is unloaded state lock -> not show it
    bool isReadonly = ! (doc->getStateLocks().size() == 1 && doc->getDocumentModLock(DocumentModLock_UNLOADED_STATE)!=NULL);
    bool res = readOnlyFilter == TriState_Unknown ? true : 
        (readOnlyFilter == TriState_Yes && !isReadonly) || (readOnlyFilter == TriState_No && isReadonly);
    if (!res) {
        return false;
    }

    //filter by object types
    if (!objectTypesToShow.isEmpty()) { 
        //show only documents that are unloaded and can possible contain the specified object types
        if (doc->isLoaded()) {
            return false;
        }
        DocumentFormatConstraints c;
        c.supportedObjectTypes<<objectTypesToShow;
        res = doc->getDocumentFormat()->checkConstraints(c);
        if (!res) {
            return false;
        }
    }
    //filter by name
    if (!tokensToShow.isEmpty()) {
        res = false;
        foreach(const QString& token, tokensToShow) {
            if (doc->getURL().contains(token)) {
                res = true;
                break;
            }
        }
        if (!res) {
            return false;
        }
    }
    return true;

}

bool ProjectTreeControllerModeSettings::isObjectShown(GObject* o) const  {
    //filter by type
    bool res = isObjectShown(o->getGObjectType());
    if (!res) {
        return false;
    }
    //filter by readonly flag
    Document* doc = o->getDocument();
    //TODO: revise readonly filters -> use isStateLocked or hasReadonlyLock ?
    res = readOnlyFilter == TriState_Unknown ? true : 
         (readOnlyFilter == TriState_Yes && !doc->isStateLocked()) || (readOnlyFilter == TriState_No && doc->isStateLocked());
    if (!res) {
        return false;
    }

    //filter by exclude list
    foreach(const QPointer<GObject>& p, excludeObjectList) {
        if (p.isNull()) {
            continue;
        }
        if (o == p.data()) {
            return false;
        }
    }

    //filter by internal obj properties
    if (!objectConstraints.isEmpty()) {
        res = true;
        foreach(const GObjectConstraints* c, objectConstraints) {
            if (o->getGObjectType() != c->objectType) {
                continue;
            }
            res = o->checkConstraints(c);
            if (!res) {
                return false;
            }
        }
    }
    
    //filter by name
    if (!tokensToShow.isEmpty()) {
        res = false;
        foreach(const QString& token, tokensToShow) {
            if (o->getGObjectName().contains(token)) {
                res = true;
                break;
            }
        }
        if (!res) {
            return false;
        }
    }

    //filter by relation
    if (objectRelation.isValid() && !o->hasObjectRelation(objectRelation)) {
        return false;
    }
    return true;
}

bool ProjectTreeControllerModeSettings::isObjectShown(GObjectType t) const {
    if (objectTypesToShow.isEmpty()) {
        return true;
    }
    return objectTypesToShow.contains(t);
}

}//namespace

Generated by  Doxygen 1.6.0   Back to index