QXRD  0.11.16
qxrdfilebrowsermodelupdater.cpp
Go to the documentation of this file.
1 #include "qxrddebug.h"
3 #include "qxrdapplication.h"
4 #include <QThread>
5 #include <QDirIterator>
6 #include "qxrdfilebrowsermodel.h"
9 
11  QcepObject("fileBrowserModelUpdater", parent),
12  m_BrowserModel(browser),
13  m_RootPath(""),
14  m_FileSystemWatcher(NULL),
15  m_UpdateNeeded(1),
16  m_UpdateTimer(),
17  m_UpdateInterval(1000),
18  m_PreviousUpdate(QDateTime::currentDateTime()),
19  m_GenerateUpdates(true)
20 {
22  g_Application->printMessage("Starting Browser Model Updater");
23  }
24 
25  m_FileSystemWatcher = new QFileSystemWatcher(this);
26 
28 
29  if (model) {
30  connect(model.data(), &QxrdFileBrowserModel::rootChanged,
32  }
33 
34  connect(m_FileSystemWatcher, &QFileSystemWatcher::directoryChanged,
35  this, &QxrdFileBrowserModelUpdater::changeContents, Qt::DirectConnection);
36  connect(&m_UpdateTimer, &QTimer::timeout,
38 
39  m_UpdateTimer.setSingleShot(true);
41 }
42 
44 {
45 #ifndef QT_NO_DEBUG
46  printf("Deleting file browser model updater\n");
47 #endif
48 
50  printf("QxrdFileBrowserModelUpdater::~QxrdFileBrowserModelUpdater(%p)\n", this);
51  }
52 
53  if (qcepDebug(DEBUG_APP)) {
54  printMessage("QxrdFileBrowserModelUpdater::~QxrdFileBrowserModelUpdater");
55  }
56 }
57 
58 void QxrdFileBrowserModelUpdater::changeRoot(const QString& path)
59 {
61  g_Application->printMessage(tr("QxrdFileBrowserModelUpdater::changeRoot %1").arg(path));
62  }
63 
64  QStringList dirs = m_FileSystemWatcher->directories();
65 
66  if (dirs.count() >= 1) {
67  m_FileSystemWatcher->removePaths(dirs);
68  }
69 
70  if (path != "") {
71  m_FileSystemWatcher->addPath(path);
72  m_RootPath = path;
73  }
74 }
75 
77 {
78  m_UpdateNeeded.fetchAndStoreOrdered(1);
79 }
80 
82 {
84  g_Application->printMessage(tr("QxrdFileBrowserModelUpdater::changeContents %1").arg(path));
85  }
86 
87  m_UpdateNeeded.fetchAndStoreOrdered(1);
88 }
89 
91 {
92  if (m_UpdateNeeded.fetchAndStoreOrdered(0)) {
94  g_Application->printMessage(tr("QxrdFileBrowserModelUpdater::updateTimeout update needed %1").arg(m_RootPath));
95  }
96 
98  }
99 
101 }
102 
104 {
105  return m_UpdateNeeded.fetchAndAddOrdered(0);
106 }
107 
108 static void checkSortInterrupt()
109 {
110  QThread *curr = QThread::currentThread();
111 
113  qobject_cast<QxrdFileBrowserModelUpdaterThread*>(curr);
114 
115  if (upthrd) {
117  = upthrd->updater();
118 
119  if (updater && updater->updateNeeded()) {
120  throw 0;
121  }
122  }
123 }
124 
125 static bool fileNameLessThan(QFileInfo f1, QFileInfo f2)
126 {
128 
129  return f1.fileName().toLower() < f2.fileName().toLower();
130 }
131 
132 static bool fileNameGreaterThan(QFileInfo f1, QFileInfo f2)
133 {
135 
136  return f1.fileName().toLower() > f2.fileName().toLower();
137 }
138 
139 static bool fileSizeLessThan(QFileInfo f1, QFileInfo f2)
140 {
142 
143  return f1.size() < f2.size();
144 }
145 
146 static bool fileSizeGreaterThan(QFileInfo f1, QFileInfo f2)
147 {
149 
150  return f1.size() > f2.size();
151 }
152 
153 static bool fileDateLessThan(QFileInfo f1, QFileInfo f2)
154 {
156 
157  return f1.lastModified() < f2.lastModified();
158 }
159 
160 static bool fileDateGreaterThan(QFileInfo f1, QFileInfo f2)
161 {
163 
164  return f1.lastModified() > f2.lastModified();
165 }
166 
168 {
169  QTime tic;
170  tic.start();
171 
172  m_UpdateNeeded.fetchAndStoreOrdered(0);
173 
175 
176  if (model) {
177  QDirIterator iterd(m_RootPath);
178  QDirIterator iter(m_RootPath, model->nameFilters());
179  QVector<QFileInfo> dirs;
180  QVector<QFileInfo> files;
181 
182  while (iterd.hasNext()) {
183  if (m_UpdateNeeded.fetchAndAddOrdered(0)) {
185  g_Application->printMessage("Directory list generation abandoned");
186  }
187 
188  return;
189  }
190 
191  QString filePath = iterd.next();
192  QFileInfo fileInfo(m_RootPath, filePath);
193 
194  if (fileInfo.isDir()) {
195  QString dirName = fileInfo.fileName();
196 
197  if ((dirName != ".") && (dirName != "..")) {
198  dirs.append(fileInfo);
199  }
200  }
201  }
202 
203  while (iter.hasNext()) {
204  if (m_UpdateNeeded.fetchAndAddOrdered(0)) {
206  g_Application->printMessage("File list generation abandoned");
207  }
208 
209  return;
210  }
211 
212  QString filePath = iter.next();
213  QFileInfo fileInfo(m_RootPath, filePath);
214 
215  if (fileInfo.isDir()) {
216  } else {
217  files.append(fileInfo);
218  }
219  }
220 
221  m_Directories = dirs;
222  m_Files = files;
223 
225  g_Application->printMessage(tr("Update file browser took %1 msec").arg(tic.restart()));
226  g_Application->printMessage(tr("File Path %1: %2 dirs, %3 files")
227  .arg(m_RootPath).arg(m_Directories.count()).arg(m_Files.count()));
228  }
229 
230  if (m_GenerateUpdates.fetchAndAddOrdered(0)) {
231  QDateTime latest = m_PreviousUpdate;
232 
233  foreach(QFileInfo file, files) {
234  QDateTime mod = file.lastModified();
235  if (mod > m_PreviousUpdate) {
236  model->updatedFile(file);
237  }
238 
239  if (mod > latest) {
240  latest = mod;
241  }
242  }
243 
244  m_PreviousUpdate = latest;
245  }
246 
247  int column = model->sortedColumn();
248  Qt::SortOrder order = model->sortOrder();
249 
250  try {
251  qStableSort(m_Directories.begin(), m_Directories.end(),
253 
254  switch(column) {
255  case 0:
256  if (order == Qt::AscendingOrder) {
257  qStableSort(m_Files.begin(), m_Files.end(),
259  } else {
260  qStableSort(m_Files.begin(), m_Files.end(),
262  }
263  break;
264 
265  case 1:
266  if (order == Qt::AscendingOrder) {
267  qStableSort(m_Files.begin(), m_Files.end(),
269  } else {
270  qStableSort(m_Files.begin(), m_Files.end(),
272  }
273  break;
274 
275  case 2:
276  if (order == Qt::AscendingOrder) {
277  qStableSort(m_Files.begin(), m_Files.end(),
279  } else {
280  qStableSort(m_Files.begin(), m_Files.end(),
282  }
283  break;
284  }
285  }
286 
287  catch (...) {
289  g_Application->printMessage("Sorting abandoned");
290  }
291 
292  return;
293  }
294 
296  g_Application->printMessage(tr("Sort file browser took %1 msec").arg(tic.elapsed()));
297  }
298 
299  int limit = 10000;
300 
301  QxrdApplication *app = qobject_cast<QxrdApplication*>(g_Application);
302 
303  if (app) {
304  limit = app->get_FileBrowserLimit();
305  }
306 
307  int trueSize = m_Files.count();
308 
309  if (limit && limit < trueSize) {
310  model->newDataAvailable(m_Directories, m_Files.mid(0,limit), limit, trueSize);
311  } else {
312  model->newDataAvailable(m_Directories, m_Files);
313  }
314  }
315 }
316 
318 {
319  if (doIt) {
320  m_PreviousUpdate = QDateTime::currentDateTime();
321  }
322 
323  m_GenerateUpdates = doIt;
324 }
static bool fileDateLessThan(QFileInfo f1, QFileInfo f2)
qint64 qcepDebug(int cond)
Definition: qcepdebug.cpp:26
void changeContents(const QString &path)
static bool fileSizeLessThan(QFileInfo f1, QFileInfo f2)
QxrdFileBrowserModelUpdaterPtr updater() const
static bool fileNameGreaterThan(QFileInfo f1, QFileInfo f2)
QxrdFileBrowserModelUpdater(QxrdFileBrowserModelWPtr browser, QcepObject *parent)
static bool fileSizeGreaterThan(QFileInfo f1, QFileInfo f2)
QSharedPointer< QxrdFileBrowserModelUpdater > QxrdFileBrowserModelUpdaterPtr
QxrdFileBrowserModelWPtr m_BrowserModel
static bool fileNameLessThan(QFileInfo f1, QFileInfo f2)
static double mod(double a, double b)
static void checkSortInterrupt()
virtual void printMessage(QString msg, QDateTime dt=QDateTime::currentDateTime()) const
Definition: qcepobject.cpp:84
QWeakPointer< QxrdFileBrowserModel > QxrdFileBrowserModelWPtr
void rootChanged(const QString &path)
virtual void printMessage(QString msg, QDateTime ts=QDateTime::currentDateTime())=0
QcepApplication * g_Application
QSharedPointer< QxrdFileBrowserModel > QxrdFileBrowserModelPtr
static bool fileDateGreaterThan(QFileInfo f1, QFileInfo f2)