~carlos-mazieri/ubuntu-filemanager-app/model

1 by carlos.mazieri at gmail
intial version of folderlistmodel, nemo-folderlistmodel is the orignal for comparing purposes, test_folderlistmodel contains tests.
1
/*
2
 * Copyright (C) 2012 Robin Burchell <robin+nemo@viroteck.net>
3
 *
4
 * You may use this file under the terms of the BSD license as follows:
5
 *
6
 * "Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions are
8
 * met:
9
 *   * Redistributions of source code must retain the above copyright
10
 *     notice, this list of conditions and the following disclaimer.
11
 *   * Redistributions in binary form must reproduce the above copyright
12
 *     notice, this list of conditions and the following disclaimer in
13
 *     the documentation and/or other materials provided with the
14
 *     distribution.
15
 *   * Neither the name of Nemo Mobile nor the names of its contributors
16
 *     may be used to endorse or promote products derived from this
17
 *     software without specific prior written permission.
18
 *
19
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
30
 */
31
32
#include "iorequest.h"
63 by carlos-mazieri
Redesign:
33
#include "qtrashutilinfo.h"
34
#include "diriteminfo.h"
35
#include "trashiteminfo.h"
1 by carlos.mazieri at gmail
intial version of folderlistmodel, nemo-folderlistmodel is the orignal for comparing purposes, test_folderlistmodel contains tests.
36
26 by carlos.mazieri at gmail
Fixed Bug 1195531: openPath() doesn't work for non-child directories
37
#include <QDirIterator>
38
#include <QDebug>
39
19.7.1 by carlos.mazieri at gmail
It works around bug #1243854.
40
#ifdef DEBUG_MESSAGES
55 by carlos-mazieri
added rename(oldName, newName)
41
#include <QDateTime>
19.7.1 by carlos.mazieri at gmail
It works around bug #1243854.
42
#include <QThread>
43
#endif
28 by carlos.mazieri at gmail
adding a "external file system watcher" which is a "auto refresh feature", it fixes: Bug #1190676 and Bug #1191282
44
26 by carlos.mazieri at gmail
Fixed Bug 1195531: openPath() doesn't work for non-child directories
45
IORequest::IORequest() : QObject(), m_type(DirList)
46
{
47
}
48
49
IORequest::RequestType IORequest::type() const
50
{
51
    return m_type;
52
}
53
63 by carlos-mazieri
Redesign:
54
//----------------------------------------------------------------------------------
55
IORequestLoader::IORequestLoader(const QString &pathName,
56
                                 QDir::Filter filter,
57
                                 bool isRecursive)
58
      : IORequest()
59
      , mLoaderType(NormalLoader)
60
      , mPathName(pathName)
61
      , mFilter(filter)
62
      , mIsRecursive(isRecursive)
63
{
64
}
65
66
IORequestLoader::IORequestLoader(const QString& trashRootDir,
67
                                 const QString &pathName,
68
                                 QDir::Filter filter,
69
                                 bool isRecursive)
70
      : IORequest()
71
      , mLoaderType(TrashLoader)
72
      , mPathName(pathName)
73
      , mFilter(filter)
74
      , mIsRecursive(isRecursive)
75
      , mTtrashRootDir(trashRootDir)
