Update debugger UI to auto-refresh the directory listing

Review URL: https://codereview.chromium.org/1462633002
diff --git a/debugger/QT/SkDebuggerGUI.cpp b/debugger/QT/SkDebuggerGUI.cpp
index 44dfb93..4422334 100644
--- a/debugger/QT/SkDebuggerGUI.cpp
+++ b/debugger/QT/SkDebuggerGUI.cpp
@@ -56,6 +56,7 @@
     connect(&fActionOpen, SIGNAL(triggered()), this, SLOT(openFile()));
     connect(&fActionDirectory, SIGNAL(triggered()), this, SLOT(toggleDirectory()));
     connect(&fDirectoryWidget, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)), this, SLOT(loadFile(QListWidgetItem *)));
+    connect(&fDirectoryWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(populateDirectoryWidget()));
     connect(&fActionDelete, SIGNAL(triggered()), this, SLOT(actionDelete()));
     connect(&fListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(toggleBreakpoint()));
     connect(&fActionRewind, SIGNAL(triggered()), this, SLOT(actionRewind()));
@@ -285,13 +286,19 @@
 }
 
 void SkDebuggerGUI::loadFile(QListWidgetItem *item) {
-    if (fDirectoryWidgetActive) {
-        fFileName = fPath.toAscii().data();
-        // don't add a '/' to files in the local directory
-        if (fFileName.size() > 0) {
-            fFileName.append("/");
-        }
-        fFileName.append(item->text().toAscii().data());
+    if (item == nullptr) {
+        return;
+    }
+
+    SkString fileName(fPath.toAscii().data());
+    // don't add a '/' to files in the local directory
+    if (fileName.size() > 0) {
+        fileName.append("/");
+    }
+    fileName.append(item->text().toAscii().data());
+
+    if (!fileName.equals(fFileName)) {
+        fFileName = fileName;
         loadPicture(fFileName);
     }
 }
@@ -303,13 +310,11 @@
 }
 
 void SkDebuggerGUI::openFile(const QString &filename) {
-    fDirectoryWidgetActive = false;
     if (!filename.isEmpty()) {
         QFileInfo pathInfo(filename);
         loadPicture(SkString(filename.toAscii().data()));
         setupDirectoryWidget(pathInfo.path());
     }
-    fDirectoryWidgetActive = true;
 }
 
 void SkDebuggerGUI::pauseDrawing(bool isPaused) {
@@ -580,11 +585,8 @@
     fToolBar.addWidget(&fFilter);
     fToolBar.addAction(&fActionCancel);
 
-    // TODO(chudy): Remove static call.
-    fDirectoryWidgetActive = false;
     fFileName = "";
     setupDirectoryWidget("");
-    fDirectoryWidgetActive = true;
 
     // Menu Bar
     fMenuFile.setTitle("File");
@@ -633,13 +635,36 @@
 
 void SkDebuggerGUI::setupDirectoryWidget(const QString& path) {
     fPath = path;
-    QDir dir(path);
+    populateDirectoryWidget();
+
+    // clear the existing watched directory and setup a new directory to watch
+    if (!fDirectoryWatcher.directories().empty()) {
+        fDirectoryWatcher.removePaths(fDirectoryWatcher.directories());
+    }
+    if (!path.isEmpty()) {
+        fDirectoryWatcher.addPath(fPath);
+    }
+}
+
+void SkDebuggerGUI::populateDirectoryWidget() {
+    QDir dir(fPath);
     QRegExp r(".skp");
-    fDirectoryWidget.clear();
     const QStringList files = dir.entryList();
+
+    // check if a file has been removed
+    for (int i = fDirectoryWidget.count() - 1; i >= 0; i--) {
+        QListWidgetItem* item = fDirectoryWidget.item(i);
+        if (!files.contains(item->text())) {
+            fDirectoryWidget.removeItemWidget(item);
+            delete item;
+        }
+    }
+
+    // add any new files
     foreach (QString f, files) {
-        if (f.contains(r))
+        if (f.contains(r) && fDirectoryWidget.findItems(f, Qt::MatchExactly).size() == 0) {
             fDirectoryWidget.addItem(f);
+        }
     }
 }
 
diff --git a/debugger/QT/SkDebuggerGUI.h b/debugger/QT/SkDebuggerGUI.h
index 3dac547..9f00efa 100644
--- a/debugger/QT/SkDebuggerGUI.h
+++ b/debugger/QT/SkDebuggerGUI.h
@@ -19,6 +19,7 @@
 #include "SkRasterWidget.h"
 #include "SkDrawCommandGeometryWidget.h"
 #include "SkSettingsWidget.h"
+#include <QtCore/QFileSystemWatcher>
 #include <QtCore/QSignalMapper>
 #include <QtCore/QVariant>
 #include <QtGui/QAction>
@@ -213,6 +214,12 @@
     void toggleDirectory();
 
     /**
+        Populates the contents of the directory widget with the skp files in the
+        current directory pointed to by fFile.
+     */
+    void populateDirectoryWidget();
+
+    /**
         Filters the list widgets command visibility based on the currently
         active selection.
      */
@@ -262,6 +269,8 @@
     QListWidget fListWidget;
     QListWidget fDirectoryWidget;
 
+    QFileSystemWatcher fDirectoryWatcher;
+
     SkDebugger fDebugger;
     SkCanvasWidget fCanvasWidget;
 
@@ -280,7 +289,6 @@
     QString fPath;
     SkString fFileName;
     SkTDArray<bool> fSkipCommands; // has a specific command been deleted?
-    bool fDirectoryWidgetActive;
 
     QMenuBar fMenuBar;
     QMenu fMenuFile;