KIO
kmimetyperesolver.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 2000, 2006 David Faure <faure@kde.org> 00003 Copyright (C) 2000 Rik Hemsley <rik@kde.org> 00004 Copyright (C) 2002 Carsten Pfeiffer <pfeiffer@kde.org> 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Library General Public 00008 License version 2 as published by the Free Software Foundation. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Library General Public License for more details. 00014 00015 You should have received a copy of the GNU Library General Public License 00016 along with this library; see the file COPYING.LIB. If not, write to 00017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00018 Boston, MA 02110-1301, USA. 00019 */ 00020 00021 #include "kmimetyperesolver.h" 00022 #include <kdebug.h> 00023 #include "defaultviewadapter_p.h" 00024 #include <kdirmodel.h> 00025 #include <kfileitem.h> 00026 #include <QAbstractItemView> 00027 #include <QAbstractProxyModel> 00028 #include <QScrollBar> 00029 #include <QTimer> 00030 00031 class KMimeTypeResolverPrivate 00032 { 00033 public: 00034 KMimeTypeResolverPrivate(KMimeTypeResolver *parent) 00035 : q(parent), 00036 m_delayForNonVisibleIcons(10), // TODO set me to 0 when image preview is enabled 00037 m_noVisibleIcon(false) 00038 { 00039 m_timer.setSingleShot(true); 00040 } 00041 00042 00043 void _k_slotRowsInserted(const QModelIndex&,int,int); 00044 void _k_slotViewportAdjusted(); 00045 void _k_slotProcessMimeIcons(); 00046 00047 void init(); 00048 QModelIndex findVisibleIcon(); 00049 00050 KMimeTypeResolver* q; 00051 KAbstractViewAdapter* m_adapter; 00052 QAbstractProxyModel* m_proxyModel; 00053 KDirModel* m_dirModel; 00054 int m_delayForNonVisibleIcons; 00055 QList<QPersistentModelIndex> m_pendingIndexes; 00056 QTimer m_timer; 00057 // Set to true when findVisibleIcon found no visible index in m_pendingIndexes. 00058 // This makes further calls to findVisibleIcon no-ops until this bool is reset to false. 00059 bool m_noVisibleIcon; 00060 }; 00061 00062 void KMimeTypeResolverPrivate::init() 00063 { 00064 QObject::connect(m_dirModel, SIGNAL(rowsInserted(QModelIndex,int,int)), 00065 q, SLOT(_k_slotRowsInserted(QModelIndex,int,int))); 00066 QObject::connect(&m_timer, SIGNAL(timeout()), 00067 q, SLOT(_k_slotProcessMimeIcons())); 00068 m_adapter->connect(KAbstractViewAdapter::ScrollBarValueChanged, q, SLOT(_k_slotViewportAdjusted())); 00069 } 00070 00071 QModelIndex KMimeTypeResolverPrivate::findVisibleIcon() 00072 { 00073 if (m_noVisibleIcon) 00074 return QModelIndex(); 00075 00076 if (m_pendingIndexes.count() < 20) { // for few items, it's faster to not bother 00077 //kDebug() << "Few items, returning first one"; 00078 return QModelIndex(m_pendingIndexes.first()); 00079 } 00080 00081 const QRect visibleArea = m_adapter->visibleArea(); 00082 QList<QPersistentModelIndex>::const_iterator it = m_pendingIndexes.constBegin(); 00083 const QList<QPersistentModelIndex>::const_iterator end = m_pendingIndexes.constEnd(); 00084 bool layoutDone = true; 00085 for ( ; it != end ; ++it ) { 00086 const QModelIndex index = m_proxyModel ? m_proxyModel->mapFromSource(*it) : QModelIndex(*it); 00087 const QRect rect = m_adapter->visualRect(index); 00088 if (rect.isNull()) 00089 layoutDone = false; 00090 else if (rect.intersects(visibleArea)) { 00091 //kDebug() << "found item at " << rect << " in visibleArea " << visibleArea; 00092 return QModelIndex(*it); 00093 } 00094 } 00095 00096 if (layoutDone) { 00097 //kDebug() << "no more visible icon found"; 00098 m_noVisibleIcon = true; 00099 return QModelIndex(); 00100 } else { 00101 // Return a random index if the layout is still ongoing 00102 return QModelIndex(m_pendingIndexes.first()); 00103 } 00104 } 00105 00107 00108 KMimeTypeResolver::KMimeTypeResolver(QAbstractItemView* view, KDirModel* model) 00109 : QObject(view), d(new KMimeTypeResolverPrivate(this)) 00110 { 00111 d->m_adapter = new KIO::DefaultViewAdapter(view, this); 00112 d->m_proxyModel = 0; 00113 d->m_dirModel = model; 00114 d->init(); 00115 } 00116 00117 KMimeTypeResolver::KMimeTypeResolver(QAbstractItemView* view, QAbstractProxyModel* model) 00118 : QObject(view), d(new KMimeTypeResolverPrivate(this)) 00119 { 00120 d->m_adapter = new KIO::DefaultViewAdapter(view, this); 00121 d->m_proxyModel = model; 00122 d->m_dirModel = static_cast<KDirModel*>(model->sourceModel()); 00123 d->init(); 00124 } 00125 00126 KMimeTypeResolver::KMimeTypeResolver(KAbstractViewAdapter* adapter) 00127 : QObject(adapter), d(new KMimeTypeResolverPrivate(this)) 00128 { 00129 QAbstractItemModel *model = adapter->model(); 00130 d->m_adapter = adapter; 00131 d->m_proxyModel = qobject_cast<QAbstractProxyModel*>(model); 00132 d->m_dirModel = d->m_proxyModel ? qobject_cast<KDirModel*>(d->m_proxyModel->sourceModel()) 00133 : qobject_cast<KDirModel*>(model); 00134 Q_ASSERT(d->m_dirModel); 00135 d->init(); 00136 } 00137 00138 KMimeTypeResolver::~KMimeTypeResolver() 00139 { 00140 delete d; 00141 } 00142 00143 void KMimeTypeResolverPrivate::_k_slotProcessMimeIcons() 00144 { 00145 if (m_pendingIndexes.isEmpty()) { 00146 // Finished 00147 return; 00148 } 00149 00150 int nextDelay = 0; 00151 QModelIndex index = findVisibleIcon(); 00152 if (index.isValid()) { 00153 // Found a visible item. 00154 const int numFound = m_pendingIndexes.removeAll(index); 00155 Q_UNUSED(numFound); // prevent warning in release builds. 00156 Q_ASSERT(numFound == 1); 00157 } else { 00158 // No more visible items. 00159 // Do the unvisible ones, then, but with a bigger delay, if so configured 00160 index = m_pendingIndexes.takeFirst(); 00161 nextDelay = m_delayForNonVisibleIcons; 00162 } 00163 KFileItem item = m_dirModel->itemForIndex(index); 00164 if (!item.isNull()) { // check that item still exists 00165 if (!item.isMimeTypeKnown()) { // check if someone did it meanwhile 00166 item.determineMimeType(); 00167 m_dirModel->itemChanged(index); 00168 } 00169 } 00170 m_timer.start(nextDelay); // singleshot 00171 } 00172 00173 void KMimeTypeResolverPrivate::_k_slotRowsInserted(const QModelIndex& parent, int first, int last) 00174 { 00175 KDirModel* model = m_dirModel; 00176 for (int row = first; row <= last; ++row) { 00177 QModelIndex idx = model->index(row, 0, parent); 00178 KFileItem item = model->itemForIndex(idx); 00179 if (!item.isMimeTypeKnown()) 00180 m_pendingIndexes.append(idx); 00181 // TODO else if (item->isDir() && !item->isLocalFile() /*nor pseudo local...*/ && 00182 // TODO model->data(idx, ChildCountRole).toInt() == KDirModel::ChildCountUnknown) 00183 // TODO d->m_pendingIndexes.append(idx); 00184 } 00185 m_noVisibleIcon = false; 00186 m_timer.start(m_delayForNonVisibleIcons); // singleshot 00187 } 00188 00189 void KMimeTypeResolverPrivate::_k_slotViewportAdjusted() 00190 { 00191 m_noVisibleIcon = false; 00192 m_timer.start(0); 00193 } 00194 00195 #include "kmimetyperesolver.moc"
KDE 4.7 API Reference