2bd3b5343ee40753fbf2c3328d76c0407060ceef
[kugel-rb.git] / utils / themeeditor / gui / editorwindow.cpp
blob2bd3b5343ee40753fbf2c3328d76c0407060ceef
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)
36 ui->setupUi(this);
37 prefs = new PreferencesDialog(this);
38 project = 0;
39 loadSettings();
40 setupUI();
41 setupMenus();
44 void EditorWindow::loadTabFromSkinFile(QString fileName)
46 /* Checking to see if the file is already open */
47 for(int i = 0; i < ui->editorTabs->count(); i++)
49 TabContent* current = dynamic_cast<TabContent*>
50 (ui->editorTabs->widget(i));
51 if(current->file() == fileName)
53 ui->editorTabs->setCurrentIndex(i);
54 return;
58 /* Adding a new document*/
59 SkinDocument* doc = new SkinDocument(parseStatus, fileName, project);
60 addTab(doc);
61 ui->editorTabs->setCurrentWidget(doc);
65 void EditorWindow::loadConfigTab(ConfigDocument* doc)
67 for(int i = 0; i < ui->editorTabs->count(); i++)
69 TabContent* current = dynamic_cast<TabContent*>
70 (ui->editorTabs->widget(i));
71 if(current->file() == doc->file())
73 ui->editorTabs->setCurrentIndex(i);
74 doc->deleteLater();
75 return;
79 addTab(doc);
80 ui->editorTabs->setCurrentWidget(doc);
82 QObject::connect(doc, SIGNAL(titleChanged(QString)),
83 this, SLOT(tabTitleChanged(QString)));
86 void EditorWindow::loadSettings()
89 QSettings settings;
91 /* Main Window location */
92 settings.beginGroup("EditorWindow");
93 QSize size = settings.value("size").toSize();
94 QPoint pos = settings.value("position").toPoint();
95 QByteArray state = settings.value("state").toByteArray();
96 settings.endGroup();
98 if(!(size.isNull() || pos.isNull() || state.isNull()))
100 resize(size);
101 move(pos);
102 restoreState(state);
107 void EditorWindow::saveSettings()
110 QSettings settings;
112 /* Saving window and panel positions */
113 settings.beginGroup("EditorWindow");
114 settings.setValue("position", pos());
115 settings.setValue("size", size());
116 settings.setValue("state", saveState());
117 settings.endGroup();
120 void EditorWindow::setupUI()
122 /* Connecting the tab bar signals */
123 QObject::connect(ui->editorTabs, SIGNAL(currentChanged(int)),
124 this, SLOT(shiftTab(int)));
125 QObject::connect(ui->editorTabs, SIGNAL(tabCloseRequested(int)),
126 this, SLOT(closeTab(int)));
128 /* Connecting the code gen button */
129 QObject::connect(ui->fromTree, SIGNAL(pressed()),
130 this, SLOT(updateCurrent()));
132 /* Connecting the preferences dialog */
133 QObject::connect(ui->actionPreferences, SIGNAL(triggered()),
134 prefs, SLOT(exec()));
136 /* Setting up the parse status label */
137 parseStatus = new QLabel(this);
138 ui->statusbar->addPermanentWidget(parseStatus);
140 /* Setting the selection for parse tree highlighting initially NULL */
141 parseTreeSelection = 0;
143 /* Adding the skin viewer */
144 viewer = new SkinViewer(this);
145 ui->skinPreviewLayout->addWidget(viewer);
149 void EditorWindow::setupMenus()
151 /* Connecting panel show actions */
152 QObject::connect(ui->actionFile_Panel, SIGNAL(triggered()),
153 this, SLOT(showPanel()));
154 QObject::connect(ui->actionDisplay_Panel, SIGNAL(triggered()),
155 this, SLOT(showPanel()));
156 QObject::connect(ui->actionPreview_Panel, SIGNAL(triggered()),
157 this, SLOT(showPanel()));
158 QObject::connect(ui->actionDevice_Configuration, SIGNAL(triggered()),
159 &deviceConfig, SLOT(show()));
161 /* Connecting the document management actions */
162 QObject::connect(ui->actionNew_Document, SIGNAL(triggered()),
163 this, SLOT(newTab()));
164 QObject::connect(ui->actionToolbarNew, SIGNAL(triggered()),
165 this, SLOT(newTab()));
167 QObject::connect(ui->actionClose_Document, SIGNAL(triggered()),
168 this, SLOT(closeCurrent()));
170 QObject::connect(ui->actionSave_Document, SIGNAL(triggered()),
171 this, SLOT(saveCurrent()));
172 QObject::connect(ui->actionSave_Document_As, SIGNAL(triggered()),
173 this, SLOT(saveCurrentAs()));
174 QObject::connect(ui->actionToolbarSave, SIGNAL(triggered()),
175 this, SLOT(saveCurrent()));
177 QObject::connect(ui->actionOpen_Document, SIGNAL(triggered()),
178 this, SLOT(openFile()));
179 QObject::connect(ui->actionToolbarOpen, SIGNAL(triggered()),
180 this, SLOT(openFile()));
182 QObject::connect(ui->actionOpen_Project, SIGNAL(triggered()),
183 this, SLOT(openProject()));
186 void EditorWindow::addTab(TabContent *doc)
188 ui->editorTabs->addTab(doc, doc->title());
190 /* Connecting to title change events */
191 QObject::connect(doc, SIGNAL(titleChanged(QString)),
192 this, SLOT(tabTitleChanged(QString)));
193 QObject::connect(doc, SIGNAL(lineChanged(int)),
194 this, SLOT(lineChanged(int)));
196 /* Connecting to settings change events */
197 if(doc->type() == TabContent::Skin)
198 dynamic_cast<SkinDocument*>(doc)->connectPrefs(prefs);
202 void EditorWindow::newTab()
204 SkinDocument* doc = new SkinDocument(parseStatus, project);
205 addTab(doc);
206 ui->editorTabs->setCurrentWidget(doc);
209 void EditorWindow::shiftTab(int index)
211 TabContent* widget = dynamic_cast<TabContent*>
212 (ui->editorTabs->currentWidget());
213 if(index < 0)
215 ui->parseTree->setModel(0);
216 ui->actionSave_Document->setEnabled(false);
217 ui->actionSave_Document_As->setEnabled(false);
218 ui->actionClose_Document->setEnabled(false);
219 ui->actionToolbarSave->setEnabled(false);
220 ui->fromTree->setEnabled(false);
221 viewer->setScene(0);
223 else if(widget->type() == TabContent::Config)
225 ui->actionSave_Document->setEnabled(true);
226 ui->actionSave_Document_As->setEnabled(true);
227 ui->actionClose_Document->setEnabled(true);
228 ui->actionToolbarSave->setEnabled(true);
229 viewer->setScene(0);
231 else if(widget->type() == TabContent::Skin)
233 /* Syncing the tree view and the status bar */
234 SkinDocument* doc = dynamic_cast<SkinDocument*>(widget);
235 ui->parseTree->setModel(doc->getModel());
236 parseStatus->setText(doc->getStatus());
238 ui->actionSave_Document->setEnabled(true);
239 ui->actionSave_Document_As->setEnabled(true);
240 ui->actionClose_Document->setEnabled(true);
241 ui->actionToolbarSave->setEnabled(true);
242 ui->fromTree->setEnabled(true);
244 sizeColumns();
246 /* Syncing the preview */
247 viewer->setScene(doc->scene());
252 bool EditorWindow::closeTab(int index)
254 TabContent* widget = dynamic_cast<TabContent*>
255 (ui->editorTabs->widget(index));
256 if(widget->requestClose())
258 ui->editorTabs->removeTab(index);
259 widget->deleteLater();
260 return true;
263 return false;
266 void EditorWindow::closeCurrent()
268 closeTab(ui->editorTabs->currentIndex());
271 void EditorWindow::saveCurrent()
273 if(ui->editorTabs->currentIndex() >= 0)
274 dynamic_cast<TabContent*>(ui->editorTabs->currentWidget())->save();
277 void EditorWindow::saveCurrentAs()
279 if(ui->editorTabs->currentIndex() >= 0)
280 dynamic_cast<TabContent*>(ui->editorTabs->currentWidget())->saveAs();
283 void EditorWindow::openFile()
285 QStringList fileNames;
286 QSettings settings;
288 settings.beginGroup("SkinDocument");
289 QString directory = settings.value("defaultDirectory", "").toString();
290 fileNames = QFileDialog::getOpenFileNames(this, tr("Open Files"), directory,
291 SkinDocument::fileFilter());
293 for(int i = 0; i < fileNames.count(); i++)
295 if(!QFile::exists(fileNames[i]))
296 continue;
298 QString current = fileNames[i];
300 loadTabFromSkinFile(current);
302 /* And setting the new default directory */
303 current.chop(current.length() - current.lastIndexOf('/') - 1);
304 settings.setValue("defaultDirectory", current);
308 settings.endGroup();
311 void EditorWindow::openProject()
313 QString fileName;
314 QSettings settings;
316 settings.beginGroup("ProjectModel");
317 QString directory = settings.value("defaultDirectory", "").toString();
318 fileName = QFileDialog::getOpenFileName(this, tr("Open Project"), directory,
319 ProjectModel::fileFilter());
321 if(QFile::exists(fileName))
324 if(project)
325 delete project;
327 project = new ProjectModel(fileName, this);
328 ui->projectTree->setModel(project);
330 QObject::connect(ui->projectTree, SIGNAL(activated(QModelIndex)),
331 project, SLOT(activated(QModelIndex)));
333 fileName.chop(fileName.length() - fileName.lastIndexOf('/') - 1);
334 settings.setValue("defaultDirectory", fileName);
336 for(int i = 0; i < ui->editorTabs->count(); i++)
338 TabContent* doc = dynamic_cast<TabContent*>
339 (ui->editorTabs->widget(i));
340 if(doc->type() == TabContent::Skin)
342 dynamic_cast<SkinDocument*>(doc)->setProject(project);
343 if(i == ui->editorTabs->currentIndex())
345 viewer->setScene(dynamic_cast<SkinDocument*>(doc)->scene());
352 settings.endGroup();
356 void EditorWindow::configFileChanged(QString configFile)
359 if(QFile::exists(configFile))
362 if(project)
363 delete project;
365 project = new ProjectModel(configFile, this);
366 ui->projectTree->setModel(project);
368 QObject::connect(ui->projectTree, SIGNAL(activated(QModelIndex)),
369 project, SLOT(activated(QModelIndex)));
371 for(int i = 0; i < ui->editorTabs->count(); i++)
373 TabContent* doc = dynamic_cast<TabContent*>
374 (ui->editorTabs->widget(i));
375 if(doc->type() == TabContent::Skin)
377 dynamic_cast<SkinDocument*>(doc)->setProject(project);
378 if(i == ui->editorTabs->currentIndex())
380 viewer->setScene(dynamic_cast<SkinDocument*>(doc)->scene());
390 void EditorWindow::tabTitleChanged(QString title)
392 TabContent* sender = dynamic_cast<TabContent*>(QObject::sender());
393 ui->editorTabs->setTabText(ui->editorTabs->indexOf(sender), title);
396 void EditorWindow::showPanel()
398 if(sender() == ui->actionFile_Panel)
399 ui->projectDock->setVisible(true);
400 if(sender() == ui->actionPreview_Panel)
401 ui->skinPreviewDock->setVisible(true);
402 if(sender() == ui->actionDisplay_Panel)
403 ui->parseTreeDock->setVisible(true);
406 void EditorWindow::closeEvent(QCloseEvent* event)
409 saveSettings();
411 /* Closing all the tabs */
412 for(int i = 0; i < ui->editorTabs->count(); i++)
414 if(!dynamic_cast<TabContent*>
415 (ui->editorTabs->widget(i))->requestClose())
417 event->ignore();
418 return;
422 event->accept();
425 void EditorWindow::updateCurrent()
427 if(ui->editorTabs->currentIndex() < 0)
428 return;
430 dynamic_cast<SkinDocument*>
431 (ui->editorTabs->currentWidget())->genCode();
434 void EditorWindow::lineChanged(int line)
436 ui->parseTree->collapseAll();
437 if(parseTreeSelection)
438 parseTreeSelection->deleteLater();
439 ParseTreeModel* model = dynamic_cast<ParseTreeModel*>
440 (ui->parseTree->model());
441 parseTreeSelection = new QItemSelectionModel(model);
442 expandLine(model, QModelIndex(), line);
443 sizeColumns();
444 ui->parseTree->setSelectionModel(parseTreeSelection);
448 void EditorWindow::expandLine(ParseTreeModel* model, QModelIndex parent,
449 int line)
451 for(int i = 0; i < model->rowCount(parent); i++)
453 QModelIndex dataType = model->index(i, ParseTreeModel::typeColumn,
454 parent);
455 QModelIndex dataVal = model->index(i, ParseTreeModel::valueColumn,
456 parent);
457 QModelIndex data = model->index(i, ParseTreeModel::lineColumn, parent);
458 QModelIndex recurse = model->index(i, 0, parent);
460 expandLine(model, recurse, line);
462 if(model->data(data, Qt::DisplayRole) == line)
464 ui->parseTree->expand(parent);
465 ui->parseTree->expand(data);
466 ui->parseTree->scrollTo(parent, QAbstractItemView::PositionAtTop);
468 parseTreeSelection->select(data, QItemSelectionModel::Select);
469 parseTreeSelection->select(dataType, QItemSelectionModel::Select);
470 parseTreeSelection->select(dataVal, QItemSelectionModel::Select);
476 void EditorWindow::sizeColumns()
478 /* Setting the column widths */
479 ui->parseTree->resizeColumnToContents(ParseTreeModel::lineColumn);
480 ui->parseTree->resizeColumnToContents(ParseTreeModel::typeColumn);
481 ui->parseTree->resizeColumnToContents(ParseTreeModel::valueColumn);
484 EditorWindow::~EditorWindow()
486 delete ui;
487 delete prefs;
488 if(project)
489 delete project;