Theme Editor: Fixed some compiler warnings and a segfault. Got some basic text rende...
[kugel-rb.git] / utils / themeeditor / gui / editorwindow.cpp
blob81d05c8ed4e1deb0de58103ca725e366523e9cbf
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),
34 ui(new Ui::EditorWindow),
35 parseTreeSelection(0)
37 ui->setupUi(this);
38 prefs = new PreferencesDialog(this);
39 project = 0;
40 loadSettings();
41 setupUI();
42 setupMenus();
45 void EditorWindow::loadTabFromSkinFile(QString fileName)
47 /* Checking to see if the file is already open */
48 for(int i = 0; i < ui->editorTabs->count(); i++)
50 TabContent* current = dynamic_cast<TabContent*>
51 (ui->editorTabs->widget(i));
52 if(current->file() == fileName)
54 ui->editorTabs->setCurrentIndex(i);
55 return;
59 /* Adding a new document*/
60 SkinDocument* doc = new SkinDocument(parseStatus, fileName, project);
61 addTab(doc);
62 ui->editorTabs->setCurrentWidget(doc);
66 void EditorWindow::loadConfigTab(ConfigDocument* doc)
68 for(int i = 0; i < ui->editorTabs->count(); i++)
70 TabContent* current = dynamic_cast<TabContent*>
71 (ui->editorTabs->widget(i));
72 if(current->file() == doc->file())
74 ui->editorTabs->setCurrentIndex(i);
75 doc->deleteLater();
76 return;
80 addTab(doc);
81 ui->editorTabs->setCurrentWidget(doc);
83 QObject::connect(doc, SIGNAL(titleChanged(QString)),
84 this, SLOT(tabTitleChanged(QString)));
87 void EditorWindow::loadSettings()
90 QSettings settings;
92 /* Main Window location */
93 settings.beginGroup("EditorWindow");
94 QSize size = settings.value("size").toSize();
95 QPoint pos = settings.value("position").toPoint();
96 QByteArray state = settings.value("state").toByteArray();
97 settings.endGroup();
99 if(!(size.isNull() || pos.isNull() || state.isNull()))
101 resize(size);
102 move(pos);
103 restoreState(state);
108 void EditorWindow::saveSettings()
111 QSettings settings;
113 /* Saving window and panel positions */
114 settings.beginGroup("EditorWindow");
115 settings.setValue("position", pos());
116 settings.setValue("size", size());
117 settings.setValue("state", saveState());
118 settings.endGroup();
121 void EditorWindow::setupUI()
123 /* Connecting the tab bar signals */
124 QObject::connect(ui->editorTabs, SIGNAL(currentChanged(int)),
125 this, SLOT(shiftTab(int)));
126 QObject::connect(ui->editorTabs, SIGNAL(tabCloseRequested(int)),
127 this, SLOT(closeTab(int)));
129 /* Connecting the code gen button */
130 QObject::connect(ui->fromTree, SIGNAL(pressed()),
131 this, SLOT(updateCurrent()));
133 /* Connecting the preferences dialog */
134 QObject::connect(ui->actionPreferences, SIGNAL(triggered()),
135 prefs, SLOT(exec()));
137 /* Setting up the parse status label */
138 parseStatus = new QLabel(this);
139 ui->statusbar->addPermanentWidget(parseStatus);
141 /* Setting the selection for parse tree highlighting initially NULL */
142 parseTreeSelection = 0;
144 /* Adding the skin viewer */
145 viewer = new SkinViewer(this);
146 ui->skinPreviewLayout->addWidget(viewer);
148 /* Positioning the device settings dialog */
149 QPoint thisPos = pos();
150 deviceConfig.move(thisPos.x() + width() / 4, thisPos.y() + height() / 4);
154 void EditorWindow::setupMenus()
156 /* Connecting panel show actions */
157 QObject::connect(ui->actionFile_Panel, SIGNAL(triggered()),
158 this, SLOT(showPanel()));
159 QObject::connect(ui->actionDisplay_Panel, SIGNAL(triggered()),
160 this, SLOT(showPanel()));
161 QObject::connect(ui->actionPreview_Panel, SIGNAL(triggered()),
162 this, SLOT(showPanel()));
163 QObject::connect(ui->actionDevice_Configuration, SIGNAL(triggered()),
164 &deviceConfig, SLOT(show()));
166 /* Connecting the document management actions */
167 QObject::connect(ui->actionNew_Document, SIGNAL(triggered()),
168 this, SLOT(newTab()));
169 QObject::connect(ui->actionToolbarNew, SIGNAL(triggered()),
170 this, SLOT(newTab()));
172 QObject::connect(ui->actionClose_Document, SIGNAL(triggered()),
173 this, SLOT(closeCurrent()));
175 QObject::connect(ui->actionSave_Document, SIGNAL(triggered()),
176 this, SLOT(saveCurrent()));
177 QObject::connect(ui->actionSave_Document_As, SIGNAL(triggered()),
178 this, SLOT(saveCurrentAs()));
179 QObject::connect(ui->actionToolbarSave, SIGNAL(triggered()),
180 this, SLOT(saveCurrent()));
182 QObject::connect(ui->actionOpen_Document, SIGNAL(triggered()),
183 this, SLOT(openFile()));
184 QObject::connect(ui->actionToolbarOpen, SIGNAL(triggered()),
185 this, SLOT(openFile()));
187 QObject::connect(ui->actionOpen_Project, SIGNAL(triggered()),
188 this, SLOT(openProject()));
191 void EditorWindow::addTab(TabContent *doc)
193 ui->editorTabs->addTab(doc, doc->title());
195 /* Connecting to title change events */
196 QObject::connect(doc, SIGNAL(titleChanged(QString)),
197 this, SLOT(tabTitleChanged(QString)));
198 QObject::connect(doc, SIGNAL(lineChanged(int)),
199 this, SLOT(lineChanged(int)));
201 /* Connecting to settings change events */
202 if(doc->type() == TabContent::Skin)
203 dynamic_cast<SkinDocument*>(doc)->connectPrefs(prefs);
207 void EditorWindow::newTab()
209 SkinDocument* doc = new SkinDocument(parseStatus, project);
210 addTab(doc);
211 ui->editorTabs->setCurrentWidget(doc);
214 void EditorWindow::shiftTab(int index)
216 TabContent* widget = dynamic_cast<TabContent*>
217 (ui->editorTabs->currentWidget());
218 if(index < 0)
220 ui->parseTree->setModel(0);
221 ui->actionSave_Document->setEnabled(false);
222 ui->actionSave_Document_As->setEnabled(false);
223 ui->actionClose_Document->setEnabled(false);
224 ui->actionToolbarSave->setEnabled(false);
225 ui->fromTree->setEnabled(false);
226 viewer->setScene(0);
228 else if(widget->type() == TabContent::Config)
230 ui->actionSave_Document->setEnabled(true);
231 ui->actionSave_Document_As->setEnabled(true);
232 ui->actionClose_Document->setEnabled(true);
233 ui->actionToolbarSave->setEnabled(true);
234 viewer->setScene(0);
236 else if(widget->type() == TabContent::Skin)
238 /* Syncing the tree view and the status bar */
239 SkinDocument* doc = dynamic_cast<SkinDocument*>(widget);
240 ui->parseTree->setModel(doc->getModel());
241 parseStatus->setText(doc->getStatus());
243 ui->actionSave_Document->setEnabled(true);
244 ui->actionSave_Document_As->setEnabled(true);
245 ui->actionClose_Document->setEnabled(true);
246 ui->actionToolbarSave->setEnabled(true);
247 ui->fromTree->setEnabled(true);
249 sizeColumns();
251 /* Syncing the preview */
252 viewer->setScene(doc->scene());
257 bool EditorWindow::closeTab(int index)
259 TabContent* widget = dynamic_cast<TabContent*>
260 (ui->editorTabs->widget(index));
261 if(widget->requestClose())
263 ui->editorTabs->removeTab(index);
264 widget->deleteLater();
265 return true;
268 return false;
271 void EditorWindow::closeCurrent()
273 closeTab(ui->editorTabs->currentIndex());
276 void EditorWindow::saveCurrent()
278 if(ui->editorTabs->currentIndex() >= 0)
279 dynamic_cast<TabContent*>(ui->editorTabs->currentWidget())->save();
282 void EditorWindow::saveCurrentAs()
284 if(ui->editorTabs->currentIndex() >= 0)
285 dynamic_cast<TabContent*>(ui->editorTabs->currentWidget())->saveAs();
288 void EditorWindow::openFile()
290 QStringList fileNames;
291 QSettings settings;
293 settings.beginGroup("SkinDocument");
294 QString directory = settings.value("defaultDirectory", "").toString();
295 fileNames = QFileDialog::getOpenFileNames(this, tr("Open Files"), directory,
296 SkinDocument::fileFilter());
298 for(int i = 0; i < fileNames.count(); i++)
300 if(!QFile::exists(fileNames[i]))
301 continue;
303 QString current = fileNames[i];
305 loadTabFromSkinFile(current);
307 /* And setting the new default directory */
308 current.chop(current.length() - current.lastIndexOf('/') - 1);
309 settings.setValue("defaultDirectory", current);
313 settings.endGroup();
316 void EditorWindow::openProject()
318 QString fileName;
319 QSettings settings;
321 settings.beginGroup("ProjectModel");
322 QString directory = settings.value("defaultDirectory", "").toString();
323 fileName = QFileDialog::getOpenFileName(this, tr("Open Project"), directory,
324 ProjectModel::fileFilter());
326 if(QFile::exists(fileName))
329 if(project)
330 delete project;
332 project = new ProjectModel(fileName, this);
333 ui->projectTree->setModel(project);
335 QObject::connect(ui->projectTree, SIGNAL(activated(QModelIndex)),
336 project, SLOT(activated(QModelIndex)));
338 fileName.chop(fileName.length() - fileName.lastIndexOf('/') - 1);
339 settings.setValue("defaultDirectory", fileName);
341 for(int i = 0; i < ui->editorTabs->count(); i++)
343 TabContent* doc = dynamic_cast<TabContent*>
344 (ui->editorTabs->widget(i));
345 if(doc->type() == TabContent::Skin)
347 dynamic_cast<SkinDocument*>(doc)->setProject(project);
348 if(i == ui->editorTabs->currentIndex())
350 viewer->setScene(dynamic_cast<SkinDocument*>(doc)->scene());
357 settings.endGroup();
361 void EditorWindow::configFileChanged(QString configFile)
364 if(QFile::exists(configFile))
367 if(project)
368 delete project;
370 project = new ProjectModel(configFile, this);
371 ui->projectTree->setModel(project);
373 QObject::connect(ui->projectTree, SIGNAL(activated(QModelIndex)),
374 project, SLOT(activated(QModelIndex)));
376 for(int i = 0; i < ui->editorTabs->count(); i++)
378 TabContent* doc = dynamic_cast<TabContent*>
379 (ui->editorTabs->widget(i));
380 if(doc->type() == TabContent::Skin)
382 dynamic_cast<SkinDocument*>(doc)->setProject(project);
383 if(i == ui->editorTabs->currentIndex())
385 viewer->setScene(dynamic_cast<SkinDocument*>(doc)->scene());
395 void EditorWindow::tabTitleChanged(QString title)
397 TabContent* sender = dynamic_cast<TabContent*>(QObject::sender());
398 ui->editorTabs->setTabText(ui->editorTabs->indexOf(sender), title);
401 void EditorWindow::showPanel()
403 if(sender() == ui->actionFile_Panel)
404 ui->projectDock->setVisible(true);
405 if(sender() == ui->actionPreview_Panel)
406 ui->skinPreviewDock->setVisible(true);
407 if(sender() == ui->actionDisplay_Panel)
408 ui->parseTreeDock->setVisible(true);
411 void EditorWindow::closeEvent(QCloseEvent* event)
414 saveSettings();
416 /* Closing all the tabs */
417 for(int i = 0; i < ui->editorTabs->count(); i++)
419 if(!dynamic_cast<TabContent*>
420 (ui->editorTabs->widget(i))->requestClose())
422 event->ignore();
423 return;
427 event->accept();
430 void EditorWindow::updateCurrent()
432 if(ui->editorTabs->currentIndex() < 0)
433 return;
435 dynamic_cast<SkinDocument*>
436 (ui->editorTabs->currentWidget())->genCode();
439 void EditorWindow::lineChanged(int line)
441 ui->parseTree->collapseAll();
442 ParseTreeModel* model = dynamic_cast<ParseTreeModel*>
443 (ui->parseTree->model());
444 parseTreeSelection = new QItemSelectionModel(model);
445 expandLine(model, QModelIndex(), line);
446 sizeColumns();
447 ui->parseTree->setSelectionModel(parseTreeSelection);
451 void EditorWindow::expandLine(ParseTreeModel* model, QModelIndex parent,
452 int line)
454 for(int i = 0; i < model->rowCount(parent); i++)
456 QModelIndex dataType = model->index(i, ParseTreeModel::typeColumn,
457 parent);
458 QModelIndex dataVal = model->index(i, ParseTreeModel::valueColumn,
459 parent);
460 QModelIndex data = model->index(i, ParseTreeModel::lineColumn, parent);
461 QModelIndex recurse = model->index(i, 0, parent);
463 expandLine(model, recurse, line);
465 if(model->data(data, Qt::DisplayRole) == line)
467 ui->parseTree->expand(parent);
468 ui->parseTree->expand(data);
469 ui->parseTree->scrollTo(parent, QAbstractItemView::PositionAtTop);
471 parseTreeSelection->select(data, QItemSelectionModel::Select);
472 parseTreeSelection->select(dataType, QItemSelectionModel::Select);
473 parseTreeSelection->select(dataVal, QItemSelectionModel::Select);
479 void EditorWindow::sizeColumns()
481 /* Setting the column widths */
482 ui->parseTree->resizeColumnToContents(ParseTreeModel::lineColumn);
483 ui->parseTree->resizeColumnToContents(ParseTreeModel::typeColumn);
484 ui->parseTree->resizeColumnToContents(ParseTreeModel::valueColumn);
487 EditorWindow::~EditorWindow()
489 delete ui;
490 delete prefs;
491 if(project)
492 delete project;