From c89026c0189dd8eabee7ae1bc5b47a4eeaf77685 Mon Sep 17 00:00:00 2001 From: nemu Date: Fri, 22 May 2009 11:38:21 +0000 Subject: [PATCH] first primitive file watcher implemented --- src/musrgui/PFileWatcher.cpp | 117 +++++++++++++++++++++++++++++++++++ src/musrgui/PFileWatcher.h | 66 ++++++++++++++++++++ src/musrgui/PSubTextEdit.cpp | 1 + src/musrgui/PSubTextEdit.h | 5 ++ src/musrgui/PTextEdit.cpp | 55 +++++++++++++++- src/musrgui/PTextEdit.h | 7 ++- src/musrgui/musrgui.pro | 4 +- 7 files changed, 252 insertions(+), 3 deletions(-) create mode 100644 src/musrgui/PFileWatcher.cpp create mode 100644 src/musrgui/PFileWatcher.h diff --git a/src/musrgui/PFileWatcher.cpp b/src/musrgui/PFileWatcher.cpp new file mode 100644 index 00000000..d79267bd --- /dev/null +++ b/src/musrgui/PFileWatcher.cpp @@ -0,0 +1,117 @@ +/**************************************************************************** + + PFileWatcher.cpp + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +*****************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2009 by Andreas Suter * + * andreas.suter@psi.ch * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include +#include +#include +#include + +#include + +#include "PFileWatcher.h" + +//---------------------------------------------------------------------------------------------------- +/** + *

+ */ +PFileWatcher::PFileWatcher(const QString &fileName, const QDateTime &lastModified) : fFileName(fileName), fLastModified(lastModified) +{ + fFileInfo = 0; + fFileInfo = new QFileInfo(fFileName); + if (!fFileInfo) { + fValid = false; + } +} + +//---------------------------------------------------------------------------------------------------- +/** + *

+ */ +PFileWatcher::~PFileWatcher() +{ + if (fFileInfo) { + delete fFileInfo; + fFileInfo = 0; + } +} + +//---------------------------------------------------------------------------------------------------- +/** + *

+ */ +bool PFileWatcher::modified() +{ + bool result = false; + + fFileInfo->refresh(); + + if (fFileInfo->lastModified() > fLastModified) + result = true; + + return result; +} + +//---------------------------------------------------------------------------------------------------- +/** + *

+ */ +void PFileWatcher::modified(int timeout) +{ + fTimerCheck = new QTimer(this); + + connect( fTimerCheck, SIGNAL(timeout()), this, SLOT(checkIfModified()) ); + QTimer::singleShot(timeout * 1000, this, SLOT(stopFileCheck())); + + fTimerCheck->start(1000); +} + +//---------------------------------------------------------------------------------------------------- +/** + *

+ */ +void PFileWatcher::checkIfModified() +{ + fFileInfo->refresh(); + + if (fFileInfo->lastModified() > fLastModified) { + fTimerCheck->stop(); + emit changed(); + } +} + +//---------------------------------------------------------------------------------------------------- +/** + *

