• Skip to content
  • Skip to link menu
KDE 4.6 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • Contact Us
 

KDEUI

kbreadcrumbselectionmodel.cpp

Go to the documentation of this file.
00001 /*
00002     Copyright (C) 2010 Klarälvdalens Datakonsult AB,
00003         a KDAB Group company, info@kdab.net,
00004         author Stephen Kelly <stephen@kdab.com>
00005 
00006     This library is free software; you can redistribute it and/or modify it
00007     under the terms of the GNU Library General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or (at your
00009     option) any later version.
00010 
00011     This library is distributed in the hope that it will be useful, but WITHOUT
00012     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00013     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00014     License for more details.
00015 
00016     You should have received a copy of the GNU Library General Public License
00017     along with this library; see the file COPYING.LIB.  If not, write to the
00018     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00019     02110-1301, USA.
00020 */
00021 
00022 
00023 #include "kbreadcrumbselectionmodel.h"
00024 
00025 #include "kdebug.h"
00026 
00027 class KBreadcrumbSelectionModelPrivate
00028 {
00029   Q_DECLARE_PUBLIC(KBreadcrumbSelectionModel)
00030   KBreadcrumbSelectionModel * const q_ptr;
00031 public:
00032   KBreadcrumbSelectionModelPrivate(KBreadcrumbSelectionModel *breadcrumbSelector, QItemSelectionModel *selectionModel, KBreadcrumbSelectionModel::BreadcrumbTarget direction)
00033     : q_ptr(breadcrumbSelector),
00034       m_includeActualSelection(true),
00035       m_selectionDepth(-1),
00036       m_showHiddenAscendantData(false),
00037       m_selectionModel(selectionModel),
00038       m_direction(direction),
00039       m_ignoreCurrentChanged(false)
00040   {
00041 
00042   }
00043 
00047   QItemSelection getBreadcrumbSelection(const QModelIndex &index);
00048 
00052   QItemSelection getBreadcrumbSelection(const QItemSelection &selection);
00053 
00054   void sourceSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
00055 
00056   void init();
00057   void syncBreadcrumbs();
00058 
00059   bool m_includeActualSelection;
00060   int m_selectionDepth;
00061   bool m_showHiddenAscendantData;
00062   QItemSelectionModel *m_selectionModel;
00063   KBreadcrumbSelectionModel::BreadcrumbTarget m_direction;
00064   bool m_ignoreCurrentChanged;
00065 };
00066 
00067 KBreadcrumbSelectionModel::KBreadcrumbSelectionModel(QItemSelectionModel *selectionModel, QObject* parent)
00068   : QItemSelectionModel(const_cast<QAbstractItemModel *>(selectionModel->model()), parent),
00069     d_ptr(new KBreadcrumbSelectionModelPrivate(this, selectionModel, MakeBreadcrumbSelectionInSelf))
00070 {
00071   d_ptr->init();
00072 }
00073 
00074 KBreadcrumbSelectionModel::KBreadcrumbSelectionModel(QItemSelectionModel *selectionModel, BreadcrumbTarget direction, QObject* parent)
00075   : QItemSelectionModel(const_cast<QAbstractItemModel *>(selectionModel->model()), parent),
00076     d_ptr(new KBreadcrumbSelectionModelPrivate(this, selectionModel, direction))
00077 {
00078   if ( direction != MakeBreadcrumbSelectionInSelf)
00079     connect(selectionModel, SIGNAL(selectionChanged(const QItemSelection&,const QItemSelection&)),
00080             this, SLOT(sourceSelectionChanged(const QItemSelection&,const QItemSelection&)));
00081 
00082   d_ptr->init();
00083 }
00084 
00085 KBreadcrumbSelectionModel::~KBreadcrumbSelectionModel()
00086 {
00087   delete d_ptr;
00088 }
00089 
00090 bool KBreadcrumbSelectionModel::isActualSelectionIncluded() const
00091 {
00092   Q_D(const KBreadcrumbSelectionModel);
00093   return d->m_includeActualSelection;
00094 }
00095 
00096 void KBreadcrumbSelectionModel::setActualSelectionIncluded(bool includeActualSelection)
00097 {
00098   Q_D(KBreadcrumbSelectionModel);
00099   d->m_includeActualSelection = includeActualSelection;
00100 }
00101 
00102 int KBreadcrumbSelectionModel::breadcrumbLength() const
00103 {
00104   Q_D(const KBreadcrumbSelectionModel);
00105   return d->m_selectionDepth;
00106 }
00107 
00108 void KBreadcrumbSelectionModel::setBreadcrumbLength(int breadcrumbLength)
00109 {
00110   Q_D(KBreadcrumbSelectionModel);
00111   d->m_selectionDepth = breadcrumbLength;
00112 }
00113 
00114 QItemSelection KBreadcrumbSelectionModelPrivate::getBreadcrumbSelection(const QModelIndex& index)
00115 {
00116   QItemSelection breadcrumbSelection;
00117 
00118   if (m_includeActualSelection)
00119     breadcrumbSelection.append(QItemSelectionRange(index));
00120 
00121   QModelIndex parent = index.parent();
00122   int sumBreadcrumbs = 0;
00123   bool includeAll = m_selectionDepth < 0;
00124   while (parent.isValid() && (includeAll || sumBreadcrumbs < m_selectionDepth)) {
00125     breadcrumbSelection.append(QItemSelectionRange(parent));
00126     parent = parent.parent();
00127   }
00128   return breadcrumbSelection;
00129 }
00130 
00131 QItemSelection KBreadcrumbSelectionModelPrivate::getBreadcrumbSelection(const QItemSelection& selection)
00132 {
00133   QItemSelection breadcrumbSelection;
00134 
00135   if (m_includeActualSelection)
00136     breadcrumbSelection = selection;
00137 
00138   QItemSelection::const_iterator it = selection.constBegin();
00139   const QItemSelection::const_iterator end = selection.constEnd();
00140 
00141   for ( ; it != end; ++it)
00142   {
00143     QModelIndex parent = it->parent();
00144 
00145     if (breadcrumbSelection.contains(parent))
00146       continue;
00147 
00148     int sumBreadcrumbs = 0;
00149     bool includeAll = m_selectionDepth < 0;
00150 
00151     while (parent.isValid() && (includeAll || sumBreadcrumbs < m_selectionDepth))
00152     {
00153       breadcrumbSelection.append(QItemSelectionRange(parent));
00154       parent = parent.parent();
00155 
00156       if (breadcrumbSelection.contains(parent))
00157         break;
00158 
00159       ++sumBreadcrumbs;
00160     }
00161   }
00162   return breadcrumbSelection;
00163 }
00164 
00165 void KBreadcrumbSelectionModelPrivate::sourceSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected)
00166 {
00167   Q_Q(KBreadcrumbSelectionModel);
00168   QItemSelection deselectedCrumbs = getBreadcrumbSelection(deselected);
00169   QItemSelection selectedCrumbs = getBreadcrumbSelection(selected);
00170 
00171   QItemSelection removed = deselectedCrumbs;
00172   foreach(const QItemSelectionRange &range, selectedCrumbs)
00173   {
00174     removed.removeAll(range);
00175   }
00176 
00177   QItemSelection added = selectedCrumbs;
00178   foreach(const QItemSelectionRange &range, deselectedCrumbs)
00179   {
00180     added.removeAll(range);
00181   }
00182 
00183   if (!removed.isEmpty())
00184   {
00185     q->QItemSelectionModel::select(removed, QItemSelectionModel::Deselect);
00186   }
00187   if (!added.isEmpty())
00188   {
00189     q->QItemSelectionModel::select(added, QItemSelectionModel::Select);
00190   }
00191 }
00192 
00193 void KBreadcrumbSelectionModel::select(const QModelIndex &index, QItemSelectionModel::SelectionFlags command)
00194 {
00195   Q_D(KBreadcrumbSelectionModel);
00196   // When an item is removed, the current index is set to the top index in the model.
00197   // That causes a selectionChanged signal with a selection which we do not want.
00198   if ( d->m_ignoreCurrentChanged )
00199   {
00200     d->m_ignoreCurrentChanged = false;
00201     return;
00202   }
00203   if ( d->m_direction == MakeBreadcrumbSelectionInOther )
00204   {
00205     d->m_selectionModel->select(d->getBreadcrumbSelection(index), command);
00206     QItemSelectionModel::select(index, command);
00207   } else {
00208     d->m_selectionModel->select(index, command);
00209     QItemSelectionModel::select(d->getBreadcrumbSelection(index), command);
00210   }
00211 }
00212 
00213 void KBreadcrumbSelectionModel::select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command)
00214 {
00215   Q_D(KBreadcrumbSelectionModel);
00216   QItemSelection bcc = d->getBreadcrumbSelection(selection);
00217   if ( d->m_direction == MakeBreadcrumbSelectionInOther )
00218   {
00219     d->m_selectionModel->select(selection, command);
00220     QItemSelectionModel::select(bcc, command);
00221   } else {
00222     d->m_selectionModel->select(bcc, command);
00223     QItemSelectionModel::select(selection, command);
00224   }
00225 }
00226 
00227 void KBreadcrumbSelectionModelPrivate::init()
00228 {
00229   Q_Q(KBreadcrumbSelectionModel);
00230   q->connect(m_selectionModel->model(), SIGNAL(layoutChanged()), SLOT(syncBreadcrumbs()));
00231   q->connect(m_selectionModel->model(), SIGNAL(modelReset()), SLOT(syncBreadcrumbs()));
00232   q->connect(m_selectionModel->model(), SIGNAL(rowsMoved(QModelIndex, int, int, QModelIndex, int)), SLOT(syncBreadcrumbs()));
00233   // Don't need to handle insert & remove because they can't change the breadcrumbs on their own.
00234 }
00235 
00236 void KBreadcrumbSelectionModelPrivate::syncBreadcrumbs()
00237 {
00238   Q_Q(KBreadcrumbSelectionModel);
00239   q->select(m_selectionModel->selection(), QItemSelectionModel::ClearAndSelect);
00240 }
00241 
00242 
00243 #include "kbreadcrumbselectionmodel.moc"

KDEUI

Skip menu "KDEUI"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.3
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal