changeset 14690:ca733a66be7a gui

Fixed bug with not opening the editor when clicking a file from the file browser. Implemented watching the file on disk. * MainWindow: Simplified opening file request calls. * FileEditor: Added new slot that closes tabs without and index and made FileEditorTabs connect to it. * FileEditorTab: Added QFileSystemWatcher and fixed bug with setting modified status on m_modified. Implemented message boxes for the cases that a file has been removed, renamed und modified from outside.
author Jacob Dawid <jacob.dawid@googlemail.com>
date Fri, 25 May 2012 23:56:31 +0200
parents dd19de736ee4
children d6d250812c01
files gui/src/MainWindow.cpp gui/src/editor/FileEditor.cpp gui/src/editor/FileEditor.h gui/src/editor/FileEditorTab.cpp gui/src/editor/FileEditorTab.h
diffstat 5 files changed, 143 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- a/gui/src/MainWindow.cpp	Fri May 25 20:54:36 2012 +0200
+++ b/gui/src/MainWindow.cpp	Fri May 25 23:56:31 2012 +0200
@@ -45,23 +45,13 @@
 void
 MainWindow::newFile ()
 {
-  if (!m_fileEditor->isVisible ())
-    {
-      m_fileEditor->show ();
-    }
   m_fileEditor->requestNewFile ();
-
 }
 
 void
 MainWindow::openFile ()
 {
-  if (!m_fileEditor->isVisible ())
-    {
-      m_fileEditor->show ();
-    }
   m_fileEditor->requestOpenFile ();
-
 }
 
 void
--- a/gui/src/editor/FileEditor.cpp	Fri May 25 20:54:36 2012 +0200
+++ b/gui/src/editor/FileEditor.cpp	Fri May 25 23:56:31 2012 +0200
@@ -75,13 +75,22 @@
   if (fileEditorTab)
     {
       addFileEditorTab (fileEditorTab);
-      fileEditorTab->openFile ();
+      if (!fileEditorTab->openFile ())
+        {
+          // If no file was loaded, remove the tab again.
+          m_tabWidget->removeTab (m_tabWidget->indexOf (fileEditorTab));
+        }
     }
 }
 
 void
 FileEditor::requestOpenFile (QString fileName)
 {
+  if (!isVisible ())
+    {
+      show ();
+    }
+
   FileEditorTab *fileEditorTab = new FileEditorTab (this);
   if (fileEditorTab)
     {
@@ -232,6 +241,18 @@
 }
 
 void
+FileEditor::handleTabCloseRequest ()
+{
+  FileEditorTab *fileEditorTab = dynamic_cast <FileEditorTab*> (sender ());
+  if (fileEditorTab)
+    if (fileEditorTab->close ())
+      {
+        m_tabWidget->removeTab (m_tabWidget->indexOf (fileEditorTab));
+        delete fileEditorTab;
+      }
+}
+
+void
 FileEditor::activeTabChanged (int index)
 {
   Q_UNUSED (index);
@@ -261,7 +282,6 @@
   m_toolBar = new QToolBar (widget);
   m_tabWidget = new QTabWidget (widget);
   m_tabWidget->setTabsClosable (true);
-  //m_longTitle = settings->value ("editor/longWindowTitle",true).toBool ();
 
   // Theme icons with QStyle icons as fallback
   QAction *newAction = new QAction (
@@ -438,6 +458,8 @@
            this, SLOT(handleFileNameChanged(QString)));
   connect (fileEditorTab, SIGNAL (editorStateChanged ()),
            this, SLOT (handleEditorStateChanged ()));
+  connect (fileEditorTab, SIGNAL (closeRequest ()),
+           this, SLOT (handleTabCloseRequest ()));
   m_tabWidget->setCurrentWidget (fileEditorTab);
 }
 
--- a/gui/src/editor/FileEditor.h	Fri May 25 20:54:36 2012 +0200
+++ b/gui/src/editor/FileEditor.h	Fri May 25 23:56:31 2012 +0200
@@ -75,6 +75,7 @@
 
   void handleFileNameChanged (QString fileName);
   void handleTabCloseRequest (int index);
+  void handleTabCloseRequest ();
   void activeTabChanged (int index);
   void handleEditorStateChanged ();
 
--- a/gui/src/editor/FileEditorTab.cpp	Fri May 25 20:54:36 2012 +0200
+++ b/gui/src/editor/FileEditorTab.cpp	Fri May 25 23:56:31 2012 +0200
@@ -82,6 +82,8 @@
            this, SLOT (newTitle (bool)));
   connect (m_editArea, SIGNAL (copyAvailable (bool)),
            this, SLOT (handleCopyAvailable (bool)));
