summaryrefslogtreecommitdiff
Side-by-side diff
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
@@ -33,7 +33,7 @@ App::App( int argc, char** argv ) : QApplication( argc, argv )
ODirNotification* tmpfoo = new ODirNotification( 0, 0 );
- int result = tmpfoo->watch( "/tmp/foo", false, CreateFile, 1 );
+ int result = tmpfoo->watch( "/tmp/foo", false, CreateFile, 2 );
QObject::connect( tmpfoo, SIGNAL(triggered(const QString&,unsigned int,const QString&)),
this, SLOT(triggered(const QString&,unsigned int,const QString&)) );
}
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
@@ -226,6 +226,12 @@ QString OFileNotification::path() const
}
+bool OFileNotification::isSingleShot() const
+{
+ return !_multi;
+}
+
+
bool OFileNotification::activate( const OFileNotificationEvent* e )
{
qDebug( "OFileNotification::activate(): e = ( %s, %d, 0x%08x, %d, %s )", (const char*) _path, e->descriptor(), e->mask(), e->cookie(), (const char*) e->name() );
@@ -331,7 +337,7 @@ void OFileNotification::unregisterEventHandler()
// ODirNotification
//=================================================================================================
ODirNotification::ODirNotification( QObject* parent, const char* name )
- :QObject( parent, name )
+ :QObject( parent, name ), _topfilenotification( 0 ), _type( Nothing ), _depth( -123 )
{
qDebug( "ODirNotification::ODirNotification()" );
}
@@ -342,15 +348,39 @@ ODirNotification::~ODirNotification()
qDebug( "ODirNotification::~ODirNotification()" );
}
+/*
+ Love-Trowbridge recursive directory scanning algorithm:
+
+ Step 1. Start at initial directory foo. Add watch.
+
+ Step 2. Setup handlers for watch created in Step 1.
+ Specifically, ensure that a directory created
+ in foo will result in a handled CREATE_SUBDIR
+ event.
+
+ Step 3. Read the contents of foo.
+
+ Step 4. For each subdirectory of foo read in step 3, repeat
+ step 1.
+
+ Step 5. For any CREATE_SUBDIR event on bar, if a watch is
+ not yet created on bar, repeat step 1 on bar.
+*/
int ODirNotification::watch( const QString& path, bool sshot, OFileNotificationType type, int recurse )
{
- qDebug( "ODirNotification::watch( %s, %d, 0x%08x, %d )", (const char*) path, sshot, type, recurse );
-
+ if ( _type == Nothing ) _type = type; // only set it once - for the top level call
+ OFileNotificationType subtype = ( recurse != 0 ) ? (OFileNotificationType) int( _type | CreateSubdir ) : _type;
+ qDebug( "ODirNotification::watch( %s, %d, 0x%08x, %d )", (const char*) path, sshot, subtype, recurse );
OFileNotification* fn = new OFileNotification( this, "ODirNotification delegate" );
- int result = fn->startWatching( path, sshot, type );
+
+ int result = fn->startWatching( path, sshot, subtype );
if ( result != -1 )
{
+
+ if ( !_topfilenotification ) _topfilenotification = fn; // only set it once - for the top level call
+ if ( _depth == -123 ) _depth = recurse; // only set it once - for the top level call
+
connect( fn, SIGNAL( triggered( const QString&, unsigned int, const QString& ) ), this, SIGNAL( triggered( const QString&, unsigned int, const QString& ) ) );
connect( fn, SIGNAL( accessed( const QString& ) ), this, SIGNAL( accessed( const QString& ) ) );
connect( fn, SIGNAL( modified( const QString& ) ), this, SIGNAL( modified( const QString& ) ) );
@@ -366,8 +396,10 @@ int ODirNotification::watch( const QString& path, bool sshot, OFileNotificationT
connect( fn, SIGNAL( deleted( const QString& ) ), this, SIGNAL( deleted( const QString& ) ) );
connect( fn, SIGNAL( unmounted( const QString& ) ), this, SIGNAL( unmounted( const QString& ) ) );
- if ( recurse )
+ if ( recurse != 0 )
{
+ connect( fn, SIGNAL( createdSubdir( const QString&, const QString& ) ), this, SLOT( subdirCreated( const QString&, const QString& ) ) );
+
QDir directory( path );
QStringList subdirs = directory.entryList( QDir::Dirs );
@@ -375,7 +407,7 @@ int ODirNotification::watch( const QString& path, bool sshot, OFileNotificationT
{
if ( (*it) == "." || (*it) == ".." ) continue;
QString subpath = QString( "%1/%2" ).arg( path ).arg( *it );
- int subresult = watch( subpath, sshot, type, recurse-1 );
+ int subresult = watch( subpath, sshot, subtype, recurse-1 );
if ( subresult == -1 )
{
qDebug( "ODirNotification::watch(): subresult for '%s' was -1. Interrupting", (const char*) (*it) );
@@ -383,33 +415,28 @@ int ODirNotification::watch( const QString& path, bool sshot, OFileNotificationT
}
}
}
-//connect( fn, SIGNAL( triggered( const QString&, unsigned int, const QString& ) ), this, SIGNAL( triggered( const QString&, unsigned int, const QString& ) ) );
}
else return -1;
}
-// void ODirNotification::subdirCreated( const QString& name )
-
-
-/*
- Love-Trowbridge recursive directory scanning algorithm:
-
- Step 1. Start at initial directory foo. Add watch.
-
- Step 2. Setup handlers for watch created in Step 1.
- Specifically, ensure that a directory created
- in foo will result in a handled CREATE_SUBDIR
- event.
-
- Step 3. Read the contents of foo.
+void ODirNotification::subdirCreated( const QString& dir, const QString& subdir )
+{
+ qDebug( "*** ODirNotification::subdirCreated '%s/%s'", (const char*) dir, (const char*) subdir );
+ QString newdir = dir;
+ if ( newdir.startsWith( _topfilenotification->path() ) )
+ {
+ newdir.replace( _topfilenotification->path(), "" );
+ int level = newdir.contains( '/' );
+ qDebug( "*** dirpart = '%s' ==> level = %d", (const char*) newdir, level );
- Step 4. For each subdirectory of foo read in step 3, repeat
- step 1.
+ if ( _depth == -1 || _depth > level )
+ {
+ watch( QString( "%1/%2" ).arg( dir ).arg( subdir ), _topfilenotification->isSingleShot(), _topfilenotification->type(), _depth == -1 ? -1 : _depth-level-1 );
+ }
- Step 5. For any CREATE_SUBDIR event on bar, if a watch is
- not yet created on bar, repeat step 1 on bar.
-*/
+ }
+}
} // namespace Ui
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
@@ -111,6 +111,7 @@ class OFileNotificationEvent;
enum OFileNotificationType
{
+ Nothing = 0,
Access = IN_ACCESS,
Modify = IN_MODIFY,
Attrib = IN_ATTRIB,
@@ -198,6 +199,10 @@ class OFileNotification : public QObject
**/
QString path() const;
/**
+ * @returns if the notification is single-shot
+ */
+ bool isSingleShot() const;
+ /**
* @returns if a file is currently being watched.
**/
bool isActive() const;
@@ -292,6 +297,14 @@ class ODirNotification : public QObject
void createdFile( const QString&, const QString& );
void deleted( const QString& );
void unmounted( const QString& );
+
+ private slots:
+ void subdirCreated( const QString&, const QString& );
+
+ private:
+ OFileNotification* _topfilenotification;
+ OFileNotificationType _type;
+ int _depth;
};
/*======================================================================================