+ */ +void PFileWatcher::stopFileCheck() +{ + fTimerCheck->stop(); +} diff --git a/src/musrgui/PFileWatcher.h b/src/musrgui/PFileWatcher.h new file mode 100644 index 00000000..79b23ec5 --- /dev/null +++ b/src/musrgui/PFileWatcher.h @@ -0,0 +1,66 @@ +/**************************************************************************** + + PFileWatcher.h + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +*****************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2009 by Andreas Suter * + * andreas.suter@psi.ch * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _PFILEWATCHER_H_ +#define _PFILEWATCHER_H_ + +#include +#include + +class PFileWatcher : public QObject +{ + Q_OBJECT + + public: + PFileWatcher(const QString &fileName, const QDateTime &lastModified); + virtual ~PFileWatcher(); + + virtual bool isValid() { return fValid; } + virtual bool modified(); + virtual void modified(int timeout); + + signals: + void changed(); + + private slots: + void checkIfModified(); + void stopFileCheck(); + + private: + bool fValid; + QString fFileName; + QFileInfo *fFileInfo; + QDateTime fLastModified; + + QTimer *fTimerCheck; +}; + +#endif // _PFILEWATCHER_H_ diff --git a/src/musrgui/PSubTextEdit.cpp b/src/musrgui/PSubTextEdit.cpp index ebac4765..a3f93971 100644 --- a/src/musrgui/PSubTextEdit.cpp +++ b/src/musrgui/PSubTextEdit.cpp @@ -60,6 +60,7 @@ PSubTextEdit::PSubTextEdit(PAdmin *admin, QTextEdit(parent, name), fAdmin(admin) { +// fLastModified = QDateTime::fromString("1900-01-01 00:00:00"); } //---------------------------------------------------------------------------------------------------- diff --git a/src/musrgui/PSubTextEdit.h b/src/musrgui/PSubTextEdit.h index f4d33f72..48edff74 100644 --- a/src/musrgui/PSubTextEdit.h +++ b/src/musrgui/PSubTextEdit.h @@ -33,6 +33,7 @@ #define _PSUBTEXTEDIT_H_ #include +#include #include "PAdmin.h" @@ -43,6 +44,9 @@ class PSubTextEdit : public QTextEdit public: PSubTextEdit(PAdmin *admin = 0, QWidget *parent = 0, const char *name = 0); + void setLastModified(const QDateTime &lastModified) { fLastModified = lastModified; } + QDateTime getLastModified() const { return fLastModified; } + protected: virtual QPopupMenu *createPopupMenu( const QPoint &pos); @@ -62,6 +66,7 @@ class PSubTextEdit : public QTextEdit private: PAdmin *fAdmin; + QDateTime fLastModified; }; #endif // _PSUBTEXTEDIT_H_ diff --git a/src/musrgui/PTextEdit.cpp b/src/musrgui/PTextEdit.cpp index 12547f65..7459efbe 100644 --- a/src/musrgui/PTextEdit.cpp +++ b/src/musrgui/PTextEdit.cpp @@ -29,8 +29,10 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ +/* #include using namespace std; +*/ #include #include @@ -57,6 +59,7 @@ using namespace std; #include #include "PTextEdit.h" +#include "PFileWatcher.h" #include "PSubTextEdit.h" #include "PAdmin.h" #include "PFindDialog.h" @@ -109,6 +112,8 @@ PTextEdit::PTextEdit( QWidget *parent, const char *name ) fMsr2DataParam = 0; fFindReplaceData = 0, + fFileWatcher = 0; + fKeepMinuit2Output = false; fDump = 0; // 0 = no dump, 1 = ascii dump, 2 = root dump @@ -134,6 +139,8 @@ PTextEdit::PTextEdit( QWidget *parent, const char *name ) } else { fileNew(); } + + connect( fTabWidget, SIGNAL( currentChanged(QWidget*) ), this, SLOT( checkIfModified(QWidget*) )); } //---------------------------------------------------------------------------------------------------- @@ -150,6 +157,10 @@ PTextEdit::~PTextEdit() delete fFindReplaceData; fFindReplaceData = 0; } + if (fFileWatcher) { + delete fFileWatcher; + fFileWatcher = 0; + } } //---------------------------------------------------------------------------------------------------- @@ -394,7 +405,10 @@ void PTextEdit::load( const QString &f, const int index ) if ( !QFile::exists( f ) ) return; + QFileInfo info(f); + PSubTextEdit *edit = new PSubTextEdit( fAdmin ); + edit->setLastModified(info.lastModified()); edit->setTextFormat( PlainText ); edit->setFamily("Courier"); edit->setPointSize(11); // 11pt @@ -524,6 +538,12 @@ void PTextEdit::fileReload() fileClose(false); load(fln, index); } + + // clean up file watcher object if present + if (fFileWatcher) { + delete fFileWatcher; + fFileWatcher = 0; + } } //---------------------------------------------------------------------------------------------------- @@ -1534,6 +1554,11 @@ void PTextEdit::musrT0() cmd += str + " &"; system(cmd.latin1()); + + QString fln = *fFilenames.find( currentEditor() ); + fFileWatcher = new PFileWatcher(fln, currentEditor()->getLastModified()); + fFileWatcher->modified(3600); + connect(fFileWatcher, SIGNAL( changed() ), this, SLOT( fileReload() )); } //---------------------------------------------------------------------------------------------------- @@ -1675,7 +1700,7 @@ void PTextEdit::fontChanged( const QFont &f ) /** *

