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

KIO

  • sources
  • kde-4.14
  • kdelibs
  • kio
  • kio
kdirmodel.cpp
Go to the documentation of this file.
1 /* This file is part of the KDE project
2  Copyright (C) 2006 David Faure <faure@kde.org>
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Library General Public
6  License as published by the Free Software Foundation; either
7  version 2 of the License, or (at your option) any later version.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Library General Public License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to
16  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  Boston, MA 02110-1301, USA.
18 */
19 
20 #include "kdirmodel.h"
21 #include "kdirlister.h"
22 #include "kfileitem.h"
23 #include <kdatetime.h>
24 #include <kicon.h>
25 #include <klocale.h>
26 #include <kglobal.h>
27 #include <kio/copyjob.h>
28 #include <kio/fileundomanager.h>
29 #include <kio/jobuidelegate.h>
30 #include <kio/joburlcache_p.h>
31 #include <kurl.h>
32 #include <kdebug.h>
33 #include <QMimeData>
34 #include <QFile>
35 #include <QFileInfo>
36 #include <QDir>
37 #include <sys/types.h>
38 #include <dirent.h>
39 
40 #ifdef Q_WS_WIN
41 #include <windows.h>
42 #endif
43 
44 class KDirModelNode;
45 class KDirModelDirNode;
46 
47 static KUrl cleanupUrl(const KUrl& url) {
48  KUrl u = url;
49  u.cleanPath(); // remove double slashes in the path, simplify "foo/." to "foo/", etc.
50  u.adjustPath(KUrl::RemoveTrailingSlash); // KDirLister does this too, so we remove the slash before comparing with the root node url.
51  u.setQuery(QString());
52  u.setRef(QString());
53  return u;
54 }
55 
56 // We create our own tree behind the scenes to have fast lookup from an item to its parent,
57 // and also to get the children of an item fast.
58 class KDirModelNode
59 {
60 public:
61  KDirModelNode( KDirModelDirNode* parent, const KFileItem& item ) :
62  m_item(item),
63  m_parent(parent),
64  m_preview()
65  {
66  }
67  // m_item is KFileItem() for the root item
68  const KFileItem& item() const { return m_item; }
69  void setItem(const KFileItem& item) { m_item = item; }
70  KDirModelDirNode* parent() const { return m_parent; }
71  // linear search
72  int rowNumber() const; // O(n)
73  QIcon preview() const { return m_preview; }
74  void setPreview( const QPixmap& pix ) { m_preview = QIcon(); m_preview.addPixmap(pix); }
75  void setPreview( const QIcon& icn ) { m_preview = icn; }
76 
77 private:
78  KFileItem m_item;
79  KDirModelDirNode* const m_parent;
80  QIcon m_preview;
81 };
82 
83 // Specialization for directory nodes
84 class KDirModelDirNode : public KDirModelNode
85 {
86 public:
87  KDirModelDirNode( KDirModelDirNode* parent, const KFileItem& item)
88  : KDirModelNode( parent, item),
89  m_childNodes(),
90  m_childCount(KDirModel::ChildCountUnknown),
91  m_populated(false)
92  {}
93  ~KDirModelDirNode() {
94  qDeleteAll(m_childNodes);
95  }
96  QList<KDirModelNode *> m_childNodes; // owns the nodes
97 
98  // If we listed the directory, the child count is known. Otherwise it can be set via setChildCount.
99  int childCount() const { return m_childNodes.isEmpty() ? m_childCount : m_childNodes.count(); }
100  void setChildCount(int count) { m_childCount = count; }
101  bool isPopulated() const { return m_populated; }
102  void setPopulated( bool populated ) { m_populated = populated; }
103  bool isSlow() const { return item().isSlow(); }
104 
105  // For removing all child urls from the global hash.
106  void collectAllChildUrls(KUrl::List &urls) const {
107  Q_FOREACH(KDirModelNode* node, m_childNodes) {
108  const KFileItem& item = node->item();
109  urls.append(cleanupUrl(item.url()));
110  if (item.isDir())
111  static_cast<KDirModelDirNode*>(node)->collectAllChildUrls(urls);
112  }
113  }
114 
115 private:
116  int m_childCount:31;
117  bool m_populated:1;
118 };
119 
120 int KDirModelNode::rowNumber() const
121 {
122  if (!m_parent) return 0;
123  return m_parent->m_childNodes.indexOf(const_cast<KDirModelNode*>(this));
124 }
125 
127 
128 class KDirModelPrivate
129 {
130 public:
131  KDirModelPrivate( KDirModel* model )
132  : q(model), m_dirLister(0),
133  m_rootNode(new KDirModelDirNode(0, KFileItem())),
134  m_dropsAllowed(KDirModel::NoDrops), m_jobTransfersVisible(false)
135  {
136  }
137  ~KDirModelPrivate() {
138  delete m_rootNode;
139  }
140 
141  void _k_slotNewItems(const KUrl& directoryUrl, const KFileItemList&);
142  void _k_slotDeleteItems(const KFileItemList&);
143  void _k_slotRefreshItems(const QList<QPair<KFileItem, KFileItem> >&);
144  void _k_slotClear();
145  void _k_slotRedirection(const KUrl& oldUrl, const KUrl& newUrl);
146  void _k_slotJobUrlsChanged(const QStringList& urlList);
147 
148  void clear() {
149  delete m_rootNode;
150  m_rootNode = new KDirModelDirNode(0, KFileItem());
151  }
152  // Emit expand for each parent and then return the
153  // last known parent if there is no node for this url
154  KDirModelNode* expandAllParentsUntil(const KUrl& url) const;
155 
156  // Return the node for a given url, using the hash.
157  KDirModelNode* nodeForUrl(const KUrl& url) const;
158  KDirModelNode* nodeForIndex(const QModelIndex& index) const;
159  QModelIndex indexForNode(KDirModelNode* node, int rowNumber = -1 /*unknown*/) const;
160  bool isDir(KDirModelNode* node) const {
161  return (node == m_rootNode) || node->item().isDir();
162  }
163  KUrl urlForNode(KDirModelNode* node) const {
171  KUrl url(node == m_rootNode ? m_dirLister->url() : node->item().url());
172  if (url.hasQuery() || url.hasRef()) { // avoid detach if not necessary.
173  url.setQuery(QString());
174  url.setRef(QString()); // kill ref (#171117)
175  }
176  return url;
177  }
178  void removeFromNodeHash(KDirModelNode* node, const KUrl& url);
179 #ifndef NDEBUG
180  void dump();
181 #endif
182 
183  KDirModel* q;
184  KDirLister* m_dirLister;
185  KDirModelDirNode* m_rootNode;
186  KDirModel::DropsAllowed m_dropsAllowed;
187  bool m_jobTransfersVisible;
188  // key = current known parent node (always a KDirModelDirNode but KDirModelNode is more convenient),
189  // value = final url[s] being fetched
190  QMap<KDirModelNode*, KUrl::List> m_urlsBeingFetched;
191  QHash<KUrl, KDirModelNode *> m_nodeHash; // global node hash: url -> node
192  QStringList m_allCurrentDestUrls; //list of all dest urls that have jobs on them (e.g. copy, download)
193 };
194 
195 KDirModelNode* KDirModelPrivate::nodeForUrl(const KUrl& _url) const // O(1), well, O(length of url as a string)
196 {
197  KUrl url = cleanupUrl(_url);
198  if (url == urlForNode(m_rootNode))
199  return m_rootNode;
200  return m_nodeHash.value(url);
201 }
202 
203 void KDirModelPrivate::removeFromNodeHash(KDirModelNode* node, const KUrl& url)
204 {
205  if (node->item().isDir()) {
206  KUrl::List urls;
207  static_cast<KDirModelDirNode *>(node)->collectAllChildUrls(urls);
208  Q_FOREACH(const KUrl& u, urls) {
209  m_nodeHash.remove(u);
210  }
211  }
212  m_nodeHash.remove(cleanupUrl(url));
213 }
214 
215 KDirModelNode* KDirModelPrivate::expandAllParentsUntil(const KUrl& _url) const // O(depth)
216 {
217  KUrl url = cleanupUrl(_url);
218 
219  //kDebug(7008) << url;
220  KUrl nodeUrl = urlForNode(m_rootNode);
221  if (url == nodeUrl)
222  return m_rootNode;
223 
224  // Protocol mismatch? Don't even start comparing paths then. #171721
225  if (url.protocol() != nodeUrl.protocol())
226  return 0;
227 
228  const QString pathStr = url.path(); // no trailing slash
229  KDirModelDirNode* dirNode = m_rootNode;
230 
231  if (!pathStr.startsWith(nodeUrl.path())) {
232  return 0;
233  }
234 
235  for (;;) {
236  const QString nodePath = nodeUrl.path(KUrl::AddTrailingSlash);
237  if(!pathStr.startsWith(nodePath)) {
238  kError(7008) << "The kioslave for" << url.protocol() << "violates the hierarchy structure:"
239  << "I arrived at node" << nodePath << ", but" << pathStr << "does not start with that path.";
240  return 0;
241  }
242 
243  // E.g. pathStr is /a/b/c and nodePath is /a/. We want to find the node with url /a/b
244  const int nextSlash = pathStr.indexOf('/', nodePath.length());
245  const QString newPath = pathStr.left(nextSlash); // works even if nextSlash==-1
246  nodeUrl.setPath(newPath);
247  nodeUrl.adjustPath(KUrl::RemoveTrailingSlash); // #172508
248  KDirModelNode* node = nodeForUrl(nodeUrl);
249  if (!node) {
250  //kDebug(7008) << "child equal or starting with" << url << "not found";
251  // return last parent found:
252  return dirNode;
253  }
254 
255  emit q->expand(indexForNode(node));
256 
257  //kDebug(7008) << " nodeUrl=" << nodeUrl;
258  if (nodeUrl == url) {
259  //kDebug(7008) << "Found node" << node << "for" << url;
260  return node;
261  }
262  //kDebug(7008) << "going into" << node->item().url();
263  Q_ASSERT(isDir(node));
264  dirNode = static_cast<KDirModelDirNode *>(node);
265  }
266  // NOTREACHED
267  //return 0;
268 }
269 
270 #ifndef NDEBUG
271 void KDirModelPrivate::dump()
272 {
273  kDebug() << "Dumping contents of KDirModel" << q << "dirLister url:" << m_dirLister->url();
274  QHashIterator<KUrl, KDirModelNode *> it(m_nodeHash);
275  while (it.hasNext()) {
276  it.next();
277  kDebug() << it.key() << it.value();
278  }
279 }
280 #endif
281 
282 // node -> index. If rowNumber is set (or node is root): O(1). Otherwise: O(n).
283 QModelIndex KDirModelPrivate::indexForNode(KDirModelNode* node, int rowNumber) const
284 {
285  if (node == m_rootNode)
286  return QModelIndex();
287 
288  Q_ASSERT(node->parent());
289  return q->createIndex(rowNumber == -1 ? node->rowNumber() : rowNumber, 0, node);
290 }
291 
292 // index -> node. O(1)
293 KDirModelNode* KDirModelPrivate::nodeForIndex(const QModelIndex& index) const
294 {
295  return index.isValid()
296  ? static_cast<KDirModelNode*>(index.internalPointer())
297  : m_rootNode;
298 }
299 
300 /*
301  * This model wraps the data held by KDirLister.
302  *
303  * The internal pointer of the QModelIndex for a given file is the node for that file in our own tree.
304  * E.g. index(2,0) returns a QModelIndex with row=2 internalPointer=<KDirModelNode for the 3rd child of the root>
305  *
306  * Invalid parent index means root of the tree, m_rootNode
307  */
308 
309 #ifndef NDEBUG
310 static QString debugIndex(const QModelIndex& index)
311 {
312  QString str;
313  if (!index.isValid())
314  str = "[invalid index, i.e. root]";
315  else {
316  KDirModelNode* node = static_cast<KDirModelNode*>(index.internalPointer());
317  str = "[index for " + node->item().url().pathOrUrl();
318  if (index.column() > 0)
319  str += ", column " + QString::number(index.column());
320  str += ']';
321  }
322  return str;
323 }
324 #endif
325 
326 KDirModel::KDirModel(QObject* parent)
327  : QAbstractItemModel(parent),
328  d(new KDirModelPrivate(this))
329 {
330  setDirLister(new KDirLister(this));
331 }
332 
333 KDirModel::~KDirModel()
334 {
335  delete d;
336 }
337 
338 void KDirModel::setDirLister(KDirLister* dirLister)
339 {
340  if (d->m_dirLister) {
341  d->clear();
342  delete d->m_dirLister;
343  }
344  d->m_dirLister = dirLister;
345  d->m_dirLister->setParent(this);
346  connect( d->m_dirLister, SIGNAL(itemsAdded(KUrl,KFileItemList)),
347  this, SLOT(_k_slotNewItems(KUrl,KFileItemList)) );
348  connect( d->m_dirLister, SIGNAL(itemsDeleted(KFileItemList)),
349  this, SLOT(_k_slotDeleteItems(KFileItemList)) );
350  connect( d->m_dirLister, SIGNAL(refreshItems(QList<QPair<KFileItem,KFileItem> >)),
351  this, SLOT(_k_slotRefreshItems(QList<QPair<KFileItem,KFileItem> >)) );
352  connect( d->m_dirLister, SIGNAL(clear()),
353  this, SLOT(_k_slotClear()) );
354  connect(d->m_dirLister, SIGNAL(redirection(KUrl,KUrl)),
355  this, SLOT(_k_slotRedirection(KUrl,KUrl)));
356 }
357 
358 KDirLister* KDirModel::dirLister() const
359 {
360  return d->m_dirLister;
361 }
362 
363 void KDirModelPrivate::_k_slotNewItems(const KUrl& directoryUrl, const KFileItemList& items)
364 {
365  //kDebug(7008) << "directoryUrl=" << directoryUrl;
366 
367  KDirModelNode* result = nodeForUrl(directoryUrl); // O(depth)
368  // If the directory containing the items wasn't found, then we have a big problem.
369  // Are you calling KDirLister::openUrl(url,true,false)? Please use expandToUrl() instead.
370  if (!result) {
371  kError(7008) << "Items emitted in directory" << directoryUrl
372  << "but that directory isn't in KDirModel!"
373  << "Root directory:" << urlForNode(m_rootNode);
374  Q_FOREACH(const KFileItem& item, items) {
375  kDebug() << "Item:" << item.url();
376  }
377 #ifndef NDEBUG
378  dump();
379 #endif
380  Q_ASSERT(result);
381  }
382  Q_ASSERT(isDir(result));
383  KDirModelDirNode* dirNode = static_cast<KDirModelDirNode *>(result);
384 
385  const QModelIndex index = indexForNode(dirNode); // O(n)
386  const int newItemsCount = items.count();
387  const int newRowCount = dirNode->m_childNodes.count() + newItemsCount;
388 #if 0
389 #ifndef NDEBUG // debugIndex only defined in debug mode
390  kDebug(7008) << items.count() << "in" << directoryUrl
391  << "index=" << debugIndex(index) << "newRowCount=" << newRowCount;
392 #endif
393 #endif
394 
395  q->beginInsertRows( index, newRowCount - newItemsCount, newRowCount - 1 ); // parent, first, last
396 
397  const KUrl::List urlsBeingFetched = m_urlsBeingFetched.value(dirNode);
398  //kDebug(7008) << "urlsBeingFetched for dir" << dirNode << directoryUrl << ":" << urlsBeingFetched;
399 
400  QList<QModelIndex> emitExpandFor;
401 
402  KFileItemList::const_iterator it = items.begin();
403  KFileItemList::const_iterator end = items.end();
404  for ( ; it != end ; ++it ) {
405  const bool isDir = it->isDir();
406  KDirModelNode* node = isDir
407  ? new KDirModelDirNode( dirNode, *it )
408  : new KDirModelNode( dirNode, *it );
409 #ifndef NDEBUG
410  // Test code for possible duplication of items in the childnodes list,
411  // not sure if/how it ever happened.
412  //if (dirNode->m_childNodes.count() &&
413  // dirNode->m_childNodes.last()->item().name() == (*it).name())
414  // kFatal() << "Already having" << (*it).name() << "in" << directoryUrl
415  // << "url=" << dirNode->m_childNodes.last()->item().url();
416 #endif
417  dirNode->m_childNodes.append(node);
418  const KUrl url = it->url();
419  m_nodeHash.insert(cleanupUrl(url), node);
420  //kDebug(7008) << url;
421 
422  if (!urlsBeingFetched.isEmpty()) {
423  const KUrl dirUrl = url;
424  foreach(const KUrl& urlFetched, urlsBeingFetched) {
425  if (dirUrl.isParentOf(urlFetched)) {
426  kDebug(7008) << "Listing found" << dirUrl << "which is a parent of fetched url" << urlFetched;
427  const QModelIndex parentIndex = indexForNode(node, dirNode->m_childNodes.count()-1);
428  Q_ASSERT(parentIndex.isValid());
429  emitExpandFor.append(parentIndex);
430  if (isDir && dirUrl != urlFetched) {
431  q->fetchMore(parentIndex);
432  m_urlsBeingFetched[node].append(urlFetched);
433  }
434  }
435  }
436  }
437  }
438 
439  m_urlsBeingFetched.remove(dirNode);
440 
441  q->endInsertRows();
442 
443  // Emit expand signal after rowsInserted signal has been emitted,
444  // so that any proxy model will have updated its mapping already
445  Q_FOREACH(const QModelIndex& idx, emitExpandFor) {
446  emit q->expand(idx);
447  }
448 }
449 
450 void KDirModelPrivate::_k_slotDeleteItems(const KFileItemList& items)
451 {
452  //kDebug(7008) << items.count();
453 
454  // I assume all items are from the same directory.
455  // From KDirLister's code, this should be the case, except maybe emitChanges?
456  const KFileItem item = items.first();
457  Q_ASSERT(!item.isNull());
458  KUrl url = item.url();
459  KDirModelNode* node = nodeForUrl(url); // O(depth)
460  if (!node) {
461  kWarning(7008) << "No node found for item that was just removed:" << url;
462  return;
463  }
464 
465  KDirModelDirNode* dirNode = node->parent();
466  if (!dirNode)
467  return;
468 
469  QModelIndex parentIndex = indexForNode(dirNode); // O(n)
470 
471  // Short path for deleting a single item
472  if (items.count() == 1) {
473  const int r = node->rowNumber();
474  q->beginRemoveRows(parentIndex, r, r);
475  removeFromNodeHash(node, url);
476  delete dirNode->m_childNodes.takeAt(r);
477  q->endRemoveRows();
478  return;
479  }
480 
481  // We need to make lists of consecutive row numbers, for the beginRemoveRows call.
482  // Let's use a bit array where each bit represents a given child node.
483  const int childCount = dirNode->m_childNodes.count();
484  QBitArray rowNumbers(childCount, false);
485  Q_FOREACH(const KFileItem& item, items) {
486  if (!node) { // don't lookup the first item twice
487  url = item.url();
488  node = nodeForUrl(url);
489  if (!node) {
490  kWarning(7008) << "No node found for item that was just removed:" << url;
491  continue;
492  }
493  if (!node->parent()) {
494  // The root node has been deleted, but it was not first in the list 'items'.
495  // see https://bugs.kde.org/show_bug.cgi?id=196695
496  return;
497  }
498  }
499  rowNumbers.setBit(node->rowNumber(), 1); // O(n)
500  removeFromNodeHash(node, url);
501  node = 0;
502  }
503 
504  int start = -1;
505  int end = -1;
506  bool lastVal = false;
507  // Start from the end, otherwise all the row numbers are offset while we go
508  for (int i = childCount - 1; i >= 0; --i) {
509  const bool val = rowNumbers.testBit(i);
510  if (!lastVal && val) {
511  end = i;
512  //kDebug(7008) << "end=" << end;
513  }
514  if ((lastVal && !val) || (i == 0 && val)) {
515  start = val ? i : i + 1;
516  //kDebug(7008) << "beginRemoveRows" << start << end;
517  q->beginRemoveRows(parentIndex, start, end);
518  for (int r = end; r >= start; --r) { // reverse because takeAt changes indexes ;)
519  //kDebug(7008) << "Removing from m_childNodes at" << r;
520  delete dirNode->m_childNodes.takeAt(r);
521  }
522  q->endRemoveRows();
523  }
524  lastVal = val;
525  }
526 }
527 
528 void KDirModelPrivate::_k_slotRefreshItems(const QList<QPair<KFileItem, KFileItem> >& items)
529 {
530  QModelIndex topLeft, bottomRight;
531 
532  // Solution 1: we could emit dataChanged for one row (if items.size()==1) or all rows
533  // Solution 2: more fine-grained, actually figure out the beginning and end rows.
534  for ( QList<QPair<KFileItem, KFileItem> >::const_iterator fit = items.begin(), fend = items.end() ; fit != fend ; ++fit ) {
535  Q_ASSERT(!fit->first.isNull());
536  Q_ASSERT(!fit->second.isNull());
537  const KUrl oldUrl = fit->first.url();
538  const KUrl newUrl = fit->second.url();
539  KDirModelNode* node = nodeForUrl(oldUrl); // O(n); maybe we could look up to the parent only once
540  //kDebug(7008) << "in model for" << m_dirLister->url() << ":" << oldUrl << "->" << newUrl << "node=" << node;
541  if (!node) // not found [can happen when renaming a dir, redirection was emitted already]
542  continue;
543  if (node != m_rootNode) { // we never set an item in the rootnode, we use m_dirLister->rootItem instead.
544  bool hasNewNode = false;
545  // A file became directory (well, it was overwritten)
546  if (fit->first.isDir() != fit->second.isDir()) {
547  //kDebug(7008) << "DIR/FILE STATUS CHANGE";
548  const int r = node->rowNumber();
549  removeFromNodeHash(node, oldUrl);
550  KDirModelDirNode* dirNode = node->parent();
551  delete dirNode->m_childNodes.takeAt(r); // i.e. "delete node"
552  node = fit->second.isDir() ? new KDirModelDirNode(dirNode, fit->second)
553  : new KDirModelNode(dirNode, fit->second);
554  dirNode->m_childNodes.insert(r, node); // same position!
555  hasNewNode = true;
556  } else {
557  node->setItem(fit->second);
558  }
559 
560  if (oldUrl != newUrl || hasNewNode) {
561  // What if a renamed dir had children? -> kdirlister takes care of emitting for each item
562  //kDebug(7008) << "Renaming" << oldUrl << "to" << newUrl << "in node hash";
563  m_nodeHash.remove(cleanupUrl(oldUrl));
564  m_nodeHash.insert(cleanupUrl(newUrl), node);
565  }
566  // Mimetype changed -> forget cached icon (e.g. from "cut", #164185 comment #13)
567  if (fit->first.mimeTypePtr()->name() != fit->second.mimeTypePtr()->name()) {
568  node->setPreview(QIcon());
569  }
570 
571  const QModelIndex index = indexForNode(node);
572  if (!topLeft.isValid() || index.row() < topLeft.row()) {
573  topLeft = index;
574  }
575  if (!bottomRight.isValid() || index.row() > bottomRight.row()) {
576  bottomRight = index;
577  }
578  }
579  }
580 #ifndef NDEBUG // debugIndex only defined in debug mode
581  kDebug(7008) << "dataChanged(" << debugIndex(topLeft) << " - " << debugIndex(bottomRight);
582 #endif
583  bottomRight = bottomRight.sibling(bottomRight.row(), q->columnCount(QModelIndex())-1);
584  emit q->dataChanged(topLeft, bottomRight);
585 }
586 
587 // Called when a kioslave redirects (e.g. smb:/Workgroup -> smb://workgroup)
588 // and when renaming a directory.
589 void KDirModelPrivate::_k_slotRedirection(const KUrl& oldUrl, const KUrl& newUrl)
590 {
591  KDirModelNode* node = nodeForUrl(oldUrl);
592  if (!node)
593  return;
594  m_nodeHash.remove(cleanupUrl(oldUrl));
595  m_nodeHash.insert(cleanupUrl(newUrl), node);
596 
597  // Ensure the node's URL is updated. In case of a listjob redirection
598  // we won't get a refreshItem, and in case of renaming a directory
599  // we'll get it too late (so the hash won't find the old url anymore).
600  KFileItem item = node->item();
601  if (!item.isNull()) { // null if root item, #180156
602  item.setUrl(newUrl);
603  node->setItem(item);
604  }
605 
606  // The items inside the renamed directory have been handled before,
607  // KDirLister took care of emitting refreshItem for each of them.
608 }
609 
610 void KDirModelPrivate::_k_slotClear()
611 {
612  const int numRows = m_rootNode->m_childNodes.count();
613  if (numRows > 0) {
614  q->beginRemoveRows( QModelIndex(), 0, numRows - 1 );
615  q->endRemoveRows();
616  }
617 
618  m_nodeHash.clear();
619  //emit layoutAboutToBeChanged();
620  clear();
621  //emit layoutChanged();
622 }
623 
624 void KDirModelPrivate::_k_slotJobUrlsChanged(const QStringList& urlList)
625 {
626  m_allCurrentDestUrls = urlList;
627 }
628 
629 void KDirModel::itemChanged( const QModelIndex& index )
630 {
631  // This method is really a itemMimeTypeChanged(), it's mostly called by KMimeTypeResolver.
632  // When the mimetype is determined, clear the old "preview" (could be
633  // mimetype dependent like when cutting files, #164185)
634  KDirModelNode* node = d->nodeForIndex(index);
635  if (node)
636  node->setPreview(QIcon());
637 
638 #ifndef NDEBUG // debugIndex only defined in debug mode
639  //kDebug(7008) << "dataChanged(" << debugIndex(index);
640 #endif
641  emit dataChanged(index, index);
642 }
643 
644 int KDirModel::columnCount( const QModelIndex & ) const
645 {
646  return ColumnCount;
647 }
648 
649 QVariant KDirModel::data( const QModelIndex & index, int role ) const
650 {
651  if (index.isValid()) {
652  KDirModelNode* node = static_cast<KDirModelNode*>(index.internalPointer());
653  const KFileItem& item( node->item() );
654  switch (role) {
655  case Qt::DisplayRole:
656  switch (index.column()) {
657  case Name:
658  return item.text();
659  case Size:
660  //
661  //return KIO::convertSize(item->size());
662  // Default to "file size in bytes" like in kde3's filedialog
663  return KGlobal::locale()->formatNumber(item.size(), 0);
664  case ModifiedTime: {
665  KDateTime dt = item.time(KFileItem::ModificationTime);
666  return KGlobal::locale()->formatDateTime(dt);
667  }
668  case Permissions:
669  return item.permissionsString();
670  case Owner:
671  return item.user();
672  case Group:
673  return item.group();
674  case Type:
675  return item.mimeComment();
676  }
677  break;
678  case Qt::EditRole:
679  switch (index.column()) {
680  case Name:
681  return item.text();
682  }
683  break;
684  case Qt::DecorationRole:
685  if (index.column() == Name) {
686  if (!node->preview().isNull()) {
687  //kDebug(7008) << item->url() << " preview found";
688  return node->preview();
689  }
690  Q_ASSERT(!item.isNull());
691  //kDebug(7008) << item->url() << " overlays=" << item->overlays();
692  return KIcon(item.iconName(), 0, item.overlays());
693  }
694  break;
695  case Qt::TextAlignmentRole:
696  if (index.column() == Size) {
697  // use a right alignment for L2R and R2L languages
698  const Qt::Alignment alignment = Qt::AlignRight | Qt::AlignVCenter;
699  return int(alignment);
700  }
701  break;
702  case Qt::ToolTipRole:
703  return item.text();
704  case FileItemRole:
705  return QVariant::fromValue(item);
706  case ChildCountRole:
707  if (!item.isDir())
708  return ChildCountUnknown;
709  else {
710  KDirModelDirNode* dirNode = static_cast<KDirModelDirNode *>(node);
711  int count = dirNode->childCount();
712  if (count == ChildCountUnknown && item.isReadable() && !dirNode->isSlow()) {
713  const QString path = item.localPath();
714  if (!path.isEmpty()) {
715 // slow
716 // QDir dir(path);
717 // count = dir.entryList(QDir::AllEntries|QDir::NoDotAndDotDot|QDir::System).count();
718 #ifdef Q_WS_WIN
719  QString s = path + QLatin1String( "\\*.*" );
720  s.replace('/', '\\');
721  count = 0;
722  WIN32_FIND_DATA findData;
723  HANDLE hFile = FindFirstFile( (LPWSTR)s.utf16(), &findData );
724  if( hFile != INVALID_HANDLE_VALUE ) {
725  do {
726  if (!( findData.cFileName[0] == '.' &&
727  findData.cFileName[1] == '\0' ) &&
728  !( findData.cFileName[0] == '.' &&
729  findData.cFileName[1] == '.' &&
730  findData.cFileName[2] == '\0' ) )
731  ++count;
732  } while( FindNextFile( hFile, &findData ) != 0 );
733  FindClose( hFile );
734  }
735 #else
736  DIR* dir = ::opendir(QFile::encodeName(path));
737  if (dir) {
738  count = 0;
739  struct dirent *dirEntry = 0;
740  while ((dirEntry = ::readdir(dir))) {
741  if (dirEntry->d_name[0] == '.') {
742  if (dirEntry->d_name[1] == '\0') // skip "."
743  continue;
744  if (dirEntry->d_name[1] == '.' && dirEntry->d_name[2] == '\0') // skip ".."
745  continue;
746  }
747  ++count;
748  }
749  ::closedir(dir);
750  }
751 #endif
752  //kDebug(7008) << "child count for " << path << ":" << count;
753  dirNode->setChildCount(count);
754  }
755  }
756  return count;
757  }
758  case HasJobRole:
759  if (d->m_jobTransfersVisible && d->m_allCurrentDestUrls.isEmpty() == false) {
760  KDirModelNode* node = d->nodeForIndex(index);
761  const QString url = node->item().url().url();
762  //return whether or not there are job dest urls visible in the view, so the delegate knows which ones to paint.
763  return QVariant(d->m_allCurrentDestUrls.contains(url));
764  }
765  }
766  }
767  return QVariant();
768 }
769 
770 void KDirModel::sort( int column, Qt::SortOrder order )
771 {
772  // Not implemented - we should probably use QSortFilterProxyModel instead.
773  return QAbstractItemModel::sort(column, order);
774 }
775 
776 bool KDirModel::setData( const QModelIndex & index, const QVariant & value, int role )
777 {
778  switch (role) {
779  case Qt::EditRole:
780  if (index.column() == Name && value.type() == QVariant::String) {
781  Q_ASSERT(index.isValid());
782  KDirModelNode* node = static_cast<KDirModelNode*>(index.internalPointer());
783  const KFileItem& item = node->item();
784  const QString newName = value.toString();
785  if (newName.isEmpty() || newName == item.text() || (newName == QLatin1String(".")) || (newName == QLatin1String("..")))
786  return true;
787  KUrl newurl(item.url());
788  newurl.setPath(newurl.directory(KUrl::AppendTrailingSlash) + KIO::encodeFileName(newName));
789  KIO::Job * job = KIO::moveAs(item.url(), newurl, newurl.isLocalFile() ? KIO::HideProgressInfo : KIO::DefaultFlags);
790  job->ui()->setAutoErrorHandlingEnabled(true);
791  // undo handling
792  KIO::FileUndoManager::self()->recordJob( KIO::FileUndoManager::Rename, item.url(), newurl, job );
793  return true;
794  }
795  break;
796  case Qt::DecorationRole:
797  if (index.column() == Name) {
798  Q_ASSERT(index.isValid());
799  // Set new pixmap - e.g. preview
800  KDirModelNode* node = static_cast<KDirModelNode*>(index.internalPointer());
801  //kDebug(7008) << "setting icon for " << node->item()->url();
802  Q_ASSERT(node);
803  if (value.type() == QVariant::Icon) {
804  const QIcon icon(qvariant_cast<QIcon>(value));
805  node->setPreview(icon);
806  } else if (value.type() == QVariant::Pixmap) {
807  node->setPreview(qvariant_cast<QPixmap>(value));
808  }
809  emit dataChanged(index, index);
810  return true;
811  }
812  break;
813  default:
814  break;
815  }
816  return false;
817 }
818 
819 int KDirModel::rowCount( const QModelIndex & parent ) const
820 {
821  KDirModelNode* node = d->nodeForIndex(parent);
822  if (!node || !d->isDir(node)) // #176555
823  return 0;
824 
825  KDirModelDirNode* parentNode = static_cast<KDirModelDirNode *>(node);
826  Q_ASSERT(parentNode);
827  const int count = parentNode->m_childNodes.count();
828 #if 0
829  QStringList filenames;
830  for (int i = 0; i < count; ++i) {
831  filenames << d->urlForNode(parentNode->m_childNodes.at(i)).fileName();
832  }
833  kDebug(7008) << "rowCount for " << d->urlForNode(parentNode) << ": " << count << filenames;
834 #endif
835  return count;
836 }
837 
838 // sibling() calls parent() and isn't virtual! So parent() should be fast...
839 QModelIndex KDirModel::parent( const QModelIndex & index ) const
840 {
841  if (!index.isValid())
842  return QModelIndex();
843  KDirModelNode* childNode = static_cast<KDirModelNode*>(index.internalPointer());
844  Q_ASSERT(childNode);
845  KDirModelNode* parentNode = childNode->parent();
846  Q_ASSERT(parentNode);
847  return d->indexForNode(parentNode); // O(n)
848 }
849 
850 static bool lessThan(const KUrl &left, const KUrl &right)
851 {
852  return left.url().compare(right.url()) < 0;
853 }
854 
855 void KDirModel::requestSequenceIcon(const QModelIndex& index, int sequenceIndex)
856 {
857  emit needSequenceIcon(index, sequenceIndex);
858 }
859 
860 void KDirModel::setJobTransfersVisible(bool value)
861 {
862  if(value) {
863  d->m_jobTransfersVisible = true;
864  connect(&JobUrlCache::instance(), SIGNAL(jobUrlsChanged(QStringList)), this, SLOT(_k_slotJobUrlsChanged(QStringList)), Qt::UniqueConnection);
865 
866  JobUrlCache::instance().requestJobUrlsChanged();
867  } else {
868  disconnect(this, SLOT(_k_slotJobUrlsChanged(QStringList)));
869  }
870 
871 }
872 
873 bool KDirModel::jobTransfersVisible() const
874 {
875  return d->m_jobTransfersVisible;
876 }
877 
878 KUrl::List KDirModel::simplifiedUrlList(const KUrl::List &urls)
879 {
880  if (!urls.count()) {
881  return urls;
882  }
883 
884  KUrl::List ret(urls);
885  qSort(ret.begin(), ret.end(), lessThan);
886 
887  KUrl::List::iterator it = ret.begin();
888  KUrl url = *it;
889  ++it;
890  while (it != ret.end()) {
891  if (url.isParentOf(*it)) {
892  it = ret.erase(it);
893  } else {
894  url = *it;
895  ++it;
896  }
897  }
898 
899  return ret;
900 }
901 
902 QStringList KDirModel::mimeTypes( ) const
903 {
904  return KUrl::List::mimeDataTypes();
905 }
906 
907 QMimeData * KDirModel::mimeData( const QModelIndexList & indexes ) const
908 {
909  KUrl::List urls, mostLocalUrls;
910  bool canUseMostLocalUrls = true;
911  foreach (const QModelIndex &index, indexes) {
912  const KFileItem& item = d->nodeForIndex(index)->item();
913  urls << item.url();
914  bool isLocal;
915  mostLocalUrls << item.mostLocalUrl(isLocal);
916  if (!isLocal)
917  canUseMostLocalUrls = false;
918  }
919  QMimeData *data = new QMimeData();
920  const bool different = canUseMostLocalUrls && (mostLocalUrls != urls);
921  urls = simplifiedUrlList(urls);
922  if (different) {
923  mostLocalUrls = simplifiedUrlList(mostLocalUrls);
924  urls.populateMimeData(mostLocalUrls, data);
925  } else {
926  urls.populateMimeData(data);
927  }
928 
929  // for compatibility reasons (when dropping or pasting into kde3 applications)
930  QString application_x_qiconlist;
931  const int items = urls.count();
932  for (int i = 0; i < items; i++) {
933  const int offset = i*16;
934  QString tmp("%1$@@$%2$@@$32$@@$32$@@$%3$@@$%4$@@$32$@@$16$@@$no data$@@$");
935  application_x_qiconlist += tmp.arg(offset).arg(offset).arg(offset).arg(offset+40);
936  }
937  data->setData("application/x-qiconlist", application_x_qiconlist.toLatin1());
938 
939  return data;
940 }
941 
942 // Public API; not much point in calling it internally
943 KFileItem KDirModel::itemForIndex( const QModelIndex& index ) const
944 {
945  if (!index.isValid()) {
946  return d->m_dirLister->rootItem();
947  } else {
948  return static_cast<KDirModelNode*>(index.internalPointer())->item();
949  }
950 }
951 
952 #ifndef KDE_NO_DEPRECATED
953 QModelIndex KDirModel::indexForItem( const KFileItem* item ) const
954 {
955  // Note that we can only use the URL here, not the pointer.
956  // KFileItems can be copied.
957  return indexForUrl(item->url()); // O(n)
958 }
959 #endif
960 
961 QModelIndex KDirModel::indexForItem( const KFileItem& item ) const
962 {
963  // Note that we can only use the URL here, not the pointer.
964  // KFileItems can be copied.
965  return indexForUrl(item.url()); // O(n)
966 }
967 
968 // url -> index. O(n)
969 QModelIndex KDirModel::indexForUrl(const KUrl& url) const
970 {
971  KDirModelNode* node = d->nodeForUrl(url); // O(depth)
972  if (!node) {
973  kDebug(7007) << url << "not found";
974  return QModelIndex();
975  }
976  return d->indexForNode(node); // O(n)
977 }
978 
979 QModelIndex KDirModel::index( int row, int column, const QModelIndex & parent ) const
980 {
981  KDirModelNode* parentNode = d->nodeForIndex(parent); // O(1)
982  Q_ASSERT(parentNode);
983  Q_ASSERT(d->isDir(parentNode));
984  KDirModelNode* childNode = static_cast<KDirModelDirNode *>(parentNode)->m_childNodes.value(row); // O(1)
985  if (childNode)
986  return createIndex(row, column, childNode);
987  else
988  return QModelIndex();
989 }
990 
991 QVariant KDirModel::headerData( int section, Qt::Orientation orientation, int role ) const
992 {
993  if (orientation == Qt::Horizontal) {
994  switch (role) {
995  case Qt::DisplayRole:
996  switch (section) {
997  case Name:
998  return i18nc("@title:column","Name");
999  case Size:
1000  return i18nc("@title:column","Size");
1001  case ModifiedTime:
1002  return i18nc("@title:column","Date");
1003  case Permissions:
1004  return i18nc("@title:column","Permissions");
1005  case Owner:
1006  return i18nc("@title:column","Owner");
1007  case Group:
1008  return i18nc("@title:column","Group");
1009  case Type:
1010  return i18nc("@title:column","Type");
1011  }
1012  }
1013  }
1014  return QVariant();
1015 }
1016 
1017 bool KDirModel::hasChildren( const QModelIndex & parent ) const
1018 {
1019  if (!parent.isValid())
1020  return true;
1021 
1022  const KFileItem& parentItem = static_cast<KDirModelNode*>(parent.internalPointer())->item();
1023  Q_ASSERT(!parentItem.isNull());
1024  return parentItem.isDir();
1025 }
1026 
1027 Qt::ItemFlags KDirModel::flags( const QModelIndex & index ) const
1028 {
1029  Qt::ItemFlags f = Qt::ItemIsEnabled;
1030  if (index.column() == Name) {
1031  f |= Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled;
1032  }
1033 
1034  // Allow dropping onto this item?
1035  if (d->m_dropsAllowed != NoDrops) {
1036  if(!index.isValid()) {
1037  if (d->m_dropsAllowed & DropOnDirectory) {
1038  f |= Qt::ItemIsDropEnabled;
1039  }
1040  } else {
1041  KFileItem item = itemForIndex(index);
1042  if (item.isNull()) {
1043  kWarning(7007) << "Invalid item returned for index";
1044  } else if (item.isDir()) {
1045  if (d->m_dropsAllowed & DropOnDirectory) {
1046  f |= Qt::ItemIsDropEnabled;
1047  }
1048  } else { // regular file item
1049  if (d->m_dropsAllowed & DropOnAnyFile)
1050  f |= Qt::ItemIsDropEnabled;
1051  else if (d->m_dropsAllowed & DropOnLocalExecutable) {
1052  if (!item.localPath().isEmpty()) {
1053  // Desktop file?
1054  if (item.mimeTypePtr()->is("application/x-desktop"))
1055  f |= Qt::ItemIsDropEnabled;
1056  // Executable, shell script ... ?
1057  else if ( QFileInfo( item.localPath() ).isExecutable() )
1058  f |= Qt::ItemIsDropEnabled;
1059  }
1060  }
1061  }
1062  }
1063  }
1064 
1065  return f;
1066 }
1067 
1068 bool KDirModel::canFetchMore( const QModelIndex & parent ) const
1069 {
1070  if (!parent.isValid())
1071  return false;
1072 
1073  // We now have a bool KDirModelNode::m_populated,
1074  // to avoid calling fetchMore more than once on empty dirs.
1075  // But this wastes memory, and how often does someone open and re-open an empty dir in a treeview?
1076  // Maybe we can ask KDirLister "have you listed <url> already"? (to discuss with M. Brade)
1077 
1078  KDirModelNode* node = static_cast<KDirModelNode*>(parent.internalPointer());
1079  const KFileItem& item = node->item();
1080  return item.isDir() && !static_cast<KDirModelDirNode *>(node)->isPopulated()
1081  && static_cast<KDirModelDirNode *>(node)->m_childNodes.isEmpty();
1082 }
1083 
1084 void KDirModel::fetchMore( const QModelIndex & parent )
1085 {
1086  if (!parent.isValid())
1087  return;
1088 
1089  KDirModelNode* parentNode = static_cast<KDirModelNode*>(parent.internalPointer());
1090 
1091  KFileItem parentItem = parentNode->item();
1092  Q_ASSERT(!parentItem.isNull());
1093  Q_ASSERT(parentItem.isDir());
1094  KDirModelDirNode* dirNode = static_cast<KDirModelDirNode *>(parentNode);
1095  if( dirNode->isPopulated() )
1096  return;
1097  dirNode->setPopulated( true );
1098 
1099  const KUrl parentUrl = parentItem.url();
1100  d->m_dirLister->openUrl(parentUrl, KDirLister::Keep);
1101 }
1102 
1103 bool KDirModel::dropMimeData( const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent )
1104 {
1105  // Not sure we want to implement any drop handling at this level,
1106  // but for sure the default QAbstractItemModel implementation makes no sense for a dir model.
1107  Q_UNUSED(data);
1108  Q_UNUSED(action);
1109  Q_UNUSED(row);
1110  Q_UNUSED(column);
1111  Q_UNUSED(parent);
1112  return false;
1113 }
1114 
1115 void KDirModel::setDropsAllowed(DropsAllowed dropsAllowed)
1116 {
1117  d->m_dropsAllowed = dropsAllowed;
1118 }
1119 
1120 void KDirModel::expandToUrl(const KUrl& url)
1121 {
1122  // emit expand for each parent and return last parent
1123  KDirModelNode* result = d->expandAllParentsUntil(url); // O(depth)
1124  //kDebug(7008) << url << result;
1125 
1126  if (!result) // doesn't seem related to our base url?
1127  return;
1128  if (!(result->item().isNull()) && result->item().url() == url) {
1129  // We have it already, nothing to do
1130  kDebug(7008) << "have it already item=" <<url /*result->item()*/;
1131  return;
1132  }
1133 
1134  d->m_urlsBeingFetched[result].append(url);
1135 
1136  if (result == d->m_rootNode) {
1137  kDebug(7008) << "Remembering to emit expand after listing the root url";
1138  // the root is fetched by default, so it must be currently being fetched
1139  return;
1140  }
1141 
1142  kDebug(7008) << "Remembering to emit expand after listing" << result->item().url();
1143 
1144  // start a new fetch to look for the next level down the URL
1145  const QModelIndex parentIndex = d->indexForNode(result); // O(n)
1146  Q_ASSERT(parentIndex.isValid());
1147  fetchMore(parentIndex);
1148 }
1149 
1150 bool KDirModel::insertRows(int , int, const QModelIndex&)
1151 {
1152  return false;
1153 }
1154 
1155 bool KDirModel::insertColumns(int, int, const QModelIndex&)
1156 {
1157  return false;
1158 }
1159 
1160 bool KDirModel::removeRows(int, int, const QModelIndex&)
1161 {
1162  return false;
1163 }
1164 
1165 bool KDirModel::removeColumns(int, int, const QModelIndex&)
1166 {
1167  return false;
1168 }
1169 
1170 #include "kdirmodel.moc"
kdirlister.h
KDirModel::rowCount
virtual int rowCount(const QModelIndex &parent=QModelIndex()) const
Reimplemented from QAbstractItemModel.
Definition: kdirmodel.cpp:819
QModelIndex
KUrl::adjustPath
void adjustPath(AdjustPathOption trailing)
QString::indexOf
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
KUrl::RemoveTrailingSlash
QList::remove
iterator remove(iterator pos)
KDirModel::Group
Definition: kdirmodel.h:125
KDirModel::ChildCountUnknown
Definition: kdirmodel.h:132
debugIndex
static QString debugIndex(const QModelIndex &index)
Definition: kdirmodel.cpp:310
Type
Type
KFileItem::isDir
bool isDir() const
Returns true if this item represents a directory.
Definition: kfileitem.cpp:1141
kdebug.h
kdatetime.h
KUrl::AddTrailingSlash
KDirModel::~KDirModel
~KDirModel()
Definition: kdirmodel.cpp:333
kurl.h
KFileItem::user
QString user() const
Returns the owner of the file.
Definition: kfileitem.cpp:681
KDirModel::mimeData
virtual QMimeData * mimeData(const QModelIndexList &indexes) const
Reimplemented from QAbstractItemModel.
Definition: kdirmodel.cpp:907
KDirModel::itemChanged
void itemChanged(const QModelIndex &index)
Notify the model that the item at this index has changed.
Definition: kdirmodel.cpp:629
KFileItem::isNull
bool isNull() const
Return true if default-constructed.
Definition: kfileitem.cpp:1714
KDirModel::Permissions
Definition: kdirmodel.h:123
KDirModel::data
virtual QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const
Reimplemented from QAbstractItemModel.
Definition: kdirmodel.cpp:649
KIO::HideProgressInfo
Hide progress information dialog, i.e.
Definition: jobclasses.h:51
KDirModel::FileItemRole
returns the KFileItem for a given index
Definition: kdirmodel.h:137
QMap< KDirModelNode *, KUrl::List >
KDirLister::Keep
Previous directories aren't forgotten (they are still watched by kdirwatch and their items are kept f...
Definition: kdirlister.h:76
KUrl::cleanPath
void cleanPath(const CleanPathOption &options=SimplifyDirSeparators)
isExecutable
bool isExecutable(const QString &file)
KDirModel::setData
virtual bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole)
Reimplemented from QAbstractItemModel.
Definition: kdirmodel.cpp:776
KDirModel::indexForUrl
QModelIndex indexForUrl(const KUrl &url) const
Return the index for a given url.
Definition: kdirmodel.cpp:969
KDirModel::mimeTypes
virtual QStringList mimeTypes() const
Reimplemented from QAbstractItemModel.
Definition: kdirmodel.cpp:902
KUrl::setRef
void setRef(const QString &fragment)
KDirModel::jobTransfersVisible
bool jobTransfersVisible() const
Returns whether or not displaying job transfers has been enabled.
Definition: kdirmodel.cpp:873
JobUrlCache::requestJobUrlsChanged
void requestJobUrlsChanged()
Definition: joburlcache.cpp:62
kError
static QDebug kError(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
f
static quint32 f(DES_KEY *key, quint32 r, char *subkey)
Definition: des.cpp:378
KDirModel::index
virtual QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const
Reimplemented from QAbstractItemModel. O(1)
Definition: kdirmodel.cpp:979
KDirModel::HasJobRole
returns whether or not there is a job on an item (file/directory)
Definition: kdirmodel.h:139
JobUrlCache::instance
static JobUrlCache & instance()
Definition: joburlcache.cpp:34
KFileItem::setUrl
void setUrl(const KUrl &url)
Sets the item's URL.
Definition: kfileitem.cpp:543
QList::erase
iterator erase(iterator pos)
KFileItem::isReadable
bool isReadable() const
Checks whether the file or directory is readable.
Definition: kfileitem.cpp:1069
KDirModel::dirLister
KDirLister * dirLister() const
Return the directory lister used by this model.
Definition: kdirmodel.cpp:358
KDirModel::setJobTransfersVisible
void setJobTransfersVisible(bool value)
Enable/Disable the displaying of an animated overlay that is shown for any destination urls (in the v...
Definition: kdirmodel.cpp:860
kDebug
static QDebug kDebug(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
KUrl::isParentOf
bool isParentOf(const KUrl &u) const
Qt::Alignment
typedef Alignment
klocale.h
QObject::disconnect
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
KDirModel::indexForItem
QModelIndex indexForItem(const KFileItem *) const
Return the index for a given kfileitem.
Definition: kdirmodel.cpp:953
KDirModel::DropOnLocalExecutable
allow drops on local executables, shell scripts and desktop files. Can be used with DropOnDirectory...
Definition: kdirmodel.h:146
QMimeData
QAbstractItemModel::sort
virtual void sort(int column, Qt::SortOrder order)
KUrl
KUrl::setQuery
void setQuery(const QString &query)
KDirModel::ChildCountRole
returns the number of items in a directory, or ChildCountUnknown
Definition: kdirmodel.h:138
i18nc
QString i18nc(const char *ctxt, const char *text)
KDirModel::requestSequenceIcon
void requestSequenceIcon(const QModelIndex &index, int sequenceIndex)
This emits the needSequenceIcon signal, requesting another sequence icon.
Definition: kdirmodel.cpp:855
KDirModel::itemForIndex
KFileItem itemForIndex(const QModelIndex &index) const
Return the fileitem for a given index.
Definition: kdirmodel.cpp:943
KUrl::setPath
void setPath(const QString &path)
KIO::Job::ui
JobUiDelegate * ui() const
Retrieves the UI delegate of this job.
Definition: job.cpp:90
QList::value
T value(int i) const
KIO::DefaultFlags
Show the progress info GUI, no Resume and no Overwrite.
Definition: jobclasses.h:46
KDirModel::DropOnAnyFile
allow drops on any file
Definition: kdirmodel.h:145
KDirModel::fetchMore
virtual void fetchMore(const QModelIndex &parent)
Reimplemented from QAbstractItemModel. Lists the subdirectory.
Definition: kdirmodel.cpp:1084
QModelIndex::isValid
bool isValid() const
KDirModel::dropMimeData
virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
Reimplemented from QAbstractItemModel. Not implemented yet.
Definition: kdirmodel.cpp:1103
kglobal.h
KDirModel::DropOnDirectory
allow drops on any directory
Definition: kdirmodel.h:144
QString::number
QString number(int n, int base)
QList::count
int count(const T &value) const
KDirModel::KDirModel
KDirModel(QObject *parent=0)
Definition: kdirmodel.cpp:326
QList::append
void append(const T &value)
KJobUiDelegate::setAutoErrorHandlingEnabled
void setAutoErrorHandlingEnabled(bool enable)
QString::insert
QString & insert(int position, QChar ch)
QAbstractItemModel::dataChanged
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
KDirModel::NoDrops
Definition: kdirmodel.h:143
QHash< KUrl, KDirModelNode * >
KFileItem::ModificationTime
Definition: kfileitem.h:58
KIO::encodeFileName
QString encodeFileName(const QString &str)
Encodes (from the text displayed to the real filename) This translates '/' into a "unicode fraction s...
Definition: global.cpp:146
QObject
KDirModel::columnCount
virtual int columnCount(const QModelIndex &parent=QModelIndex()) const
Reimplemented from QAbstractItemModel. Returns ColumnCount.
Definition: kdirmodel.cpp:644
KUrl::protocol
QString protocol() const
QList::isEmpty
bool isEmpty() const
QHashIterator
KFileItem::localPath
QString localPath() const
Returns the local path if isLocalFile() == true or the KIO item has a UDS_LOCAL_PATH atom...
Definition: kfileitem.cpp:602
QString::isEmpty
bool isEmpty() const
QModelIndex::row
int row() const
QString::startsWith
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
cleanupUrl
static KUrl cleanupUrl(const KUrl &url)
Definition: kdirmodel.cpp:47
KFileItemList
List of KFileItems, which adds a few helper methods to QList.
Definition: kfileitem.h:674
KIcon
clear
KAction * clear(const QObject *recvr, const char *slot, QObject *parent)
KFileItem::mimeComment
QString mimeComment() const
Returns the user-readable string representing the type of this file, like "OpenDocument Text File"...
Definition: kfileitem.cpp:823
QModelIndex::internalPointer
void * internalPointer() const
copyjob.h
QList::first
T & first()
QString
KFileItem::group
QString group() const
Returns the group of the file.
Definition: kfileitem.cpp:712
QList< KDirModelNode * >
KUrl::path
QString path(AdjustPathOption trailing=LeaveTrailingSlash) const
KFileItem::size
KIO::filesize_t size() const
Returns the size of the file, if known.
Definition: kfileitem.cpp:610
QBitArray
KFileItem::iconName
QString iconName() const
Returns the full path name to the icon that represents this mime type.
Definition: kfileitem.cpp:879
KFileItem::permissionsString
QString permissionsString() const
Returns the access permissions for the file as a string.
Definition: kfileitem.cpp:1403
KDirModel::hasChildren
virtual bool hasChildren(const QModelIndex &parent=QModelIndex()) const
Reimplemented from QAbstractItemModel. Returns true for directories.
Definition: kdirmodel.cpp:1017
KDirModel::sort
virtual void sort(int column, Qt::SortOrder order=Qt::AscendingOrder)
Reimplemented from QAbstractItemModel. Not implemented.
Definition: kdirmodel.cpp:770
QStringList
QPair
QPixmap
QAbstractItemModel::createIndex
QModelIndex createIndex(int row, int column, void *ptr) const
KFileItem::text
QString text() const
Returns the text of the file item.
Definition: kfileitem.cpp:1583
jobuidelegate.h
QFileInfo
KDirModel::Name
Definition: kdirmodel.h:120
QList::end
iterator end()
KDateTime
QVariant::fromValue
QVariant fromValue(const T &value)
KLocale::formatDateTime
QString formatDateTime(const QDateTime &dateTime, DateFormat format=ShortDate, bool includeSecs=false) const
KFileItem::mimeTypePtr
KMimeType::Ptr mimeTypePtr() const
Returns the currently known mimetype of the file item.
Definition: kfileitem.cpp:1649
KDirModel::flags
virtual Qt::ItemFlags flags(const QModelIndex &index) const
Reimplemented from QAbstractItemModel.
Definition: kdirmodel.cpp:1027
KGlobal::locale
KLocale * locale()
KIO::moveAs
CopyJob * moveAs(const KUrl &src, const KUrl &dest, JobFlags flags=DefaultFlags)
Moves a file or directory src to the given destination dest.
Definition: copyjob.cpp:2196
QString::replace
QString & replace(int position, int n, QChar after)
KUrl::List
kdirmodel.h
QString::toLatin1
QByteArray toLatin1() const
QString::utf16
const ushort * utf16() const
KFileItem::time
KDateTime time(FileTimes which) const
Requests the modification, access or creation time, depending on which.
Definition: kfileitem.cpp:655
KRecentDirs::dir
QString dir(const QString &fileClass)
Returns the most recently used directory accociated with this file-class.
Definition: krecentdirs.cpp:68
KDirModel::needSequenceIcon
void needSequenceIcon(const QModelIndex &index, int sequenceIndex)
Emitted when another icon sequence index is requested.
KDirModel::setDirLister
void setDirLister(KDirLister *dirLister)
Set the directory lister to use by this model, instead of the default KDirLister created internally...
Definition: kdirmodel.cpp:338
QLatin1String
QModelIndex::sibling
QModelIndex sibling(int row, int column) const
joburlcache_p.h
fileundomanager.h
KIO::FileUndoManager::Rename
Definition: fileundomanager.h:135
KDirModel::ModifiedTime
Definition: kdirmodel.h:122
KIO::Job
The base class for all jobs.
Definition: jobclasses.h:94
KDirModel::canFetchMore
virtual bool canFetchMore(const QModelIndex &parent) const
Reimplemented from QAbstractItemModel. Returns true for empty directories.
Definition: kdirmodel.cpp:1068
KUrl::AppendTrailingSlash
QModelIndex::column
int column() const
QString::length
int length() const
kWarning
static QDebug kWarning(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
QAbstractItemModel
QString::left
QString left(int n) const
KDirModel::expandToUrl
void expandToUrl(const KUrl &url)
Lists subdirectories using fetchMore() as needed until the given url exists in the model...
Definition: kdirmodel.cpp:1120
KUrl::List::mimeDataTypes
static QStringList mimeDataTypes()
KDirModel::setDropsAllowed
void setDropsAllowed(DropsAllowed dropsAllowed)
Set whether dropping onto items should be allowed, and for which kind of item Drops are disabled by d...
Definition: kdirmodel.cpp:1115
KDirModel::simplifiedUrlList
static KUrl::List simplifiedUrlList(const KUrl::List &urls)
Remove urls from the list if an ancestor is present on the list.
Definition: kdirmodel.cpp:878
KUrl::url
QString url(AdjustPathOption trailing=LeaveTrailingSlash) const
QMimeData::setData
void setData(const QString &mimeType, const QByteArray &data)
KDirLister
Helper class for the kiojob used to list and update a directory.
Definition: kdirlister.h:57
KLocale::formatNumber
QString formatNumber(double num, int precision=-1) const
KIO::FileUndoManager::self
static FileUndoManager * self()
Definition: fileundomanager.cpp:208
QVariant::type
Type type() const
kicon.h
lessThan
static bool lessThan(const KUrl &left, const KUrl &right)
Definition: kdirmodel.cpp:850
KDirModel::headerData
virtual QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const
Reimplemented from QAbstractItemModel. Returns the column titles.
Definition: kdirmodel.cpp:991
KUrl::isLocalFile
bool isLocalFile() const
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject::parent
QObject * parent() const
QString::compare
int compare(const QString &other) const
end
const KShortcut & end()
QString::arg
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
QVariant::toString
QString toString() const
KDirModel::Size
Definition: kdirmodel.h:121
KDirModel::ColumnCount
Definition: kdirmodel.h:127
KDirModel
A model for a KIO-based directory tree.
Definition: kdirmodel.h:48
QList::begin
iterator begin()
kfileitem.h
KFileItem::overlays
QStringList overlays() const
Returns the overlays (bitfield of KIconLoader::*Overlay flags) that are used for this item's pixmap...
Definition: kfileitem.cpp:952
KFileItem::url
KUrl url() const
Returns the url of the file.
Definition: kfileitem.cpp:1543
KDirModel::Owner
Definition: kdirmodel.h:124
QFile::encodeName
QByteArray encodeName(const QString &fileName)
KFileItem::mostLocalUrl
KUrl mostLocalUrl(bool &local) const
Tries to give a local URL for this file item if possible.
Definition: kfileitem.cpp:1470
KFileItem
A KFileItem is a generic class to handle a file, local or remote.
Definition: kfileitem.h:45
QIcon
KIO::FileUndoManager::recordJob
void recordJob(CommandType op, const KUrl::List &src, const KUrl &dst, KIO::Job *job)
Record this job while it's happening and add a command for it so that the user can undo it...
Definition: fileundomanager.cpp:247
QVariant
Qt::ItemFlags
typedef ItemFlags
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:24:53 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KIO

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

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • 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

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal