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

KDEUI

klinkitemselectionmodel.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 "klinkitemselectionmodel.h"
00024 
00025 #include "kmodelindexproxymapper.h"
00026 
00027 #include "kdebug.h"
00028 
00029 #include <QItemSelection>
00030 
00031 class KLinkItemSelectionModelPrivate
00032 {
00033 public:
00034     KLinkItemSelectionModelPrivate(KLinkItemSelectionModel *proxySelectionModel, QAbstractItemModel *model,
00035                                     QItemSelectionModel *linkedItemSelectionModel)
00036       : q_ptr(proxySelectionModel),
00037         m_model(model),
00038         m_linkedItemSelectionModel(linkedItemSelectionModel),
00039         m_ignoreCurrentChanged(false),
00040         m_indexMapper(new KModelIndexProxyMapper(model, linkedItemSelectionModel->model(), proxySelectionModel))
00041     {
00042     }
00043 
00044     Q_DECLARE_PUBLIC(KLinkItemSelectionModel)
00045     KLinkItemSelectionModel * const q_ptr;
00046 
00047 
00048     bool assertSelectionValid(const QItemSelection &selection) const {
00049       foreach(const QItemSelectionRange &range, selection) {
00050         if (!range.isValid()) {
00051           kDebug() << selection;
00052         }
00053         Q_ASSERT(range.isValid());
00054       }
00055       return true;
00056     }
00057 
00058     void sourceSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected);
00059 
00060     QAbstractItemModel * const m_model;
00061     QItemSelectionModel * const m_linkedItemSelectionModel;
00062     bool m_ignoreCurrentChanged;
00063     KModelIndexProxyMapper * const m_indexMapper;
00064 };
00065 
00066 KLinkItemSelectionModel::KLinkItemSelectionModel(QAbstractItemModel *model, QItemSelectionModel *proxySelector, QObject *parent)
00067         : QItemSelectionModel(model, parent),
00068         d_ptr(new KLinkItemSelectionModelPrivate(this, model, proxySelector))
00069 {
00070     connect(proxySelector, SIGNAL(selectionChanged(QItemSelection, QItemSelection)), SLOT(sourceSelectionChanged(QItemSelection, QItemSelection)));
00071 }
00072 
00073 KLinkItemSelectionModel::~KLinkItemSelectionModel()
00074 {
00075     delete d_ptr;
00076 }
00077 
00078 void KLinkItemSelectionModel::select(const QModelIndex &index, QItemSelectionModel::SelectionFlags command)
00079 {
00080     Q_D(KLinkItemSelectionModel);
00081     // When an item is removed, the current index is set to the top index in the model.
00082     // That causes a selectionChanged signal with a selection which we do not want.
00083     if (d->m_ignoreCurrentChanged) {
00084         return;
00085     }
00086     QItemSelectionModel::select(index, command);
00087     if (index.isValid())
00088         d->m_linkedItemSelectionModel->select(d->m_indexMapper->mapSelectionLeftToRight(QItemSelection(index, index)), command);
00089     else {
00090         d->m_linkedItemSelectionModel->clearSelection();
00091     }
00092 }
00093 
00094 // QAbstractProxyModel::mapSelectionFromSource creates invalid ranges to we filter
00095 // those out manually in a loop. Hopefully fixed in Qt 4.7.2, so we ifdef it out.
00096 // http://qt.gitorious.org/qt/qt/merge_requests/2474
00097 // http://qt.gitorious.org/qt/qt/merge_requests/831
00098 #if QT_VERSION < 0x040702
00099 #define RANGE_FIX_HACK
00100 #endif
00101 
00102 #ifdef RANGE_FIX_HACK
00103 static QItemSelection klink_removeInvalidRanges(const QItemSelection &selection)
00104 {
00105   QItemSelection result;
00106   Q_FOREACH(const QItemSelectionRange &range, selection)
00107   {
00108     if (!range.isValid())
00109       continue;
00110     result << range;
00111   }
00112   return result;
00113 }
00114 #endif
00115 
00116 void KLinkItemSelectionModel::select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command)
00117 {
00118     Q_D(KLinkItemSelectionModel);
00119     d->m_ignoreCurrentChanged = true;
00120 #ifdef RANGE_FIX_HACK
00121     QItemSelection _selection = klink_removeInvalidRanges(selection);
00122 #else
00123     QItemSelection _selection = selection;
00124 #endif
00125     QItemSelectionModel::select(_selection, command);
00126     Q_ASSERT(d->assertSelectionValid(_selection));
00127     QItemSelection mappedSelection = d->m_indexMapper->mapSelectionLeftToRight(_selection);
00128     Q_ASSERT(d->assertSelectionValid(mappedSelection));
00129     d->m_linkedItemSelectionModel->select(mappedSelection, command);
00130     d->m_ignoreCurrentChanged = false;
00131 }
00132 
00133 void KLinkItemSelectionModelPrivate::sourceSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected)
00134 {
00135     Q_Q(KLinkItemSelectionModel);
00136 #ifdef RANGE_FIX_HACK
00137     QItemSelection _selected = klink_removeInvalidRanges(selected);
00138     QItemSelection _deselected = klink_removeInvalidRanges(deselected);
00139 #else
00140     QItemSelection _selected = selected;
00141     QItemSelection _deselected = deselected;
00142 #endif
00143     Q_ASSERT(assertSelectionValid(_selected));
00144     Q_ASSERT(assertSelectionValid(_deselected));
00145     const QItemSelection mappedDeselection = m_indexMapper->mapSelectionRightToLeft(_deselected);
00146     const QItemSelection mappedSelection = m_indexMapper->mapSelectionRightToLeft(_selected);
00147 
00148     q->QItemSelectionModel::select(mappedDeselection, QItemSelectionModel::Deselect);
00149     q->QItemSelectionModel::select(mappedSelection, QItemSelectionModel::Select);
00150 }
00151 
00152 #include "klinkitemselectionmodel.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