+  connect (&m_fileSystemWatcher, SIGNAL (fileChanged (QString)),
+           this, SLOT (fileHasChanged (QString)));
 
   m_fileName = "";
   newTitle (false);
@@ -105,7 +107,7 @@
   else
     {
       // ignore close event if file is not saved and user cancels closing this window
-      if (checkFileModified ("Close File",QMessageBox::Cancel) == QMessageBox::Cancel)
+      if (checkFileModified ("Close File", QMessageBox::Cancel) == QMessageBox::Cancel)
         {
           event->ignore ();
         }
@@ -117,6 +119,13 @@
 }
 
 void
+FileEditorTab::setFileName (QString fileName)
+{
+  m_fileName = fileName;
+  updateTrackedFile ();
+}
+
+void
 FileEditorTab::handleMarginClicked(int margin, int line, Qt::KeyboardModifiers state)
 {
   Q_UNUSED (state);
@@ -195,6 +204,17 @@
   emit editorStateChanged ();
 }
 
+void
+FileEditorTab::updateTrackedFile ()
+{
+  QStringList trackedFiles = m_fileSystemWatcher.files ();
+  if (!trackedFiles.isEmpty ())
+    m_fileSystemWatcher.removePaths (trackedFiles);
+
+  if (m_fileName != UNNAMED_FILE)
+    m_fileSystemWatcher.addPath (m_fileName);
+}
+
 int
 FileEditorTab::checkFileModified (QString msg, int cancelButton)
 {
@@ -299,10 +319,10 @@
 void
 FileEditorTab::setModified (bool modified)
 {
-  m_modified = modified;
+  m_editArea->setModified (true);
 }
 
-void
+bool
 FileEditorTab::openFile ()
 {
   QString openFileName;
@@ -310,18 +330,29 @@
   fileDialog.setNameFilter(SAVE_FILE_FILTER);
   fileDialog.setAcceptMode(QFileDialog::AcceptOpen);
   fileDialog.setViewMode(QFileDialog::Detail);
-  if ( fileDialog.exec() )
+  if (fileDialog.exec () == QDialog::Accepted)
     {
       openFileName = fileDialog.selectedFiles().at(0);
       if (openFileName.isEmpty ())
-        return;
+        return false;
+
       loadFile(openFileName);
+      return true;
+    }
+  else
+    {
+      return false;
     }
 }
 
 void
 FileEditorTab::loadFile (QString fileName)
 {
+  if (!m_fileEditor->isVisible ())
+    {
+      m_fileEditor->show ();
+    }
+
   QFile file (fileName);
   if (!file.open (QFile::ReadOnly))
     {
@@ -336,35 +367,40 @@
   m_editArea->setText (in.readAll ());
   QApplication::restoreOverrideCursor ();
 
-  m_fileName = fileName;
+  setFileName (fileName);
+  updateTrackedFile ();
+
+
   newTitle (false); // window title (no modification)
-  //m_statusBar->showMessage (tr ("File loaded."), 2000);
   m_editArea->setModified (false); // loaded file is not modified yet
 }
 
 void
 FileEditorTab::newFile ()
 {
-  m_fileName = UNNAMED_FILE;
+  if (!m_fileEditor->isVisible ())
+    {
+      m_fileEditor->show ();
+    }
+
+  setFileName (UNNAMED_FILE);
   newTitle (false); // window title (no modification)
   m_editArea->setText ("");
   m_editArea->setModified (false); // new file is not modified yet
 }
 
-void
-FileEditorTab::saveFile ()
+bool FileEditorTab::saveFile()
 {
-  saveFile (m_fileName);
+  return saveFile (m_fileName);
 }
 
-void
+bool
 FileEditorTab::saveFile (QString saveFileName)
 {
   // it is a new file with the name "<unnamed>" -> call saveFielAs
   if (saveFileName == UNNAMED_FILE || saveFileName.isEmpty ())
     {
-      saveFileAs();
-      return;
+      return saveFileAs();
     }
 
   // open the file for writing
@@ -374,7 +410,7 @@
       QMessageBox::warning (this, tr ("Octave Editor"),
                             tr ("Could not open file %1 for write:\n%2.").
                             arg (saveFileName).arg (file.errorString ()));
-      return;
+      return false;
     }
 
   // save the contents into the file
@@ -382,13 +418,13 @@
   QApplication::setOverrideCursor (Qt::WaitCursor);
   out << m_editArea->text ();
   QApplication::restoreOverrideCursor ();
-  m_fileName = saveFileName;  // save file name for later use
+  setFileName (saveFileName);  // save file name for later use
   newTitle (false);      // set the window title to actual file name (not modified)
-  //m_statusBar->showMessage (tr ("File %1 saved").arg(m_fileName), 2000);
   m_editArea->setModified (false); // files is save -> not modified
+  return true;
 }
 
-void
+bool
 FileEditorTab::saveFileAs ()
 {
   QString saveFileName(m_fileName);
@@ -411,9 +447,12 @@
     {
       saveFileName = fileDialog.selectedFiles ().at (0);
       if (saveFileName.isEmpty ())
-        return;
-      saveFile (saveFileName);
+        return false;
+
+      return saveFile (saveFileName);
     }
+
+  return false;
 }
 
 void
@@ -425,3 +464,51 @@
   m_fileEditor->terminal ()->sendText (QString ("run \'%1\'\n").arg (m_fileName));
   m_fileEditor->terminal ()->setFocus ();
 }