76
{
77
78
}
79
80
DirItemInfoList  IORequestLoader::getContents()
81
{
82
   return mLoaderType == NormalLoader ?
83
                getNormalContent() :
84
                getTrashContent();
85
}
86
87
DirItemInfoList  IORequestLoader::getNormalContent()
26 by carlos.mazieri at gmail
Fixed Bug 1195531: openPath() doesn't work for non-child directories
88
{
28 by carlos.mazieri at gmail
adding a "external file system watcher" which is a "auto refresh feature", it fixes: Bug #1190676 and Bug #1191282
89
#if DEBUG_EXT_FS_WATCHER
90
    qDebug() << "[exfsWatcher]" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz")
43 by carlos.mazieri at gmail
External file system watcher now is the class ExternalFSWatcher which inherits QFileSystemWatcher.
91
             << Q_FUNC_INFO;
28 by carlos.mazieri at gmail
adding a "external file system watcher" which is a "auto refresh feature", it fixes: Bug #1190676 and Bug #1191282
92
#endif
55 by carlos-mazieri
added rename(oldName, newName)
93
    DirItemInfoList directoryContents;
26 by carlos.mazieri at gmail
Fixed Bug 1195531: openPath() doesn't work for non-child directories
94
    directoryContents = add(mPathName, mFilter, mIsRecursive, directoryContents);
95
    return directoryContents;
96
}
97
63 by carlos-mazieri
Redesign:
98
DirItemInfoList IORequestLoader::add(const QString &pathName,
26 by carlos.mazieri at gmail
Fixed Bug 1195531: openPath() doesn't work for non-child directories
99
                                      QDir::Filter filter,
63 by carlos-mazieri
Redesign:
100
                                      bool isRecursive,
55 by carlos-mazieri
added rename(oldName, newName)
101
                                      DirItemInfoList directoryContents)
26 by carlos.mazieri at gmail
Fixed Bug 1195531: openPath() doesn't work for non-child directories
102
{
103
    QDir tmpDir = QDir(pathName, QString(), QDir::NoSort, filter);
104
    QDirIterator it(tmpDir);
105
    while (it.hasNext()) {
106
        it.next();
107
108
        if(it.fileInfo().isDir() && isRecursive) {
55 by carlos-mazieri
added rename(oldName, newName)
109
            directoryContents = add(it.fileInfo().filePath(),
110
                                    filter, isRecursive, directoryContents);
26 by carlos.mazieri at gmail
Fixed Bug 1195531: openPath() doesn't work for non-child directories
111
        } else {
55 by carlos-mazieri
added rename(oldName, newName)
112
            directoryContents.append(DirItemInfo(it.fileInfo()));
26 by carlos.mazieri at gmail
Fixed Bug 1195531: openPath() doesn't work for non-child directories
113
        }
114
115
        if (directoryContents.count() >= 50) {
116
            emit itemsAdded(directoryContents);
117
118
            // clear() would force a deallocation, micro-optimization
119
            directoryContents.erase(directoryContents.begin(), directoryContents.end());
120
        }
121
    }
122
    return directoryContents;
123
}
124
63 by carlos-mazieri
Redesign:
125
DirItemInfoList  IORequestLoader::getTrashContent()
126
{
127
   DirItemInfoList directoryContents;
128
   QTrashUtilInfo trashInfo;
129
   QDir tmpDir = QDir(mPathName, QString(), QDir::NoSort, mFilter);
130
   bool isTopLevel = QFileInfo(mPathName).absolutePath() == mTtrashRootDir;
131
   QDirIterator it(tmpDir);
132
   while (it.hasNext())
133
   {
134
       it.next();
135
       trashInfo.setInfo(mTtrashRootDir, it.fileInfo().absoluteFilePath());
136
       if (!isTopLevel || (isTopLevel && trashInfo.existsInfoFile() && trashInfo.existsFile()) )
137
       {
138
          //TODO read the trashinfo file and set it into  a display field
139
          //     the display field can be a string the usally points to absoluteFilePath()
140
          //     it would be used only in the DirModel::data()
141
           TrashItemInfo item(QTrashUtilInfo::filesTrashDir(mTtrashRootDir),
142
                              it.fileInfo().absoluteFilePath());
143
           directoryContents.append(item);
144
       }
145
   }
146
   return directoryContents;
147
}
148
149
150
//-----------------------------------------------------------------------------------------------
151
DirListWorker::DirListWorker(const QString &pathName, QDir::Filter filter, const bool isRecursive)
152
    : IORequestLoader(pathName, filter, isRecursive)
