Theme Editor: Began integrating device configuration panel with renderer
[kugel-rb.git] / utils / themeeditor / gui / editorwindow.cpp
blobb778a1fba45e2c31206fbe513bee0dc0ff1e64ee
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2010 Robert Bieber
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include "editorwindow.h"
23 #include "projectmodel.h"
24 #include "ui_editorwindow.h"
26 #include <QDesktopWidget>
27 #include <QFileSystemModel>
28 #include <QSettings>
29 #include <QFileDialog>
30 #include <QGraphicsScene>
32 EditorWindow::EditorWindow(QWidget *parent) :
33 QMainWindow(parent), ui(new Ui::EditorWindow), parseTreeSelection(0)
35 ui->setupUi(this);
36 prefs = new PreferencesDialog(this);
37 project = 0;
38 setupUI();
39 loadSettings();
40 setupMenus();
44 EditorWindow::~EditorWindow()
46 delete ui;
47 delete prefs;
48 if(project)
49 delete project;
50 delete deviceConfig;
51 delete deviceDock;
54 void EditorWindow::loadTabFromSkinFile(QString fileName)
56 /* Checking to see if the file is already open */
57 for(int i = 0; i < ui->editorTabs->count(); i++)
59 TabContent* current = dynamic_cast<TabContent*>
60 (ui->editorTabs->widget(i));
61 if(current->file() == fileName)
63 ui->editorTabs->setCurrentIndex(i);
64 return;
68 /* Adding a new document*/
69 SkinDocument* doc = new SkinDocument(parseStatus, fileName, project,
70 deviceConfig);
71 addTab(doc);
72 ui->editorTabs->setCurrentWidget(doc);
76 void EditorWindow::loadConfigTab(ConfigDocument* doc)
78 for(int i = 0; i < ui->editorTabs->count(); i++)
80 TabContent* current = dynamic_cast<TabContent*>
81 (ui->editorTabs->widget(i));
82 if(current->file() == doc->file())
84 ui->editorTabs->setCurrentIndex(i);
85 doc->deleteLater();
86 return;
90 addTab(doc);
91 ui->editorTabs->setCurrentWidget(doc);
93 QObject::connect(doc, SIGNAL(titleChanged(QString)),
94 this, SLOT(tabTitleChanged(QString)));
97 void EditorWindow::loadSettings()
100 QSettings settings;
102 /* Main Window location */
103 settings.beginGroup("EditorWindow");
104 QSize size = settings.value("size").toSize();
105 QPoint pos = settings.value("position").toPoint();
106 QByteArray state = settings.value("state").toByteArray();
107 settings.endGroup();
109 if(!(size.isNull() || pos.isNull() || state.isNull()))
111 resize(size);
112 move(pos);
113 restoreState(state);
118 void EditorWindow::saveSettings()
121 QSettings settings;
123 /* Saving window and panel positions */
124 settings.beginGroup("EditorWindow");
125 settings.setValue("position", pos());
126 settings.setValue("size", size());
127 settings.setValue("state", saveState());
128 settings.endGroup();
131 void EditorWindow::setupUI()
133 /* Connecting the tab bar signals */
134 QObject::connect(ui->editorTabs, SIGNAL(currentChanged(int)),
135 this, SLOT(shiftTab(int)));
136 QObject::connect(ui->editorTabs, SIGNAL(tabCloseRequested(int)),
137 this, SLOT(closeTab(int)));
139 /* Connecting the code gen button */
140 QObject::connect(ui->fromTree, SIGNAL(pressed()),
141 this, SLOT(updateCurrent()));
143 /* Connecting the preferences dialog */
144 QObject::connect(ui->actionPreferences, SIGNAL(triggered()),
145 prefs, SLOT(exec()));
147 /* Setting up the parse status label */
148 parseStatus = new QLabel(this);
149 ui->statusbar->addPermanentWidget(parseStatus);
151 /* Setting the selection for parse tree highlighting initially NULL */
152 parseTreeSelection = 0;
154 /* Adding the skin viewer */
155 viewer = new SkinViewer(this);
156 ui->skinPreviewLayout->addWidget(viewer);
158 /* Positioning the device settings dialog */
159 deviceDock = new QDockWidget(tr("Device Configuration"), this);
160 deviceConfig = new DeviceState(deviceDock);
162 deviceDock->setObjectName("deviceDock");
163 deviceDock->setWidget(deviceConfig);
164 deviceDock->setFloating(true);
165 deviceDock->hide();
168 void EditorWindow::setupMenus()
170 /* Connecting panel show actions */
171 QObject::connect(ui->actionFile_Panel, SIGNAL(triggered()),
172 this, SLOT(showPanel()));
173 QObject::connect(ui->actionDisplay_Panel, SIGNAL(triggered()),
174 this, SLOT(showPanel()));
175 QObject::connect(ui->actionPreview_Panel, SIGNAL(triggered()),
176 this, SLOT(showPanel()));
177 QObject::connect(ui->actionDevice_Configuration, SIGNAL(triggered()),
178 deviceDock, SLOT(show()));
180 /* Connecting the document management actions */
181 QObject::connect(ui->actionNew_Document, SIGNAL(triggered()),
182 this, SLOT(newTab()));
183 QObject::connect(ui->actionToolbarNew, SIGNAL(triggered()),
184 this, SLOT(newTab()));
186 QObject::connect(ui->actionClose_Document, SIGNAL(triggered()),
187 this, SLOT(closeCurrent()));
189 QObject::connect(ui->actionSave_Document, SIGNAL(triggered()),
190 this, SLOT(saveCurrent()));
191 QObject::connect(ui->actionSave_Document_As, SIGNAL(triggered()),
192 this, SLOT(saveCurrentAs()));
193 QObject::connect(ui->actionToolbarSave, SIGNAL(triggered()),
194 this, SLOT(saveCurrent()));
196 QObject::connect(ui->actionOpen_Document, SIGNAL(triggered()),
197 this, SLOT(openFile()));
198 QObject::connect(ui->actionToolbarOpen, SIGNAL(triggered()),
199 this, SLOT(openFile()));
201 QObject::connect(ui->actionOpen_Project, SIGNAL(triggered()),
202 this, SLOT(openProject()));
205 void EditorWindow::addTab(TabContent *doc)
207 ui->editorTabs->addTab(doc, doc->title());
209 /* Connecting to title change events */
210 QObject::connect(doc, SIGNAL(titleChanged(QString)),
211 this, SLOT(tabTitleChanged(QString)));
212 QObject::connect(doc, SIGNAL(lineChanged(int)),
213 this, SLOT(lineChanged(int)));
215 /* Connecting to settings change events */
216 if(doc->type() == TabContent::Skin)
217 dynamic_cast<SkinDocument*>(doc)->connectPrefs(prefs);
221 void EditorWindow::newTab()
223 SkinDocument* doc = new SkinDocument(parseStatus, project, deviceConfig);
224 addTab(doc);
225 ui->editorTabs->setCurrentWidget(doc);
228 void EditorWindow::shiftTab(int index)
230 TabContent* widget = dynamic_cast<TabContent*>
231 (ui->editorTabs->currentWidget());
232 if(index < 0)
234 ui->parseTree->setModel(0);
235 ui->actionSave_Document->setEnabled(false);
236 ui->actionSave_Document_As->setEnabled(false);
237 ui->actionClose_Document->setEnabled(false);
238 ui->actionToolbarSave->setEnabled(false);
239 ui->fromTree->setEnabled(false);
240 viewer->setScene(0);
242 else if(widget->type() == TabContent::Config)
244 ui->actionSave_Document->setEnabled(true);
245 ui->actionSave_Document_As->setEnabled(true);
246 ui->actionClose_Document->setEnabled(true);
247 ui->actionToolbarSave->setEnabled(true);
248 viewer->setScene(0);
250 else if(widget->type() == TabContent::Skin)
252 /* Syncing the tree view and the status bar */
253 SkinDocument* doc = dynamic_cast<SkinDocument*>(widget);
254 ui->parseTree->setModel(doc->getModel());
255 parseStatus->setText(doc->getStatus());
257 ui->actionSave_Document->setEnabled(true);
258 ui->actionSave_Document_As->setEnabled(true);
259 ui->actionClose_Document->setEnabled(true);
260 ui->actionToolbarSave->setEnabled(true);
261 ui->fromTree->setEnabled(true);
263 sizeColumns();
265 /* Syncing the preview */
266 viewer->setScene(doc->scene());
271 bool EditorWindow::closeTab(int index)
273 TabContent* widget = dynamic_cast<TabContent*>
274 (ui->editorTabs->widget(index));
275 if(widget->requestClose())
277 ui->editorTabs->removeTab(index);
278 widget->deleteLater();
279 return true;
282 return false;
285 void EditorWindow::closeCurrent()
287 closeTab(ui->editorTabs->currentIndex());
290 void EditorWindow::saveCurrent()
292 if(ui->editorTabs->currentIndex() >= 0)
293 dynamic_cast<TabContent*>(ui->editorTabs->currentWidget())->save();
296 void EditorWindow::saveCurrentAs()
298 if(ui->editorTabs->currentIndex() >= 0)
299 dynamic_cast<TabContent*>(ui->editorTabs->currentWidget())->saveAs();
302 void EditorWindow::openFile()
304 QStringList fileNames;
305 QSettings settings;
307 settings.beginGroup("SkinDocument");
308 QString directory = settings.value("defaultDirectory", "").toString();
309 fileNames = QFileDialog::getOpenFileNames(this, tr("Open Files"), directory,
310 SkinDocument::fileFilter());
312 for(int i = 0; i < fileNames.count(); i++)
314 if(!QFile::exists(fileNames[i]))
315 continue;
317 QString current = fileNames[i];
319 loadTabFromSkinFile(current);
321 /* And setting the new default directory */
322 current.chop(current.length() - current.lastIndexOf('/') - 1);
323 settings.setValue("defaultDirectory", current);
327 settings.endGroup();
330 void EditorWindow::openProject()
332 QString fileName;
333 QSettings settings;
335 settings.beginGroup("ProjectModel");
336 QString directory = settings.value("defaultDirectory", "").toString();
337 fileName = QFileDialog::getOpenFileName(this, tr("Open Project"), directory,
338 ProjectModel::fileFilter());
340 if(QFile::exists(fileName))
343 if(project)
344 delete project;
346 project = new ProjectModel(fileName, this);
347 ui->projectTree->setModel(project);
349 if(project->getSetting("#screenwidth") != "")
350 deviceConfig->setData("screenwidth",
351 project->getSetting("#screenwidth"));
352 if(project->getSetting("#screenheight") != "")
353 deviceConfig->setData("screenheight",
354 project->getSetting("#screenheight"));
356 QObject::connect(ui->projectTree, SIGNAL(activated(QModelIndex)),
357 project, SLOT(activated(QModelIndex)));
359 fileName.chop(fileName.length() - fileName.lastIndexOf('/') - 1);
360 settings.setValue("defaultDirectory", fileName);
362 for(int i = 0; i < ui->editorTabs->count(); i++)
364 TabContent* doc = dynamic_cast<TabContent*>
365 (ui->editorTabs->widget(i));
366 if(doc->type() == TabContent::Skin)
368 dynamic_cast<SkinDocument*>(doc)->setProject(project);
369 if(i == ui->editorTabs->currentIndex())
371 viewer->setScene(dynamic_cast<SkinDocument*>(doc)->scene());
378 settings.endGroup();
382 void EditorWindow::configFileChanged(QString configFile)
385 if(QFile::exists(configFile))
388 if(project)
389 delete project;
391 project = new ProjectModel(configFile, this);
392 ui->projectTree->setModel(project);
394 QObject::connect(ui->projectTree, SIGNAL(activated(QModelIndex)),
395 project, SLOT(activated(QModelIndex)));
397 for(int i = 0; i < ui->editorTabs->count(); i++)
399 TabContent* doc = dynamic_cast<TabContent*>
400 (ui->editorTabs->widget(i));
401 if(doc->type() == TabContent::Skin)
403 dynamic_cast<SkinDocument*>(doc)->setProject(project);
404 if(i == ui->editorTabs->currentIndex())
406 viewer->setScene(dynamic_cast<SkinDocument*>(doc)->scene());
416 void EditorWindow::tabTitleChanged(QString title)
418 TabContent* sender = dynamic_cast<TabContent*>(QObject::sender());
419 ui->editorTabs->setTabText(ui->editorTabs->indexOf(sender), title);
422 void EditorWindow::showPanel()
424 if(sender() == ui->actionFile_Panel)
425 ui->projectDock->setVisible(true);
426 if(sender() == ui->actionPreview_Panel)
427 ui->skinPreviewDock->setVisible(true);
428 if(sender() == ui->actionDisplay_Panel)
429 ui->parseTreeDock->setVisible(true);
432 void EditorWindow::closeEvent(QCloseEvent* event)
435 saveSettings();
437 /* Closing all the tabs */
438 for(int i = 0; i < ui->editorTabs->count(); i++)
440 if(!dynamic_cast<TabContent*>
441 (ui->editorTabs->widget(i))->requestClose())
443 event->ignore();
444 return;
448 event->accept();
451 void EditorWindow::updateCurrent()
453 if(ui->editorTabs->currentIndex() < 0)
454 return;
456 dynamic_cast<SkinDocument*>
457 (ui->editorTabs->currentWidget())->genCode();
460 void EditorWindow::lineChanged(int line)
462 ui->parseTree->collapseAll();
463 ParseTreeModel* model = dynamic_cast<ParseTreeModel*>
464 (ui->parseTree->model());
465 parseTreeSelection = new QItemSelectionModel(model);
466 expandLine(model, QModelIndex(), line);
467 sizeColumns();
468 ui->parseTree->setSelectionModel(parseTreeSelection);
472 void EditorWindow::expandLine(ParseTreeModel* model, QModelIndex parent,
473 int line)
475 for(int i = 0; i < model->rowCount(parent); i++)
477 QModelIndex dataType = model->index(i, ParseTreeModel::typeColumn,
478 parent);
479 QModelIndex dataVal = model->index(i, ParseTreeModel::valueColumn,
480 parent);
481 QModelIndex data = model->index(i, ParseTreeModel::lineColumn, parent);
482 QModelIndex recurse = model->index(i, 0, parent);
484 expandLine(model, recurse, line);
486 if(model->data(data, Qt::DisplayRole) == line)
488 ui->parseTree->expand(parent);
489 ui->parseTree->expand(data);
490 ui->parseTree->scrollTo(parent, QAbstractItemView::PositionAtTop);
492 parseTreeSelection->select(data, QItemSelectionModel::Select);
493 parseTreeSelection->select(dataType, QItemSelectionModel::Select);
494 parseTreeSelection->select(dataVal, QItemSelectionModel::Select);
500 void EditorWindow::sizeColumns()
502 /* Setting the column widths */
503 ui->parseTree->resizeColumnToContents(ParseTreeModel::lineColumn);
504 ui->parseTree->resizeColumnToContents(ParseTreeModel::typeColumn);
505 ui->parseTree->resizeColumnToContents(ParseTreeModel::valueColumn);