3 #include "AbstractTreeModel.h"     8 #include <QFutureWatcher>    10 #include <QModelIndex>    15 #include <QtConcurrentFilter>    17 #include <QtConcurrentMap>    23 #include "BusyLeafItem.h"    30 #include "AbstractTreeItem.h"    31 #include "FilterWidget.h"    36   AbstractTreeModel::AbstractTreeModel(ControlNet *controlNet, TreeView *v,
    37       QObject *parent) : 
QObject(parent), m_view(v), m_cNet(controlNet) {
    40     m_filterWatcher = NULL;
    41     m_rebuildWatcher = NULL;
    44     m_expandedState = NULL;
    45     m_selectedState = NULL;
    46     m_guisFilterWidget = NULL;
    47     m_localFilterWidgetCopy = NULL;
    50     m_busyItem = 
new BusyLeafItem(NULL);
    51     rootItem = 
new RootItem;
    59     connect(m_filterWatcher, SIGNAL(finished()), 
this, SLOT(applyFilterDone()));
    60     connect(m_rebuildWatcher, SIGNAL(finished()), 
this, SLOT(rebuildItemsDone()));
    62     connect(m_filterWatcher, SIGNAL(progressValueChanged(
int)),
    63         this, SIGNAL(filterProgressChanged(
int)));
    64     connect(m_filterWatcher, SIGNAL(progressRangeChanged(
int, 
int)),
    65         this, SIGNAL(filterProgressRangeChanged(
int, 
int)));
    66     connect(m_rebuildWatcher, SIGNAL(progressValueChanged(
int)),
    67         this, SIGNAL(rebuildProgressChanged(
int)));
    68     connect(m_rebuildWatcher, SIGNAL(progressRangeChanged(
int, 
int)),
    69         this, SIGNAL(rebuildProgressRangeChanged(
int, 
int)));
    72     m_filterAgain = 
false;
    73     m_filterRunning = 
false;
    74     m_rebuildRunning = 
false;
    76     m_rebuildPending = 
false;
    80   AbstractTreeModel::~AbstractTreeModel() {
    81     delete m_filterWatcher;
    82     m_filterWatcher = NULL;
    84     delete m_rebuildWatcher;
    85     m_rebuildWatcher = NULL;
    93     delete m_expandedState;
    94     m_expandedState = NULL;
    96     delete m_selectedState;
    97     m_selectedState = NULL;
   102     delete m_localFilterWidgetCopy;
   103     m_localFilterWidgetCopy = NULL;
   105     m_guisFilterWidget = NULL;
   114       InterestingItemsFlag flags, 
bool ignoreExpansion) {
   116     int rowCount = end - start;
   117     const AbstractTreeItem *lastVisibleFilteredItem =
   118       rootItem->getLastVisibleFilteredItem();
   120     bool grabToEnd = (start >= 0 && end < 0);
   122     if (lastVisibleFilteredItem && (rowCount > 0 || grabToEnd) &&
   123         rootItem->childCount()) {
   125       AbstractTreeItem *currentItem = rootItem->getFirstVisibleChild();
   127       if (currentItem && !itemIsInteresting(currentItem, flags)) {
   128         currentItem = nextItem(currentItem, flags, ignoreExpansion);
   131       bool listStillValid = 
true;
   133       while (row < start && listStillValid && currentItem) {
   135         listStillValid = (currentItem != lastVisibleFilteredItem ||
   136             currentItem == currentItem->parent()->getLastVisibleChild());
   139           currentItem = nextItem(currentItem, flags, ignoreExpansion);
   142       while ((row < end || grabToEnd) && listStillValid && currentItem) {
   144         foundItems.append(currentItem);
   145         listStillValid = (currentItem != lastVisibleFilteredItem ||
   146             currentItem == currentItem->parent()->getLastVisibleChild());
   150           currentItem = nextItem(currentItem, flags, ignoreExpansion);
   156       while (!grabToEnd && isFiltering() && foundItems.size() < rowCount) {
   157         foundItems.append(m_busyItem);
   166     AbstractTreeItem *item1, AbstractTreeItem *item2,
   167     InterestingItemsFlag flags, 
bool ignoreExpansion) {
   170     if (rootItem->childCount()) {
   171       AbstractTreeItem *start = NULL;
   173       AbstractTreeItem *curItem = rootItem->getFirstVisibleChild();
   175       while (!start && curItem) {
   176         if (curItem == item1)
   178         else if (curItem == item2)
   182           curItem = nextItem(curItem, flags, ignoreExpansion);
   186         QString msg = 
"The first item passed to getItems(AbstractTreeItem*, "   187             "AbstractTreeItem*) is not visible in this model's tree";
   191       AbstractTreeItem *end = item2;
   198         AbstractTreeItem * 
const &);
   201       if (start == item2) {
   206       while (curItem && curItem != end) {
   207         (foundItems.*someKindaPend)(curItem);
   208         curItem = nextItem(curItem, flags, ignoreExpansion);
   212         QString msg = 
"The second item passed to getItems(AbstractTreeItem*, "   213             "AbstractTreeItem*) is not visible in this model's tree";
   217       (foundItems.*someKindaPend)(end);
   225     InterestingItemsFlag flags, 
bool ignoreExpansion) {
   230     if (!isFiltering()) {
   231       AbstractTreeItem *currentItem = rootItem->getFirstVisibleChild();
   233       if (currentItem && !itemIsInteresting(currentItem, flags))
   234         currentItem = nextItem(currentItem, flags, ignoreExpansion);
   236       while (currentItem) {
   237         if (currentItem->isSelected())
   238           selectedItems.append(currentItem);
   240         currentItem = nextItem(currentItem, flags, ignoreExpansion);
   244     return selectedItems;
   248   QMutex *AbstractTreeModel::getMutex()
 const {
   253   int AbstractTreeModel::getItemCount(InterestingItemsFlag flags)
 const {
   254     return getItemCount(rootItem, flags);
   258   int AbstractTreeModel::getTopLevelItemCount()
 const {
   259     return rootItem->childCount();
   262   int AbstractTreeModel::getVisibleItemCount(InterestingItemsFlag flags,
   263       bool ignoreExpansion)
 const {
   264     AbstractTreeItem *currentItem = rootItem->getFirstVisibleChild();
   267     if (!isFiltering()) {
   270       while (currentItem) {
   271         if (itemIsInteresting(currentItem, flags)) {
   275         currentItem = nextItem(currentItem, flags, ignoreExpansion);
   283   int AbstractTreeModel::getVisibleTopLevelItemCount()
 const {
   284     AbstractTreeItem *currentItem = rootItem->getFirstVisibleChild();
   287     if (!isFiltering()) {
   290       while (currentItem) {
   292         currentItem = currentItem->getNextVisiblePeer();
   300   int AbstractTreeModel::indexOfVisibleItem(AbstractTreeItem 
const *item,
   301       InterestingItemsFlag flags, 
bool ignoreExpansion)
 const {
   302     AbstractTreeItem *currentItem = rootItem->getFirstVisibleChild();
   305     if (!isFiltering()) {
   306       while (currentItem && currentItem != item) {
   307         if (itemIsInteresting(currentItem, flags))
   310         currentItem = nextItem(currentItem, flags, ignoreExpansion);
   323   void AbstractTreeModel::setFrozen(
bool newFrozenState) {
   324     m_frozen = newFrozenState;
   326       if (m_rebuildPending) {
   328         m_rebuildPending = 
false;
   337   bool AbstractTreeModel::isFrozen()
 const {
   342   void AbstractTreeModel::queueRebuild() {
   343     m_rebuildPending = 
true;
   347   bool AbstractTreeModel::isFiltering()
 const {
   348     return m_filterRunning;
   352   bool AbstractTreeModel::isRebuilding()
 const {
   353     return m_rebuildRunning;
   357   void AbstractTreeModel::setFilter(FilterWidget *fw) {
   358     m_guisFilterWidget = fw;
   360       connect(m_guisFilterWidget, SIGNAL(filterChanged()),
   361           this, SLOT(applyFilter()));
   367   void AbstractTreeModel::clear() {
   372     rootItem = 
new RootItem;
   376   ControlNet *AbstractTreeModel::getControlNetwork()
 const {
   382   AbstractTreeModel::getRebuildWatcher()
 const {
   383     return m_rebuildWatcher;
   387   RootItem *AbstractTreeModel::getRootItem()
 const {
   392   TreeView *AbstractTreeModel::getView()
 const {
   397   void AbstractTreeModel::stopWorking() {
   398     m_filterWatcher->cancel();
   399     m_filterWatcher->waitForFinished();
   400     m_rebuildWatcher->cancel();
   401     m_rebuildWatcher->waitForFinished();
   409     if (!isFiltering()) {
   410       int visibleRowCount = 0;
   413       if (rootItem && rootItem->getFirstVisibleChild()) {
   416         while (current != NULL) {
   417           int depth = current->getDepth();
   420           maxWidth = qMax(maxWidth,
   421               current->getDataWidth() + indentation * depth);
   422           current = nextItem(current, AllItems, 
false);
   426       size = QSize(maxWidth, visibleRowCount);
   433   void AbstractTreeModel::applyFilter() {
   436     if (!m_frozen && !m_filterAgain && m_guisFilterWidget &&
   437         m_rebuildWatcher->isFinished()) {
   439       QFuture< QAtomicPointer< AbstractTreeItem> > futureRoot;
   441       if (m_filterRunning) {
   442         m_filterAgain = 
true;
   443         futureRoot = m_filterWatcher->future();
   452         if (m_localFilterWidgetCopy) {
   453           delete m_localFilterWidgetCopy;
   454           m_localFilterWidgetCopy = NULL;
   457         m_localFilterWidgetCopy = 
new FilterWidget(*m_guisFilterWidget);
   462         m_filterRunning = 
true;
   463         rootItem->setLastVisibleFilteredItem(NULL);
   464         futureRoot = QtConcurrent::filteredReduced(rootItem->getChildren(),
   465             FilterFunctor(m_localFilterWidgetCopy),
   466             &FilterFunctor::updateTopLevelLinks,
   467             QtConcurrent::OrderedReduce | QtConcurrent::SequentialReduce);
   469         m_filterWatcher->setFuture(futureRoot);
   475   void AbstractTreeModel::setGlobalSelection(
bool selected,
   476       InterestingItemsFlag flags) {
   477     selectItems(rootItem, selected, flags);
   481   void AbstractTreeModel::selectItems(
   482     AbstractTreeItem *item, 
bool selected, InterestingItemsFlag flags) {
   483     if (item && itemIsInteresting(item, flags)) {
   484       item->setSelected(selected);
   487     if (item->childCount()) {
   488       foreach (AbstractTreeItem * childItem, item->getChildren()) {
   489         selectItems(childItem, selected, flags);
   495   bool AbstractTreeModel::itemIsInteresting(AbstractTreeItem *item,
   496       InterestingItemsFlag flags) {
   497     AbstractTreeItem::InternalPointerType pointerType =
   498       item->getPointerType();
   500     if ((pointerType == AbstractTreeItem::Point && flags.testFlag(PointItems)) ||
   501         (pointerType == AbstractTreeItem::Measure && flags.testFlag(MeasureItems)) ||
   502         (pointerType == AbstractTreeItem::ImageAndNet && flags.testFlag(ImageItems))) {
   511   int AbstractTreeModel::getItemCount(AbstractTreeItem *item,
   512       InterestingItemsFlag flags)
 const {
   515     if (item && itemIsInteresting(item, flags)) {
   519     if (item->childCount()) {
   520       foreach (AbstractTreeItem * childItem, item->getChildren()) {
   521         count += getItemCount(childItem, flags);
   529   AbstractTreeItem *AbstractTreeModel::nextItem(AbstractTreeItem *current,
   530       InterestingItemsFlag flags, 
bool ignoreExpansion)
 const {
   533         if ((ignoreExpansion || current->isExpanded()) &&
   534             current->getFirstVisibleChild())
   535           current = current->getFirstVisibleChild();
   536         else if (current->getNextVisiblePeer())
   537           current = current->getNextVisiblePeer();
   538         else if (current->parent())
   539           current = current->parent()->getNextVisiblePeer();
   543       while (current && !itemIsInteresting(current, flags));
   550   void AbstractTreeModel::applyFilterDone() {
   551     m_filterRunning = 
false;
   554       m_filterAgain = 
false;
   558       emit modelModified();
   560           getTopLevelItemCount());
   565   void AbstractTreeModel::rebuildItemsDone() {
   569     RootItem *newRoot = newRootPtr.loadAcquire();
   571     if (newRoot && newRoot->childCount()) {
   585     setRebuilding(
false);
   586     emit modelModified();
   590   AbstractTreeModel::FilterFunctor::FilterFunctor(
   591     FilterWidget *fw) : m_filter(fw) {
   595   AbstractTreeModel::FilterFunctor::FilterFunctor(FilterFunctor 
const &other) {
   596     m_filter = other.m_filter;
   600   AbstractTreeModel::FilterFunctor::~FilterFunctor() {
   604   bool AbstractTreeModel::FilterFunctor::operator()(
   605     AbstractTreeItem *
const &item)
 const {
   611   AbstractTreeModel::FilterFunctor &
   612   AbstractTreeModel::FilterFunctor::operator=(FilterFunctor 
const &other) {
   614       m_filter = other.m_filter;
   620   void AbstractTreeModel::FilterFunctor::filterWorker(
   621     AbstractTreeItem *item)
 const {
   622     switch (item->getPointerType()) {
   624       case AbstractTreeItem::Point:
   625         item->setVisible((!m_filter || m_filter->evaluate(
   626             (ControlPoint *) item->getPointer())) ? true : 
false);
   629       case AbstractTreeItem::Measure:
   630         item->setVisible((!m_filter || m_filter->evaluate(
   631             (ControlMeasure *) item->getPointer())) ? true : 
false);
   634       case AbstractTreeItem::ImageAndNet:
   635         item->setVisible((!m_filter || m_filter->evaluate(
   639       case AbstractTreeItem::None:
   640         item->setVisible(
true);
   645     if (item->getFirstVisibleChild())
   646       item->setFirstVisibleChild(NULL);
   648     if (item->getLastVisibleChild())
   649       item->setLastVisibleChild(NULL);
   651     item->setNextVisiblePeer(NULL);
   655     if (item->childCount()) {
   656       for (
int i = 0; i < item->childCount(); i++) {
   657         AbstractTreeItem *child = item->childAt(i);
   660         if (child->isVisible()) {
   661           if (!item->getFirstVisibleChild()) {
   662             item->setFirstVisibleChild(child);
   663             item->setLastVisibleChild(child);
   666             item->getLastVisibleChild()->setNextVisiblePeer(child);
   667             item->setLastVisibleChild(child);
   675   void AbstractTreeModel::FilterFunctor::updateTopLevelLinks(
   677     AbstractTreeItem *
const &item) {
   679     if ( root.testAndSetOrdered(NULL, item->parent()) ) {
   680       AbstractTreeItem *loadedRoot = root.loadAcquire();
   681       loadedRoot->setFirstVisibleChild(NULL);
   682       loadedRoot->setLastVisibleChild(NULL);
   683       loadedRoot->setLastVisibleFilteredItem(NULL);
   687     AbstractTreeItem *loadedRoot = root.loadAcquire();
   688     if (item->isVisible()) {
   689       if (!loadedRoot->getFirstVisibleChild()) {
   690         loadedRoot->setFirstVisibleChild(item);
   691         loadedRoot->setLastVisibleChild(item);
   694         loadedRoot->getLastVisibleChild()->setNextVisiblePeer(item);
   695         loadedRoot->setLastVisibleChild(item);
   698       loadedRoot->setLastVisibleFilteredItem(item);
 QSize getVisibleSize(int indentation) const
indentation is in pixels 
 
void filterCountsChanged(int visibleTopLevelItemCount, int topLevelItemCount)
This signal is emitted after filtering to provide the number of visible top-level items remaining aft...
 
This error is for when a programmer made an API call that was illegal. 
 
#define _FILEINFO_
Macro for the filename and line number. 
 
Namespace for ISIS/Bullet specific routines. 
 
Base class for an item in the tree.