Debugger improvements

This CL:
  improves the 'SaveAs' functionality
  allows switching between # and offset indexing in the command list
  minor nit cleanup

R=bsalomon@google.com

Author: robertphillips@google.com

Review URL: https://codereview.chromium.org/211383003

git-svn-id: http://skia.googlecode.com/svn/trunk@13950 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/debugger/QT/SkDebuggerGUI.cpp b/debugger/QT/SkDebuggerGUI.cpp
index 619aa0a..c8ef58b 100644
--- a/debugger/QT/SkDebuggerGUI.cpp
+++ b/debugger/QT/SkDebuggerGUI.cpp
@@ -34,6 +34,7 @@
     , fToolBar(this)
     , fActionOpen(this)
     , fActionBreakpoint(this)
+    , fActionToggleIndexStyle(this)
     , fActionProfile(this)
     , fActionCancel(this)
     , fActionClearBreakpoints(this)
@@ -65,6 +66,7 @@
     , fMenuNavigate(this)
     , fMenuView(this)
     , fBreakpointsActivated(false)
+    , fIndexStyleToggle(false)
     , fDeletesActivated(false)
     , fPause(false)
     , fLoading(false)
@@ -82,6 +84,7 @@
     connect(&fActionStepBack, SIGNAL(triggered()), this, SLOT(actionStepBack()));
     connect(&fActionStepForward, SIGNAL(triggered()), this, SLOT(actionStepForward()));
     connect(&fActionBreakpoint, SIGNAL(triggered()), this, SLOT(actionBreakpoints()));
+    connect(&fActionToggleIndexStyle, SIGNAL(triggered()), this, SLOT(actionToggleIndexStyle()));
     connect(&fActionInspector, SIGNAL(triggered()), this, SLOT(actionInspector()));
     connect(&fActionSettings, SIGNAL(triggered()), this, SLOT(actionSettings()));
     connect(&fFilter, SIGNAL(activated(QString)), this, SLOT(toggleFilter(QString)));
@@ -135,12 +138,19 @@
     }
 }
 
+void SkDebuggerGUI::actionToggleIndexStyle() {
+    fIndexStyleToggle = !fIndexStyleToggle;
+    SkListWidget* list = (SkListWidget*) fListWidget.itemDelegate();
+    list->setIndexStyle(fIndexStyleToggle ? SkListWidget::kIndex_IndexStyle : 
+                                            SkListWidget::kOffset_IndexStyle);
+    fListWidget.update();
+}
+
 void SkDebuggerGUI::showDeletes() {
     fDeletesActivated = !fDeletesActivated;
     for (int row = 0; row < fListWidget.count(); row++) {
         QListWidgetItem *item = fListWidget.item(row);
-        item->setHidden(fDebugger.isCommandVisible(row)
-                && fDeletesActivated);
+        item->setHidden(fDebugger.isCommandVisible(row) && fDeletesActivated);
     }
 }
 
@@ -709,6 +719,9 @@
     fActionBreakpoint.setIcon(breakpoint);
     fActionBreakpoint.setText("Breakpoints");
 
+    fActionToggleIndexStyle.setShortcut(QKeySequence(tr("Ctrl+T")));
+    fActionToggleIndexStyle.setText("Toggle Index Style");
+
     QIcon cancel;
     cancel.addFile(QString::fromUtf8(":/reload.png"), QSize(),
             QIcon::Normal, QIcon::Off);
@@ -906,6 +919,7 @@
     fMenuView.setTitle("View");
     fMenuView.addAction(&fActionBreakpoint);
     fMenuView.addAction(&fActionShowDeletes);
+    fMenuView.addAction(&fActionToggleIndexStyle);
     fMenuView.addAction(&fActionZoomIn);
     fMenuView.addAction(&fActionZoomOut);
 
@@ -966,6 +980,8 @@
 
     // Will this automatically clear out due to nature of refcnt?
     SkTArray<SkString>* commands = fDebugger.getDrawCommandsAsStrings();
+    SkTDArray<size_t>* offsets = fDebugger.getDrawCommandOffsets();
+    SkASSERT(commands->count() == offsets->count());
 
     fActionProfile.setDisabled(false);
 
@@ -976,9 +992,9 @@
      * */
     fDebugger.highlightCurrentCommand(fSettingsWidget.getVisibilityFilter());
 
-    setupListWidget(commands);
-    setupComboBox(commands);
-    setupOverviewText(NULL, 0.0, 1);
+    this->setupListWidget(commands, offsets);
+    this->setupComboBox(commands);
+    this->setupOverviewText(NULL, 0.0, 1);
     fInspectorWidget.setDisabled(false);
     fSettingsWidget.setDisabled(false);
     fMenuEdit.setDisabled(false);
@@ -990,31 +1006,33 @@
     actionPlay();
 }
 