+
+void
+FileEditorTab::fileHasChanged (QString fileName)
+{
+  Q_UNUSED (fileName);
+  if (QFile::exists (m_fileName))
+    {
+      // Prevent popping up multiple message boxes when the file has been changed multiple times.
+      static bool alreadyAsking = false;
+      if (!alreadyAsking)
+        {
+          alreadyAsking = true;
+
+          int decision =
+          QMessageBox::warning (this, tr ("Octave Editor"),
+                                tr ("It seems that \'%1\' has been modified by another application. Do you want to reload it?").
+                                arg (m_fileName), QMessageBox::Yes, QMessageBox::No);
+
+          if (decision == QMessageBox::Yes)
+            {
+              loadFile (m_fileName);
+            }
+
+          alreadyAsking = false;
+        }
+    }
+  else
+    {
+      int decision =
+      QMessageBox::warning (this, tr ("Octave Editor"),
+                            tr ("It seems that \'%1\' has been deleted or renamed. Do you want to save it now?").
+                            arg (m_fileName), QMessageBox::Save, QMessageBox::Close);
+      if (decision == QMessageBox::Save)
+        {
+          if (!saveFileAs ())
+            {
+              setFileName (UNNAMED_FILE);
+              newTitle (true); // window title (no modification)
+              setModified (true);
+              updateTrackedFile ();
+            }
+        }
+      else
+        {
+          emit closeRequest ();
+        }
+    }
+}
--- a/gui/src/editor/FileEditorTab.h	Fri May 25 20:54:36 2012 +0200
+++ b/gui/src/editor/FileEditorTab.h	Fri May 25 23:56:31 2012 +0200
@@ -21,6 +21,7 @@
 #include <Qsci/qsciscintilla.h>
 #include <QWidget>
 #include <QCloseEvent>
+#include <QFileSystemWatcher>
 
 class FileEditor;
 class FileEditorTab : public QWidget
@@ -48,22 +49,27 @@
 
   void setModified (bool modified);
 
-  void openFile ();
+  bool openFile();
   void loadFile (QString fileName);
   void newFile ();
-  void saveFile ();
-  void saveFile (QString saveFileName);
-  void saveFileAs ();
+  bool saveFile ();
+  bool saveFile(QString saveFileName);
+  bool saveFileAs();
   void runFile ();
 
+  void fileHasChanged (QString fileName);
+
 signals:
   void fileNameChanged (QString fileName);
   void editorStateChanged ();
+  void closeRequest ();
 
 protected:
   void closeEvent (QCloseEvent *event);
+  void setFileName (QString fileName);
 
 private:
+  void updateTrackedFile ();
   int checkFileModified (QString msg, int cancelButton);
   void doCommentSelectedText (bool comment);
 
@@ -73,11 +79,10 @@
   QString m_fileName;
   QString m_fileNameShort;
 
-  bool m_modified;
   bool m_longTitle;
   bool m_copyAvailable;
 
-  // TODO: Use QFileSystemWatcher to sync with disc.
+  QFileSystemWatcher m_fileSystemWatcher;
 };
 
 #endif // FILEEDITORTAB_H