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 <kdirlister.h> 00027 #include <QAbstractItemView> 00028 #include <QAbstractProxyModel> 00029 #include <QScrollBar> 00030 #include <QTimer> 00031 00032 class KMimeTypeResolverPrivate 00033 { 00034 public: 00035 KMimeTypeResolverPrivate(KMimeTypeResolver *parent) 00036 : q(parent), 00037 m_delayForNonVisibleIcons(10), // TODO set me to 0 when image preview is enabled 00038 m_noVisibleIcon(false) 00039 { 00040 m_timer.setSingleShot(true); 00041 } 00042 00043 00044 void _k_slotRowsInserted(const QModelIndex&,int,int); 00045 void _k_slotViewportAdjusted(); 00046 void _k_slotProcessMimeIcons(); 00047 00048 void init(); 00049 QModelIndex findVisibleIcon(); 00050 00051 KMimeTypeResolver* q; 00052 KAbstractViewAdapter* m_adapter; 00053 QAbstractProxyModel* m_proxyModel; 00054 KDirModel* m_dirModel; 00055 int m_delayForNonVisibleIcons; 00056 QList<QPersistentModelIndex> m_pendingIndexes; 00057 QTimer m_timer; 00058 // Set to true when findVisibleIcon found no visible index in m_pendingIndexes. 00059 // This makes further calls to findVisibleIcon no-ops until this bool is reset to false. 00060 bool m_noVisibleIcon; 00061 }; 00062 00063 void KMimeTypeResolverPrivate::init() 00064 { 00065 QObject::connect(m_dirModel, SIGNAL(rowsInserted(QModelIndex,int,int)), 00066 q, SLOT(_k_slotRowsInserted(QModelIndex,int,int))); 00067 QObject::connect(&m_timer, SIGNAL(timeout()), 00068 q, SLOT(_k_slotProcessMimeIcons())); 00069 m_adapter->connect(KAbstractViewAdapter::ScrollBarValueChanged, q, SLOT(_k_slotViewportAdjusted())); 00070 } 00071 00072 QModelIndex KMimeTypeResolverPrivate::findVisibleIcon() 00073 { 00074 if (m_noVisibleIcon) 00075 return QModelIndex(); 00076 00077 if (m_pendingIndexes.count() < 20) { // for few items, it's faster to not bother 00078 //kDebug() << "Few items, returning first one"; 00079 return QModelIndex(m_pendingIndexes.first()); 00080 } 00081 00082 const QRect visibleArea = m_adapter->visibleArea(); 00083 QList<QPersistentModelIndex>::const_iterator it = m_pendingIndexes.constBegin(); 00084 const QList<QPersistentModelIndex>::const_iterator end = m_pendingIndexes.constEnd(); 00085 bool layoutDone = true; 00086 for ( ; it != end ; ++it ) { 00087 const QModelIndex index = m_proxyModel ? m_proxyModel->mapFromSource(*it) : QModelIndex(*it); 00088 const QRect rect = m_adapter->visualRect(index); 00089 if (rect.isNull()) 00090 layoutDone = false; 00091 else if (rect.intersects(visibleArea)) { 00092 //kDebug() << "found item at " << rect << " in visibleArea " << visibleArea; 00093 return QModelIndex(*it); 00094 } 00095 } 00096 00097 if (layoutDone) { 00098 //kDebug() << "no more visible icon found"; 00099 m_noVisibleIcon = true; 00100 return QModelIndex(); 00101 } else { 00102 // Return a random index if the layout is still ongoing 00103 return QModelIndex(m_pendingIndexes.first()); 00104 } 00105 } 00106 00108 00109 KMimeTypeResolver::KMimeTypeResolver(QAbstractItemView* view, KDirModel* model) 00110 : QObject(view), d(new KMimeTypeResolverPrivate(this)) 00111 { 00112 d->m_adapter = new KIO::DefaultViewAdapter(view, this); 00113 d->m_proxyModel = 0; 00114 d->m_dirModel = model; 00115 d->init(); 00116 } 00117 00118 KMimeTypeResolver::KMimeTypeResolver(QAbstractItemView* view, QAbstractProxyModel* model) 00119 : QObject(view), d(new KMimeTypeResolverPrivate(this)) 00120 { 00121 d->m_adapter = new KIO::DefaultViewAdapter(view, this); 00122 d->m_proxyModel = model; 00123 d->m_dirModel = static_cast<KDirModel*>(model->sourceModel()); 00124 d->init(); 00125 } 00126 00127 KMimeTypeResolver::KMimeTypeResolver(KAbstractViewAdapter* adapter) 00128 : QObject(adapter), d(new KMimeTypeResolverPrivate(this)) 00129 { 00130 QAbstractItemModel *model = adapter->model(); 00131 d->m_adapter = adapter; 00132 d->m_proxyModel = qobject_cast<QAbstractProxyModel*>(model); 00133 d->m_dirModel = d->m_proxyModel ? qobject_cast<KDirModel*>(d->m_proxyModel->sourceModel()) 00134 : qobject_cast<KDirModel*>(model); 00135 Q_ASSERT(d->m_dirModel); 00136 d->init(); 00137 } 00138 00139 KMimeTypeResolver::~KMimeTypeResolver() 00140 { 00141 delete d; 00142 } 00143 00144 void KMimeTypeResolverPrivate::_k_slotProcessMimeIcons() 00145 { 00146 if (m_pendingIndexes.isEmpty()) { 00147 // Finished 00148 return; 00149 } 00150 00151 int nextDelay = 0; 00152 QModelIndex index = findVisibleIcon(); 00153 if (index.isValid()) { 00154 // Found a visible item. 00155 const int numFound = m_pendingIndexes.removeAll(index); 00156 Q_UNUSED(numFound); // prevent warning in release builds. 00157 Q_ASSERT(numFound == 1); 00158 } else { 00159 // No more visible items. 00160 // Do the unvisible ones, then, but with a bigger delay, if so configured 00161 index = m_pendingIndexes.takeFirst(); 00162 nextDelay = m_delayForNonVisibleIcons; 00163 } 00164 KFileItem item = m_dirModel->itemForIndex(index); 00165 if (!item.isNull()) { // check that item still exists 00166 if (!item.isMimeTypeKnown()) { // check if someone did it meanwhile 00167 item.determineMimeType(); 00168 m_dirModel->itemChanged(index); 00169 } 00170 } 00171 m_timer.start(nextDelay); // singleshot 00172 } 00173 00174 void KMimeTypeResolverPrivate::_k_slotRowsInserted(const QModelIndex& parent, int first, int last) 00175 { 00176 KDirModel* model = m_dirModel; 00177 for (int row = first; row <= last; ++row) { 00178 QModelIndex idx = model->index(row, 0, parent); 00179 KFileItem item = model->itemForIndex(idx); 00180 if (!item.isMimeTypeKnown()) 00181 m_pendingIndexes.append(idx); 00182 // TODO else if (item->isDir() && !item->isLocalFile() /*nor pseudo local...*/ && 00183 // TODO model->data(idx, ChildCountRole).toInt() == KDirModel::ChildCountUnknown) 00184 // TODO d->m_pendingIndexes.append(idx); 00185 } 00186 m_noVisibleIcon = false; 00187 m_timer.start(m_delayForNonVisibleIcons); // singleshot 00188 } 00189 00190 void KMimeTypeResolverPrivate::_k_slotViewportAdjusted() 00191 { 00192 m_noVisibleIcon = false; 00193 m_timer.start(0); 00194 } 00195 00196 #include "kmimetyperesolver.moc"
KDE 4.6 API Reference