-void SkDebuggerGUI::setupListWidget(SkTArray<SkString>* command) {
+void SkDebuggerGUI::setupListWidget(SkTArray<SkString>* commands, SkTDArray<size_t>* offsets) {
+    SkASSERT(commands->count() == offsets->count());
     fListWidget.clear();
     int counter = 0;
     int indent = 0;
-    for (int i = 0; i < command->count(); i++) {
+    for (int i = 0; i < commands->count(); i++) {
         QListWidgetItem *item = new QListWidgetItem();
-        item->setData(Qt::DisplayRole, (*command)[i].c_str());
+        item->setData(Qt::DisplayRole, (*commands)[i].c_str());
         item->setData(Qt::UserRole + 1, counter++);
 
-        if (0 == strcmp("Restore", (*command)[i].c_str()) ||
-            0 == strcmp("EndCommentGroup", (*command)[i].c_str()) ||
-            0 == strcmp("PopCull", (*command)[i].c_str())) {
+        if (0 == strcmp("Restore", (*commands)[i].c_str()) ||
+            0 == strcmp("EndCommentGroup", (*commands)[i].c_str()) ||
+            0 == strcmp("PopCull", (*commands)[i].c_str())) {
             indent -= 10;
         }
 
         item->setData(Qt::UserRole + 3, indent);
 
-        if (0 == strcmp("Save", (*command)[i].c_str()) ||
-            0 == strcmp("Save Layer", (*command)[i].c_str()) ||
-            0 == strcmp("BeginCommentGroup", (*command)[i].c_str()) ||
-            0 == strcmp("PushCull", (*command)[i].c_str())) {
+        if (0 == strcmp("Save", (*commands)[i].c_str()) ||
+            0 == strcmp("Save Layer", (*commands)[i].c_str()) ||
+            0 == strcmp("BeginCommentGroup", (*commands)[i].c_str()) ||
+            0 == strcmp("PushCull", (*commands)[i].c_str())) {
             indent += 10;
         }
 
-        item->setData(Qt::UserRole + 4, -1.0);
+        item->setData(Qt::UserRole + 4, -1);
+        item->setData(Qt::UserRole + 5, (int)(*offsets)[i]);
 
         fListWidget.addItem(item);
     }
diff --git a/debugger/QT/SkDebuggerGUI.h b/debugger/QT/SkDebuggerGUI.h
index 50ebfc2..41c5e24 100644
--- a/debugger/QT/SkDebuggerGUI.h
+++ b/debugger/QT/SkDebuggerGUI.h
@@ -79,6 +79,11 @@
     void actionBreakpoints();
 
     /**
+        Toggles between count and offset style of command indexing in GUI
+     */
+    void actionToggleIndexStyle();
+
+    /**
         Profile the commands
      */
     void actionProfile();
@@ -246,6 +251,7 @@
 
     QAction fActionOpen;
     QAction fActionBreakpoint;
+    QAction fActionToggleIndexStyle;
     QAction fActionProfile;
     QAction fActionCancel;
     QAction fActionClearBreakpoints;
@@ -300,6 +306,7 @@
     QMenu fMenuWindows;
 
     bool fBreakpointsActivated;
+    bool fIndexStyleToggle;
     bool fDeletesActivated;
     bool fPause;
     bool fLoading;
@@ -324,7 +331,7 @@
     /**
         Populates the list widget with the vector of strings passed in.
      */
-    void setupListWidget(SkTArray<SkString>* command);
+    void setupListWidget(SkTArray<SkString>* commands, SkTDArray<size_t>* offsets);
 
     /**
         Populates the combo box widget with the vector of strings passed in.
diff --git a/debugger/QT/SkListWidget.cpp b/debugger/QT/SkListWidget.cpp
index cc94ff8..b5f9038 100644
--- a/debugger/QT/SkListWidget.cpp
+++ b/debugger/QT/SkListWidget.cpp
@@ -9,13 +9,9 @@
 
 #include "SkListWidget.h"
 
-SkListWidget::SkListWidget(QObject *parent) {}
-
-SkListWidget::~SkListWidget() {}
-
 void SkListWidget::paint (QPainter *painter,
-        const QStyleOptionViewItem &option,
-        const QModelIndex &index) const {
+                          const QStyleOptionViewItem &option,
+                          const QModelIndex &index) const {
     /* We adjust the initial position of the list item so that
      * we don't have overlapping top and bottom borders of concurrent
      * widget items. */
@@ -64,7 +60,12 @@
     int indent = index.data(Qt::UserRole + 3).toInt();
 
     QString drawCommandText = index.data(Qt::DisplayRole).toString();
-    QString drawCommandNumber = index.data(Qt::UserRole + 1).toString();
+    QString drawCommandNumber;
+    if (kIndex_IndexStyle == fIndexStyle) {
+        drawCommandNumber = index.data(Qt::UserRole + 1).toString();
+    } else {
+        drawCommandNumber = index.data(Qt::UserRole + 5).toString();
+    }
     float time = index.data(Qt::UserRole + 4).toFloat();
     QString drawTime;
     drawTime.setNum(time, 'f', 2);
@@ -104,17 +105,17 @@
     // Draw Command Number
     r = option.rect.adjusted(kImageSpace, 0, -10, -7);
     painter->drawText(r.left(), r.top(), r.width(), r.height(),
-            Qt::AlignBottom|Qt::AlignLeft, drawCommandNumber, &r);
+                      Qt::AlignBottom|Qt::AlignLeft, drawCommandNumber, &r);
 
     if (time >= 0.0) {
         // Draw time
         r = option.rect.adjusted(kImageSpace+kCommandNumberSpace, 0, -10, -7);
         painter->drawText(r.left(), r.top(), r.width(), r.height(),
-                Qt::AlignBottom|Qt::AlignLeft, drawTime, &r);
+                          Qt::AlignBottom|Qt::AlignLeft, drawTime, &r);
     }
 }
 
-QSize SkListWidget::sizeHint ( const QStyleOptionViewItem & option,
-        const QModelIndex & index ) const{
+QSize SkListWidget::sizeHint (const QStyleOptionViewItem& option,
+                              const QModelIndex& index) const{
     return QSize(200, 30);
 }
diff --git a/debugger/QT/SkListWidget.h b/debugger/QT/SkListWidget.h
index 12a2120..d6e797a 100644
--- a/debugger/QT/SkListWidget.h
+++ b/debugger/QT/SkListWidget.h
@@ -19,25 +19,38 @@
  */
 class SkListWidget : public QAbstractItemDelegate {
 public:
+    enum IndexStyle {
+        kIndex_IndexStyle,
+        kOffset_IndexStyle,
+    };
+
     /**
         Constructs the list widget with the specified parent for layout purposes.
         @param parent  The parent container of this widget
      */
-    SkListWidget(QObject* parent = NULL);
+    SkListWidget(QObject* parent = NULL) : fIndexStyle(kIndex_IndexStyle) {}
 
-    ~SkListWidget();
+    virtual ~SkListWidget() {}
 
     /**
         Draws the current state of the widget. Overriden from QWidget.
      */
-    void paint (QPainter* painter, const QStyleOptionViewItem& option,
-            const QModelIndex& index ) const;
+    void paint(QPainter* painter, const QStyleOptionViewItem& option,
+               const QModelIndex& index ) const;
 
     /**
         Returns the default size of the widget. Overriden from QWidget.
      */
-    QSize sizeHint (const QStyleOptionViewItem& option,
-            const QModelIndex& index) const;
+    QSize sizeHint(const QStyleOptionViewItem& option,
+                   const QModelIndex& index) const;
+
+
+    void setIndexStyle(IndexStyle indexStyle) {
+        fIndexStyle = indexStyle;
+    }
+
+protected:
+    IndexStyle fIndexStyle;
 };
 
 #endif
diff --git a/debugger/SkDebugger.cpp b/debugger/SkDebugger.cpp
index f684dd8..82b26a1 100644
--- a/debugger/SkDebugger.cpp
+++ b/debugger/SkDebugger.cpp
@@ -31,7 +31,9 @@
     delete fDebugCanvas;
     fDebugCanvas = new SkDebugCanvas(fPictureWidth, fPictureHeight);
     fDebugCanvas->setBounds(fPictureWidth, fPictureHeight);
+    fDebugCanvas->setPicture(picture);
     picture->draw(fDebugCanvas);
+    fDebugCanvas->setPicture(NULL);
     fIndex = fDebugCanvas->getSize() - 1;
     SkRefCnt_SafeAssign(fPicture, picture);
 }
@@ -41,7 +43,25 @@
     // commands. Playing back will strip those out.
     SkPicture* newPicture = new SkPicture;
     SkCanvas* canvas = newPicture->beginRecording(fPictureWidth, fPictureHeight);
+
+    bool vizMode = fDebugCanvas->getMegaVizMode();
+    fDebugCanvas->setMegaVizMode(false);
+    bool overDraw = fDebugCanvas->getOverdrawViz();
+    fDebugCanvas->setOverdrawViz(false);
+    int saveCount = fDebugCanvas->getOutstandingSaveCount();
+    fDebugCanvas->setOutstandingSaveCount(0);
+
     fDebugCanvas->draw(canvas);
+
+    int temp = fDebugCanvas->getOutstandingSaveCount();
+    for (int i = 0; i < temp; ++i) {
+        canvas->restore();
+    }
+
+    fDebugCanvas->setMegaVizMode(vizMode);
+    fDebugCanvas->setOverdrawViz(overDraw);
+    fDebugCanvas->setOutstandingSaveCount(saveCount);
+
     newPicture->endRecording();
     return newPicture;
 }
diff --git a/debugger/SkDebugger.h b/debugger/SkDebugger.h
index 20c4a78..94300d8 100644
--- a/debugger/SkDebugger.h
+++ b/debugger/SkDebugger.h
@@ -48,6 +48,10 @@
         return fDebugCanvas->getDrawCommandsAsStrings();
     }
 
+    SkTDArray<size_t>* getDrawCommandOffsets() {
+        return fDebugCanvas->getDrawCommandOffsets();
+    }
+
     const SkTDArray<SkDrawCommand*>& getDrawCommands() const {
         return fDebugCanvas->getDrawCommands();
     }