Theme Editor: Items from line under cursor now selected in parse tree view
[kugel-rb.git] / utils / themeeditor / editorwindow.cpp
blob0721ee913134216159d87283be989aa7af7b36a6
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>
31 EditorWindow::EditorWindow(QWidget *parent) :
32 QMainWindow(parent),
33 ui(new Ui::EditorWindow)
35 ui->setupUi(this);
36 prefs = new PreferencesDialog(this);
37 project = 0;
38 loadSettings();
39 setupUI();
40 setupMenus();
43 void EditorWindow::loadTabFromSkinFile(QString fileName)
45 /* Checking to see if the file is already open */
46 for(int i = 0; i < ui->editorTabs->count(); i++)
48 TabContent* current = dynamic_cast<TabContent*>
49 (ui->editorTabs->widget(i));
50 if(current->file() == fileName)
52 ui->editorTabs->setCurrentIndex(i);
53 return;
57 /* Adding a new document*/
58 SkinDocument* doc = new SkinDocument(parseStatus, fileName);
59 addTab(doc);
60 ui->editorTabs->setCurrentWidget(doc);
64 void EditorWindow::loadConfigTab(ConfigDocument* doc)
66 for(int i = 0; i < ui->editorTabs->count(); i++)
68 TabContent* current = dynamic_cast<TabContent*>
69 (ui->editorTabs->widget(i));
70 if(current->file() == doc->file())
72 ui->editorTabs->setCurrentIndex(i);
73 doc->deleteLater();
74 return;
78 addTab(doc);
79 ui->editorTabs->setCurrentWidget(doc);
81 QObject::connect(doc, SIGNAL(titleChanged(QString)),
82 this, SLOT(tabTitleChanged(QString)));
85 void EditorWindow::loadSettings()
88 QSettings settings;
90 /* Main Window location */
91 settings.beginGroup("EditorWindow");
92 QSize size = settings.value("size").toSize();
93 QPoint pos = settings.value("position").toPoint();
94 QByteArray state = settings.value("state").toByteArray();
95 settings.endGroup();
97 if(!(size.isNull() || pos.isNull() || state.isNull()))
99 resize(size);
100 move(pos);
101 restoreState(state);
106 void EditorWindow::saveSettings()
109 QSettings settings;
111 /* Saving window and panel positions */
112 settings.beginGroup("EditorWindow");
113 settings.setValue("position", pos());
114 settings.setValue("size", size());
115 settings.setValue("state", saveState());
116 settings.endGroup();
119 void EditorWindow::setupUI()
121 /* Connecting the tab bar signals */
122 QObject::connect(ui->editorTabs, SIGNAL(currentChanged(int)),
123 this, SLOT(shiftTab(int)));
124 QObject::connect(ui->editorTabs, SIGNAL(tabCloseRequested(int)),
125 this, SLOT(closeTab(int)));
127 /* Connecting the code gen button */
128 QObject::connect(ui->fromTree, SIGNAL(pressed()),
129 this, SLOT(updateCurrent()));
131 /* Connecting the preferences dialog */
132 QObject::connect(ui->actionPreferences, SIGNAL(triggered()),
133 prefs, SLOT(exec()));
135 /* Setting up the parse status label */
136 parseStatus = new QLabel(this);
137 ui->statusbar->addPermanentWidget(parseStatus);
139 parseTreeSelection = 0;
142 void EditorWindow::setupMenus()
144 /* Connecting panel show actions */
145 QObject::connect(ui->actionFile_Panel, SIGNAL(triggered()),
146 this, SLOT(showPanel()));
147 QObject::connect(ui->actionDisplay_Panel, SIGNAL(triggered()),
148 this, SLOT(showPanel()));
149 QObject::connect(ui->actionPreview_Panel, SIGNAL(triggered()),
150 this, SLOT(showPanel()));
152 /* Connecting the document management actions */
153 QObject::connect(ui->actionNew_Document, SIGNAL(triggered()),
154 this, SLOT(newTab()));
155 QObject::connect(ui->actionToolbarNew, SIGNAL(triggered()),
156 this, SLOT(newTab()));
158 QObject::connect(ui->actionClose_Document, SIGNAL(triggered()),
159 this, SLOT(closeCurrent()));
161 QObject::connect(ui->actionSave_Document, SIGNAL(triggered()),
162 this, SLOT(saveCurrent()));
163 QObject::connect(ui->actionSave_Document_As, SIGNAL(triggered()),
164 this, SLOT(saveCurrentAs()));
165 QObject::connect(ui->actionToolbarSave, SIGNAL(triggered()),
166 this, SLOT(saveCurrent()));
168 QObject::connect(ui->actionOpen_Document, SIGNAL(triggered()),
169 this, SLOT(openFile()));
170 QObject::connect(ui->actionToolbarOpen, SIGNAL(triggered()),
171 this, SLOT(openFile()));
173 QObject::connect(ui->actionOpen_Project, SIGNAL(triggered()),
174 this, SLOT(openProject()));
177 void EditorWindow::addTab(TabContent *doc)
179 ui->editorTabs->addTab(doc, doc->title());
181 /* Connecting to title change events */
182 QObject::connect(doc, SIGNAL(titleChanged(QString)),
183 this, SLOT(tabTitleChanged(QString)));
184 QObject::connect(doc, SIGNAL(lineChanged(int)),
185 this, SLOT(lineChanged(int)));
187 /* Connecting to settings change events */
188 if(doc->type() == TabContent::Skin)
189 dynamic_cast<SkinDocument*>(doc)->connectPrefs(prefs);
193 void EditorWindow::newTab()
195 SkinDocument* doc = new SkinDocument(parseStatus);
196 addTab(doc);
197 ui->editorTabs->setCurrentWidget(doc);
200 void EditorWindow::shiftTab(int index)
202 TabContent* widget = dynamic_cast<TabContent*>
203 (ui->editorTabs->currentWidget());
204 if(index < 0)
206 ui->parseTree->setModel(0);
207 ui->actionSave_Document->setEnabled(false);
208 ui->actionSave_Document_As->setEnabled(false);
209 ui->actionClose_Document->setEnabled(false);
210 ui->actionToolbarSave->setEnabled(false);
211 ui->fromTree->setEnabled(false);
213 else if(widget->type() == TabContent::Config)
215 ui->actionSave_Document->setEnabled(true);
216 ui->actionSave_Document_As->setEnabled(true);
217 ui->actionClose_Document->setEnabled(true);
218 ui->actionToolbarSave->setEnabled(true);
220 else
222 /* Syncing the tree view and the status bar */
223 SkinDocument* doc = dynamic_cast<SkinDocument*>(widget);
224 ui->parseTree->setModel(doc->getModel());
225 parseStatus->setText(doc->getStatus());
227 ui->actionSave_Document->setEnabled(true);
228 ui->actionSave_Document_As->setEnabled(true);
229 ui->actionClose_Document->setEnabled(true);
230 ui->actionToolbarSave->setEnabled(true);
231 ui->fromTree->setEnabled(true);
233 sizeColumns();
238 bool EditorWindow::closeTab(int index)
240 TabContent* widget = dynamic_cast<TabContent*>
241 (ui->editorTabs->widget(index));
242 if(widget->requestClose())
244 ui->editorTabs->removeTab(index);
245 widget->deleteLater();
246 return true;
249 return false;
252 void EditorWindow::closeCurrent()
254 closeTab(ui->editorTabs->currentIndex());
257 void EditorWindow::saveCurrent()
259 if(ui->editorTabs->currentIndex() >= 0)
260 dynamic_cast<TabContent*>(ui->editorTabs->currentWidget())->save();
263 void EditorWindow::saveCurrentAs()
265 if(ui->editorTabs->currentIndex() >= 0)
266 dynamic_cast<TabContent*>(ui->editorTabs->currentWidget())->saveAs();
269 void EditorWindow::openFile()
271 QStringList fileNames;
272 QSettings settings;
274 settings.beginGroup("SkinDocument");
275 QString directory = settings.value("defaultDirectory", "").toString();
276 fileNames = QFileDialog::getOpenFileNames(this, tr("Open Files"), directory,
277 SkinDocument::fileFilter());
279 for(int i = 0; i < fileNames.count(); i++)
281 if(!QFile::exists(fileNames[i]))
282 continue;
284 QString current = fileNames[i];
286 loadTabFromSkinFile(current);
288 /* And setting the new default directory */
289 current.chop(current.length() - current.lastIndexOf('/') - 1);
290 settings.setValue("defaultDirectory", current);
294 settings.endGroup();
297 void EditorWindow::openProject()
299 QString fileName;
300 QSettings settings;
302 settings.beginGroup("ProjectModel");
303 QString directory = settings.value("defaultDirectory", "").toString();
304 fileName = QFileDialog::getOpenFileName(this, tr("Open Project"), directory,
305 ProjectModel::fileFilter());
307 if(QFile::exists(fileName))
310 if(project)
311 delete project;
313 project = new ProjectModel(fileName, this);
314 ui->projectTree->setModel(project);
316 QObject::connect(ui->projectTree, SIGNAL(activated(QModelIndex)),
317 project, SLOT(activated(QModelIndex)));
319 fileName.chop(fileName.length() - fileName.lastIndexOf('/') - 1);
320 settings.setValue("defaultDirectory", fileName);
324 settings.endGroup();
328 void EditorWindow::configFileChanged(QString configFile)
331 QSettings settings;
333 settings.beginGroup("ProjectModel");
335 if(QFile::exists(configFile))
338 if(project)
339 delete project;
341 project = new ProjectModel(configFile, this);
342 ui->projectTree->setModel(project);
344 QObject::connect(ui->projectTree, SIGNAL(activated(QModelIndex)),
345 project, SLOT(activated(QModelIndex)));
347 configFile.chop(configFile.length() - configFile.lastIndexOf('/') - 1);
348 settings.setValue("defaultDirectory", configFile);
352 settings.endGroup();
356 void EditorWindow::tabTitleChanged(QString title)
358 TabContent* sender = dynamic_cast<TabContent*>(QObject::sender());
359 ui->editorTabs->setTabText(ui->editorTabs->indexOf(sender), title);
362 void EditorWindow::showPanel()
364 if(sender() == ui->actionFile_Panel)
365 ui->projectDock->setVisible(true);
366 if(sender() == ui->actionPreview_Panel)
367 ui->skinPreviewDock->setVisible(true);
368 if(sender() == ui->actionDisplay_Panel)
369 ui->parseTreeDock->setVisible(true);
372 void EditorWindow::closeEvent(QCloseEvent* event)
375 saveSettings();
377 /* Closing all the tabs */
378 for(int i = 0; i < ui->editorTabs->count(); i++)
380 if(!dynamic_cast<TabContent*>
381 (ui->editorTabs->widget(i))->requestClose())
383 event->ignore();
384 return;
388 event->accept();
391 void EditorWindow::updateCurrent()
393 if(ui->editorTabs->currentIndex() < 0)
394 return;
396 dynamic_cast<SkinDocument*>
397 (ui->editorTabs->currentWidget())->genCode();
400 void EditorWindow::lineChanged(int line)
402 ui->parseTree->collapseAll();
403 if(parseTreeSelection)
404 parseTreeSelection->deleteLater();
405 ParseTreeModel* model = dynamic_cast<ParseTreeModel*>
406 (ui->parseTree->model());
407 parseTreeSelection = new QItemSelectionModel(model);
408 expandLine(model, QModelIndex(), line);
409 sizeColumns();
410 ui->parseTree->setSelectionModel(parseTreeSelection);
414 void EditorWindow::expandLine(ParseTreeModel* model, QModelIndex parent,
415 int line)
417 for(int i = 0; i < model->rowCount(parent); i++)
419 QModelIndex dataType = model->index(i, ParseTreeModel::typeColumn,
420 parent);
421 QModelIndex dataVal = model->index(i, ParseTreeModel::valueColumn,
422 parent);
423 QModelIndex data = model->index(i, ParseTreeModel::lineColumn, parent);
424 QModelIndex recurse = model->index(i, 0, parent);
426 expandLine(model, recurse, line);
428 if(model->data(data, Qt::DisplayRole) == line)
430 ui->parseTree->expand(parent);
431 ui->parseTree->expand(data);
432 ui->parseTree->scrollTo(parent, QAbstractItemView::PositionAtTop);
434 parseTreeSelection->select(data, QItemSelectionModel::Select);
435 parseTreeSelection->select(dataType, QItemSelectionModel::Select);
436 parseTreeSelection->select(dataVal, QItemSelectionModel::Select);
442 void EditorWindow::sizeColumns()
444 /* Setting the column widths */
445 ui->parseTree->resizeColumnToContents(ParseTreeModel::lineColumn);
446 ui->parseTree->resizeColumnToContents(ParseTreeModel::typeColumn);
447 ui->parseTree->resizeColumnToContents(ParseTreeModel::valueColumn);
450 EditorWindow::~EditorWindow()
452 delete ui;
453 delete prefs;
454 if(project)
455 delete project;