m_minimumUpdateIntervalTimer(0),
m_maximumUpdateIntervalTimer(0),
m_pendingItemsToInsert(),
- m_pendingItemsToDelete(),
m_rootExpansionLevel(-1)
{
resetRoles();
connect(dirLister, SIGNAL(completed()), this, SLOT(slotCompleted()));
connect(dirLister, SIGNAL(newItems(KFileItemList)), this, SLOT(slotNewItems(KFileItemList)));
connect(dirLister, SIGNAL(itemsDeleted(KFileItemList)), this, SLOT(slotItemsDeleted(KFileItemList)));
+ connect(dirLister, SIGNAL(refreshItems(QList<QPair<KFileItem,KFileItem> >)), this, SLOT(slotRefreshItems(QList<QPair<KFileItem,KFileItem> >)));
connect(dirLister, SIGNAL(clear()), this, SLOT(slotClear()));
connect(dirLister, SIGNAL(clear(KUrl)), this, SLOT(slotClear(KUrl)));
m_minimumUpdateIntervalTimer = new QTimer(this);
m_minimumUpdateIntervalTimer->setInterval(1000);
m_minimumUpdateIntervalTimer->setSingleShot(true);
- connect(m_minimumUpdateIntervalTimer, SIGNAL(timeout()), this, SLOT(dispatchPendingItems()));
+ connect(m_minimumUpdateIntervalTimer, SIGNAL(timeout()), this, SLOT(dispatchPendingItemsToInsert()));
// For slow KIO-slaves like used for searching it makes sense to show results periodically even
// before the completed() or canceled() signal has been emitted.
m_maximumUpdateIntervalTimer = new QTimer(this);
m_maximumUpdateIntervalTimer->setInterval(2000);
m_maximumUpdateIntervalTimer->setSingleShot(true);
- connect(m_maximumUpdateIntervalTimer, SIGNAL(timeout()), this, SLOT(dispatchPendingItems()));
+ connect(m_maximumUpdateIntervalTimer, SIGNAL(timeout()), this, SLOT(dispatchPendingItemsToInsert()));
Q_ASSERT(m_minimumUpdateIntervalTimer->interval() <= m_maximumUpdateIntervalTimer->interval());
}
return false;
}
-int KFileItemModel::indexForKeyboardSearch(const QString& text, int startFromIndex) const
-{
- startFromIndex = qMax(0, startFromIndex);
- for (int i = startFromIndex; i < count(); i++) {
- if (data(i)["name"].toString().startsWith(text, Qt::CaseInsensitive)) {
- kDebug() << data(i)["name"].toString();
- return i;
- }
- }
- for (int i = 0; i < startFromIndex; i++) {
- if (data(i)["name"].toString().startsWith(text, Qt::CaseInsensitive)) {
- kDebug() << data(i)["name"].toString();
- return i;
- }
- }
- return -1;
-}
-
bool KFileItemModel::supportsGrouping() const
{
return true;
}
const bool different = canUseMostLocalUrls && mostLocalUrls != urls;
- urls = KDirModel::simplifiedUrlList(urls);
+ urls = KDirModel::simplifiedUrlList(urls); // TODO: Check if we still need KDirModel for this in KDE 5.0
if (different) {
mostLocalUrls = KDirModel::simplifiedUrlList(mostLocalUrls);
urls.populateMimeData(mostLocalUrls, data);
return data;
}
+int KFileItemModel::indexForKeyboardSearch(const QString& text, int startFromIndex) const
+{
+ startFromIndex = qMax(0, startFromIndex);
+ for (int i = startFromIndex; i < count(); i++) {
+ if (data(i)["name"].toString().startsWith(text, Qt::CaseInsensitive)) {
+ kDebug() << data(i)["name"].toString();
+ return i;
+ }
+ }
+ for (int i = 0; i < startFromIndex; i++) {
+ if (data(i)["name"].toString().startsWith(text, Qt::CaseInsensitive)) {
+ kDebug() << data(i)["name"].toString();
+ return i;
+ }
+ }
+ return -1;
+}
+
+bool KFileItemModel::supportsDropping(int index) const
+{
+ const KFileItem item = fileItem(index);
+ return item.isNull() ? false : item.isDir();
+}
+
KFileItem KFileItemModel::fileItem(int index) const
{
if (index >= 0 && index < count()) {
return KFileItem();
}
+KFileItem KFileItemModel::fileItem(const KUrl& url) const
+{
+ const int index = m_items.value(url, -1);
+ if (index >= 0) {
+ return m_sortedItems.at(index);
+ }
+ return KFileItem();
+}
+
int KFileItemModel::index(const KFileItem& item) const
{
if (item.isNull()) {
return -1;
}
- return m_items.value(item, -1);
+ return m_items.value(item.url(), -1);
+}
+
+KUrl KFileItemModel::rootDirectory() const
+{
+ const KDirLister* dirLister = m_dirLister.data();
+ if (dirLister) {
+ return dirLister->url();
+ }
+ return KUrl();
}
void KFileItemModel::clear()
int index = 0;
foreach (const KFileItem& item, sortedItems) {
m_sortedItems.append(item);
- m_items.insert(item, index);
+ m_items.insert(item.url(), index);
m_data.append(retrieveData(item));
++index;
return;
}
- dispatchPendingItems();
+ dispatchPendingItemsToInsert();
m_minimumUpdateIntervalTimer->start();
}
{
m_minimumUpdateIntervalTimer->stop();
m_maximumUpdateIntervalTimer->stop();
- dispatchPendingItems();
+ dispatchPendingItemsToInsert();
}
void KFileItemModel::slotNewItems(const KFileItemList& items)
{
- if (!m_pendingItemsToDelete.isEmpty()) {
- removeItems(m_pendingItemsToDelete);
- m_pendingItemsToDelete.clear();
- }
m_pendingItemsToInsert.append(items);
if (useMaximumUpdateInterval() && !m_maximumUpdateIntervalTimer->isActive()) {
insertItems(m_pendingItemsToInsert);
m_pendingItemsToInsert.clear();
}
- m_pendingItemsToDelete.append(items);
+ removeItems(items);
+}
+
+void KFileItemModel::slotRefreshItems(const QList<QPair<KFileItem, KFileItem> >& items)
+{
+ Q_ASSERT(!items.isEmpty());
+#ifdef KFILEITEMMODEL_DEBUG
+ kDebug() << "Refreshing" << items.count() << "items";
+#endif
+
+ // Get the indexes of all items that have been refreshed
+ QList<int> indexes;
+ indexes.reserve(items.count());
+
+ QListIterator<QPair<KFileItem, KFileItem> > it(items);
+ while (it.hasNext()) {
+ const QPair<KFileItem, KFileItem>& itemPair = it.next();
+ const int index = m_items.value(itemPair.second.url(), -1);
+ if (index >= 0) {
+ indexes.append(index);
+ }
+ }
+
+ // Extract the item-ranges out of the changed indexes
+ qSort(indexes);
+
+ KItemRangeList itemRangeList;
+ int rangeIndex = 0;
+ int rangeCount = 1;
+ int previousIndex = indexes.at(0);
+
+ const int maxIndex = indexes.count() - 1;
+ for (int i = 1; i <= maxIndex; ++i) {
+ const int currentIndex = indexes.at(i);
+ if (currentIndex == previousIndex + 1) {
+ ++rangeCount;
+ } else {
+ itemRangeList.append(KItemRange(rangeIndex, rangeCount));
+
+ rangeIndex = currentIndex;
+ rangeCount = 1;
+ }
+ previousIndex = currentIndex;
+ }
+
+ if (rangeCount > 0) {
+ itemRangeList.append(KItemRange(rangeIndex, rangeCount));
+ }
+
+ emit itemsChanged(itemRangeList, QSet<QByteArray>());
}
void KFileItemModel::slotClear()
m_minimumUpdateIntervalTimer->stop();
m_maximumUpdateIntervalTimer->stop();
m_pendingItemsToInsert.clear();
- m_pendingItemsToDelete.clear();
m_rootExpansionLevel = -1;
Q_UNUSED(url);
}
-void KFileItemModel::dispatchPendingItems()
+void KFileItemModel::dispatchPendingItemsToInsert()
{
if (!m_pendingItemsToInsert.isEmpty()) {
- Q_ASSERT(m_pendingItemsToDelete.isEmpty());
insertItems(m_pendingItemsToInsert);
m_pendingItemsToInsert.clear();
- } else if (!m_pendingItemsToDelete.isEmpty()) {
- Q_ASSERT(m_pendingItemsToInsert.isEmpty());
- removeItems(m_pendingItemsToDelete);
- m_pendingItemsToDelete.clear();
}
}
// The indexes of all m_items must be adjusted, not only the index
// of the new items
for (int i = 0; i < m_sortedItems.count(); ++i) {
- m_items.insert(m_sortedItems.at(i), i);
+ m_items.insert(m_sortedItems.at(i).url(), i);
}
itemRanges << KItemRange(insertedAtIndex, insertedCount);
// Delete the items
for (int i = indexesToRemove.count() - 1; i >= 0; --i) {
const int indexToRemove = indexesToRemove.at(i);
- m_items.remove(m_sortedItems.at(indexToRemove));
+ m_items.remove(m_sortedItems.at(indexToRemove).url());
m_sortedItems.removeAt(indexToRemove);
m_data.removeAt(indexToRemove);
}
// The indexes of all m_items must be adjusted, not only the index
// of the removed items
for (int i = 0; i < m_sortedItems.count(); ++i) {
- m_items.insert(m_sortedItems.at(i), i);
+ m_items.insert(m_sortedItems.at(i).url(), i);
}
if (count() <= 0) {