• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017 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 
8 #include <QtWidgets>
9 
10 #include "MainWindow.h"
11 
MainWindow()12 MainWindow::MainWindow() {
13     this->createActions();
14     this->createStatusBar();
15     this->createDockWindows();
16 
17     this->setWindowTitle("MDB Viz");
18 
19     this->readSettings();
20     this->setUnifiedTitleAndToolBarOnMac(true);
21 }
22 
openFile()23 void MainWindow::openFile() {
24     QString fileName = QFileDialog::getOpenFileName(this);
25     if (!fileName.isEmpty()) {
26         this->loadFile(fileName);
27     }
28 }
29 
setupOpsTaskWidget()30 void MainWindow::setupOpsTaskWidget() {
31     fOpsTaskWidget->clear();
32 
33     QTreeWidgetItem* item = nullptr;
34     SkTDArray<QTreeWidgetItem*> parents;
35 
36     for (int i = 0; i < fModel.numOps(); i++) {
37         item = new QTreeWidgetItem();
38 
39         item->setText(0, QString::number(i));
40         item->setData(0, Qt::UserRole, i);
41         item->setText(1, fModel.getOpName(i));
42 
43         if (fModel.isHierarchyPop(i)) {
44             parents.pop();
45         }
46 
47         if (parents.isEmpty()) {
48             fOpsTaskWidget->addTopLevelItem(item);
49         } else {
50             parents.top()->addChild(item);
51         }
52 
53         if (fModel.isHierarchyPush(i)) {
54             *parents.push() = item;
55         }
56     }
57 
58     fOpsTaskWidget->setCurrentItem(item);
59     fOpsTaskWidget->expandToDepth(100);
60 }
61 
presentCurrentRenderState()62 void MainWindow::presentCurrentRenderState() {
63     fImage = QImage((uchar*)fModel.getPixels(), fModel.width(), fModel.height(),
64                     QImage::Format_RGBA8888);
65     fImageLabel->setPixmap(QPixmap::fromImage(fImage));
66 }
67 
loadFile(const QString & fileName)68 void MainWindow::loadFile(const QString &fileName) {
69     QFile file(fileName);
70     if (!file.open(QFile::ReadOnly | QFile::Text)) {
71         QMessageBox::warning(this, tr("MDB Viz"),
72                              tr("Cannot read file %1:\n%2.")
73                              .arg(QDir::toNativeSeparators(fileName), file.errorString()));
74         return;
75     }
76 
77     QTextStream in(&file);
78 #ifndef QT_NO_CURSOR
79     QApplication::setOverrideCursor(Qt::WaitCursor);
80 #endif
81 
82     std::string str = file.fileName().toLocal8Bit().constData();
83 
84     Model::ErrorCode err = fModel.load(str.c_str());
85     if (Model::ErrorCode::kOK != err) {
86         this->statusBar()->showMessage(Model::ErrorString(err));
87         return;
88     }
89 
90     this->setupOpsTaskWidget();
91     this->presentCurrentRenderState();
92 
93 #ifndef QT_NO_CURSOR
94     QApplication::restoreOverrideCursor();
95 #endif
96 }
97 
98 
about()99 void MainWindow::about() {
100    QMessageBox::about(this, "About MDB Viz", "Visualize MDB");
101 }
102 
createActions()103 void MainWindow::createActions() {
104 
105     // File menu
106     QMenu* fileMenu = this->menuBar()->addMenu(tr("&File"));
107     QToolBar* fileToolBar = this->addToolBar(tr("File"));
108 
109     const QIcon openIcon = QIcon::fromTheme("document-open", QIcon(":/images/open.png"));
110     QAction* openAct = new QAction(openIcon, tr("&Open..."), this);
111     openAct->setShortcuts(QKeySequence::Open);
112     openAct->setStatusTip(tr("Open an existing file"));
113     connect(openAct, &QAction::triggered, this, &MainWindow::openFile);
114     fileMenu->addAction(openAct);
115     fileToolBar->addAction(openAct);
116 
117     fileMenu->addSeparator();
118 
119     const QIcon exitIcon = QIcon::fromTheme("application-exit");
120     QAction *exitAct = fileMenu->addAction(exitIcon, tr("E&xit"), this, &QWidget::close);
121     exitAct->setShortcuts(QKeySequence::Quit);
122     exitAct->setStatusTip(tr("Exit the application"));
123 
124     // View menu
125     fViewMenu = this->menuBar()->addMenu(tr("&View"));
126 
127     // Help menu
128     this->menuBar()->addSeparator();
129 
130     QMenu* helpMenu = this->menuBar()->addMenu(tr("&Help"));
131 
132     QAction *aboutAct = helpMenu->addAction(tr("&About"), this, &MainWindow::about);
133     aboutAct->setStatusTip(tr("Show the application's About box"));
134 }
135 
onCurrentItemChanged(QTreeWidgetItem * cur,QTreeWidgetItem *)136 void MainWindow::onCurrentItemChanged(QTreeWidgetItem* cur, QTreeWidgetItem* /* prev */) {
137     int currentRow = cur->data(0, Qt::UserRole).toInt();
138     fModel.setCurOp(currentRow);
139     this->presentCurrentRenderState();
140 }
141 
createStatusBar()142 void MainWindow::createStatusBar() {
143     this->statusBar()->showMessage(tr("Ready"));
144 }
145 
createDockWindows()146 void MainWindow::createDockWindows() {
147 
148     // Op List Window
149     {
150         QDockWidget* opsTaskDock = new QDockWidget("Ops", this);
151         opsTaskDock->setAllowedAreas(Qt::LeftDockWidgetArea);
152 
153         fOpsTaskWidget = new QTreeWidget(opsTaskDock);
154 
155         QTreeWidgetItem* headerItem = new QTreeWidgetItem;
156         headerItem->setText(0, "Index");
157         headerItem->setText(1, "Op Name");
158         fOpsTaskWidget->setHeaderItem(headerItem);
159 
160         fOpsTaskWidget->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
161         fOpsTaskWidget->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
162 
163         opsTaskDock->setWidget(fOpsTaskWidget);
164         this->addDockWidget(Qt::LeftDockWidgetArea, opsTaskDock);
165 
166         fViewMenu->addAction(opsTaskDock->toggleViewAction());
167 
168         connect(fOpsTaskWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
169                 this, SLOT(onCurrentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)));
170     }
171 
172     // Main canvas Window
173     {
174         QDockWidget* mainCanvasDock = new QDockWidget("Main Canvas", this);
175         mainCanvasDock->setAllowedAreas(Qt::RightDockWidgetArea);
176 
177         fImageLabel = new QLabel(mainCanvasDock);
178 
179         fImage = QImage(1024, 1024, QImage::Format_RGBA8888);
180         fImage.fill(0);
181         fImageLabel->setPixmap(QPixmap::fromImage(fImage));
182 
183         mainCanvasDock->setWidget(fImageLabel);
184         this->addDockWidget(Qt::RightDockWidgetArea, mainCanvasDock);
185 
186         fViewMenu->addAction(mainCanvasDock->toggleViewAction());
187     }
188 }
189 
readSettings()190 void MainWindow::readSettings() {
191     QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName());
192     const QByteArray geometry = settings.value("geometry", QByteArray()).toByteArray();
193     if (geometry.isEmpty()) {
194         const QRect availableGeometry = QApplication::desktop()->availableGeometry(this);
195         resize(availableGeometry.width() / 3, availableGeometry.height() / 2);
196         move((availableGeometry.width() - width()) / 2,
197              (availableGeometry.height() - height()) / 2);
198     } else {
199         this->restoreGeometry(geometry);
200     }
201 }
202 
writeSettings()203 void MainWindow::writeSettings() {
204     QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName());
205     settings.setValue("geometry", this->saveGeometry());
206 }
207