19#include "editorwatcher.h"
25#include <tdemessagebox.h>
27#include <tdeprocess.h>
28#include <kuserprofile.h>
30#include <tqsocketnotifier.h>
35#ifdef HAVE_SYS_INOTIFY
37#include <sys/inotify.h>
42#include <sys/inotify.h>
43#include <sys/syscall.h>
44#include <linux/types.h>
52 TQObject * parent, TQWidget *parentWidget) :
55 mMimeType( mimeType ),
56 mOpenWith( openWith ),
58 mParentWidget( parentWidget ),
59 mHaveInotify( false ),
61 mEditorRunning( false ),
62 mFileModified( true ),
65 assert( mUrl.isLocalFile() );
66 connect( &mTimer, TQ_SIGNAL(timeout()), TQ_SLOT(checkEditDone()) );
69bool EditorWatcher::start()
74 KService::Ptr offer = KServiceTypeProfile::preferredService( mMimeType, "Application" );
75 if ( mOpenWith || !offer ) {
76 KOpenWithDlg dlg( list, i18n( "Edit with:"), TQString(), 0 );
79 offer = dlg.service();
86 mInotifyFd = inotify_init();
87 if ( mInotifyFd > 0 ) {
88 mInotifyWatch = inotify_add_watch( mInotifyFd, mUrl.path().latin1(), IN_CLOSE | IN_OPEN | IN_MODIFY );
89 if ( mInotifyWatch >= 0 ) {
90 TQSocketNotifier *sn = new TQSocketNotifier( mInotifyFd, TQSocketNotifier::Read, this );
91 connect( sn, TQ_SIGNAL(activated( int)), TQ_SLOT(inotifyEvent()) );
93 mFileModified = false;
96 kdWarning(5006) << k_funcinfo << "Failed to activate INOTIFY!" << endl;
101 TQStringList params = KRun::processDesktopExec( *offer, list, false );
102 mEditor = new TDEProcess( this );
104 connect( mEditor, TQ_SIGNAL(processExited(TDEProcess*)), TQ_SLOT(editorExited()) );
105 if ( !mEditor->start() )
107 mEditorRunning = true;
113void EditorWatcher::inotifyEvent()
115 assert( mHaveInotify );
119 ioctl( mInotifyFd, FIONREAD, &pending );
120 while ( pending > 0 ) {
121 int size = read( mInotifyFd, buffer, TQMIN( pending, ( int) sizeof(buffer) ) );
127 struct inotify_event * event = ( struct inotify_event *) &buffer[offset];
128 size -= sizeof( struct inotify_event ) + event->len;
129 offset += sizeof( struct inotify_event ) + event->len;
130 if ( event->mask & IN_OPEN )
132 if ( event->mask & IN_CLOSE )
134 if ( event->mask & IN_MODIFY )
135 mFileModified = true;
139 mTimer.start( 500, true );
143void EditorWatcher::editorExited()
145 mEditorRunning = false;
146 mTimer.start( 500, true );
149void EditorWatcher::checkEditDone()
151 if ( mEditorRunning || (mFileOpen && mHaveInotify) || mDone )
158 if ( mEditTime.elapsed() <= 3000 ) {
159 KMessageBox::information(
161 i18n( "KMail is unable to detect when the chosen editor is closed. "
162 "To avoid data loss, editing the attachment will be aborted." ),
163 i18n( "Unable to edit attachment" ),
164 "UnableToEditAttachment" );
168 emit editDone( this );
172#include "editorwatcher.moc"
EditorWatcher(const KURL &url, const TQString &mimeType, bool openWith, TQObject *parent, TQWidget *parentWidget) Constructs an EditorWatcher.
|