blob: 6ad4805aa555055ecc1cea7c30160ea048548400 [file] [log] [blame]
chudy@google.com902ebe52012-06-29 14:21:22 +00001/*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
chudy@google.com902ebe52012-06-29 14:21:22 +00008#include "SkDebuggerGUI.h"
chudy@google.combbad34d2012-08-13 14:26:36 +00009#include "SkGraphics.h"
scroggo@google.comb4467e62012-11-06 23:10:09 +000010#include "SkImageDecoder.h"
chudy@google.com902ebe52012-06-29 14:21:22 +000011#include <QListWidgetItem>
robertphillips@google.com2bde91d2012-11-15 14:57:57 +000012#include "PictureBenchmark.h"
13#include "PictureRenderer.h"
14#include "SkBenchLogger.h"
15#include "SkPictureRecord.h"
16#include "SkPicturePlayback.h"
17#include "BenchTimer.h"
chudy@google.com902ebe52012-06-29 14:21:22 +000018
19SkDebuggerGUI::SkDebuggerGUI(QWidget *parent) :
chudy@google.comc432f002012-07-10 13:19:25 +000020 QMainWindow(parent)
chudy@google.com2d537a12012-07-31 12:49:52 +000021 , fCentralWidget(this)
22 , fStatusBar(this)
23 , fToolBar(this)
chudy@google.comc432f002012-07-10 13:19:25 +000024 , fActionOpen(this)
25 , fActionBreakpoint(this)
robertphillips@google.comd26c7062012-11-12 20:42:12 +000026 , fActionProfile(this)
chudy@google.comc432f002012-07-10 13:19:25 +000027 , fActionCancel(this)
chudy@google.com7e4cfbf2012-07-17 15:40:51 +000028 , fActionClearBreakpoints(this)
chudy@google.come504de02012-07-16 18:35:23 +000029 , fActionClearDeletes(this)
chudy@google.comc432f002012-07-10 13:19:25 +000030 , fActionClose(this)
chudy@google.come504de02012-07-16 18:35:23 +000031 , fActionCreateBreakpoint(this)
chudy@google.comc432f002012-07-10 13:19:25 +000032 , fActionDelete(this)
33 , fActionDirectory(this)
34 , fActionGoToLine(this)
35 , fActionInspector(this)
36 , fActionPlay(this)
chudy@google.come504de02012-07-16 18:35:23 +000037 , fActionPause(this)
chudy@google.comc432f002012-07-10 13:19:25 +000038 , fActionRewind(this)
chudy@google.com0ab03392012-07-28 20:16:11 +000039 , fActionSave(this)
40 , fActionSaveAs(this)
chudy@google.com7e4cfbf2012-07-17 15:40:51 +000041 , fActionShowDeletes(this)
chudy@google.comc432f002012-07-10 13:19:25 +000042 , fActionStepBack(this)
43 , fActionStepForward(this)
chudy@google.coma1226312012-07-26 20:26:44 +000044 , fActionZoomIn(this)
45 , fActionZoomOut(this)
46 , fMapper(this)
chudy@google.comc432f002012-07-10 13:19:25 +000047 , fListWidget(&fCentralWidget)
48 , fDirectoryWidget(&fCentralWidget)
chudy@google.com607357f2012-08-07 16:12:23 +000049 , fCanvasWidget(this, &fDebugger)
chudy@google.comc432f002012-07-10 13:19:25 +000050 , fMenuBar(this)
51 , fMenuFile(this)
52 , fMenuNavigate(this)
53 , fMenuView(this)
chudy@google.com7e4cfbf2012-07-17 15:40:51 +000054 , fBreakpointsActivated(false)
55 , fDeletesActivated(false)
56 , fPause(false)
chudy@google.comd3058f52012-07-19 13:41:27 +000057 , fLoading(false)
chudy@google.comc432f002012-07-10 13:19:25 +000058{
chudy@google.com902ebe52012-06-29 14:21:22 +000059 setupUi(this);
chudy@google.comea5488b2012-07-26 19:38:22 +000060 connect(&fListWidget, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)), this, SLOT(registerListClick(QListWidgetItem *)));
chudy@google.comc432f002012-07-10 13:19:25 +000061 connect(&fActionOpen, SIGNAL(triggered()), this, SLOT(openFile()));
chudy@google.comea5488b2012-07-26 19:38:22 +000062 connect(&fActionDirectory, SIGNAL(triggered()), this, SLOT(toggleDirectory()));
63 connect(&fDirectoryWidget, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)), this, SLOT(loadFile(QListWidgetItem *)));
chudy@google.comc432f002012-07-10 13:19:25 +000064 connect(&fActionDelete, SIGNAL(triggered()), this, SLOT(actionDelete()));
chudy@google.comea5488b2012-07-26 19:38:22 +000065 connect(&fListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(toggleBreakpoint()));
chudy@google.comc432f002012-07-10 13:19:25 +000066 connect(&fActionRewind, SIGNAL(triggered()), this, SLOT(actionRewind()));
67 connect(&fActionPlay, SIGNAL(triggered()), this, SLOT(actionPlay()));
68 connect(&fActionStepBack, SIGNAL(triggered()), this, SLOT(actionStepBack()));
chudy@google.comea5488b2012-07-26 19:38:22 +000069 connect(&fActionStepForward, SIGNAL(triggered()), this, SLOT(actionStepForward()));
70 connect(&fActionBreakpoint, SIGNAL(triggered()), this, SLOT(actionBreakpoints()));
71 connect(&fActionInspector, SIGNAL(triggered()), this, SLOT(actionInspector()));
72 connect(&fActionInspector, SIGNAL(triggered()), this, SLOT(actionSettings()));
73 connect(&fFilter, SIGNAL(activated(QString)), this, SLOT(toggleFilter(QString)));
robertphillips@google.comd26c7062012-11-12 20:42:12 +000074 connect(&fActionProfile, SIGNAL(triggered()), this, SLOT(actionProfile()));
chudy@google.comc432f002012-07-10 13:19:25 +000075 connect(&fActionCancel, SIGNAL(triggered()), this, SLOT(actionCancel()));
chudy@google.com7e4cfbf2012-07-17 15:40:51 +000076 connect(&fActionClearBreakpoints, SIGNAL(triggered()), this, SLOT(actionClearBreakpoints()));
77 connect(&fActionClearDeletes, SIGNAL(triggered()), this, SLOT(actionClearDeletes()));
chudy@google.comc432f002012-07-10 13:19:25 +000078 connect(&fActionClose, SIGNAL(triggered()), this, SLOT(actionClose()));
chudy@google.comea5488b2012-07-26 19:38:22 +000079 connect(fSettingsWidget.getVisibilityButton(), SIGNAL(toggled(bool)), this, SLOT(actionCommandFilter()));
80 connect(fSettingsWidget.getGLCheckBox(), SIGNAL(toggled(bool)), this, SLOT(actionGLWidget(bool)));
81 connect(fSettingsWidget.getRasterCheckBox(), SIGNAL(toggled(bool)), this, SLOT(actionRasterWidget(bool)));
82 connect(&fActionPause, SIGNAL(toggled(bool)), this, SLOT(pauseDrawing(bool)));
chudy@google.come504de02012-07-16 18:35:23 +000083 connect(&fActionCreateBreakpoint, SIGNAL(activated()), this, SLOT(toggleBreakpoint()));
chudy@google.com7e4cfbf2012-07-17 15:40:51 +000084 connect(&fActionShowDeletes, SIGNAL(triggered()), this, SLOT(showDeletes()));
chudy@google.comea5488b2012-07-26 19:38:22 +000085 connect(&fCanvasWidget, SIGNAL(hitChanged(int)), this, SLOT(selectCommand(int)));
86 connect(&fCanvasWidget, SIGNAL(hitChanged(int)), &fSettingsWidget, SLOT(updateHit(int)));
87 connect(&fCanvasWidget, SIGNAL(scaleFactorChanged(float)), this, SLOT(actionScale(float)));
88 connect(&fCanvasWidget, SIGNAL(commandChanged(int)), &fSettingsWidget, SLOT(updateCommand(int)));
chudy@google.com0ab03392012-07-28 20:16:11 +000089 connect(&fActionSaveAs, SIGNAL(triggered()), this, SLOT(actionSaveAs()));
90 connect(&fActionSave, SIGNAL(triggered()), this, SLOT(actionSave()));
chudy@google.com7e4cfbf2012-07-17 15:40:51 +000091
chudy@google.coma1226312012-07-26 20:26:44 +000092 fMapper.setMapping(&fActionZoomIn, 1);
93 fMapper.setMapping(&fActionZoomOut, -1);
94
95 connect(&fActionZoomIn, SIGNAL(triggered()), &fMapper, SLOT(map()));
96 connect(&fActionZoomOut, SIGNAL(triggered()), &fMapper, SLOT(map()));
97 connect(&fMapper, SIGNAL(mapped(int)), &fCanvasWidget, SLOT(keyZoom(int)));
98
chudy@google.com7e4cfbf2012-07-17 15:40:51 +000099 fInspectorWidget.setDisabled(true);
chudy@google.comd3058f52012-07-19 13:41:27 +0000100 fMenuEdit.setDisabled(true);
101 fMenuNavigate.setDisabled(true);
102 fMenuView.setDisabled(true);
chudy@google.combbad34d2012-08-13 14:26:36 +0000103
104 SkGraphics::Init();
chudy@google.com902ebe52012-06-29 14:21:22 +0000105}
106
chudy@google.combbad34d2012-08-13 14:26:36 +0000107SkDebuggerGUI::~SkDebuggerGUI() {
108 SkGraphics::Term();
109}
chudy@google.com902ebe52012-06-29 14:21:22 +0000110
111void SkDebuggerGUI::actionBreakpoints() {
chudy@google.com7e4cfbf2012-07-17 15:40:51 +0000112 fBreakpointsActivated = !fBreakpointsActivated;
chudy@google.comc432f002012-07-10 13:19:25 +0000113 for (int row = 0; row < fListWidget.count(); row++) {
114 QListWidgetItem *item = fListWidget.item(row);
chudy@google.com7e4cfbf2012-07-17 15:40:51 +0000115 item->setHidden(item->checkState() == Qt::Unchecked && fBreakpointsActivated);
116 }
117}
chudy@google.com902ebe52012-06-29 14:21:22 +0000118
chudy@google.com7e4cfbf2012-07-17 15:40:51 +0000119void SkDebuggerGUI::showDeletes() {
120 fDeletesActivated = !fDeletesActivated;
121 for (int row = 0; row < fListWidget.count(); row++) {
122 QListWidgetItem *item = fListWidget.item(row);
chudy@google.com607357f2012-08-07 16:12:23 +0000123 item->setHidden(fDebugger.isCommandVisible(row)
124 && fDeletesActivated);
chudy@google.com902ebe52012-06-29 14:21:22 +0000125 }
126}
127
robertphillips@google.com2bde91d2012-11-15 14:57:57 +0000128// The timed picture playback uses the SkPicturePlayback's profiling stubs
129// to time individual commands. The offsets are needed to map SkPicture
130// offsets to individual commands.
131class SkTimedPicturePlayback : public SkPicturePlayback {
132public:
133 SkTimedPicturePlayback(SkStream* stream, const SkPictInfo& info, bool* isValid,
134 SkSerializationHelpers::DecodeBitmap decoder,
135 const SkTDArray<size_t>& offsets)
136 : INHERITED(stream, info, isValid, decoder)
137 , fTot(0.0)
138 , fCurCommand(0)
139 , fOffsets(offsets) {
140 fTimes.setCount(fOffsets.count());
141 for (int i = 0; i < fOffsets.count(); ++i) {
142 fTimes[i] = 0;
143 }
144 }
145
146 int count() const { return fTimes.count(); }
147
148 double time(int index) const { return fTimes[index] / fTot; }
149
150protected:
151 BenchTimer fTimer;
152 SkTDArray<size_t> fOffsets; // offset in the SkPicture for each command
153 SkTDArray<double> fTimes; // sum of time consumed for each command
154 double fTot; // total of all times in 'fTimes'
155 size_t fCurOffset;
156 int fCurCommand; // the current command being executed/timed
157
158 virtual void preDraw(size_t offset, int type) {
159 // This search isn't as bad as it seems. In normal playback mode, the
160 // base class steps through the commands in order and can only skip ahead
161 // a bit on a clip. This class is only used during profiling so we
162 // don't have to worry about forward/backward scrubbing through commands.
163 for (int i = 0; offset != fOffsets[fCurCommand]; ++i) {
164 fCurCommand = (fCurCommand+1) % fOffsets.count();
165 SkASSERT(i <= fOffsets.count()); // should always find the offset in the list
166 }
167
168 fCurOffset = offset;
169
170 fTimer.start();
171 }
172
173 virtual void postDraw(size_t offset) {
174 fTimer.end();
175
176 SkASSERT(offset == fCurOffset);
177
178 fTimes[fCurCommand] += fTimer.fWall;
179 fTot += fTimer.fWall;
180 }
181
182private:
183 typedef SkPicturePlayback INHERITED;
184};
185
186// Wrap SkPicture to allow installation of an SkTimedPicturePlayback object
187class SkTimedPicture : public SkPicture {
188public:
189 explicit SkTimedPicture(SkStream* stream,
190 bool* success,
191 SkSerializationHelpers::DecodeBitmap decoder,
192 const SkTDArray<size_t>& offsets) {
193 if (success) {
194 *success = false;
195 }
196 fRecord = NULL;
197 fPlayback = NULL;
198 fWidth = fHeight = 0;
199
200 SkPictInfo info;
201
202 if (!stream->read(&info, sizeof(info))) {
203 return;
204 }
205 if (SkPicture::PICTURE_VERSION != info.fVersion) {
206 return;
207 }
208
209 if (stream->readBool()) {
210 bool isValid = false;
211 fPlayback = SkNEW_ARGS(SkTimedPicturePlayback,
212 (stream, info, &isValid, decoder, offsets));
213 if (!isValid) {
214 SkDELETE(fPlayback);
215 fPlayback = NULL;
216 return;
217 }
218 }
219
220 // do this at the end, so that they will be zero if we hit an error.
221 fWidth = info.fWidth;
222 fHeight = info.fHeight;
223 if (success) {
224 *success = true;
225 }
226 }
227
228 int count() const { return ((SkTimedPicturePlayback*) fPlayback)->count(); }
229
230 // return the fraction of the total time this command consumed
231 double time(int index) const { return ((SkTimedPicturePlayback*) fPlayback)->time(index); }
232
233private:
234 typedef SkPicture INHERITED;
235};
236
robertphillips@google.comd26c7062012-11-12 20:42:12 +0000237void SkDebuggerGUI::actionProfile() {
robertphillips@google.com2bde91d2012-11-15 14:57:57 +0000238 // In order to profile we pass the command offsets (that were read-in
239 // in loadPicture by the SkOffsetPicture) to an SkTimedPlaybackPicture.
240 // The SkTimedPlaybackPicture in turn passes the offsets to an
241 // SkTimedPicturePlayback object which uses them to track the performance
242 // of individual commands.
243 if (fFileName.isEmpty()) {
244 return;
245 }
246
247 SkFILEStream inputStream;
248
249 inputStream.setPath(fFileName.c_str());
250 if (!inputStream.isValid()) {
251 return;
252 }
253
254 bool success = false;
255 SkTimedPicture picture(&inputStream, &success, &SkImageDecoder::DecodeStream, fOffsets);
256 if (!success) {
257 return;
258 }
259
260 sk_tools::PictureBenchmark benchmark;
261
262 sk_tools::TiledPictureRenderer* renderer = NULL;
263
264 renderer = SkNEW(sk_tools::TiledPictureRenderer);
265 renderer->setTileWidth(256);
266 renderer->setTileHeight(256);
267
268
269 benchmark.setRepeats(2);
270 benchmark.setRenderer(renderer);
271 benchmark.setTimersToShow(true, false, true, false, false);
272
273 SkBenchLogger logger;
274
275 benchmark.setLogger(&logger);
276
277 benchmark.run(&picture);
278
279 SkASSERT(picture.count() == fListWidget.count());
280
281 // extract the individual command times from the SkTimedPlaybackPicture
282 for (int i = 0; i < picture.count(); ++i) {
283 double temp = picture.time(i);
284
285 QListWidgetItem* item = fListWidget.item(i);
286
287 item->setData(Qt::UserRole + 4, 100.0*temp);
288 }
robertphillips@google.comd26c7062012-11-12 20:42:12 +0000289}
290
chudy@google.com902ebe52012-06-29 14:21:22 +0000291void SkDebuggerGUI::actionCancel() {
chudy@google.comc432f002012-07-10 13:19:25 +0000292 for (int row = 0; row < fListWidget.count(); row++) {
293 fListWidget.item(row)->setHidden(false);
chudy@google.com902ebe52012-06-29 14:21:22 +0000294 }
295}
296
chudy@google.com7e4cfbf2012-07-17 15:40:51 +0000297void SkDebuggerGUI::actionClearBreakpoints() {
298 for (int row = 0; row < fListWidget.count(); row++) {
299 QListWidgetItem* item = fListWidget.item(row);
300 item->setCheckState(Qt::Unchecked);
301 item->setData(Qt::DecorationRole,
302 QPixmap(":/images/Icons/blank.png"));
303 }
304}
305
306void SkDebuggerGUI::actionClearDeletes() {
307 for (int row = 0; row < fListWidget.count(); row++) {
308 QListWidgetItem* item = fListWidget.item(row);
309 item->setData(Qt::UserRole + 2, QPixmap(":/images/Icons/blank.png"));
chudy@google.com607357f2012-08-07 16:12:23 +0000310 fDebugger.setCommandVisible(row, true);
chudy@google.com7e4cfbf2012-07-17 15:40:51 +0000311 }
312 if (fPause) {
313 fCanvasWidget.drawTo(fPausedRow);
314 } else {
315 fCanvasWidget.drawTo(fListWidget.currentRow());
316 }
317}
318
chudy@google.com902ebe52012-06-29 14:21:22 +0000319void SkDebuggerGUI::actionCommandFilter() {
chudy@google.com607357f2012-08-07 16:12:23 +0000320 fDebugger.highlightCurrentCommand(
chudy@google.comc432f002012-07-10 13:19:25 +0000321 fSettingsWidget.getVisibilityButton()->isChecked());
322 fCanvasWidget.drawTo(fListWidget.currentRow());
chudy@google.com902ebe52012-06-29 14:21:22 +0000323}
324
325void SkDebuggerGUI::actionClose() {
326 this->close();
327}
328
329void SkDebuggerGUI::actionDelete() {
chudy@google.comc432f002012-07-10 13:19:25 +0000330 int currentRow = fListWidget.currentRow();
chudy@google.com7e4cfbf2012-07-17 15:40:51 +0000331 QListWidgetItem* item = fListWidget.currentItem();
332
chudy@google.com607357f2012-08-07 16:12:23 +0000333 if (fDebugger.isCommandVisible(currentRow)) {
chudy@google.com7e4cfbf2012-07-17 15:40:51 +0000334 item->setData(Qt::UserRole + 2, QPixmap(":/images/Icons/delete.png"));
chudy@google.com607357f2012-08-07 16:12:23 +0000335 fDebugger.setCommandVisible(currentRow, false);
chudy@google.com7e4cfbf2012-07-17 15:40:51 +0000336 } else {
337 item->setData(Qt::UserRole + 2, QPixmap(":/images/Icons/blank.png"));
chudy@google.com607357f2012-08-07 16:12:23 +0000338 fDebugger.setCommandVisible(currentRow, true);
chudy@google.com7e4cfbf2012-07-17 15:40:51 +0000339 }
340
chudy@google.come504de02012-07-16 18:35:23 +0000341 if (fPause) {
342 fCanvasWidget.drawTo(fPausedRow);
343 } else {
344 fCanvasWidget.drawTo(currentRow);
345 }
chudy@google.com902ebe52012-06-29 14:21:22 +0000346}
347
chudy@google.comea5488b2012-07-26 19:38:22 +0000348void SkDebuggerGUI::actionGLWidget(bool isToggled) {
349 fCanvasWidget.setWidgetVisibility(SkCanvasWidget::kGPU_WidgetType, !isToggled);
350}
351
chudy@google.com902ebe52012-06-29 14:21:22 +0000352void SkDebuggerGUI::actionInspector() {
chudy@google.comc432f002012-07-10 13:19:25 +0000353 if (fInspectorWidget.isHidden()) {
354 fInspectorWidget.setHidden(false);
chudy@google.com902ebe52012-06-29 14:21:22 +0000355 } else {
chudy@google.comc432f002012-07-10 13:19:25 +0000356 fInspectorWidget.setHidden(true);
chudy@google.com902ebe52012-06-29 14:21:22 +0000357 }
358}
359
360void SkDebuggerGUI::actionPlay() {
chudy@google.comc432f002012-07-10 13:19:25 +0000361 for (int row = fListWidget.currentRow() + 1; row < fListWidget.count();
chudy@google.com7dcae672012-07-09 20:26:53 +0000362 row++) {
chudy@google.comc432f002012-07-10 13:19:25 +0000363 QListWidgetItem *item = fListWidget.item(row);
chudy@google.com902ebe52012-06-29 14:21:22 +0000364 if (item->checkState() == Qt::Checked) {
chudy@google.comc432f002012-07-10 13:19:25 +0000365 fListWidget.setCurrentItem(item);
chudy@google.com902ebe52012-06-29 14:21:22 +0000366 return;
367 }
368 }
chudy@google.comc432f002012-07-10 13:19:25 +0000369 fListWidget.setCurrentRow(fListWidget.count() - 1);
chudy@google.com902ebe52012-06-29 14:21:22 +0000370}
371
chudy@google.comea5488b2012-07-26 19:38:22 +0000372void SkDebuggerGUI::actionRasterWidget(bool isToggled) {
373 fCanvasWidget.setWidgetVisibility(SkCanvasWidget::kRaster_8888_WidgetType, !isToggled);
374}
375
chudy@google.com902ebe52012-06-29 14:21:22 +0000376void SkDebuggerGUI::actionRewind() {
chudy@google.come504de02012-07-16 18:35:23 +0000377 fListWidget.setCurrentRow(0);
chudy@google.com902ebe52012-06-29 14:21:22 +0000378}
379
chudy@google.com0ab03392012-07-28 20:16:11 +0000380void SkDebuggerGUI::actionSave() {
robertphillips@google.comd26c7062012-11-12 20:42:12 +0000381 fFileName = fPath.toAscii();
382 fFileName.append("/");
383 fFileName.append(fDirectoryWidget.currentItem()->text().toAscii());
384 saveToFile(fFileName);
chudy@google.com0ab03392012-07-28 20:16:11 +0000385}
386
387void SkDebuggerGUI::actionSaveAs() {
388 QString filename = QFileDialog::getSaveFileName(this, "Save File", "",
389 "Skia Picture (*skp)");
chudy@google.com38b08ce2012-07-28 23:26:10 +0000390 if (!filename.endsWith(".skp", Qt::CaseInsensitive)) {
chudy@google.com0ab03392012-07-28 20:16:11 +0000391 filename.append(".skp");
392 }
djsollen@google.comc3c82162012-11-13 18:35:10 +0000393 saveToFile(SkString(filename.toAscii().data()));
chudy@google.com0ab03392012-07-28 20:16:11 +0000394}
395
chudy@google.com7dcae672012-07-09 20:26:53 +0000396void SkDebuggerGUI::actionScale(float scaleFactor) {
chudy@google.comc432f002012-07-10 13:19:25 +0000397 fSettingsWidget.setZoomText(scaleFactor);
chudy@google.com7dcae672012-07-09 20:26:53 +0000398}
399
chudy@google.com902ebe52012-06-29 14:21:22 +0000400void SkDebuggerGUI::actionSettings() {
chudy@google.comc432f002012-07-10 13:19:25 +0000401 if (fSettingsWidget.isHidden()) {
402 fSettingsWidget.setHidden(false);
chudy@google.com902ebe52012-06-29 14:21:22 +0000403 } else {
chudy@google.comc432f002012-07-10 13:19:25 +0000404 fSettingsWidget.setHidden(true);
chudy@google.com902ebe52012-06-29 14:21:22 +0000405 }
406}
407
408void SkDebuggerGUI::actionStepBack() {
chudy@google.comc432f002012-07-10 13:19:25 +0000409 int currentRow = fListWidget.currentRow();
chudy@google.com902ebe52012-06-29 14:21:22 +0000410 if (currentRow != 0) {
chudy@google.comc432f002012-07-10 13:19:25 +0000411 fListWidget.setCurrentRow(currentRow - 1);
chudy@google.com902ebe52012-06-29 14:21:22 +0000412 }
413}
414
415void SkDebuggerGUI::actionStepForward() {
chudy@google.comc432f002012-07-10 13:19:25 +0000416 int currentRow = fListWidget.currentRow();
chudy@google.com902ebe52012-06-29 14:21:22 +0000417 QString curRow = QString::number(currentRow);
chudy@google.comc432f002012-07-10 13:19:25 +0000418 QString curCount = QString::number(fListWidget.count());
419 if (currentRow < fListWidget.count() - 1) {
420 fListWidget.setCurrentRow(currentRow + 1);
chudy@google.com902ebe52012-06-29 14:21:22 +0000421 }
422}
423
chudy@google.coma9e937c2012-08-03 17:32:05 +0000424void SkDebuggerGUI::drawComplete() {
chudy@google.com607357f2012-08-07 16:12:23 +0000425 fInspectorWidget.setMatrix(fDebugger.getCurrentMatrix());
426 fInspectorWidget.setClip(fDebugger.getCurrentClip());
chudy@google.coma9e937c2012-08-03 17:32:05 +0000427}
428
robertphillips@google.comd26c7062012-11-12 20:42:12 +0000429void SkDebuggerGUI::saveToFile(const SkString& filename) {
430 SkFILEWStream file(filename.c_str());
chudy@google.com607357f2012-08-07 16:12:23 +0000431 fDebugger.makePicture()->serialize(&file);
chudy@google.com0ab03392012-07-28 20:16:11 +0000432}
433
chudy@google.com902ebe52012-06-29 14:21:22 +0000434void SkDebuggerGUI::loadFile(QListWidgetItem *item) {
435 if (fDirectoryWidgetActive) {
robertphillips@google.comd26c7062012-11-12 20:42:12 +0000436 fFileName = fPath.toAscii();
437 fFileName.append("/");
438 fFileName.append(item->text().toAscii());
439 loadPicture(fFileName);
chudy@google.com902ebe52012-06-29 14:21:22 +0000440 }
441}
442
443void SkDebuggerGUI::openFile() {
robertphillips@google.comd26c7062012-11-12 20:42:12 +0000444 QString temp = QFileDialog::getOpenFileName(this, tr("Open File"), "",
chudy@google.com7dcae672012-07-09 20:26:53 +0000445 tr("Files (*.*)"));
chudy@google.com902ebe52012-06-29 14:21:22 +0000446 fDirectoryWidgetActive = false;
robertphillips@google.comd26c7062012-11-12 20:42:12 +0000447 if (!temp.isEmpty()) {
448 QFileInfo pathInfo(temp);
chudy@google.com902ebe52012-06-29 14:21:22 +0000449 fPath = pathInfo.path();
djsollen@google.comc3c82162012-11-13 18:35:10 +0000450 loadPicture(SkString(temp.toAscii().data()));
chudy@google.com902ebe52012-06-29 14:21:22 +0000451 setupDirectoryWidget();
452 }
chudy@google.com902ebe52012-06-29 14:21:22 +0000453 fDirectoryWidgetActive = true;
454}
455
chudy@google.comc432f002012-07-10 13:19:25 +0000456void SkDebuggerGUI::pauseDrawing(bool isPaused) {
chudy@google.com607357f2012-08-07 16:12:23 +0000457 fPause = isPaused;
458 fPausedRow = fListWidget.currentRow();
459 fCanvasWidget.drawTo(fPausedRow);
chudy@google.com7dcae672012-07-09 20:26:53 +0000460}
461
chudy@google.com902ebe52012-06-29 14:21:22 +0000462void SkDebuggerGUI::registerListClick(QListWidgetItem *item) {
chudy@google.comd3058f52012-07-19 13:41:27 +0000463 if(!fLoading) {
464 int currentRow = fListWidget.currentRow();
chudy@google.comd3058f52012-07-19 13:41:27 +0000465
chudy@google.comea5488b2012-07-26 19:38:22 +0000466 if (currentRow != -1) {
467 if (!fPause) {
468 fCanvasWidget.drawTo(currentRow);
chudy@google.comd3058f52012-07-19 13:41:27 +0000469 }
chudy@google.com97cee972012-08-07 20:41:37 +0000470 SkTDArray<SkString*> *currInfo = fDebugger.getCommandInfo(
chudy@google.comea5488b2012-07-26 19:38:22 +0000471 currentRow);
472
473 /* TODO(chudy): Add command type before parameters. Rename v
474 * to something more informative. */
chudy@google.com97cee972012-08-07 20:41:37 +0000475 if (currInfo) {
chudy@google.comea5488b2012-07-26 19:38:22 +0000476 QString info;
477 info.append("<b>Parameters: </b><br/>");
chudy@google.com97cee972012-08-07 20:41:37 +0000478 for (int i = 0; i < currInfo->count(); i++) {
479
480 info.append(QString((*currInfo)[i]->c_str()));
chudy@google.comea5488b2012-07-26 19:38:22 +0000481 info.append("<br/>");
482 }
chudy@google.com6bd109a2012-08-14 19:34:13 +0000483 fInspectorWidget.setText(info, SkInspectorWidget::kDetail_TabType);
chudy@google.comea5488b2012-07-26 19:38:22 +0000484 fInspectorWidget.setDisabled(false);
chudy@google.comea5488b2012-07-26 19:38:22 +0000485 }
chudy@google.comd3058f52012-07-19 13:41:27 +0000486 }
chudy@google.comea5488b2012-07-26 19:38:22 +0000487
chudy@google.com902ebe52012-06-29 14:21:22 +0000488 }
489}
490
chudy@google.com9ca9bfe2012-07-12 21:58:14 +0000491void SkDebuggerGUI::selectCommand(int command) {
492 if (fPause) {
493 fListWidget.setCurrentRow(command);
494 }
495}
496
chudy@google.com902ebe52012-06-29 14:21:22 +0000497void SkDebuggerGUI::toggleBreakpoint() {
chudy@google.comc432f002012-07-10 13:19:25 +0000498 QListWidgetItem* item = fListWidget.currentItem();
chudy@google.com902ebe52012-06-29 14:21:22 +0000499 if (item->checkState() == Qt::Unchecked) {
500 item->setCheckState(Qt::Checked);
chudy@google.come565de42012-07-12 14:15:54 +0000501 item->setData(Qt::DecorationRole,
502 QPixmap(":/images/Icons/breakpoint_16x16.png"));
chudy@google.com902ebe52012-06-29 14:21:22 +0000503 } else {
chudy@google.com902ebe52012-06-29 14:21:22 +0000504 item->setCheckState(Qt::Unchecked);
chudy@google.come565de42012-07-12 14:15:54 +0000505 item->setData(Qt::DecorationRole,
506 QPixmap(":/images/Icons/blank.png"));
chudy@google.com902ebe52012-06-29 14:21:22 +0000507 }
508}
509
510void SkDebuggerGUI::toggleDirectory() {
chudy@google.com607357f2012-08-07 16:12:23 +0000511 fDirectoryWidget.setHidden(!fDirectoryWidget.isHidden());
chudy@google.com902ebe52012-06-29 14:21:22 +0000512}
513
514void SkDebuggerGUI::toggleFilter(QString string) {
chudy@google.comc432f002012-07-10 13:19:25 +0000515 for (int row = 0; row < fListWidget.count(); row++) {
516 QListWidgetItem *item = fListWidget.item(row);
chudy@google.com607357f2012-08-07 16:12:23 +0000517 item->setHidden(item->text() != string);
chudy@google.com902ebe52012-06-29 14:21:22 +0000518 }
519}
520
521void SkDebuggerGUI::setupUi(QMainWindow *SkDebuggerGUI) {
522 QIcon windowIcon;
chudy@google.com7dcae672012-07-09 20:26:53 +0000523 windowIcon.addFile(QString::fromUtf8(":/images/Icons/skia.png"), QSize(),
524 QIcon::Normal, QIcon::Off);
chudy@google.com902ebe52012-06-29 14:21:22 +0000525 SkDebuggerGUI->setObjectName(QString::fromUtf8("SkDebuggerGUI"));
526 SkDebuggerGUI->resize(1200, 1000);
527 SkDebuggerGUI->setWindowIcon(windowIcon);
chudy@google.comc432f002012-07-10 13:19:25 +0000528 SkDebuggerGUI->setWindowTitle("Skia Debugger");
chudy@google.com902ebe52012-06-29 14:21:22 +0000529
chudy@google.come504de02012-07-16 18:35:23 +0000530 fActionOpen.setShortcuts(QKeySequence::Open);
chudy@google.comc432f002012-07-10 13:19:25 +0000531 fActionOpen.setText("Open");
chudy@google.com902ebe52012-06-29 14:21:22 +0000532
533 QIcon breakpoint;
chudy@google.com7dcae672012-07-09 20:26:53 +0000534 breakpoint.addFile(QString::fromUtf8(":/images/Icons/breakpoint.png"),
535 QSize(), QIcon::Normal, QIcon::Off);
chudy@google.come504de02012-07-16 18:35:23 +0000536 fActionBreakpoint.setShortcut(QKeySequence(tr("Ctrl+B")));
chudy@google.comc432f002012-07-10 13:19:25 +0000537 fActionBreakpoint.setIcon(breakpoint);
chudy@google.com7e4cfbf2012-07-17 15:40:51 +0000538 fActionBreakpoint.setText("Breakpoints");
chudy@google.com902ebe52012-06-29 14:21:22 +0000539
540 QIcon cancel;
chudy@google.come504de02012-07-16 18:35:23 +0000541 cancel.addFile(QString::fromUtf8(":/images/Ico/reload.png"), QSize(),
chudy@google.com7dcae672012-07-09 20:26:53 +0000542 QIcon::Normal, QIcon::Off);
chudy@google.comc432f002012-07-10 13:19:25 +0000543 fActionCancel.setIcon(cancel);
544 fActionCancel.setText("Clear Filter");
chudy@google.com902ebe52012-06-29 14:21:22 +0000545
chudy@google.com7e4cfbf2012-07-17 15:40:51 +0000546 fActionClearBreakpoints.setShortcut(QKeySequence(tr("Alt+B")));
547 fActionClearBreakpoints.setText("Clear Breakpoints");
548
549 fActionClearDeletes.setShortcut(QKeySequence(tr("Alt+X")));
550 fActionClearDeletes.setText("Clear Deletes");
551
chudy@google.come504de02012-07-16 18:35:23 +0000552 fActionClose.setShortcuts(QKeySequence::Quit);
chudy@google.comc432f002012-07-10 13:19:25 +0000553 fActionClose.setText("Exit");
chudy@google.com902ebe52012-06-29 14:21:22 +0000554
chudy@google.come504de02012-07-16 18:35:23 +0000555 fActionCreateBreakpoint.setShortcut(QKeySequence(tr("B")));
556 fActionCreateBreakpoint.setText("Set Breakpoint");
557
558 fActionDelete.setShortcut(QKeySequence(tr("X")));
chudy@google.comc432f002012-07-10 13:19:25 +0000559 fActionDelete.setText("Delete Command");
chudy@google.com902ebe52012-06-29 14:21:22 +0000560
chudy@google.come504de02012-07-16 18:35:23 +0000561 fActionDirectory.setShortcut(QKeySequence(tr("Ctrl+D")));
562 fActionDirectory.setText("Directory");
chudy@google.com902ebe52012-06-29 14:21:22 +0000563
robertphillips@google.comd26c7062012-11-12 20:42:12 +0000564 QIcon profile;
565 profile.addFile(QString::fromUtf8(":/images/Ico/reload.png"), QSize(),
566 QIcon::Normal, QIcon::Off);
567 fActionProfile.setIcon(profile);
568 fActionProfile.setText("Profile");
569
chudy@google.comc432f002012-07-10 13:19:25 +0000570 QIcon inspector;
chudy@google.come504de02012-07-16 18:35:23 +0000571 inspector.addFile(QString::fromUtf8(":/images/Ico/inspector.png"),
chudy@google.comc432f002012-07-10 13:19:25 +0000572 QSize(), QIcon::Normal, QIcon::Off);
chudy@google.come504de02012-07-16 18:35:23 +0000573 fActionInspector.setShortcut(QKeySequence(tr("Ctrl+I")));
chudy@google.comc432f002012-07-10 13:19:25 +0000574 fActionInspector.setIcon(inspector);
chudy@google.come504de02012-07-16 18:35:23 +0000575 fActionInspector.setText("Inspector");
chudy@google.com902ebe52012-06-29 14:21:22 +0000576
chudy@google.comc432f002012-07-10 13:19:25 +0000577 QIcon play;
chudy@google.come504de02012-07-16 18:35:23 +0000578 play.addFile(QString::fromUtf8(":/images/Ico/play.png"), QSize(),
chudy@google.comc432f002012-07-10 13:19:25 +0000579 QIcon::Normal, QIcon::Off);
chudy@google.come504de02012-07-16 18:35:23 +0000580 fActionPlay.setShortcut(QKeySequence(tr("Ctrl+P")));
chudy@google.comc432f002012-07-10 13:19:25 +0000581 fActionPlay.setIcon(play);
582 fActionPlay.setText("Play");
chudy@google.com902ebe52012-06-29 14:21:22 +0000583
chudy@google.come504de02012-07-16 18:35:23 +0000584 QIcon pause;
585 pause.addFile(QString::fromUtf8(":/images/Ico/pause.png"), QSize(),
chudy@google.comc432f002012-07-10 13:19:25 +0000586 QIcon::Normal, QIcon::Off);
chudy@google.come504de02012-07-16 18:35:23 +0000587 fActionPause.setShortcut(QKeySequence(tr("Space")));
588 fActionPause.setCheckable(true);
589 fActionPause.setIcon(pause);
590 fActionPause.setText("Pause");
591
chudy@google.comc432f002012-07-10 13:19:25 +0000592 QIcon rewind;
chudy@google.come504de02012-07-16 18:35:23 +0000593 rewind.addFile(QString::fromUtf8(":/images/Ico/rewind.png"), QSize(),
chudy@google.comc432f002012-07-10 13:19:25 +0000594 QIcon::Normal, QIcon::Off);
chudy@google.come504de02012-07-16 18:35:23 +0000595 fActionRewind.setShortcut(QKeySequence(tr("Ctrl+R")));
chudy@google.comc432f002012-07-10 13:19:25 +0000596 fActionRewind.setIcon(rewind);
597 fActionRewind.setText("Rewind");
chudy@google.com902ebe52012-06-29 14:21:22 +0000598
chudy@google.com0ab03392012-07-28 20:16:11 +0000599 fActionSave.setShortcut(QKeySequence::Save);
600 fActionSave.setText("Save");
601 fActionSave.setDisabled(true);
602 fActionSaveAs.setShortcut(QKeySequence::SaveAs);
603 fActionSaveAs.setText("Save As");
604 fActionSaveAs.setDisabled(true);
605
chudy@google.com7e4cfbf2012-07-17 15:40:51 +0000606 fActionShowDeletes.setShortcut(QKeySequence(tr("Ctrl+X")));
607 fActionShowDeletes.setText("Deleted Commands");
608
chudy@google.comc432f002012-07-10 13:19:25 +0000609 QIcon stepBack;
chudy@google.come504de02012-07-16 18:35:23 +0000610 stepBack.addFile(QString::fromUtf8(":/images/Ico/previous.png"), QSize(),
chudy@google.comc432f002012-07-10 13:19:25 +0000611 QIcon::Normal, QIcon::Off);
chudy@google.come504de02012-07-16 18:35:23 +0000612 fActionStepBack.setShortcut(QKeySequence(tr("[")));
chudy@google.comc432f002012-07-10 13:19:25 +0000613 fActionStepBack.setIcon(stepBack);
614 fActionStepBack.setText("Step Back");
chudy@google.com902ebe52012-06-29 14:21:22 +0000615
chudy@google.comc432f002012-07-10 13:19:25 +0000616 QIcon stepForward;
chudy@google.come504de02012-07-16 18:35:23 +0000617 stepForward.addFile(QString::fromUtf8(":/images/Ico/next.png"),
chudy@google.comc432f002012-07-10 13:19:25 +0000618 QSize(), QIcon::Normal, QIcon::Off);
chudy@google.come504de02012-07-16 18:35:23 +0000619 fActionStepForward.setShortcut(QKeySequence(tr("]")));
chudy@google.comc432f002012-07-10 13:19:25 +0000620 fActionStepForward.setIcon(stepForward);
621 fActionStepForward.setText("Step Forward");
622
chudy@google.coma1226312012-07-26 20:26:44 +0000623 fActionZoomIn.setShortcut(QKeySequence(tr("Ctrl+=")));
624 fActionZoomIn.setText("Zoom In");
625 fActionZoomOut.setShortcut(QKeySequence(tr("Ctrl+-")));
626 fActionZoomOut.setText("Zoom Out");
627
chudy@google.comc432f002012-07-10 13:19:25 +0000628 fListWidget.setItemDelegate(new SkListWidget(&fListWidget));
629 fListWidget.setObjectName(QString::fromUtf8("listWidget"));
630 fListWidget.setMaximumWidth(250);
631
632 fFilter.addItem("--Filter By Available Commands--");
633
634 fDirectoryWidget.setMaximumWidth(250);
635 fDirectoryWidget.setStyleSheet("QListWidget::Item {padding: 5px;}");
636
637 fCanvasWidget.setSizePolicy(QSizePolicy::Expanding,
chudy@google.com7dcae672012-07-09 20:26:53 +0000638 QSizePolicy::Expanding);
chudy@google.com902ebe52012-06-29 14:21:22 +0000639
chudy@google.comc432f002012-07-10 13:19:25 +0000640 fInspectorWidget.setSizePolicy(QSizePolicy::Expanding,
chudy@google.com7dcae672012-07-09 20:26:53 +0000641 QSizePolicy::Expanding);
chudy@google.comc432f002012-07-10 13:19:25 +0000642 fInspectorWidget.setMaximumHeight(300);
chudy@google.com902ebe52012-06-29 14:21:22 +0000643
chudy@google.comc432f002012-07-10 13:19:25 +0000644 fSettingsWidget.setSizePolicy(QSizePolicy::Expanding,
645 QSizePolicy::Expanding);
646 fSettingsWidget.setMaximumWidth(250);
chudy@google.com902ebe52012-06-29 14:21:22 +0000647
chudy@google.comc432f002012-07-10 13:19:25 +0000648 fLeftColumnLayout.setSpacing(6);
649 fLeftColumnLayout.addWidget(&fListWidget);
650 fLeftColumnLayout.addWidget(&fDirectoryWidget);
chudy@google.com902ebe52012-06-29 14:21:22 +0000651
chudy@google.comc432f002012-07-10 13:19:25 +0000652 fCanvasAndSettingsLayout.setSpacing(6);
653 fCanvasAndSettingsLayout.addWidget(&fCanvasWidget);
654 fCanvasAndSettingsLayout.addWidget(&fSettingsWidget);
chudy@google.com902ebe52012-06-29 14:21:22 +0000655
chudy@google.comc432f002012-07-10 13:19:25 +0000656 fMainAndRightColumnLayout.setSpacing(6);
657 fMainAndRightColumnLayout.addLayout(&fCanvasAndSettingsLayout);
658 fMainAndRightColumnLayout.addWidget(&fInspectorWidget);
chudy@google.com902ebe52012-06-29 14:21:22 +0000659
chudy@google.com2d537a12012-07-31 12:49:52 +0000660 fCentralWidget.setLayout(&fContainerLayout);
chudy@google.comc432f002012-07-10 13:19:25 +0000661 fContainerLayout.setSpacing(6);
662 fContainerLayout.setContentsMargins(11, 11, 11, 11);
663 fContainerLayout.addLayout(&fLeftColumnLayout);
664 fContainerLayout.addLayout(&fMainAndRightColumnLayout);
665
666 SkDebuggerGUI->setCentralWidget(&fCentralWidget);
667 SkDebuggerGUI->setStatusBar(&fStatusBar);
668
chudy@google.come504de02012-07-16 18:35:23 +0000669 fToolBar.setIconSize(QSize(32, 32));
chudy@google.comc432f002012-07-10 13:19:25 +0000670 fToolBar.setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
671 SkDebuggerGUI->addToolBar(Qt::TopToolBarArea, &fToolBar);
chudy@google.com902ebe52012-06-29 14:21:22 +0000672
chudy@google.com0ab03392012-07-28 20:16:11 +0000673 fSpacer.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
chudy@google.com902ebe52012-06-29 14:21:22 +0000674
chudy@google.comc432f002012-07-10 13:19:25 +0000675 fToolBar.addAction(&fActionRewind);
676 fToolBar.addAction(&fActionStepBack);
chudy@google.come504de02012-07-16 18:35:23 +0000677 fToolBar.addAction(&fActionPause);
chudy@google.comc432f002012-07-10 13:19:25 +0000678 fToolBar.addAction(&fActionStepForward);
679 fToolBar.addAction(&fActionPlay);
680 fToolBar.addSeparator();
chudy@google.come504de02012-07-16 18:35:23 +0000681 fToolBar.addAction(&fActionInspector);
chudy@google.comc432f002012-07-10 13:19:25 +0000682 fToolBar.addSeparator();
robertphillips@google.comd26c7062012-11-12 20:42:12 +0000683 fToolBar.addAction(&fActionProfile);
684
685 fToolBar.addSeparator();
chudy@google.com0ab03392012-07-28 20:16:11 +0000686 fToolBar.addWidget(&fSpacer);
chudy@google.comc432f002012-07-10 13:19:25 +0000687 fToolBar.addWidget(&fFilter);
688 fToolBar.addAction(&fActionCancel);
chudy@google.com902ebe52012-06-29 14:21:22 +0000689
690 // TODO(chudy): Remove static call.
691 fDirectoryWidgetActive = false;
robertphillips@google.comd26c7062012-11-12 20:42:12 +0000692 fPath = "";
693 fFileName = "";
chudy@google.com902ebe52012-06-29 14:21:22 +0000694 setupDirectoryWidget();
695 fDirectoryWidgetActive = true;
696
chudy@google.com902ebe52012-06-29 14:21:22 +0000697 // Menu Bar
chudy@google.comc432f002012-07-10 13:19:25 +0000698 fMenuFile.setTitle("File");
699 fMenuFile.addAction(&fActionOpen);
chudy@google.com0ab03392012-07-28 20:16:11 +0000700 fMenuFile.addAction(&fActionSave);
701 fMenuFile.addAction(&fActionSaveAs);
chudy@google.comc432f002012-07-10 13:19:25 +0000702 fMenuFile.addAction(&fActionClose);
chudy@google.come504de02012-07-16 18:35:23 +0000703
704 fMenuEdit.setTitle("Edit");
705 fMenuEdit.addAction(&fActionDelete);
chudy@google.com7e4cfbf2012-07-17 15:40:51 +0000706 fMenuEdit.addAction(&fActionClearDeletes);
707 fMenuEdit.addSeparator();
chudy@google.come504de02012-07-16 18:35:23 +0000708 fMenuEdit.addAction(&fActionCreateBreakpoint);
chudy@google.com7e4cfbf2012-07-17 15:40:51 +0000709 fMenuEdit.addAction(&fActionClearBreakpoints);
chudy@google.come504de02012-07-16 18:35:23 +0000710
chudy@google.comc432f002012-07-10 13:19:25 +0000711 fMenuNavigate.setTitle("Navigate");
chudy@google.come504de02012-07-16 18:35:23 +0000712 fMenuNavigate.addAction(&fActionRewind);
713 fMenuNavigate.addAction(&fActionStepBack);
714 fMenuNavigate.addAction(&fActionStepForward);
715 fMenuNavigate.addAction(&fActionPlay);
716 fMenuNavigate.addAction(&fActionPause);
chudy@google.comc432f002012-07-10 13:19:25 +0000717 fMenuNavigate.addAction(&fActionGoToLine);
chudy@google.come504de02012-07-16 18:35:23 +0000718
chudy@google.comc432f002012-07-10 13:19:25 +0000719 fMenuView.setTitle("View");
chudy@google.come504de02012-07-16 18:35:23 +0000720 fMenuView.addAction(&fActionBreakpoint);
chudy@google.com7e4cfbf2012-07-17 15:40:51 +0000721 fMenuView.addAction(&fActionShowDeletes);
chudy@google.coma1226312012-07-26 20:26:44 +0000722 fMenuView.addAction(&fActionZoomIn);
723 fMenuView.addAction(&fActionZoomOut);
chudy@google.come504de02012-07-16 18:35:23 +0000724
725 fMenuWindows.setTitle("Window");
726 fMenuWindows.addAction(&fActionInspector);
727 fMenuWindows.addAction(&fActionDirectory);
chudy@google.comc432f002012-07-10 13:19:25 +0000728
729 fActionGoToLine.setText("Go to Line...");
730 fActionGoToLine.setDisabled(true);
731 fMenuBar.addAction(fMenuFile.menuAction());
chudy@google.come504de02012-07-16 18:35:23 +0000732 fMenuBar.addAction(fMenuEdit.menuAction());
chudy@google.comc432f002012-07-10 13:19:25 +0000733 fMenuBar.addAction(fMenuView.menuAction());
734 fMenuBar.addAction(fMenuNavigate.menuAction());
chudy@google.come504de02012-07-16 18:35:23 +0000735 fMenuBar.addAction(fMenuWindows.menuAction());
chudy@google.com902ebe52012-06-29 14:21:22 +0000736
chudy@google.com7dcae672012-07-09 20:26:53 +0000737 fPause = false;
738
chudy@google.comc432f002012-07-10 13:19:25 +0000739 SkDebuggerGUI->setMenuBar(&fMenuBar);
chudy@google.com902ebe52012-06-29 14:21:22 +0000740 QMetaObject::connectSlotsByName(SkDebuggerGUI);
741}
742
743void SkDebuggerGUI::setupDirectoryWidget() {
chudy@google.comc432f002012-07-10 13:19:25 +0000744 QDir dir(fPath);
chudy@google.com902ebe52012-06-29 14:21:22 +0000745 QRegExp r(".skp");
chudy@google.comc432f002012-07-10 13:19:25 +0000746 fDirectoryWidget.clear();
747 const QStringList files = dir.entryList();
chudy@google.com902ebe52012-06-29 14:21:22 +0000748 foreach (QString f, files) {
chudy@google.com7dcae672012-07-09 20:26:53 +0000749 if (f.contains(r))
chudy@google.comc432f002012-07-10 13:19:25 +0000750 fDirectoryWidget.addItem(f);
chudy@google.com902ebe52012-06-29 14:21:22 +0000751 }
752}
753
robertphillips@google.com2bde91d2012-11-15 14:57:57 +0000754// SkOffsetPicturePlayback records the offset of each command in the picture.
755// These are needed by the profiling system.
756class SkOffsetPicturePlayback : public SkPicturePlayback {
757public:
758 SkOffsetPicturePlayback(SkStream* stream, const SkPictInfo& info, bool* isValid,
759 SkSerializationHelpers::DecodeBitmap decoder)
760 : INHERITED(stream, info, isValid, decoder) {
761 }
762
763 const SkTDArray<size_t>& offsets() const { return fOffsets; }
764
765protected:
766 SkTDArray<size_t> fOffsets;
767
768 virtual void preDraw(size_t offset, int type) {
769 *fOffsets.append() = offset;
770 }
771
772private:
773 typedef SkPicturePlayback INHERITED;
774};
775
776// Picture to wrap an SkOffsetPicturePlayback.
777class SkOffsetPicture : public SkPicture {
778public:
779 SkOffsetPicture(SkStream* stream,
780 bool* success,
781 SkSerializationHelpers::DecodeBitmap decoder) {
782 if (success) {
783 *success = false;
784 }
785 fRecord = NULL;
786 fPlayback = NULL;
787 fWidth = fHeight = 0;
788
789 SkPictInfo info;
790
791 if (!stream->read(&info, sizeof(info))) {
792 return;
793 }
794 if (PICTURE_VERSION != info.fVersion) {
795 return;
796 }
797
798 if (stream->readBool()) {
799 bool isValid = false;
800 fPlayback = SkNEW_ARGS(SkOffsetPicturePlayback, (stream, info, &isValid, decoder));
801 if (!isValid) {
802 SkDELETE(fPlayback);
803 fPlayback = NULL;
804 return;
805 }
806 }
807
808 // do this at the end, so that they will be zero if we hit an error.
809 fWidth = info.fWidth;
810 fHeight = info.fHeight;
811 if (success) {
812 *success = true;
813 }
814 }
815
816 const SkTDArray<size_t>& offsets() const {
817 return ((SkOffsetPicturePlayback*) fPlayback)->offsets();
818 }
819
820private:
821 typedef SkPicture INHERITED;
822};
823
824
825
robertphillips@google.comd26c7062012-11-12 20:42:12 +0000826void SkDebuggerGUI::loadPicture(const SkString& fileName) {
827 fFileName = fileName;
chudy@google.comd3058f52012-07-19 13:41:27 +0000828 fLoading = true;
robertphillips@google.comd26c7062012-11-12 20:42:12 +0000829 SkStream* stream = SkNEW_ARGS(SkFILEStream, (fileName.c_str()));
robertphillips@google.com2bde91d2012-11-15 14:57:57 +0000830 SkOffsetPicture* picture = SkNEW_ARGS(SkOffsetPicture, (stream, NULL, &SkImageDecoder::DecodeStream));
831
chudy@google.com686e6802012-08-14 16:00:32 +0000832 fCanvasWidget.resetWidgetTransform();
chudy@google.com607357f2012-08-07 16:12:23 +0000833 fDebugger.loadPicture(picture);
chudy@google.com4c7962e2012-08-14 19:38:31 +0000834
robertphillips@google.com2bde91d2012-11-15 14:57:57 +0000835 fOffsets = picture->offsets();
836
chudy@google.com607357f2012-08-07 16:12:23 +0000837 SkSafeUnref(stream);
838 SkSafeUnref(picture);
839
chudy@google.com97cee972012-08-07 20:41:37 +0000840 // Will this automatically clear out due to nature of refcnt?
841 SkTDArray<SkString*>* commands = fDebugger.getDrawCommands();
chudy@google.com607357f2012-08-07 16:12:23 +0000842
robertphillips@google.com2bde91d2012-11-15 14:57:57 +0000843 SkASSERT(commands->count() == fOffsets.count());
844
chudy@google.com7dcae672012-07-09 20:26:53 +0000845 /* fDebugCanvas is reinitialized every load picture. Need it to retain value
chudy@google.com607357f2012-08-07 16:12:23 +0000846 * of the visibility filter.
847 * TODO(chudy): This should be deprecated since fDebugger is not
848 * recreated.
849 * */
850 fDebugger.highlightCurrentCommand(fSettingsWidget.getVisibilityButton()->isChecked());
851
chudy@google.com97cee972012-08-07 20:41:37 +0000852 setupListWidget(commands);
853 setupComboBox(commands);
chudy@google.com7e4cfbf2012-07-17 15:40:51 +0000854 fInspectorWidget.setDisabled(false);
chudy@google.come606d6e2012-07-12 14:31:25 +0000855 fSettingsWidget.setDisabled(false);
chudy@google.comd3058f52012-07-19 13:41:27 +0000856 fMenuEdit.setDisabled(false);
857 fMenuNavigate.setDisabled(false);
858 fMenuView.setDisabled(false);
chudy@google.com0ab03392012-07-28 20:16:11 +0000859 fActionSave.setDisabled(false);
860 fActionSaveAs.setDisabled(false);
chudy@google.comd3058f52012-07-19 13:41:27 +0000861 fLoading = false;
862 actionPlay();
chudy@google.com902ebe52012-06-29 14:21:22 +0000863}
864
chudy@google.com97cee972012-08-07 20:41:37 +0000865void SkDebuggerGUI::setupListWidget(SkTDArray<SkString*>* command) {
chudy@google.comc432f002012-07-10 13:19:25 +0000866 fListWidget.clear();
chudy@google.com902ebe52012-06-29 14:21:22 +0000867 int counter = 0;
robertphillips@google.com30d35f22012-11-06 16:45:36 +0000868 int indent = 0;
chudy@google.com97cee972012-08-07 20:41:37 +0000869 for (int i = 0; i < command->count(); i++) {
chudy@google.com902ebe52012-06-29 14:21:22 +0000870 QListWidgetItem *item = new QListWidgetItem();
chudy@google.com97cee972012-08-07 20:41:37 +0000871 item->setData(Qt::DisplayRole, (*command)[i]->c_str());
chudy@google.com902ebe52012-06-29 14:21:22 +0000872 item->setData(Qt::UserRole + 1, counter++);
robertphillips@google.com30d35f22012-11-06 16:45:36 +0000873
874 if (0 == strcmp("Restore", (*command)[i]->c_str())) {
875 indent -= 10;
876 }
877
878 item->setData(Qt::UserRole + 3, indent);
879
880 if (0 == strcmp("Save", (*command)[i]->c_str()) ||
881 0 == strcmp("Save Layer", (*command)[i]->c_str())) {
882 indent += 10;
883 }
884
robertphillips@google.comd26c7062012-11-12 20:42:12 +0000885 item->setData(Qt::UserRole + 4, -1.0);
886
chudy@google.comc432f002012-07-10 13:19:25 +0000887 fListWidget.addItem(item);
chudy@google.com902ebe52012-06-29 14:21:22 +0000888 }
889}
890
chudy@google.com97cee972012-08-07 20:41:37 +0000891void SkDebuggerGUI::setupComboBox(SkTDArray<SkString*>* command) {
chudy@google.comc432f002012-07-10 13:19:25 +0000892 fFilter.clear();
893 fFilter.addItem("--Filter By Available Commands--");
chudy@google.com902ebe52012-06-29 14:21:22 +0000894
895 std::map<std::string, int> map;
chudy@google.com97cee972012-08-07 20:41:37 +0000896 for (int i = 0; i < command->count(); i++) {
897 map[(*command)[i]->c_str()]++;
chudy@google.com902ebe52012-06-29 14:21:22 +0000898 }
899
900 QString overview;
chudy@google.com607357f2012-08-07 16:12:23 +0000901 int counter = 0;
chudy@google.com7dcae672012-07-09 20:26:53 +0000902 for (std::map<std::string, int>::iterator it = map.begin(); it != map.end();
903 ++it) {
chudy@google.com902ebe52012-06-29 14:21:22 +0000904 overview.append((it->first).c_str());
905 overview.append(": ");
906 overview.append(QString::number(it->second));
907 overview.append("<br/>");
chudy@google.com7dcae672012-07-09 20:26:53 +0000908 counter += it->second;
chudy@google.comc432f002012-07-10 13:19:25 +0000909 fFilter.addItem((it->first).c_str());
chudy@google.com902ebe52012-06-29 14:21:22 +0000910 }
911 QString total;
912 total.append("Total Draw Commands: ");
913 total.append(QString::number(counter));
914 total.append("<br/>");
915 overview.insert(0, total);
916
917 overview.append("<br/>");
chudy@google.com607357f2012-08-07 16:12:23 +0000918 overview.append("SkPicture Width: ");
chudy@google.com902ebe52012-06-29 14:21:22 +0000919 // NOTE(chudy): This is where we can pull out the SkPictures width.
chudy@google.com607357f2012-08-07 16:12:23 +0000920 overview.append(QString::number(fDebugger.pictureWidth()));
chudy@google.com902ebe52012-06-29 14:21:22 +0000921 overview.append("px<br/>");
chudy@google.com607357f2012-08-07 16:12:23 +0000922 overview.append("SkPicture Height: ");
923 overview.append(QString::number(fDebugger.pictureHeight()));
chudy@google.com902ebe52012-06-29 14:21:22 +0000924 overview.append("px");
chudy@google.com6bd109a2012-08-14 19:34:13 +0000925 fInspectorWidget.setText(overview, SkInspectorWidget::kOverview_TabType);
chudy@google.com902ebe52012-06-29 14:21:22 +0000926
927 // NOTE(chudy): Makes first item unselectable.
chudy@google.com7dcae672012-07-09 20:26:53 +0000928 QStandardItemModel* model = qobject_cast<QStandardItemModel*>(
chudy@google.comc432f002012-07-10 13:19:25 +0000929 fFilter.model());
930 QModelIndex firstIndex = model->index(0, fFilter.modelColumn(),
931 fFilter.rootModelIndex());
chudy@google.com902ebe52012-06-29 14:21:22 +0000932 QStandardItem* firstItem = model->itemFromIndex(firstIndex);
933 firstItem->setSelectable(false);
934}