summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--examples/opiecore/onotifydemo/onotifydemo.cpp14
-rw-r--r--examples/opiecore/onotifydemo/onotifydemo.h2
-rw-r--r--libopie2/opiecore/ofilenotify.cpp122
-rw-r--r--libopie2/opiecore/ofilenotify.h63
4 files changed, 163 insertions, 38 deletions
diff --git a/examples/opiecore/onotifydemo/onotifydemo.cpp b/examples/opiecore/onotifydemo/onotifydemo.cpp
index 2beda2a..e147c6a 100644
--- a/examples/opiecore/onotifydemo/onotifydemo.cpp
+++ b/examples/opiecore/onotifydemo/onotifydemo.cpp
@@ -1,178 +1,180 @@
1#include "onotifydemo.h" 1#include "onotifydemo.h"
2 2
3/* OPIE */ 3/* OPIE */
4#include <opie2/odebug.h> 4#include <opie2/odebug.h>
5#include <opie2/oapplication.h> 5#include <opie2/oapplication.h>
6#include <opie2/ofiledialog.h> 6#include <opie2/ofiledialog.h>
7#include <opie2/olistview.h> 7#include <opie2/olistview.h>
8#include <opie2/ofilenotify.h> 8#include <opie2/ofilenotify.h>
9using namespace Opie::Core; 9using namespace Opie::Core;
10using namespace Opie::Ui; 10using namespace Opie::Ui;
11 11
12/* QT */ 12/* QT */
13#include <qcheckbox.h> 13#include <qcheckbox.h>
14#include <qfileinfo.h> 14#include <qfileinfo.h>
15#include <qvbox.h> 15#include <qvbox.h>
16#include <qhbox.h> 16#include <qhbox.h>
17#include <qhbuttongroup.h> 17#include <qhbuttongroup.h>
18#include <qvbuttongroup.h> 18#include <qvbuttongroup.h>
19#include <qmessagebox.h> 19#include <qmessagebox.h>
20#include <qpushbutton.h> 20#include <qpushbutton.h>
21 21
22DemoApp::DemoApp( int argc, char** argv ) : OApplication( argc, argv, "libopie2 notify demo" ) 22DemoApp::DemoApp( int argc, char** argv ) : OApplication( argc, argv, "libopie2 notify demo" )
23 { 23 {
24 24
25 QVBox* vbox = new QVBox(); 25 QVBox* vbox = new QVBox();
26 setMainWidget( vbox ); 26 setMainWidget( vbox );
27 27
28 l = new OListView( vbox ); 28 l = new OListView( vbox );
29 l->addColumn( "Notification Path" ); 29 l->addColumn( "Notification Path" );
30 l->addColumn( "Trigger Type" ); 30 l->addColumn( "Trigger Type" );
31 l->addColumn( "Trigger Mask" ); 31 l->addColumn( "Trigger Mask" );
32 l->setColumnAlignment( 1, AlignCenter ); 32 l->setColumnAlignment( 1, AlignCenter );
33 l->setColumnAlignment( 2, AlignCenter ); 33 l->setColumnAlignment( 2, AlignCenter );
34 34
35 QHBox* hbox = new QHBox( vbox ); 35 QHBox* hbox = new QHBox( vbox );
36 g2 = new QVButtonGroup( "Specify Trigger Type", hbox ); 36 g2 = new QVButtonGroup( "Specify Trigger Type", hbox );
37 QCheckBox* c1 = new QCheckBox( "Access", g2 ); 37 QCheckBox* c1 = new QCheckBox( "Access", g2 );
38 QCheckBox* c2 = new QCheckBox( "Modify", g2 ); 38 QCheckBox* c2 = new QCheckBox( "Modify", g2 );
39 QCheckBox* c3 = new QCheckBox( "Attrib", g2 ); 39 QCheckBox* c3 = new QCheckBox( "Attrib", g2 );
40 QCheckBox* c4 = new QCheckBox( "CloseWrite", g2 ); 40 QCheckBox* c4 = new QCheckBox( "CloseWrite", g2 );
41 QCheckBox* c5 = new QCheckBox( "CloseNoWrite", g2 ); 41 QCheckBox* c5 = new QCheckBox( "CloseNoWrite", g2 );
42 QCheckBox* c6 = new QCheckBox( "MovedFrom", g2 ); 42 QCheckBox* c6 = new QCheckBox( "MovedFrom", g2 );
43 QCheckBox* c7 = new QCheckBox( "MovedTo", g2 ); 43 QCheckBox* c7 = new QCheckBox( "MovedTo", g2 );
44 QCheckBox* c8 = new QCheckBox( "DeleteSubdir", g2 ); 44 QCheckBox* c8 = new QCheckBox( "DeleteSubdir", g2 );
45 QCheckBox* c9 = new QCheckBox( "DeleteFile", g2 ); 45 QCheckBox* c9 = new QCheckBox( "DeleteFile", g2 );
46 QCheckBox* c10 = new QCheckBox( "CreateSubdir", g2 ); 46 QCheckBox* c10 = new QCheckBox( "CreateSubdir", g2 );
47 QCheckBox* c11 = new QCheckBox( "CreateFile", g2 ); 47 QCheckBox* c11 = new QCheckBox( "CreateFile", g2 );
48 QCheckBox* c12 = new QCheckBox( "Unmount", g2 ); 48 QCheckBox* c12 = new QCheckBox( "Unmount", g2 );
49 g2->insert( c1, Access ); 49 g2->insert( c1, Access );
50 g2->insert( c2, Modify ); 50 g2->insert( c2, Modify );
51 g2->insert( c3, Attrib ); 51 g2->insert( c3, Attrib );
52 g2->insert( c4, CloseWrite ); 52 g2->insert( c4, CloseWrite );
53 g2->insert( c5, CloseNoWrite ); 53 g2->insert( c5, CloseNoWrite );
54 g2->insert( c6, MovedFrom ); 54 g2->insert( c6, MovedFrom );
55 g2->insert( c7, MovedTo ); 55 g2->insert( c7, MovedTo );
56 g2->insert( c8, DeleteSubdir ); 56 g2->insert( c8, DeleteSubdir );
57 g2->insert( c9, DeleteFile ); 57 g2->insert( c9, DeleteFile );
58 g2->insert( c10, CreateSubdir ); 58 g2->insert( c10, CreateSubdir );
59 g2->insert( c11, CreateFile ); 59 g2->insert( c11, CreateFile );
60 g2->insert( c12, Unmount ); 60 g2->insert( c12, Unmount );
61 connect( g2, SIGNAL( pressed(int) ), this, SLOT( modifierClicked(int) ) ); 61 connect( g2, SIGNAL( pressed(int) ), this, SLOT( modifierClicked(int) ) );
62 62
63 g1 = new QVButtonGroup( "Add/Remove", hbox ); 63 g1 = new QVButtonGroup( "Add/Remove", hbox );
64 QPushButton* plus1 = new QPushButton( "Add\n&Single", g1 ); 64 QPushButton* plus1 = new QPushButton( "Add\n&Single", g1 );
65 QPushButton* plus2 = new QPushButton( "Add\n&Multi", g1 ); 65 QPushButton* plus2 = new QPushButton( "Add\n&Multi", g1 );
66 QPushButton* minus = new QPushButton( "&Remove\nIt!", g1 ); 66 QPushButton* minus = new QPushButton( "&Remove\nIt!", g1 );
67 g1->insert( plus1, 0 ); 67 g1->insert( plus1, 0 );
68 g1->insert( plus2, 1 ); 68 g1->insert( plus2, 1 );
69 g1->insert( minus, 2 ); 69 g1->insert( minus, 2 );
70 connect( plus1, SIGNAL( clicked() ), this, SLOT( addSingle() ) ); 70 connect( plus1, SIGNAL( clicked() ), this, SLOT( addSingle() ) );
71 connect( plus2, SIGNAL( clicked() ), this, SLOT( addMulti() ) ); 71 connect( plus2, SIGNAL( clicked() ), this, SLOT( addMulti() ) );
72 connect( minus, SIGNAL( clicked() ), this, SLOT( delTrigger() ) ); 72 connect( minus, SIGNAL( clicked() ), this, SLOT( delTrigger() ) );
73 73
74 g1->show(); 74 g1->show();
75 g2->show(); 75 g2->show();
76 l->show(); 76 l->show();
77 hbox->show(); 77 hbox->show();
78 vbox->show(); 78 vbox->show();
79 showMainWidget( vbox ); 79 showMainWidget( vbox );
80 } 80 }
81 81
82 void DemoApp::addTrigger( bool multi ) 82 void DemoApp::addTrigger( bool multi )
83 { 83 {
84 if ( !m ) 84 if ( !m )
85 { 85 {
86 QMessageBox::warning( 0, "Add Trigger", "<p>Can't add trigger without at least one selected trigger type</p>", "&Sorry", 0 ); 86 QMessageBox::warning( 0, "Add Trigger", "<p>Can't add trigger without at least one selected trigger type</p>", "&Sorry", 0 );
87 return; 87 return;
88 } 88 }
89 89
90 QString filename = OFileDialog::getOpenFileName( OFileSelector::ExtendedAll ); 90 QString filename = OFileDialog::getOpenFileName( OFileSelector::ExtendedAll );
91 if ( !filename.isEmpty() ) 91 if ( !filename.isEmpty() )
92 { 92 {
93 bool success = true; 93 bool success = true;
94 odebug << "Filename = " << filename << oendl; 94 odebug << "Filename = " << filename << oendl;
95 95
96 int fntype = m; 96 int fntype = m;
97 QString modifier = QString().sprintf( " = 0x%08x", fntype ); 97 QString modifier = QString().sprintf( " = 0x%08x", fntype );
98 98
99 if ( QFileInfo( filename ).isFile() ) 99 if ( QFileInfo( filename ).isFile() )
100 { 100 {
101 if ( !multi ) 101 if ( !multi )
102 { 102 {
103 success = OFileNotification::singleShot( filename, this, SLOT( unnamedTrigger() ), (OFileNotificationType) fntype ); 103 success = OFileNotification::singleShot( filename, this, SLOT(unnamedTrigger()), (OFileNotificationType) fntype );
104 } 104 }
105 else 105 else
106 { 106 {
107 OFileNotification* fn = new OFileNotification(); 107 OFileNotification* fn = new OFileNotification();
108 success = fn->watch( filename, false, (OFileNotificationType) fntype ); 108 success = fn->watch( filename, false, (OFileNotificationType) fntype );
109 connect( fn, SIGNAL( triggered( const QString& ) ), this, SLOT( namedTrigger( const QString& ) ) ); 109 connect( fn, SIGNAL(triggered(const QString&,unsigned int,const QString&)),
110 } 110 this, SLOT(namedTrigger(const QString&,unsigned int,const QString&)) );
111 }
111 } 112 }
112 else if ( QFileInfo( filename ).isDir() ) 113 else if ( QFileInfo( filename ).isDir() )
113 { 114 {
114 ODirNotification* dn = new ODirNotification(); 115 ODirNotification* dn = new ODirNotification();
115 success = dn->watch( filename, !multi, (OFileNotificationType) fntype ); 116 success = dn->watch( filename, !multi, (OFileNotificationType) fntype );
116 connect( dn, SIGNAL( triggered( const QString& ) ), this, SLOT( namedTrigger( const QString& ) ) ); 117 connect( dn, SIGNAL(triggered(const QString&,unsigned int,const QString&)),
118 this, SLOT(namedTrigger(const QString&,unsigned int,const QString&)) );
117 } 119 }
118 else 120 else
119 { 121 {
120 odebug << "Huh!? Neither file nor directory..." << oendl; 122 odebug << "Huh!? Neither file nor directory..." << oendl;
121 return; 123 return;
122 } 124 }
123 125
124/* if ( !success ) 126/* if ( !success )
125 { 127 {
126 QMessageBox::warning( 0, "Add Trigger", "<p>Couldn't add trigger :(</p>", "&Sorry", 0 ); 128 QMessageBox::warning( 0, "Add Trigger", "<p>Couldn't add trigger :(</p>", "&Sorry", 0 );
127 return; 129 return;
128 } 130 }
129 else 131 else
130*/ { 132*/ {
131 new OListViewItem( l, filename, multi ? "MULTI" : "SINGLE", modifier ); 133 new OListViewItem( l, filename, multi ? "MULTI" : "SINGLE", modifier );
132 } 134 }
133 return; 135 return;
134 } 136 }
135 else 137 else
136 { 138 {
137 odebug << "cancelled." << oendl; 139 odebug << "cancelled." << oendl;
138 } 140 }
139 } 141 }
140 142
141 void DemoApp::modifierClicked( int modifier ) { m = static_cast<OFileNotificationType>( (int)m ^ int(modifier) ); }; 143 void DemoApp::modifierClicked( int modifier ) { m = static_cast<OFileNotificationType>( (int)m ^ int(modifier) ); };
142 void DemoApp::addSingle() { addTrigger(); }; 144 void DemoApp::addSingle() { addTrigger(); };
143 void DemoApp::addMulti() { addTrigger( true ); }; 145 void DemoApp::addMulti() { addTrigger( true ); };
144 146
145 void DemoApp::delTrigger() 147 void DemoApp::delTrigger()
146 { 148 {
147 QListViewItem* item = l->selectedItem(); 149 QListViewItem* item = l->selectedItem();
148 if ( !item ) 150 if ( !item )
149 { 151 {
150 QMessageBox::warning( 0, "Del Trigger", "<p>No trigger selected!</p>", "&Sorry", 0 ); 152 QMessageBox::warning( 0, "Del Trigger", "<p>No trigger selected!</p>", "&Sorry", 0 );
151 return; 153 return;
152 } 154 }
153 else 155 else
154 { 156 {
155 QString filename( item->text( 0 ) ); 157 QString filename( item->text( 0 ) );
156 odebug << "Filename = " << filename << oendl; 158 odebug << "Filename = " << filename << oendl;
157 } 159 }
158 } 160 }
159 161
160 void DemoApp::unnamedTrigger() 162 void DemoApp::unnamedTrigger()
161 { 163 {
162 owarn << "DemoApp::singleShotStrigger() : F I R E !!!!!" << oendl; 164 owarn << "DemoApp::singleShotStrigger() : F I R E !!!!!" << oendl;
163 } 165 }
164 166
165 void DemoApp::namedTrigger( const QString& path ) 167 void DemoApp::namedTrigger( const QString& path, unsigned int type, const QString& name )
166 { 168 {
167 owarn << "DemoApp::named trigger = " << path << " : F I R E !!!!!" << oendl; 169 owarn << "DemoApp::named trigger = ( " << path << ", " << type << ", " << name << " ) : F I R E !!!!!" << oendl;
168 } 170 }
169 171
170int main( int argc, char** argv ) 172int main( int argc, char** argv )
171{ 173{
172 DemoApp* app = new DemoApp( argc, argv ); 174 DemoApp* app = new DemoApp( argc, argv );
173 app->exec(); 175 app->exec();
174 176
175 return 0; 177 return 0;
176 178
177} 179}
178 180
diff --git a/examples/opiecore/onotifydemo/onotifydemo.h b/examples/opiecore/onotifydemo/onotifydemo.h
index f6ac5ea..20019e4 100644
--- a/examples/opiecore/onotifydemo/onotifydemo.h
+++ b/examples/opiecore/onotifydemo/onotifydemo.h
@@ -1,30 +1,30 @@
1/* OPIE */ 1/* OPIE */
2#include <opie2/olistview.h> 2#include <opie2/olistview.h>
3#include <opie2/odebug.h> 3#include <opie2/odebug.h>
4#include <opie2/oapplication.h> 4#include <opie2/oapplication.h>
5#include <opie2/ofilenotify.h> 5#include <opie2/ofilenotify.h>
6 6
7class QButtonGroup; 7class QButtonGroup;
8 8
9class DemoApp : public Opie::Core::OApplication 9class DemoApp : public Opie::Core::OApplication
10{ 10{
11 Q_OBJECT 11 Q_OBJECT
12public: 12public:
13 DemoApp( int argc, char** argv ); 13 DemoApp( int argc, char** argv );
14 14
15public: 15public:
16 void addTrigger( bool multi = false ); 16 void addTrigger( bool multi = false );
17public slots: 17public slots:
18 void modifierClicked( int modifier ); 18 void modifierClicked( int modifier );
19 void addSingle(); 19 void addSingle();
20 void addMulti(); 20 void addMulti();
21 void delTrigger(); 21 void delTrigger();
22 void unnamedTrigger(); 22 void unnamedTrigger();
23 void namedTrigger( const QString& name ); 23 void namedTrigger( const QString&, unsigned int, const QString& );
24 24
25private: 25private:
26 Opie::Ui::OListView* l; 26 Opie::Ui::OListView* l;
27 QButtonGroup* g1; 27 QButtonGroup* g1;
28 QButtonGroup* g2; 28 QButtonGroup* g2;
29 Opie::Core::OFileNotificationType m; 29 Opie::Core::OFileNotificationType m;
30}; 30};
diff --git a/libopie2/opiecore/ofilenotify.cpp b/libopie2/opiecore/ofilenotify.cpp
index 11d4f87..4264327 100644
--- a/libopie2/opiecore/ofilenotify.cpp
+++ b/libopie2/opiecore/ofilenotify.cpp
@@ -1,278 +1,350 @@
1/* 1/*
2                This file is part of the Opie Project 2                This file is part of the Opie Project
3 =. Copyright (C) 2004-2005 Michael 'Mickey' Lauer <mickey@Vanille.de> 3 =. Copyright (C) 2004-2005 Michael 'Mickey' Lauer <mickey@Vanille.de>
4 .=l. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 .=l. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5          .>+-= 5          .>+-=
6_;:,     .>    :=|. This program is free software; you can 6_;:,     .>    :=|. This program is free software; you can
7.> <`_,   >  .   <= redistribute it and/or modify it under 7.> <`_,   >  .   <= redistribute it and/or modify it under
8:`=1 )Y*s>-.--   : the terms of the GNU Library General Public 8:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
9.="- .-=="i,     .._ License as published by the Free Software 9.="- .-=="i,     .._ License as published by the Free Software
10- .   .-<_>     .<> Foundation; version 2 of the License. 10- .   .-<_>     .<> Foundation; version 2 of the License.
11    ._= =}       : 11    ._= =}       :
12   .%`+i>       _;_. 12   .%`+i>       _;_.
13   .i_,=:_.      -<s. This program is distributed in the hope that 13   .i_,=:_.      -<s. This program is distributed in the hope that
14    +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY; 14    +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY;
15   : ..    .:,     . . . without even the implied warranty of 15   : ..    .:,     . . . without even the implied warranty of
16   =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A 16   =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
17 _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU 17 _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU
18..}^=.=       =       ; Library General Public License for more 18..}^=.=       =       ; Library General Public License for more
19++=   -.     .`     .: details. 19++=   -.     .`     .: details.
20:     =  ...= . :.=- 20:     =  ...= . :.=-
21-.   .:....=;==+<; You should have received a copy of the GNU 21-.   .:....=;==+<; You should have received a copy of the GNU
22 -_. . .   )=.  = Library General Public License along with 22 -_. . .   )=.  = Library General Public License along with
23   --        :-=` this library; see the file COPYING.LIB. 23   --        :-=` this library; see the file COPYING.LIB.
24 If not, write to the Free Software Foundation, 24 If not, write to the Free Software Foundation,
25 Inc., 59 Temple Place - Suite 330, 25 Inc., 59 Temple Place - Suite 330,
26 Boston, MA 02111-1307, USA. 26 Boston, MA 02111-1307, USA.
27*/ 27*/
28 28
29#include "ofilenotify.h" 29#include "ofilenotify.h"
30using namespace Opie::Core; 30using namespace Opie::Core;
31 31
32/* OPIE */ 32/* OPIE */
33 33
34/* QT */ 34/* QT */
35#include <qobject.h> 35#include <qobject.h>
36#include <qsocketnotifier.h> 36#include <qsocketnotifier.h>
37#include <qsignal.h> 37#include <qsignal.h>
38#include <qintdict.h> 38#include <qintdict.h>
39#include <qdir.h> 39#include <qdir.h>
40 40
41/* STD */ 41/* STD */
42#include <sys/types.h> 42#include <sys/types.h>
43#include <sys/stat.h> 43#include <sys/stat.h>
44#include <sys/ioctl.h> 44#include <sys/ioctl.h>
45#include <fcntl.h> 45#include <fcntl.h>
46#include <assert.h> 46#include <assert.h>
47#include <string.h> 47#include <string.h>
48#include <errno.h> 48#include <errno.h>
49#include <unistd.h> 49#include <unistd.h>
50 50
51static QIntDict<OFileNotification> notification_list; 51static QIntDict<OFileNotification> notification_list;
52 52
53QSocketNotifier* OFileNotification::_sn; 53QSocketNotifier* OFileNotification::_sn;
54int OFileNotification::_fd = -1; 54int OFileNotification::_fd = -1;
55 55
56#define INOTIFY_DEVICE "/dev/inotify" 56#define INOTIFY_DEVICE "/dev/inotify"
57 57
58namespace Opie { 58namespace Opie {
59namespace Core { 59namespace Core {
60 60
61//=================================================================================================
62// OFileNotificationEvent
63//=================================================================================================
64OFileNotificationEvent::OFileNotificationEvent( OFileNotification* parent, int wd, unsigned int mask, unsigned int cookie, const QString& name )
65 :_parent( parent ), _wd( wd ), _mask( mask ), _cookie( cookie ), _name( name )
66{
67 qDebug( "OFileNotificationEvent()" );
68}
69
70
71OFileNotificationEvent::~OFileNotificationEvent()
72{
73 qDebug( "~OFileNotificationEvent()" );
74}
75
76//=================================================================================================
77// OFileNotification
78//=================================================================================================
61OFileNotification::OFileNotification( QObject* parent, const char* name ) 79OFileNotification::OFileNotification( QObject* parent, const char* name )
62 :QObject( parent, name ), _active( false ), _multi( true ) 80 :QObject( parent, name ), _active( false ), _multi( true )
63{ 81{
64 qDebug( "OFileNotification::OFileNotification()" ); 82 qDebug( "OFileNotification::OFileNotification()" );
65} 83}
66 84
67 85
68OFileNotification::~OFileNotification() 86OFileNotification::~OFileNotification()
69{ 87{
70 stop(); 88 stop();
71 qDebug( "OFileNotification::~OFileNotification()" ); 89 qDebug( "OFileNotification::~OFileNotification()" );
72} 90}
73 91
74 92
75bool OFileNotification::isActive() const 93bool OFileNotification::isActive() const
76{ 94{
77 return _active; 95 return _active;
78} 96}
79 97
80 98
81int OFileNotification::watch( const QString& path, bool sshot, OFileNotificationType type ) 99int OFileNotification::watch( const QString& path, bool sshot, OFileNotificationType type )
82{ 100{
83 // check if path exists and is a regular file 101 // check if path exists and is a regular file
84 struct stat s; 102 struct stat s;
85 if ( ::stat( (const char*) path, &s ) == -1 ) 103 if ( ::stat( (const char*) path, &s ) == -1 )
86 { 104 {
87 qWarning( "OFileNotification::watch(): Can't watch '%s': %s.", (const char*) path, strerror( errno ) ); 105 qWarning( "OFileNotification::watch(): Can't watch '%s': %s.", (const char*) path, strerror( errno ) );
88 return -1; 106 return -1;
89 } 107 }
90 if ( !S_ISREG( s.st_mode ) ) 108 if ( !S_ISREG( s.st_mode ) )
91 { 109 {
92 qWarning( "OFileNotification::watch(): Can't watch '%s': %s.", (const char*) path, "not a regular file" ); 110 qWarning( "OFileNotification::watch(): Can't watch '%s': %s.", (const char*) path, "not a regular file" );
93 return -1; 111 return -1;
94 } 112 }
95 113
96 return startWatching( path, sshot, type ); 114 return startWatching( path, sshot, type );
97} 115}
98 116
99 117
100int OFileNotification::startWatching( const QString& path, bool sshot, OFileNotificationType type ) 118int OFileNotification::startWatching( const QString& path, bool sshot, OFileNotificationType type )
101{ 119{
102 if ( notification_list.isEmpty() ) 120 if ( notification_list.isEmpty() )
103 { 121 {
104 OFileNotification::registerEventHandler(); 122 OFileNotification::registerEventHandler();
105 } 123 }
106 124
107 struct inotify_watch_request iwr; 125 struct inotify_watch_request iwr;
108 ::memset( &iwr, 0, sizeof iwr ); 126 ::memset( &iwr, 0, sizeof iwr );
109 iwr.name = const_cast<char*>( (const char*) path ); 127 iwr.name = const_cast<char*>( (const char*) path );
110 iwr.mask = type; 128 iwr.mask = type;
111 129
112 _wd = ::ioctl( OFileNotification::_fd, INOTIFY_WATCH, &iwr ); 130 _wd = ::ioctl( OFileNotification::_fd, INOTIFY_WATCH, &iwr );
113 131
114 if ( _wd < 0 ) 132 if ( _wd < 0 )
115 { 133 {
116 qWarning( "OFileNotification::watch(): inotify can't watch '%s': %s.", (const char*) path, strerror( errno ) ); 134 qWarning( "OFileNotification::watch(): inotify can't watch '%s': %s.", (const char*) path, strerror( errno ) );
117 return -1; 135 return -1;
118 } 136 }
119 137
120 notification_list.insert( _wd, this ); 138 notification_list.insert( _wd, this );
121 _path = path; 139 _path = path;
122 _multi = !sshot; 140 _multi = !sshot;
123 _type = type; 141 _type = type;
124 _active = true; 142 _active = true;
125 qDebug( "OFileNotification::watch(): watching '%s' [wd=%d].", (const char*) path, _wd ); 143 qDebug( "OFileNotification::watch(): watching '%s' [wd=%d].", (const char*) path, _wd );
126 return _wd; 144 return _wd;
127} 145}
128 146
129 147
130void OFileNotification::stop() 148void OFileNotification::stop()
131{ 149{
132 notification_list.remove( _wd ); 150 notification_list.remove( _wd );
133 _path = QString::null; 151 _path = QString::null;
134 _wd = 0; 152 _wd = 0;
135 _active = false; 153 _active = false;
136 if ( notification_list.isEmpty() ) 154 if ( notification_list.isEmpty() )
137 { 155 {
138 OFileNotification::unregisterEventHandler(); 156 OFileNotification::unregisterEventHandler();
139 } 157 }
140} 158}
141 159
142 160
143OFileNotificationType OFileNotification::type() const 161OFileNotificationType OFileNotification::type() const
144{ 162{
145 return _type; 163 return _type;
146} 164}
147 165
148 166
149QString OFileNotification::path() const 167QString OFileNotification::path() const
150{ 168{
151 return _path; 169 return _path;
152} 170}
153 171
154 172
155bool OFileNotification::activate() 173bool OFileNotification::activate( const OFileNotificationEvent* e )
156{ 174{
157 emit triggered( _path ); 175 qDebug( "OFileNotification::activate(): e = ( %s, %d, 0x%08x, %d, %s )", (const char*) _path, e->descriptor(), e->mask(), e->cookie(), (const char*) e->name() );
176
177 // dumb signal
158 _signal.activate(); 178 _signal.activate();
179
180 // generic signal
181 emit triggered( _path, e->mask(), e->name() );
182
183 // specialized signals
184 switch ( e->mask() )
185 {
186 case Access: emit accessed( _path ); break;
187 case Modify: emit modified( _path ); break;
188 case Attrib: emit attributed( _path); break;
189 case CloseWrite: emit closed( _path, true ); break;
190 case CloseNoWrite: emit closed( _path, false ); break;
191 case Open: emit opened( _path ); break;
192 case MovedFrom: emit movedFrom( _path, e->name() ); break;
193 case MovedTo: emit movedTo( _path, e->name() ); break;
194 case DeleteSubdir: emit deletedSubdir( _path, e->name() ); break;
195 case DeleteFile: emit deletedFile( _path, e->name() ); break;
196 case CreateSubdir: emit createdSubdir( _path, e->name() ); break;
197 case CreateFile: emit createdFile( _path, e->name() ); break;
198 case DeleteSelf: emit deleted( _path ); break;
199 case Unmount: emit unmounted( _path ); break;
200 default: assert( 0 );
201 }
202
159 if ( !_multi ) stop(); 203 if ( !_multi ) stop();
204
160 return true; 205 return true;
161} 206}
162 207
163 208
164bool OFileNotification::singleShot( const QString& path, QObject* receiver, const char* member, OFileNotificationType type ) 209bool OFileNotification::singleShot( const QString& path, QObject* receiver, const char* member, OFileNotificationType type )
165{ 210{
166 OFileNotification* ofn = new OFileNotification(); 211 OFileNotification* ofn = new OFileNotification();
167 ofn->_signal.connect( receiver, member ); 212 ofn->_signal.connect( receiver, member );
168 return ofn->watch( path, true, type ) != -1; 213 return ofn->watch( path, true, type ) != -1;
169} 214}
170 215
171 216
172void OFileNotification::inotifyEventHandler() 217void OFileNotification::inotifyEventHandler()
173{ 218{
174 qWarning( "OFileNotification::__eventHandler(): reached." ); 219 qDebug( "OFileNotification::inotifyEventHandler(): reached." );
175 220
176 char buffer[16384]; 221 char buffer[16384];
177 size_t buffer_i; 222 size_t buffer_i;
178 struct inotify_event *pevent, *event; 223 struct inotify_event *pevent, *event;
179 ssize_t r; 224 ssize_t r;
180 size_t event_size; 225 size_t event_size;
181 int count = 0; 226 int count = 0;
182 227
183 r = ::read(_fd, buffer, 16384); 228 r = ::read(_fd, buffer, 16384);
184 229
185 if ( r <= 0 ) 230 if ( r <= 0 )
186 return; 231 return;
187 232
188 buffer_i = 0; 233 buffer_i = 0;
189 while ( buffer_i < r ) 234 while ( buffer_i < r )
190 { 235 {
191 /* Parse events and queue them ! */ 236 pevent = (struct inotify_event *)&buffer[buffer_i];
192 pevent = (struct inotify_event *)&buffer[buffer_i]; 237 event_size = sizeof(struct inotify_event) + pevent->len;
193 event_size = sizeof(struct inotify_event) + pevent->len; 238 OFileNotificationEvent* e = new OFileNotificationEvent( notification_list[ pevent->wd ], pevent->wd, pevent->mask,
194 qDebug( "pevent->len = %d\n", pevent->len); 239 pevent->cookie, pevent->len ? pevent->name : 0 );
195 240 e->activate();
196 OFileNotification* fn = notification_list[ pevent->wd ]; 241 buffer_i += event_size;
197 if ( fn ) 242 count++;
198 fn->activate();
199 else
200 assert( false );
201
202 //event = malloc(event_size);
203 //memmove(event, pevent, event_size);
204 //queue_enqueue(event, q);
205 buffer_i += event_size;
206 count++;
207 } 243 }
208 244
209 qDebug( "received %d events...", count ); 245 qDebug( "OFileNotification::inotifyEventHandler(): processed %d events", count );
210 return;
211} 246}
212 247
213 248
214bool OFileNotification::registerEventHandler() 249bool OFileNotification::registerEventHandler()
215{ 250{
216 OFileNotification::_fd = ::open( INOTIFY_DEVICE, O_RDONLY ); 251 OFileNotification::_fd = ::open( INOTIFY_DEVICE, O_RDONLY );
217 if ( OFileNotification::_fd < 0 ) 252 if ( OFileNotification::_fd < 0 )
218 { 253 {
219 qWarning( "OFileNotification::registerEventHandler(): couldn't register event handler: %s", strerror( errno ) ); 254 qWarning( "OFileNotification::registerEventHandler(): couldn't register event handler: %s", strerror( errno ) );
220 return false; 255 return false;
221 } 256 }
222 257
223 OFileNotification::_sn = new QSocketNotifier( _fd, QSocketNotifier::Read, this, "inotify event" ); 258 OFileNotification::_sn = new QSocketNotifier( _fd, QSocketNotifier::Read, this, "inotify event" );
224 connect( OFileNotification::_sn, SIGNAL( activated(int) ), this, SLOT( inotifyEventHandler() ) ); 259 connect( OFileNotification::_sn, SIGNAL( activated(int) ), this, SLOT( inotifyEventHandler() ) );
225 260
226 qDebug( "OFileNotification::registerEventHandler(): done" ); 261 qDebug( "OFileNotification::registerEventHandler(): done" );
227 return true; 262 return true;
228} 263}
229 264
230 265
231void OFileNotification::unregisterEventHandler() 266void OFileNotification::unregisterEventHandler()
232{ 267{
233 if ( _sn ) delete _sn; 268 if ( _sn ) delete _sn;
234 if ( OFileNotification::_fd ) 269 if ( OFileNotification::_fd )
235 ::close( OFileNotification::_fd ); 270 ::close( OFileNotification::_fd );
236 qDebug( "OFileNotification::unregisterEventHandler(): done" ); 271 qDebug( "OFileNotification::unregisterEventHandler(): done" );
237} 272}
238 273
239//================================================================================================= 274//=================================================================================================
240// ODirNotification 275// ODirNotification
241//================================================================================================= 276//=================================================================================================
242ODirNotification::ODirNotification( QObject* parent, const char* name ) 277ODirNotification::ODirNotification( QObject* parent, const char* name )
243 :QObject( parent, name ) 278 :QObject( parent, name )
244{ 279{
245 qDebug( "ODirNotification::ODirNotification()" ); 280 qDebug( "ODirNotification::ODirNotification()" );
246} 281}
247 282
248 283
249ODirNotification::~ODirNotification() 284ODirNotification::~ODirNotification()
250{ 285{
251 qDebug( "ODirNotification::~ODirNotification()" ); 286 qDebug( "ODirNotification::~ODirNotification()" );
252} 287}
253 288
254 289
255int ODirNotification::watch( const QString& path, bool sshot, OFileNotificationType type, int recurse ) 290int ODirNotification::watch( const QString& path, bool sshot, OFileNotificationType type, int recurse )
256{ 291{
257 qDebug( "ODirNotification::watch( %s, %d, 0x%08x, %d )", (const char*) path, sshot, type, recurse ); 292 qDebug( "ODirNotification::watch( %s, %d, 0x%08x, %d )", (const char*) path, sshot, type, recurse );
258 293
259 if ( recurse == 0 ) 294 if ( recurse == 0 )
260 { 295 {
261 OFileNotification* fn = new OFileNotification( this, "ODirNotification delegate" ); 296 OFileNotification* fn = new OFileNotification( this, "ODirNotification delegate" );
262 int result = fn->startWatching( path, sshot, type ); 297 int result = fn->startWatching( path, sshot, type );
263 if ( result != -1 ) 298 if ( result != -1 )
264 { 299 {
265 connect( fn, SIGNAL( triggered( const QString& ) ), this, SIGNAL( triggered( const QString& ) ) ); 300 connect( fn, SIGNAL( triggered( const QString&, unsigned int, const QString& ) ), this, SIGNAL( triggered( const QString&, unsigned int, const QString& ) ) );
266 return result; 301 connect( fn, SIGNAL( accessed( const QString& ) ), this, SIGNAL( accessed( const QString& ) ) );
302 connect( fn, SIGNAL( modified( const QString& ) ), this, SIGNAL( modified( const QString& ) ) );
303 connect( fn, SIGNAL( attributed( const QString& ) ), this, SIGNAL( attributed( const QString& ) ) );
304 connect( fn, SIGNAL( closed( const QString&, bool ) ), this, SIGNAL( closed( const QString&, bool ) ) );
305 connect( fn, SIGNAL( opened( const QString& ) ), this, SIGNAL( opened( const QString& ) ) );
306 connect( fn, SIGNAL( movedTo( const QString&, const QString& ) ), this, SIGNAL( movedTo( const QString&, const QString& ) ) );
307 connect( fn, SIGNAL( movedFrom( const QString&, const QString& ) ), this, SIGNAL( movedFrom( const QString&, const QString& ) ) );
308 connect( fn, SIGNAL( deletedSubdir( const QString&, const QString& ) ), this, SIGNAL( deletedSubdir( const QString&, const QString& ) ) );
309 connect( fn, SIGNAL( deletedFile( const QString&, const QString& ) ), this, SIGNAL( deletedFile( const QString&, const QString& ) ) );;
310 connect( fn, SIGNAL( createdSubdir( const QString&, const QString& ) ), this, SIGNAL( createdSubdir( const QString&, const QString& ) ) );
311 connect( fn, SIGNAL( createdFile( const QString&, const QString& ) ), this, SIGNAL( createdFile( const QString&, const QString& ) ) );
312 connect( fn, SIGNAL( deleted( const QString& ) ), this, SIGNAL( deleted( const QString& ) ) );
313 connect( fn, SIGNAL( unmounted( const QString& ) ), this, SIGNAL( unmounted( const QString& ) ) );
267 } 314 }
315 return result;
268 } 316 }
269 else 317 else
270 { 318 {
271 qDebug( "ODirNotification::watch(), recursion not yet implemented... :)" ); 319
272 return -1; 320 return 1;
273 } 321 }
274} 322}
275 323
324
325// void ODirNotification::subdirCreated( const QString& name )
326
327
328/*
329 Love-Trowbridge recursive directory scanning algorithm:
330
331 Step 1. Start at initial directory foo. Add watch.
332
333 Step 2. Setup handlers for watch created in Step 1.
334 Specifically, ensure that a directory created
335 in foo will result in a handled CREATE_SUBDIR
336 event.
337
338 Step 3. Read the contents of foo.
339
340 Step 4. For each subdirectory of foo read in step 3, repeat
341 step 1.
342
343 Step 5. For any CREATE_SUBDIR event on bar, if a watch is
344 not yet created on bar, repeat step 1 on bar.
345*/
346
347
276} // namespace Ui 348} // namespace Ui
277 349
278} // namespace Opie 350} // namespace Opie
diff --git a/libopie2/opiecore/ofilenotify.h b/libopie2/opiecore/ofilenotify.h
index 3eb917e..5bbf421 100644
--- a/libopie2/opiecore/ofilenotify.h
+++ b/libopie2/opiecore/ofilenotify.h
@@ -1,238 +1,289 @@
1/* 1/*
2                This file is part of the Opie Project 2                This file is part of the Opie Project
3 =. Copyright (C) 2004-2005 Michael 'Mickey' Lauer <mickey@Vanille.de> 3 =. Copyright (C) 2004-2005 Michael 'Mickey' Lauer <mickey@Vanille.de>
4 .=l. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 .=l. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5          .>+-= 5          .>+-=
6_;:,     .>    :=|. This program is free software; you can 6_;:,     .>    :=|. This program is free software; you can
7.> <`_,   >  .   <= redistribute it and/or modify it under 7.> <`_,   >  .   <= redistribute it and/or modify it under
8:`=1 )Y*s>-.--   : the terms of the GNU Library General Public 8:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
9.="- .-=="i,     .._ License as published by the Free Software 9.="- .-=="i,     .._ License as published by the Free Software
10- .   .-<_>     .<> Foundation; version 2 of the License. 10- .   .-<_>     .<> Foundation; version 2 of the License.
11    ._= =}       : 11    ._= =}       :
12   .%`+i>       _;_. 12   .%`+i>       _;_.
13   .i_,=:_.      -<s. This program is distributed in the hope that 13   .i_,=:_.      -<s. This program is distributed in the hope that
14    +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY; 14    +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY;
15   : ..    .:,     . . . without even the implied warranty of 15   : ..    .:,     . . . without even the implied warranty of
16   =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A 16   =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
17 _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU 17 _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU
18..}^=.=       =       ; Library General Public License for more 18..}^=.=       =       ; Library General Public License for more
19++=   -.     .`     .: details. 19++=   -.     .`     .: details.
20:     =  ...= . :.=- 20:     =  ...= . :.=-
21-.   .:....=;==+<; You should have received a copy of the GNU 21-.   .:....=;==+<; You should have received a copy of the GNU
22 -_. . .   )=.  = Library General Public License along with 22 -_. . .   )=.  = Library General Public License along with
23   --        :-=` this library; see the file COPYING.LIB. 23   --        :-=` this library; see the file COPYING.LIB.
24 If not, write to the Free Software Foundation, 24 If not, write to the Free Software Foundation,
25 Inc., 59 Temple Place - Suite 330, 25 Inc., 59 Temple Place - Suite 330,
26 Boston, MA 02111-1307, USA. 26 Boston, MA 02111-1307, USA.
27*/ 27*/
28 28
29#ifndef OFILENOTIFY_H 29#ifndef OFILENOTIFY_H
30#define OFILENOTIFY_H 30#define OFILENOTIFY_H
31#if defined (__GNUC__) && (__GNUC__ < 3) 31#if defined (__GNUC__) && (__GNUC__ < 3)
32#define _GNU_SOURCE 32#define _GNU_SOURCE
33#endif 33#endif
34 34
35#include "linux_inotify.h" 35#include "linux_inotify.h"
36 36
37/* QT */ 37/* QT */
38#include <qsocketnotifier.h> 38#include <qsocketnotifier.h>
39#include <qsignal.h> 39#include <qsignal.h>
40#include <qstring.h> 40#include <qstring.h>
41 41
42namespace Opie { 42namespace Opie {
43namespace Core { 43namespace Core {
44 44
45class OFileNotificationEvent;
46
45/*====================================================================================== 47/*======================================================================================
46 * OFileNotificationType 48 * OFileNotificationType
47 *======================================================================================*/ 49 *======================================================================================*/
48 50
49/** 51/**
50 * @brief An enumerate for the different types of file notifications 52 * @brief An enumerate for the different types of file notifications
51 * 53 *
52 * This enumerate provides a means to specify the type of events that you are interest in. 54 * This enumerate provides a means to specify the type of events that you are interest in.
53 * Valid values are: 55 * Valid values are:
54 * <ul> 56 * <ul>
55 * <li>Access: The file was accessed (read) 57 * <li>Access: The file was accessed (read)
56 * <li>Modify The file was modified (write,truncate) 58 * <li>Modify The file was modified (write,truncate)
57 * <li>Attrib = The file had its attributes changed (chmod,chown,chgrp) 59 * <li>Attrib = The file had its attributes changed (chmod,chown,chgrp)
58 * <li>CloseWrite = Writable file was closed 60 * <li>CloseWrite = Writable file was closed
59 * <li>CloseNoWrite = Unwritable file was closed 61 * <li>CloseNoWrite = Unwritable file was closed
60 * <li>Open = File was opened 62 * <li>Open = File was opened
61 * <li>MovedFrom = File was moved from X 63 * <li>MovedFrom = File was moved from X
62 * <li>MovedTo = File was moved to Y 64 * <li>MovedTo = File was moved to Y
63 * <li>DeleteSubdir = Subdir was deleted 65 * <li>DeleteSubdir = Subdir was deleted
64 * <li>DeleteFile = Subfile was deleted 66 * <li>DeleteFile = Subfile was deleted
65 * <li>CreateSubdir = Subdir was created 67 * <li>CreateSubdir = Subdir was created
66 * <li>CreateFile = Subfile was created 68 * <li>CreateFile = Subfile was created
67 * <li>DeleteSelf = Self was deleted 69 * <li>DeleteSelf = Self was deleted
68 * <li>Unmount = The backing filesystem was unmounted 70 * <li>Unmount = The backing filesystem was unmounted
69 * </ul> 71 * </ul>
70 * 72 *
71 **/ 73 **/
72 74
73enum OFileNotificationType 75enum OFileNotificationType
74{ 76{
75 Access = IN_ACCESS, 77 Access = IN_ACCESS,
76 Modify = IN_MODIFY, 78 Modify = IN_MODIFY,
77 Attrib = IN_ATTRIB, 79 Attrib = IN_ATTRIB,
78 CloseWrite = IN_CLOSE_WRITE, 80 CloseWrite = IN_CLOSE_WRITE,
79 CloseNoWrite = IN_CLOSE_NOWRITE, 81 CloseNoWrite = IN_CLOSE_NOWRITE,
80 Open = IN_OPEN, 82 Open = IN_OPEN,
81 MovedFrom = IN_MOVED_FROM, 83 MovedFrom = IN_MOVED_FROM,
82 MovedTo = IN_MOVED_TO, 84 MovedTo = IN_MOVED_TO,
83 DeleteSubdir = IN_DELETE_SUBDIR, 85 DeleteSubdir = IN_DELETE_SUBDIR,
84 DeleteFile = IN_DELETE_FILE, 86 DeleteFile = IN_DELETE_FILE,
85 CreateSubdir = IN_CREATE_SUBDIR, 87 CreateSubdir = IN_CREATE_SUBDIR,
86 CreateFile = IN_CREATE_FILE, 88 CreateFile = IN_CREATE_FILE,
87 DeleteSelf = IN_DELETE_SELF, 89 DeleteSelf = IN_DELETE_SELF,
88 Unmount = IN_UNMOUNT, 90 Unmount = IN_UNMOUNT,
89 _QueueOverflow = IN_Q_OVERFLOW, /* Internal, don't use this in client code */ 91 _QueueOverflow = IN_Q_OVERFLOW, /* Internal, don't use this in client code */
90 _Ignored = IN_IGNORED, /* Internal, don't use this in client code */ 92 _Ignored = IN_IGNORED, /* Internal, don't use this in client code */
91}; 93};
92 94
93/*====================================================================================== 95/*======================================================================================
94 * OFileNotification 96 * OFileNotification
95 *======================================================================================*/ 97 *======================================================================================*/
96 98
97/** 99/**
98 * @brief Represents a file notification 100 * @brief Represents a file notification
99 * 101 *
100 * This class allows to watch for events happening to files. 102 * This class allows to watch for events happening to files.
101 * It uses the inotify linux (2.6.x) kernel interface. 103 * It uses the inotify linux (2.6.x) kernel interface.
102 * 104 *
103 * @see http://www.kernel.org/pub/linux/kernel/people/rml/inotify/ 105 * @see http://www.kernel.org/pub/linux/kernel/people/rml/inotify/
104 * 106 *
105 * @author Michael 'Mickey' Lauer <mickey@vanille.de> 107 * @author Michael 'Mickey' Lauer <mickey@vanille.de>
106 * 108 *
107 **/ 109 **/
108 110
109class OFileNotification : public QObject 111class OFileNotification : public QObject
110{ 112{
111 Q_OBJECT 113 Q_OBJECT
112 114
113 public: 115 public:
114 OFileNotification( QObject* parent = 0, const char* name = 0 ); 116 OFileNotification( QObject* parent = 0, const char* name = 0 );
115 ~OFileNotification(); 117 ~OFileNotification();
116 /** 118 /**
117 * This static function calls a slot when an event with @a type happens to file @a path. 119 * This static function calls a slot when an event with @a type happens to file @a path.
118 * 120 *
119 * It is very convenient to use this function because you do not need to 121 * It is very convenient to use this function because you do not need to
120 * bother with a timerEvent or to create a local QTimer object. 122 * bother with a timerEvent or to create a local QTimer object.
121 * 123 *
122 * Example: 124 * Example:
123 * <pre> 125 * <pre>
124 * 126 *
125 * #include <opie2/oapplication.h> 127 * #include <opie2/oapplication.h>
126 * #include <opie2/ofilenotify.h> 128 * #include <opie2/ofilenotify.h>
127 * using namespace Opie::Core; 129 * using namespace Opie::Core;
128 * 130 *
129 * int main( int argc, char **argv ) 131 * int main( int argc, char **argv )
130 * { 132 * {
131 * OApplication a( argc, argv, "File Notification Example" ); 133 * OApplication a( argc, argv, "File Notification Example" );
132 * OFileNotification::singleShot( "/tmp/quit", &a, SLOT(quit()), Access ); 134 * OFileNotification::singleShot( "/tmp/quit", &a, SLOT(quit()), Access );
133 * ... // create and show your widgets 135 * ... // create and show your widgets
134 * return a.exec(); 136 * return a.exec();
135 * } 137 * }
136 * </pre> 138 * </pre>
137 * 139 *
138 * This sample program automatically terminates when the file "/tmp/quit" has been accessed. 140 * This sample program automatically terminates when the file "/tmp/quit" has been accessed.
139 * 141 *
140 * 142 *
141 * The @a receiver is the receiving object and the @a member is the slot. 143 * The @a receiver is the receiving object and the @a member is the slot.
142 **/ 144 **/
143 static bool singleShot( const QString& path, QObject* receiver, const char* member, OFileNotificationType type = Modify ); 145 static bool singleShot( const QString& path, QObject* receiver, const char* member, OFileNotificationType type = Modify );
144 /** 146 /**
145 * Starts to watch for @a type changes to @a path. Set @a sshot to True if you want to be notified only once. 147 * Starts to watch for @a type changes to @a path. Set @a sshot to True if you want to be notified only once.
146 * Note that in that case it may be more convenient to use @ref OFileNotification::singleShot() then. 148 * Note that in that case it may be more convenient to use @ref OFileNotification::singleShot() then.
147 **/ 149 **/
148 int watch( const QString& path, bool sshot = false, OFileNotificationType type = Modify ); 150 int watch( const QString& path, bool sshot = false, OFileNotificationType type = Modify );
149 /** 151 /**
150 * Stop watching for file events. 152 * Stop watching for file events.
151 **/ 153 **/
152 void stop(); 154 void stop();
153 /** 155 /**
154 * @returns the notification type as set by @ref start(). 156 * @returns the notification type as set by @ref start().
155 **/ 157 **/
156 OFileNotificationType type() const; 158 OFileNotificationType type() const;
157 /** 159 /**
158 * @returns the path to the file being watched by this instance. 160 * @returns the path to the file being watched by this instance.
159 **/ 161 **/
160 QString path() const; 162 QString path() const;
161 /** 163 /**
162 * @returns if a file is currently being watched. 164 * @returns if a file is currently being watched.
163 **/ 165 **/
164 bool isActive() const; 166 bool isActive() const;
165 /** 167 /**
166 * @internal 168 * @internal
167 */ 169 */
168 int startWatching( const QString& path, bool sshot = false, OFileNotificationType type = Modify ); 170 int startWatching( const QString& path, bool sshot = false, OFileNotificationType type = Modify );
169 171
170 signals: 172 signals:
171 /** 173 void triggered( const QString&, unsigned int, const QString& );
172 * This signal is emitted if an event happens of the specified type happens to the file being watched. 174 void accessed( const QString& );
173 **/ 175 void modified( const QString& );
174 void triggered( const QString& name ); 176 void attributed( const QString& );
177 void closed( const QString&, bool );
178 void opened( const QString& );
179 void movedTo( const QString&, const QString& );
180 void movedFrom( const QString&, const QString& );
181 void deletedSubdir( const QString&, const QString& );
182 void deletedFile( const QString&, const QString& );
183 void createdSubdir( const QString&, const QString& );
184 void createdFile( const QString&, const QString& );
185 void deleted( const QString& );
186 void unmounted( const QString& );
175 187
176 protected: 188 protected:
177 bool activate(); 189 bool activate( const OFileNotificationEvent* e );
178 190
179 private slots: 191 private slots:
180 void inotifyEventHandler(); 192 void inotifyEventHandler();
181 193
182 private: 194 private:
183 bool registerEventHandler(); 195 bool registerEventHandler();
184 void unregisterEventHandler(); 196 void unregisterEventHandler();
185 197
186 QString _path; 198 QString _path;
187 OFileNotificationType _type; 199 OFileNotificationType _type;
188 QSignal _signal; 200 QSignal _signal;
189 bool _active; 201 bool _active;
190 bool _multi; 202 bool _multi;
191 static QSocketNotifier* _sn; 203 static QSocketNotifier* _sn;
192 int _wd; // inotify watch descriptor 204 int _wd; // inotify watch descriptor
193 static int _fd; // inotify device descriptor 205 static int _fd; // inotify device descriptor
206
207 friend class OFileNotificationEvent;
194}; 208};
195 209
196/*====================================================================================== 210/*======================================================================================
197 * ODirNotification 211 * ODirNotification
198 *======================================================================================*/ 212 *======================================================================================*/
199 213
200/** 214/**
201 * @brief Represents a directory notification 215 * @brief Represents a directory notification
202 * 216 *
203 * This class allows to watch for events happening to directories 217 * This class allows to watch for events happening to directories
204 * It uses the OFileNotification class 218 * It uses the OFileNotification class
205 * 219 *
206 * @see http://www.kernel.org/pub/linux/kernel/people/rml/inotify/ 220 * @see http://www.kernel.org/pub/linux/kernel/people/rml/inotify/
207 * 221 *
208 * @author Michael 'Mickey' Lauer <mickey@vanille.de> 222 * @author Michael 'Mickey' Lauer <mickey@vanille.de>
209 * 223 *
210 **/ 224 **/
211 225
212class ODirNotification : public QObject 226class ODirNotification : public QObject
213{ 227{
214 Q_OBJECT 228 Q_OBJECT
215 229
216 public: 230 public:
217 ODirNotification( QObject* parent = 0, const char* name = 0 ); 231 ODirNotification( QObject* parent = 0, const char* name = 0 );
218 ~ODirNotification(); 232 ~ODirNotification();
219 /** 233 /**
220 * Starts to watch for @a type changes to @a path. Recurse @a recurse levels down the filesystem tree, 234 * Starts to watch for @a type changes to @a path. Recurse @a recurse levels down the filesystem tree,
221 * use 0 for no recursion and -1 for unlimited recursion. 235 * use 0 for no recursion and -1 for unlimited recursion.
222 * Set @a sshot to True if you want to be notified only once. 236 * Set @a sshot to True if you want to be notified only once.
223 **/ 237 **/
224 int watch( const QString& path, bool sshot = false, OFileNotificationType type = Modify, int recurse = 0 ); 238 int watch( const QString& path, bool sshot = false, OFileNotificationType type = Modify, int recurse = 0 );
225 239
226 signals: 240 signals:
227 /** 241 /**
228 * This signal is emitted if an event happens of the specified type happens to the directory being watched. 242 * This signal is emitted if an event happens of the specified type happens to the directory being watched.
229 **/ 243 **/
230 void triggered( const QString& name ); 244 void triggered( const QString&, unsigned int, const QString& );
245 void accessed( const QString& );
246 void modified( const QString& );
247 void attributed( const QString& );
248 void closed( const QString&, bool );
249 void opened( const QString& );
250 void movedTo( const QString&, const QString& );
251 void movedFrom( const QString&, const QString& );
252 void deletedSubdir( const QString&, const QString& );
253 void deletedFile( const QString&, const QString& );
254 void createdSubdir( const QString&, const QString& );
255 void createdFile( const QString&, const QString& );
256 void deleted( const QString& );
257 void unmounted( const QString& );
258};
259
260/*======================================================================================
261 * OFileNotificationEvent
262 *======================================================================================*/
263
264class OFileNotificationEvent
265{
266 public:
267 OFileNotificationEvent( OFileNotification* parent, int wd, unsigned int mask, unsigned int cookie, const QString& name );
268 ~OFileNotificationEvent();
269 OFileNotification* parent() const { return _parent; };
270 int descriptor() const { return _wd; };
271 unsigned int mask() const { return _mask; };
272 unsigned int cookie() const { return _cookie; };
273 QString name() const { return _name; };
274 void activate() { _parent->activate( this ); };
275
276 private:
277 OFileNotification* _parent;
278 int _wd;
279 unsigned int _mask;
280 unsigned int _cookie;
281 QString _name;
231}; 282};
232 283
233 284
234} 285}
235} 286}
236 287
237#endif 288#endif
238 289