153
{
154
155
}
156
157
158
DirListWorker::DirListWorker(const QString& trashRootDir, const QString &pathName, QDir::Filter filter, const bool isRecursive)
159
    : IORequestLoader(trashRootDir, pathName, filter, isRecursive)
160
{
161
162
}
163
164
165
void DirListWorker::run()
166
{
167
#if DEBUG_MESSAGES
168
    qDebug() << Q_FUNC_INFO << "Running on: " << QThread::currentThreadId();
169
#endif
170
171
    DirItemInfoList directoryContents = getContents();
172
173
    // last batch
174
    emit itemsAdded(directoryContents);
175
    emit workerFinished();
176
}
177
178
179
180
181
//-------------------------------------------------------------------------------------
182
TrashListWorker::TrashListWorker(const QString& trashRoot, const QString &path, QDir::Filter filter)
183
  : DirListWorker(trashRoot, path, filter, false)
184
{
185
    mLoaderType = TrashLoader;
186
}
187
26 by carlos.mazieri at gmail
Fixed Bug 1195531: openPath() doesn't work for non-child directories
188
189
//---------------------------------------------------------------------------------------------------------
55 by carlos-mazieri
added rename(oldName, newName)
190
ExternalFileSystemChangesWorker::ExternalFileSystemChangesWorker(const DirItemInfoList &content,
26 by carlos.mazieri at gmail
Fixed Bug 1195531: openPath() doesn't work for non-child directories
191
                                                   const QString &pathName,
192
                                                   QDir::Filter filter,
193
                                                   const bool isRecursive)
63 by carlos-mazieri
Redesign:
194
    : IORequestLoader(pathName, filter, isRecursive)
