summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--examples/opiecore/onotifytest/main.cpp2
-rw-r--r--libopie2/opiecore/linux/ofilenotify.cpp79
-rw-r--r--libopie2/opiecore/linux/ofilenotify.h13
3 files changed, 67 insertions, 27 deletions
diff --git a/examples/opiecore/onotifytest/main.cpp b/examples/opiecore/onotifytest/main.cpp
index 8374c59..b773da9 100644
--- a/examples/opiecore/onotifytest/main.cpp
+++ b/examples/opiecore/onotifytest/main.cpp
@@ -24,25 +24,25 @@ App::App( int argc, char** argv ) : QApplication( argc, argv )
24 if ( tmpfoo->open( IO_ReadWrite ) ) 24 if ( tmpfoo->open( IO_ReadWrite ) )
25 { 25 {
26 QTextStream stream( tmpfoo ); 26 QTextStream stream( tmpfoo );
27 stream << "This is my content"; 27 stream << "This is my content";
28 } 28 }
29 29
30 QObject::connect( tmpfoo, SIGNAL(accessed(const QString&)), this, SLOT(quit()) ); 30 QObject::connect( tmpfoo, SIGNAL(accessed(const QString&)), this, SLOT(quit()) );
31 QObject::connect( tmpfoo, SIGNAL(closed(const QString&,bool)), this, SLOT(quit()) ); 31 QObject::connect( tmpfoo, SIGNAL(closed(const QString&,bool)), this, SLOT(quit()) );
32#endif 32#endif
33 33
34 ODirNotification* tmpfoo = new ODirNotification( 0, 0 ); 34 ODirNotification* tmpfoo = new ODirNotification( 0, 0 );
35 35
36 int result = tmpfoo->watch( "/tmp/foo", false, CreateFile, 1 ); 36 int result = tmpfoo->watch( "/tmp/foo", false, CreateFile, 2 );
37 QObject::connect( tmpfoo, SIGNAL(triggered(const QString&,unsigned int,const QString&)), 37 QObject::connect( tmpfoo, SIGNAL(triggered(const QString&,unsigned int,const QString&)),
38 this, SLOT(triggered(const QString&,unsigned int,const QString&)) ); 38 this, SLOT(triggered(const QString&,unsigned int,const QString&)) );
39} 39}
40 40
41App::~App() 41App::~App()
42{ 42{
43 odebug << "~App()" << oendl; 43 odebug << "~App()" << oendl;
44} 44}
45 45
46void App::triggered( const QString& str1, unsigned int id, const QString& str2 ) 46void App::triggered( const QString& str1, unsigned int id, const QString& str2 )
47{ 47{
48 QMessageBox::information( qApp->desktop(), "info", QString( "%1\n%2\n%3" ).arg( str1 ).arg( id ).arg( str2 ) ); 48 QMessageBox::information( qApp->desktop(), "info", QString( "%1\n%2\n%3" ).arg( str1 ).arg( id ).arg( str2 ) );
diff --git a/libopie2/opiecore/linux/ofilenotify.cpp b/libopie2/opiecore/linux/ofilenotify.cpp
index 3096f7e..a7820ee 100644
--- a/libopie2/opiecore/linux/ofilenotify.cpp
+++ b/libopie2/opiecore/linux/ofilenotify.cpp
@@ -217,24 +217,30 @@ void OFileNotification::stop()
217OFileNotificationType OFileNotification::type() const 217OFileNotificationType OFileNotification::type() const
218{ 218{
219 return _type; 219 return _type;
220} 220}
221 221
222 222
223QString OFileNotification::path() const 223QString OFileNotification::path() const
224{ 224{
225 return _path; 225 return _path;
226} 226}
227 227
228 228
229bool OFileNotification::isSingleShot() const
230{
231 return !_multi;
232}
233
234
229bool OFileNotification::activate( const OFileNotificationEvent* e ) 235bool OFileNotification::activate( const OFileNotificationEvent* e )
230{ 236{
231 qDebug( "OFileNotification::activate(): e = ( %s, %d, 0x%08x, %d, %s )", (const char*) _path, e->descriptor(), e->mask(), e->cookie(), (const char*) e->name() ); 237 qDebug( "OFileNotification::activate(): e = ( %s, %d, 0x%08x, %d, %s )", (const char*) _path, e->descriptor(), e->mask(), e->cookie(), (const char*) e->name() );
232 238
233 // dumb signal 239 // dumb signal
234 _signal.activate(); 240 _signal.activate();
235 241
236 // generic signal 242 // generic signal
237 emit triggered( _path, e->mask(), e->name() ); 243 emit triggered( _path, e->mask(), e->name() );
238 244
239 // specialized signals 245 // specialized signals
240 switch ( e->mask() ) 246 switch ( e->mask() )
@@ -322,96 +328,117 @@ bool OFileNotification::registerEventHandler()
322void OFileNotification::unregisterEventHandler() 328void OFileNotification::unregisterEventHandler()
323{ 329{
324 if ( _sn ) delete _sn; 330 if ( _sn ) delete _sn;
325 if ( OFileNotification::_fd ) 331 if ( OFileNotification::_fd )
326 ::close( OFileNotification::_fd ); 332 ::close( OFileNotification::_fd );
327 qDebug( "OFileNotification::unregisterEventHandler(): done" ); 333 qDebug( "OFileNotification::unregisterEventHandler(): done" );
328} 334}
329 335
330//================================================================================================= 336//=================================================================================================
331// ODirNotification 337// ODirNotification
332//================================================================================================= 338//=================================================================================================
333ODirNotification::ODirNotification( QObject* parent, const char* name ) 339ODirNotification::ODirNotification( QObject* parent, const char* name )
334 :QObject( parent, name ) 340 :QObject( parent, name ), _topfilenotification( 0 ), _type( Nothing ), _depth( -123 )
335{ 341{
336 qDebug( "ODirNotification::ODirNotification()" ); 342 qDebug( "ODirNotification::ODirNotification()" );
337} 343}
338 344
339 345
340ODirNotification::~ODirNotification() 346ODirNotification::~ODirNotification()
341{ 347{
342 qDebug( "ODirNotification::~ODirNotification()" ); 348 qDebug( "ODirNotification::~ODirNotification()" );
343} 349}
344 350
351/*
352 Love-Trowbridge recursive directory scanning algorithm:
353
354 Step 1. Start at initial directory foo. Add watch.
355
356 Step 2. Setup handlers for watch created in Step 1.
357 Specifically, ensure that a directory created
358 in foo will result in a handled CREATE_SUBDIR
359 event.
360
361 Step 3. Read the contents of foo.
362
363 Step 4. For each subdirectory of foo read in step 3, repeat
364 step 1.
365
366 Step 5. For any CREATE_SUBDIR event on bar, if a watch is
367 not yet created on bar, repeat step 1 on bar.
368*/
345 369
346int ODirNotification::watch( const QString& path, bool sshot, OFileNotificationType type, int recurse ) 370int ODirNotification::watch( const QString& path, bool sshot, OFileNotificationType type, int recurse )
347{ 371{
348 qDebug( "ODirNotification::watch( %s, %d, 0x%08x, %d )", (const char*) path, sshot, type, recurse ); 372 if ( _type == Nothing ) _type = type; // only set it once - for the top level call
349 373 OFileNotificationType subtype = ( recurse != 0 ) ? (OFileNotificationType) int( _type | CreateSubdir ) : _type;
374 qDebug( "ODirNotification::watch( %s, %d, 0x%08x, %d )", (const char*) path, sshot, subtype, recurse );
350 OFileNotification* fn = new OFileNotification( this, "ODirNotification delegate" ); 375 OFileNotification* fn = new OFileNotification( this, "ODirNotification delegate" );
351 int result = fn->startWatching( path, sshot, type ); 376
377 int result = fn->startWatching( path, sshot, subtype );
352 if ( result != -1 ) 378 if ( result != -1 )
353 { 379 {
380
381 if ( !_topfilenotification ) _topfilenotification = fn; // only set it once - for the top level call
382 if ( _depth == -123 ) _depth = recurse; // only set it once - for the top level call
383
354 connect( fn, SIGNAL( triggered( const QString&, unsigned int, const QString& ) ), this, SIGNAL( triggered( const QString&, unsigned int, const QString& ) ) ); 384 connect( fn, SIGNAL( triggered( const QString&, unsigned int, const QString& ) ), this, SIGNAL( triggered( const QString&, unsigned int, const QString& ) ) );
355 connect( fn, SIGNAL( accessed( const QString& ) ), this, SIGNAL( accessed( const QString& ) ) ); 385 connect( fn, SIGNAL( accessed( const QString& ) ), this, SIGNAL( accessed( const QString& ) ) );
356 connect( fn, SIGNAL( modified( const QString& ) ), this, SIGNAL( modified( const QString& ) ) ); 386 connect( fn, SIGNAL( modified( const QString& ) ), this, SIGNAL( modified( const QString& ) ) );
357 connect( fn, SIGNAL( attributed( const QString& ) ), this, SIGNAL( attributed( const QString& ) ) ); 387 connect( fn, SIGNAL( attributed( const QString& ) ), this, SIGNAL( attributed( const QString& ) ) );
358 connect( fn, SIGNAL( closed( const QString&, bool ) ), this, SIGNAL( closed( const QString&, bool ) ) ); 388 connect( fn, SIGNAL( closed( const QString&, bool ) ), this, SIGNAL( closed( const QString&, bool ) ) );
359 connect( fn, SIGNAL( opened( const QString& ) ), this, SIGNAL( opened( const QString& ) ) ); 389 connect( fn, SIGNAL( opened( const QString& ) ), this, SIGNAL( opened( const QString& ) ) );
360 connect( fn, SIGNAL( movedTo( const QString&, const QString& ) ), this, SIGNAL( movedTo( const QString&, const QString& ) ) ); 390 connect( fn, SIGNAL( movedTo( const QString&, const QString& ) ), this, SIGNAL( movedTo( const QString&, const QString& ) ) );
361 connect( fn, SIGNAL( movedFrom( const QString&, const QString& ) ), this, SIGNAL( movedFrom( const QString&, const QString& ) ) ); 391 connect( fn, SIGNAL( movedFrom( const QString&, const QString& ) ), this, SIGNAL( movedFrom( const QString&, const QString& ) ) );
362 connect( fn, SIGNAL( deletedSubdir( const QString&, const QString& ) ), this, SIGNAL( deletedSubdir( const QString&, const QString& ) ) ); 392 connect( fn, SIGNAL( deletedSubdir( const QString&, const QString& ) ), this, SIGNAL( deletedSubdir( const QString&, const QString& ) ) );
363 connect( fn, SIGNAL( deletedFile( const QString&, const QString& ) ), this, SIGNAL( deletedFile( const QString&, const QString& ) ) );; 393 connect( fn, SIGNAL( deletedFile( const QString&, const QString& ) ), this, SIGNAL( deletedFile( const QString&, const QString& ) ) );;
364 connect( fn, SIGNAL( createdSubdir( const QString&, const QString& ) ), this, SIGNAL( createdSubdir( const QString&, const QString& ) ) ); 394 connect( fn, SIGNAL( createdSubdir( const QString&, const QString& ) ), this, SIGNAL( createdSubdir( const QString&, const QString& ) ) );
365 connect( fn, SIGNAL( createdFile( const QString&, const QString& ) ), this, SIGNAL( createdFile( const QString&, const QString& ) ) ); 395 connect( fn, SIGNAL( createdFile( const QString&, const QString& ) ), this, SIGNAL( createdFile( const QString&, const QString& ) ) );
366 connect( fn, SIGNAL( deleted( const QString& ) ), this, SIGNAL( deleted( const QString& ) ) ); 396 connect( fn, SIGNAL( deleted( const QString& ) ), this, SIGNAL( deleted( const QString& ) ) );
367 connect( fn, SIGNAL( unmounted( const QString& ) ), this, SIGNAL( unmounted( const QString& ) ) ); 397 connect( fn, SIGNAL( unmounted( const QString& ) ), this, SIGNAL( unmounted( const QString& ) ) );
368 398
369 if ( recurse ) 399 if ( recurse != 0 )
370 { 400 {
401 connect( fn, SIGNAL( createdSubdir( const QString&, const QString& ) ), this, SLOT( subdirCreated( const QString&, const QString& ) ) );
402
371 QDir directory( path ); 403 QDir directory( path );
372 QStringList subdirs = directory.entryList( QDir::Dirs ); 404 QStringList subdirs = directory.entryList( QDir::Dirs );
373 405
374 for ( QStringList::Iterator it = subdirs.begin(); it != subdirs.end(); ++it ) 406 for ( QStringList::Iterator it = subdirs.begin(); it != subdirs.end(); ++it )
375 { 407 {
376 if ( (*it) == "." || (*it) == ".." ) continue; 408 if ( (*it) == "." || (*it) == ".." ) continue;
377 QString subpath = QString( "%1/%2" ).arg( path ).arg( *it ); 409 QString subpath = QString( "%1/%2" ).arg( path ).arg( *it );
378 int subresult = watch( subpath, sshot, type, recurse-1 ); 410 int subresult = watch( subpath, sshot, subtype, recurse-1 );
379 if ( subresult == -1 ) 411 if ( subresult == -1 )
380 { 412 {
381 qDebug( "ODirNotification::watch(): subresult for '%s' was -1. Interrupting", (const char*) (*it) ); 413 qDebug( "ODirNotification::watch(): subresult for '%s' was -1. Interrupting", (const char*) (*it) );
382 return -1; 414 return -1;
383 } 415 }
384 } 416 }
385 } 417 }
386//connect( fn, SIGNAL( triggered( const QString&, unsigned int, const QString& ) ), this, SIGNAL( triggered( const QString&, unsigned int, const QString& ) ) );
387 } 418 }
388 else return -1; 419 else return -1;
389} 420}
390 421
391 422
392// void ODirNotification::subdirCreated( const QString& name ) 423void ODirNotification::subdirCreated( const QString& dir, const QString& subdir )
393 424{
394 425 qDebug( "*** ODirNotification::subdirCreated '%s/%s'", (const char*) dir, (const char*) subdir );
395/* 426 QString newdir = dir;
396 Love-Trowbridge recursive directory scanning algorithm: 427 if ( newdir.startsWith( _topfilenotification->path() ) )
397 428 {
398 Step 1. Start at initial directory foo. Add watch. 429 newdir.replace( _topfilenotification->path(), "" );
399 430 int level = newdir.contains( '/' );
400 Step 2. Setup handlers for watch created in Step 1. 431 qDebug( "*** dirpart = '%s' ==> level = %d", (const char*) newdir, level );
401 Specifically, ensure that a directory created
402 in foo will result in a handled CREATE_SUBDIR
403 event.
404
405 Step 3. Read the contents of foo.
406 432
407 Step 4. For each subdirectory of foo read in step 3, repeat 433 if ( _depth == -1 || _depth > level )
408 step 1. 434 {
435 watch( QString( "%1/%2" ).arg( dir ).arg( subdir ), _topfilenotification->isSingleShot(), _topfilenotification->type(), _depth == -1 ? -1 : _depth-level-1 );
436 }
409 437
410 Step 5. For any CREATE_SUBDIR event on bar, if a watch is 438 }
411 not yet created on bar, repeat step 1 on bar. 439}
412*/
413 440
414 441
415} // namespace Ui 442} // namespace Ui
416 443
417} // namespace Opie 444} // namespace Opie
diff --git a/libopie2/opiecore/linux/ofilenotify.h b/libopie2/opiecore/linux/ofilenotify.h
index 05343b9..17e6b5d 100644
--- a/libopie2/opiecore/linux/ofilenotify.h
+++ b/libopie2/opiecore/linux/ofilenotify.h
@@ -102,24 +102,25 @@ class OFileNotificationEvent;
102 * <li>DeleteSubdir = Subdir was deleted 102 * <li>DeleteSubdir = Subdir was deleted
103 * <li>DeleteFile = Subfile was deleted 103 * <li>DeleteFile = Subfile was deleted
104 * <li>CreateSubdir = Subdir was created 104 * <li>CreateSubdir = Subdir was created
105 * <li>CreateFile = Subfile was created 105 * <li>CreateFile = Subfile was created
106 * <li>DeleteSelf = Self was deleted 106 * <li>DeleteSelf = Self was deleted
107 * <li>Unmount = The backing filesystem was unmounted 107 * <li>Unmount = The backing filesystem was unmounted
108 * </ul> 108 * </ul>
109 * 109 *
110 **/ 110 **/
111 111
112enum OFileNotificationType 112enum OFileNotificationType
113{ 113{
114 Nothing = 0,
114 Access = IN_ACCESS, 115 Access = IN_ACCESS,
115 Modify = IN_MODIFY, 116 Modify = IN_MODIFY,
116 Attrib = IN_ATTRIB, 117 Attrib = IN_ATTRIB,
117 CloseWrite = IN_CLOSE_WRITE, 118 CloseWrite = IN_CLOSE_WRITE,
118 CloseNoWrite = IN_CLOSE_NOWRITE, 119 CloseNoWrite = IN_CLOSE_NOWRITE,
119 Open = IN_OPEN, 120 Open = IN_OPEN,
120 MovedFrom = IN_MOVED_FROM, 121 MovedFrom = IN_MOVED_FROM,
121 MovedTo = IN_MOVED_TO, 122 MovedTo = IN_MOVED_TO,
122 DeleteSubdir = IN_DELETE_SUBDIR, 123 DeleteSubdir = IN_DELETE_SUBDIR,
123 DeleteFile = IN_DELETE_FILE, 124 DeleteFile = IN_DELETE_FILE,
124 CreateSubdir = IN_CREATE_SUBDIR, 125 CreateSubdir = IN_CREATE_SUBDIR,
125 CreateFile = IN_CREATE_FILE, 126 CreateFile = IN_CREATE_FILE,
@@ -189,24 +190,28 @@ class OFileNotification : public QObject
189 * Stop watching for file events. 190 * Stop watching for file events.
190 **/ 191 **/
191 void stop(); 192 void stop();
192 /** 193 /**
193 * @returns the notification type as set by @ref start(). 194 * @returns the notification type as set by @ref start().
194 **/ 195 **/
195 OFileNotificationType type() const; 196 OFileNotificationType type() const;
196 /** 197 /**
197 * @returns the path to the file being watched by this instance. 198 * @returns the path to the file being watched by this instance.
198 **/ 199 **/
199 QString path() const; 200 QString path() const;
200 /** 201 /**
202 * @returns if the notification is single-shot
203 */
204 bool isSingleShot() const;
205 /**
201 * @returns if a file is currently being watched. 206 * @returns if a file is currently being watched.
202 **/ 207 **/
203 bool isActive() const; 208 bool isActive() const;
204 /** 209 /**
205 * @internal 210 * @internal
206 */ 211 */
207 int startWatching( const QString& path, bool sshot = false, OFileNotificationType type = Modify ); 212 int startWatching( const QString& path, bool sshot = false, OFileNotificationType type = Modify );
208 213
209 signals: 214 signals:
210 void triggered( const QString&, unsigned int, const QString& ); 215 void triggered( const QString&, unsigned int, const QString& );
211 void accessed( const QString& ); 216 void accessed( const QString& );
212 void modified( const QString& ); 217 void modified( const QString& );
@@ -283,24 +288,32 @@ class ODirNotification : public QObject
283 void modified( const QString& ); 288 void modified( const QString& );
284 void attributed( const QString& ); 289 void attributed( const QString& );
285 void closed( const QString&, bool ); 290 void closed( const QString&, bool );
286 void opened( const QString& ); 291 void opened( const QString& );
287 void movedTo( const QString&, const QString& ); 292 void movedTo( const QString&, const QString& );
288 void movedFrom( const QString&, const QString& ); 293 void movedFrom( const QString&, const QString& );
289 void deletedSubdir( const QString&, const QString& ); 294 void deletedSubdir( const QString&, const QString& );
290 void deletedFile( const QString&, const QString& ); 295 void deletedFile( const QString&, const QString& );
291 void createdSubdir( const QString&, const QString& ); 296 void createdSubdir( const QString&, const QString& );
292 void createdFile( const QString&, const QString& ); 297 void createdFile( const QString&, const QString& );
293 void deleted( const QString& ); 298 void deleted( const QString& );
294 void unmounted( const QString& ); 299 void unmounted( const QString& );
300
301 private slots:
302 void subdirCreated( const QString&, const QString& );
303
304 private:
305 OFileNotification* _topfilenotification;
306 OFileNotificationType _type;
307 int _depth;
295}; 308};
296 309
297/*====================================================================================== 310/*======================================================================================
298 * OFileNotificationEvent 311 * OFileNotificationEvent
299 *======================================================================================*/ 312 *======================================================================================*/
300 313
301class OFileNotificationEvent 314class OFileNotificationEvent
302{ 315{
303 public: 316 public:
304 OFileNotificationEvent( OFileNotification* parent, int wd, unsigned int mask, unsigned int cookie, const QString& name ); 317 OFileNotificationEvent( OFileNotification* parent, int wd, unsigned int mask, unsigned int cookie, const QString& name );
305 ~OFileNotificationEvent(); 318 ~OFileNotificationEvent();
306 OFileNotification* parent() const { return _parent; }; 319 OFileNotification* parent() const { return _parent; };