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

kdevplatform/project

  • sources
  • kfour-appscomplete
  • kdevelop
  • kdevplatform
  • project
filemanagerlistjob.cpp
Go to the documentation of this file.
1 /* This file is part of KDevelop
2  Copyright 2009 Radu Benea <[email protected]>
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 "filemanagerlistjob.h"
21 
22 #include <interfaces/iproject.h>
23 #include <project/projectmodel.h>
24 
25 #include "path.h"
26 #include "debug.h"
27 // Qt
28 #include <QtConcurrentRun>
29 #include <QDir>
30 
31 using namespace KDevelop;
32 
33 namespace {
34 bool isChildItem(ProjectBaseItem* parent, ProjectBaseItem* child)
35 {
36  do {
37  if (child == parent) {
38  return true;
39  }
40  child = child->parent();
41  } while(child);
42  return false;
43 }
44 }
45 
46 class SemaReleaser
47 {
48 public:
49  SemaReleaser(QSemaphore* sem)
50  : m_sem(sem)
51  {}
52 
53  ~SemaReleaser()
54  {
55  m_sem->release();
56  }
57 
58 private:
59  QSemaphore* m_sem;
60 };
61 
62 FileManagerListJob::FileManagerListJob(ProjectFolderItem* item)
63  : KIO::Job(), m_item(item), m_aborted(false), m_listing(1)
64 {
65  qRegisterMetaType<KIO::UDSEntryList>("KIO::UDSEntryList");
66  qRegisterMetaType<KIO::Job*>();
67  qRegisterMetaType<KJob*>();
68 
69  /* the following line is not an error in judgment, apparently starting a
70  * listJob while the previous one hasn't self-destructed takes a lot of time,
71  * so we give the job a chance to selfdestruct first */
72  connect( this, &FileManagerListJob::nextJob, this, &FileManagerListJob::startNextJob, Qt::QueuedConnection );
73 
74  addSubDir(item);
75 
76 #ifdef TIME_IMPORT_JOB
77  m_timer.start();
78 #endif
79 }
80 
81 FileManagerListJob::~FileManagerListJob()
82 {
83  // abort and lock to ensure our background list job is stopped
84  m_aborted = true;
85  m_listing.acquire();
86  Q_ASSERT(m_listing.available() == 0);
87 }
88 
89 void FileManagerListJob::addSubDir( ProjectFolderItem* item )
90 {
91  Q_ASSERT(!m_listQueue.contains(item));
92  Q_ASSERT(!m_item || m_item == item || m_item->path().isDirectParentOf(item->path()));
93 
94  m_listQueue.enqueue(item);
95 }
96 
97 void FileManagerListJob::handleRemovedItem(ProjectBaseItem* item)
98 {
99  // NOTE: the item could be (partially) destroyed already, thus it's not save
100  // to call e.g. item->folder to cast the base item to a folder item...
101  auto *folder = reinterpret_cast<ProjectFolderItem*>(item);
102  m_listQueue.removeAll(folder);
103 
104  if (isChildItem(item, m_item)) {
105  abort();
106  }
107 }
108 
109 void FileManagerListJob::slotEntries(KIO::Job* job, const KIO::UDSEntryList& entriesIn)
110 {
111  Q_UNUSED(job);
112  entryList.append(entriesIn);
113 }
114 
115 void FileManagerListJob::startNextJob()
116 {
117  if ( m_listQueue.isEmpty() || m_aborted ) {
118  return;
119  }
120 
121 #ifdef TIME_IMPORT_JOB
122  m_subTimer.start();
123 #endif
124 
125  m_item = m_listQueue.dequeue();
126  if (m_item->path().isLocalFile()) {
127  // optimized version for local projects using QDir directly
128  // start locking to ensure we don't get destroyed while waiting for the list to finish
129  m_listing.acquire();
130  QtConcurrent::run([this] (const Path& path) {
131  SemaReleaser lock(&m_listing);
132  if (m_aborted) {
133  return;
134  }
135  QDir dir(path.toLocalFile());
136  const auto entries = dir.entryInfoList(QDir::NoDotAndDotDot | QDir::AllEntries | QDir::Hidden);
137  if (m_aborted) {
138  return;
139  }
140  KIO::UDSEntryList results;
141  std::transform(entries.begin(), entries.end(), std::back_inserter(results), [] (const QFileInfo& info) -> KIO::UDSEntry {
142  KIO::UDSEntry entry;
143  entry.fastInsert(KIO::UDSEntry::UDS_NAME, info.fileName());
144  if (info.isDir()) {
145  entry.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, QT_STAT_DIR);
146  }
147  if (info.isSymLink()) {
148  entry.fastInsert(KIO::UDSEntry::UDS_LINK_DEST, info.symLinkTarget());
149  }
150  return entry;
151  });
152  QMetaObject::invokeMethod(this, "handleResults", Q_ARG(KIO::UDSEntryList, results));
153  }, m_item->path());
154  } else {
155  KIO::ListJob* job = KIO::listDir( m_item->path().toUrl(), KIO::HideProgressInfo );
156  job->addMetaData(QStringLiteral("details"), QStringLiteral("0"));
157  job->setParentJob( this );
158  connect( job, &KIO::ListJob::entries,
159  this, &FileManagerListJob::slotEntries );
160  connect( job, &KIO::ListJob::result, this, &FileManagerListJob::slotResult );
161  }
162 }
163 
164 void FileManagerListJob::slotResult(KJob* job)
165 {
166  if (m_aborted) {
167  return;
168  }
169 
170  if( job && job->error() ) {
171  qCDebug(FILEMANAGER) << "error in list job:" << job->error() << job->errorString();
172  }
173 
174  handleResults(entryList);
175  entryList.clear();
176 }
177 
178 
179 void FileManagerListJob::handleResults(const KIO::UDSEntryList& entriesIn)
180 {
181  if (m_aborted) {
182  return;
183  }
184 
185 #ifdef TIME_IMPORT_JOB
186  {
187  auto waited = m_subTimer.elapsed();
188  m_subWaited += waited;
189  qCDebug(PROJECT) << "TIME FOR SUB JOB:" << waited << m_subWaited;
190  }
191 #endif
192 
193  emit entries(this, m_item, entriesIn);
194 
195  if( m_listQueue.isEmpty() ) {
196  emitResult();
197 
198 #ifdef TIME_IMPORT_JOB
199  qCDebug(PROJECT) << "TIME FOR LISTJOB:" << m_timer.elapsed();
200 #endif
201  } else {
202  emit nextJob();
203  }
204 }
205 
206 void FileManagerListJob::abort()
207 {
208  m_aborted = true;
209 
210  bool killed = kill();
211  Q_ASSERT(killed);
212  Q_UNUSED(killed);
213 }
214 
215 void FileManagerListJob::start()
216 {
217  startNextJob();
218 }
KDevelop::ProjectFolderItem
Implementation of the ProjectBaseItem interface that is specific to a folder.
Definition: projectmodel.h:268
KDevelop::ProjectBaseItem::parent
virtual ProjectBaseItem * parent() const
Definition: projectmodel.cpp:309
QSemaphore::available
int available() const
KDevelop::FileManagerListJob::addSubDir
void addSubDir(ProjectFolderItem *item)
Definition: filemanagerlistjob.cpp:89
KDevelop::ProjectBaseItem
Interface that allows a developer to implement the three basic types of items you would see in a mult...
Definition: projectmodel.h:101
QDir
KDevelop::FileManagerListJob::start
void start() override
Definition: filemanagerlistjob.cpp:215
filemanagerlistjob.h
KDevelop::FileManagerListJob::entries
void entries(FileManagerListJob *job, ProjectFolderItem *baseItem, const KIO::UDSEntryList &entries)
KDevelop::FileManagerListJob::nextJob
void nextJob()
projectmodel.h
KJob
QSemaphore::acquire
void acquire(int n)
QtConcurrent::run
QFuture< T > run(Function function,...)
KDevelop::FileManagerListJob::handleRemovedItem
void handleRemovedItem(ProjectBaseItem *item)
Definition: filemanagerlistjob.cpp:97
KDevelop::FileManagerListJob::abort
void abort()
Definition: filemanagerlistjob.cpp:206
QFileInfo
QMetaObject::invokeMethod
bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType type, QGenericReturnArgument ret, QGenericArgument val0, QGenericArgument val1, QGenericArgument val2, QGenericArgument val3, QGenericArgument val4, QGenericArgument val5, QGenericArgument val6, QGenericArgument val7, QGenericArgument val8, QGenericArgument val9)
KDevelop
Definition: abstractfilemanagerplugin.h:33
KDevelop::FileManagerListJob::FileManagerListJob
FileManagerListJob(ProjectFolderItem *item)
Definition: filemanagerlistjob.cpp:62
QSemaphore
KDevelop::ProjectBaseItem::path
Path path() const
Definition: projectmodel.cpp:449
debug.h
KDevelop::FileManagerListJob::~FileManagerListJob
virtual ~FileManagerListJob()
Definition: filemanagerlistjob.cpp:81
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Mon Mar 8 2021 23:30:20 by doxygen 1.8.16 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kdevplatform/project

Skip menu "kdevplatform/project"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdevelop API Reference

Skip menu "kdevelop API Reference"
  • kdevplatform
  •   debugger
  •   documentation
  •   interfaces
  •   language
  •     assistant
  •     backgroundparser
  •     checks
  •     classmodel
  •     codecompletion
  •     codegen
  •     duchain
  •     editor
  •     highlighting
  •     interfaces
  •     util
  •   outputview
  •   project
  •   serialization
  •   shell
  •   sublime
  •   tests
  •   util
  •   vcs

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