26 by carlos.mazieri at gmail
Fixed Bug 1195531: openPath() doesn't work for non-child directories
195
196
{
197
    m_type        = DirListExternalFSChanges;
27 by carlos.mazieri at gmail
auto refresh feature almost done
198
    int counter = content.count();
199
    while (counter--)
200
    {
201
        m_curContent.insert( content.at(counter).absoluteFilePath(), content.at(counter) );
202
    }
26 by carlos.mazieri at gmail
Fixed Bug 1195531: openPath() doesn't work for non-child directories
203
}
204
205
63 by carlos-mazieri
Redesign:
206
int ExternalFileSystemChangesWorker::compareItems(const DirItemInfoList& contentNew)
26 by carlos.mazieri at gmail
Fixed Bug 1195531: openPath() doesn't work for non-child directories
207
{
43 by carlos.mazieri at gmail
External file system watcher now is the class ExternalFSWatcher which inherits QFileSystemWatcher.
208
    int   addedCounter=0;
209
    int   removedCounter=0;
28 by carlos.mazieri at gmail
adding a "external file system watcher" which is a "auto refresh feature", it fixes: Bug #1190676 and Bug #1191282
210
#if DEBUG_EXT_FS_WATCHER
211
        qDebug() << "[exfsWatcher]" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz")
43 by carlos.mazieri at gmail
External file system watcher now is the class ExternalFSWatcher which inherits QFileSystemWatcher.
212
                 << Q_FUNC_INFO
213
                 << "m_curContent.count():"      << m_curContent.count()
63 by carlos-mazieri
Redesign:
214
                 << "contentNew.count():" << contentNew.count();
28 by carlos.mazieri at gmail
adding a "external file system watcher" which is a "auto refresh feature", it fixes: Bug #1190676 and Bug #1191282
215
#endif
63 by carlos-mazieri
Redesign:
216
    int counter = contentNew.count();
43 by carlos.mazieri at gmail
External file system watcher now is the class ExternalFSWatcher which inherits QFileSystemWatcher.
217
    if (counter > 0)
27 by carlos.mazieri at gmail
auto refresh feature almost done
218
    {
50 by carlos.mazieri at gmail
Fixed copy of an item that already exists when origin and destination paths are not the same, the item is overwritten.
219
        int tmpCounter = counter;
220
        while (tmpCounter--)
43 by carlos.mazieri at gmail
External file system watcher now is the class ExternalFSWatcher which inherits QFileSystemWatcher.
221
        {
63 by carlos-mazieri
Redesign:
222
            const DirItemInfo& originalItem = contentNew.at(tmpCounter);
55 by carlos-mazieri
added rename(oldName, newName)
223
            const DirItemInfo  existItem    = m_curContent.value(originalItem.absoluteFilePath());
43 by carlos.mazieri at gmail
External file system watcher now is the class ExternalFSWatcher which inherits QFileSystemWatcher.
224
            if ( existItem.exists() )
225
            {
226
                //it may have changed
227
                if (   originalItem.size()         != existItem.size()
228
                       || originalItem.lastModified() != existItem.lastModified()
229
                       || originalItem.permissions()  != existItem.permissions()
230
                       )
231
                {
232
                    emit changed(originalItem);
233
                }
234
                //remove this item
235
                m_curContent.remove(originalItem.absoluteFilePath());
236
            }
237
            else // originalItem was added
238
            {
239
                emit added(originalItem);
240
                ++addedCounter;
241
            }
27 by carlos.mazieri at gmail
auto refresh feature almost done
242
        }
43 by carlos.mazieri at gmail
External file system watcher now is the class ExternalFSWatcher which inherits QFileSystemWatcher.
243
55 by carlos-mazieri
added rename(oldName, newName)
244
        QHash<QString, DirItemInfo>::iterator  i = m_curContent.begin();
43 by carlos.mazieri at gmail
External file system watcher now is the class ExternalFSWatcher which inherits QFileSystemWatcher.
245
        for ( ;  i != m_curContent.end();  ++removedCounter, ++i )
246
        {
247
            emit removed(i.value());
27 by carlos.mazieri at gmail
auto refresh feature almost done
248
        }
249
    }
28 by carlos.mazieri at gmail
adding a "external file system watcher" which is a "auto refresh feature", it fixes: Bug #1190676 and Bug #1191282
250
#if DEBUG_EXT_FS_WATCHER
251
        qDebug() << "[exfsWatcher]" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz")
43 by carlos.mazieri at gmail
External file system watcher now is the class ExternalFSWatcher which inherits QFileSystemWatcher.
252
                 << Q_FUNC_INFO
253
                 << "addedCounter:"   << addedCounter
254
                 << "removedCounter:" << removedCounter;
28 by carlos.mazieri at gmail
adding a "external file system watcher" which is a "auto refresh feature", it fixes: Bug #1190676 and Bug #1191282
255
#endif
63 by carlos-mazieri
Redesign:
256
257
   return counter;
258
}
259
260
void ExternalFileSystemChangesWorker::run()
261
{
262
    DirItemInfoList directoryContents = getContents();    
263
    int remainingitemsCounter = compareItems(directoryContents);
264
    emit finished(remainingitemsCounter);
265
}
266
267
268
//---------------------------------------------------------------------
269
ExternalFileSystemTrashChangesWorker::ExternalFileSystemTrashChangesWorker(const QStringList &pathNames,
270
                                                                           const DirItemInfoList &list,
271
                                                                           QDir::Filter filter)
272
    :  ExternalFileSystemChangesWorker(list, pathNames.at(0), filter, false)
273
    ,  m_pathList(pathNames)
274
{
275
    mLoaderType = TrashLoader;
276
}
277
278
void ExternalFileSystemTrashChangesWorker::run()
279
{
280
    DirItemInfoList directoryContents;
281
    for(int counter = 0; counter < m_pathList.count(); counter++)
282
    {
283
        mPathName = QTrashUtilInfo::filesTrashDir(m_pathList.at(counter));
284
        directoryContents += getContents();
285
    }
286
    int remainingitemsCounter = compareItems(directoryContents);
287
    emit finished(remainingitemsCounter);
1 by carlos.mazieri at gmail
intial version of folderlistmodel, nemo-folderlistmodel is the orignal for comparing purposes, test_folderlistmodel contains tests.
288
}