summaryrefslogtreecommitdiff
authormickeyl <mickeyl>2005-06-02 10:38:42 (UTC)
committer mickeyl <mickeyl>2005-06-02 10:38:42 (UTC)
commit9d6c759ac1adc5cb654bb3ada6b1d64cddc7217d (patch) (side-by-side diff)
tree05f7572469fe6c5721b44ed64796bd1104ea3525
parentb30f28de8d5fa29001bc73a0a0e56ef653f1269f (diff)
downloadopie-9d6c759ac1adc5cb654bb3ada6b1d64cddc7217d.zip
opie-9d6c759ac1adc5cb654bb3ada6b1d64cddc7217d.tar.gz
opie-9d6c759ac1adc5cb654bb3ada6b1d64cddc7217d.tar.bz2
more work on recursive watches
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 )
if ( tmpfoo->open( IO_ReadWrite ) )
{
QTextStream stream( tmpfoo );
stream << "This is my content";
}
QObject::connect( tmpfoo, SIGNAL(accessed(const QString&)), this, SLOT(quit()) );
QObject::connect( tmpfoo, SIGNAL(closed(const QString&,bool)), this, SLOT(quit()) );
#endif
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&)) );
}
App::~App()
{
odebug << "~App()" << oendl;
}
void App::triggered( const QString& str1, unsigned int id, const QString& str2 )
{
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()
OFileNotificationType OFileNotification::type() const
{
return _type;
}
QString OFileNotification::path() const
{
return _path;
}
+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() );
// dumb signal
_signal.activate();
// generic signal
emit triggered( _path, e->mask(), e->name() );
// specialized signals
switch ( e->mask() )
@@ -322,96 +328,117 @@ bool OFileNotification::registerEventHandler()
void OFileNotification::unregisterEventHandler()
{
if ( _sn ) delete _sn;
if ( OFileNotification::_fd )
::close( OFileNotification::_fd );
qDebug( "OFileNotification::unregisterEventHandler(): done" );
}
//=================================================================================================
// ODirNotification
//=================================================================================================
ODirNotification::ODirNotification( QObject* parent, const char* name )
- :QObject( parent, name )
+ :QObject( parent, name ), _topfilenotification( 0 ), _type( Nothing ), _depth( -123 )
{
qDebug( "ODirNotification::ODirNotification()" );
}
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& ) ) );
connect( fn, SIGNAL( attributed( const QString& ) ), this, SIGNAL( attributed( const QString& ) ) );
connect( fn, SIGNAL( closed( const QString&, bool ) ), this, SIGNAL( closed( const QString&, bool ) ) );
connect( fn, SIGNAL( opened( const QString& ) ), this, SIGNAL( opened( const QString& ) ) );
connect( fn, SIGNAL( movedTo( const QString&, const QString& ) ), this, SIGNAL( movedTo( const QString&, const QString& ) ) );
connect( fn, SIGNAL( movedFrom( const QString&, const QString& ) ), this, SIGNAL( movedFrom( const QString&, const QString& ) ) );
connect( fn, SIGNAL( deletedSubdir( const QString&, const QString& ) ), this, SIGNAL( deletedSubdir( const QString&, const QString& ) ) );
connect( fn, SIGNAL( deletedFile( const QString&, const QString& ) ), this, SIGNAL( deletedFile( const QString&, const QString& ) ) );;
connect( fn, SIGNAL( createdSubdir( const QString&, const QString& ) ), this, SIGNAL( createdSubdir( const QString&, const QString& ) ) );
connect( fn, SIGNAL( createdFile( const QString&, const QString& ) ), this, SIGNAL( createdFile( const QString&, const QString& ) ) );
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 );
for ( QStringList::Iterator it = subdirs.begin(); it != subdirs.end(); ++it )
{
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) );
return -1;
}
}
}
-//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
} // 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;
* <li>DeleteSubdir = Subdir was deleted
* <li>DeleteFile = Subfile was deleted
* <li>CreateSubdir = Subdir was created
* <li>CreateFile = Subfile was created
* <li>DeleteSelf = Self was deleted
* <li>Unmount = The backing filesystem was unmounted
* </ul>
*
**/
enum OFileNotificationType
{
+ Nothing = 0,
Access = IN_ACCESS,
Modify = IN_MODIFY,
Attrib = IN_ATTRIB,
CloseWrite = IN_CLOSE_WRITE,
CloseNoWrite = IN_CLOSE_NOWRITE,
Open = IN_OPEN,
MovedFrom = IN_MOVED_FROM,
MovedTo = IN_MOVED_TO,
DeleteSubdir = IN_DELETE_SUBDIR,
DeleteFile = IN_DELETE_FILE,
CreateSubdir = IN_CREATE_SUBDIR,
CreateFile = IN_CREATE_FILE,
@@ -189,24 +190,28 @@ class OFileNotification : public QObject
* Stop watching for file events.
**/
void stop();
/**
* @returns the notification type as set by @ref start().
**/
OFileNotificationType type() const;
/**
* @returns the path to the file being watched by this instance.
**/
QString path() const;
/**
+ * @returns if the notification is single-shot
+ */
+ bool isSingleShot() const;
+ /**
* @returns if a file is currently being watched.
**/
bool isActive() const;
/**
* @internal
*/
int startWatching( const QString& path, bool sshot = false, OFileNotificationType type = Modify );
signals:
void triggered( const QString&, unsigned int, const QString& );
void accessed( const QString& );
void modified( const QString& );
@@ -283,24 +288,32 @@ class ODirNotification : public QObject
void modified( const QString& );
void attributed( const QString& );
void closed( const QString&, bool );
void opened( const QString& );
void movedTo( const QString&, const QString& );
void movedFrom( const QString&, const QString& );
void deletedSubdir( const QString&, const QString& );
void deletedFile( const QString&, const QString& );
void createdSubdir( const QString&, const QString& );
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;
};
/*======================================================================================
* OFileNotificationEvent
*======================================================================================*/
class OFileNotificationEvent
{
public:
OFileNotificationEvent( OFileNotification* parent, int wd, unsigned int mask, unsigned int cookie, const QString& name );
~OFileNotificationEvent();
OFileNotification* parent() const { return _parent; };