*/ -void PTextEdit::textChanged() +void PTextEdit::textChanged(const bool forced) { if (!currentEditor()) return; @@ -1691,6 +1716,10 @@ void PTextEdit::textChanged() if ((fTabWidget->label(fTabWidget->currentPageIndex()).find("*") < 0) && currentEditor()->isModified()) fTabWidget->setTabLabel(fTabWidget->currentPage(), tabLabel+"*"); + + if ((fTabWidget->label(fTabWidget->currentPageIndex()).find("*") < 0) && + forced) + fTabWidget->setTabLabel(fTabWidget->currentPage(), tabLabel+"*"); } //---------------------------------------------------------------------------------------------------- @@ -1744,6 +1773,30 @@ void PTextEdit::replaceAll() currentEditor()->setCursorPosition(currentPara, currentIndex); } +//---------------------------------------------------------------------------------------------------- +/** + *

+ */ +void PTextEdit::checkIfModified(QWidget*) +{ + if ( fTabWidget->currentPage() && fTabWidget->currentPage()->inherits( "PSubTextEdit" ) ) { + QString fln = *fFilenames.find( currentEditor() ); + PFileWatcher fw(fln, currentEditor()->getLastModified()); + if (fw.isValid()) { + if (fw.modified()) { + int result = QMessageBox::information( this, "**INFO**", + "File modified on disk. Do you want to reload it?", + QMessageBox::Yes, QMessageBox::No); + if (result == QMessageBox::Yes) { + fileReload(); + } else { + textChanged(true); + } + } + } + } +} + //---------------------------------------------------------------------------------------------------- // END //---------------------------------------------------------------------------------------------------- diff --git a/src/musrgui/PTextEdit.h b/src/musrgui/PTextEdit.h index 97d0881f..391d651d 100644 --- a/src/musrgui/PTextEdit.h +++ b/src/musrgui/PTextEdit.h @@ -36,6 +36,7 @@ #include #include "musrgui.h" +#include "PFileWatcher.h" class PSubTextEdit; class PAdmin; @@ -109,12 +110,14 @@ private slots: void helpAbout(); void fontChanged( const QFont &f ); - void textChanged(); + void textChanged(const bool forced = false); void replace(); void replaceAndClose(); void replaceAll(); + void checkIfModified(QWidget*); + private: PAdmin *fAdmin; @@ -129,6 +132,8 @@ private: QTabWidget *fTabWidget; QMap fFilenames; + + PFileWatcher *fFileWatcher; }; diff --git a/src/musrgui/musrgui.pro b/src/musrgui/musrgui.pro index 77f3307e..224b1b63 100644 --- a/src/musrgui/musrgui.pro +++ b/src/musrgui/musrgui.pro @@ -14,6 +14,7 @@ CONFIG += qt \ debug HEADERS = musrgui.h \ + PFileWatcher.h \ PTextEdit.h \ PSubTextEdit.h \ PAdmin.h \ @@ -32,7 +33,8 @@ HEADERS = musrgui.h \ PMsr2DataDialog.h \ PGetPlotDialog.h -SOURCES = PTextEdit.cpp \ +SOURCES = PFileWatcher.cpp \ + PTextEdit.cpp \ PSubTextEdit.cpp \ PAdmin.cpp \ PFindDialog.cpp \