2
* dirwatch_unix.cpp - detect changes of directory content
3
* Copyright (C) 2003 Justin Karneges
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Lesser General Public
7
* License as published by the Free Software Foundation; either
8
* version 2.1 of the License, or (at your option) any later version.
10
* This library is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Lesser General Public License for more details.
15
* You should have received a copy of the GNU Lesser General Public
16
* License along with this library; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30
class DWEvent : public QEvent
42
class DWThread : public QThread
45
DWThread(QObject *_par, HANDLE _h) : QThread()
53
while(WaitForSingleObject(h, INFINITE) == WAIT_OBJECT_0) {
54
// send a changed event
55
QThread::postEvent(par, new DWEvent(1));
56
if(!FindNextChangeNotification(h)) {
57
// send an error event
58
QThread::postEvent(par, new DWEvent(0));
68
class DWEntry : public QObject
72
static DWEntry * create(const QString &s)
74
HANDLE h = FindFirstChangeNotificationA(QFile::encodeName(QDir::convertSeparators(s)), TRUE,
75
FILE_NOTIFY_CHANGE_FILE_NAME |
76
FILE_NOTIFY_CHANGE_DIR_NAME |
77
FILE_NOTIFY_CHANGE_ATTRIBUTES |
78
FILE_NOTIFY_CHANGE_SIZE |
79
FILE_NOTIFY_CHANGE_LAST_WRITE |
80
FILE_NOTIFY_CHANGE_SECURITY);
82
if(h == INVALID_HANDLE_VALUE)
85
DWEntry *e = new DWEntry;
88
e->thread = new DWThread(e, h);
96
FindCloseChangeNotification(h);
106
bool event(QEvent *e)
108
if(e->type() == QEvent::User) {
109
DWEvent *de = (DWEvent *)e;
114
FindCloseChangeNotification(h);
129
QValueList<int> idList;
142
class DirWatchPlatform::Private : public QObject
146
Private(DirWatchPlatform *_par)
149
list.setAutoDelete(true);
150
connect(&t, SIGNAL(timeout()), this, SLOT(slotNotify()));
159
DirWatchPlatform *par;
160
QPtrList<DWEntry> list;
162
int addItem(const QString &s)
164
DWEntry *e = findEntryByDir(s);
166
e = DWEntry::create(s);
169
connect(e, SIGNAL(changed()), SLOT(slotChanged()));
172
int id = getUniqueId();
173
e->idList.append(id);
177
void removeItem(int id)
179
DWEntry *e = findEntryById(id);
182
e->idList.remove(id);
183
if(e->idList.isEmpty())
189
for(int n = 0;; ++n) {
190
QPtrListIterator<DWEntry> it(list);
192
for(DWEntry *e; (e = it.current()); ++it) {
193
for(QValueList<int>::ConstIterator idi = e->idList.begin(); idi != e->idList.end(); ++idi) {
207
DWEntry * findEntryByDir(const QString &s)
209
QPtrListIterator<DWEntry> it(list);
210
for(DWEntry *e; (e = it.current()); ++it) {
217
DWEntry * findEntryById(int id)
219
QPtrListIterator<DWEntry> it(list);
220
for(DWEntry *e; (e = it.current()); ++it) {
221
for(QValueList<int>::ConstIterator idi = e->idList.begin(); idi != e->idList.end(); ++idi) {
232
// use a timer to combine multiple changed events into one
240
QPtrListIterator<DWEntry> it(list);
241
for(DWEntry *e; (e = it.current()); ++it) {
244
for(QValueList<int>::ConstIterator idi = e->idList.begin(); idi != e->idList.end(); ++idi) {
245
par->triggerDirChanged(*idi);
252
DirWatchPlatform::DirWatchPlatform()
255
d = new Private(this);
258
DirWatchPlatform::~DirWatchPlatform()
263
bool DirWatchPlatform::init()
268
int DirWatchPlatform::addDir(const QString &s)
270
return d->addItem(s);
273
void DirWatchPlatform::removeDir(int id)
278
#include"dirwatch_win.moc"