1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
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>
29 #include <QFileDialog>
30 #include <QGraphicsScene>
32 EditorWindow::EditorWindow(QWidget
*parent
) :
34 ui(new Ui::EditorWindow
)
37 prefs
= new PreferencesDialog(this);
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
);
58 /* Adding a new document*/
59 SkinDocument
* doc
= new SkinDocument(parseStatus
, fileName
, project
);
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
);
80 ui
->editorTabs
->setCurrentWidget(doc
);
82 QObject::connect(doc
, SIGNAL(titleChanged(QString
)),
83 this, SLOT(tabTitleChanged(QString
)));
86 void EditorWindow::loadSettings()
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();
98 if(!(size
.isNull() || pos
.isNull() || state
.isNull()))
107 void EditorWindow::saveSettings()
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());
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
);
147 /* Positioning the device settings dialog */
148 QPoint thisPos
= pos();
149 deviceConfig
.move(thisPos
.x() + width() / 4, thisPos
.y() + height() / 4);
153 void EditorWindow::setupMenus()
155 /* Connecting panel show actions */
156 QObject::connect(ui
->actionFile_Panel
, SIGNAL(triggered()),
157 this, SLOT(showPanel()));
158 QObject::connect(ui
->actionDisplay_Panel
, SIGNAL(triggered()),
159 this, SLOT(showPanel()));
160 QObject::connect(ui
->actionPreview_Panel
, SIGNAL(triggered()),
161 this, SLOT(showPanel()));
162 QObject::connect(ui
->actionDevice_Configuration
, SIGNAL(triggered()),
163 &deviceConfig
, SLOT(show()));
165 /* Connecting the document management actions */
166 QObject::connect(ui
->actionNew_Document
, SIGNAL(triggered()),
167 this, SLOT(newTab()));
168 QObject::connect(ui
->actionToolbarNew
, SIGNAL(triggered()),
169 this, SLOT(newTab()));
171 QObject::connect(ui
->actionClose_Document
, SIGNAL(triggered()),
172 this, SLOT(closeCurrent()));
174 QObject::connect(ui
->actionSave_Document
, SIGNAL(triggered()),
175 this, SLOT(saveCurrent()));
176 QObject::connect(ui
->actionSave_Document_As
, SIGNAL(triggered()),
177 this, SLOT(saveCurrentAs()));
178 QObject::connect(ui
->actionToolbarSave
, SIGNAL(triggered()),
179 this, SLOT(saveCurrent()));
181 QObject::connect(ui
->actionOpen_Document
, SIGNAL(triggered()),
182 this, SLOT(openFile()));
183 QObject::connect(ui
->actionToolbarOpen
, SIGNAL(triggered()),
184 this, SLOT(openFile()));
186 QObject::connect(ui
->actionOpen_Project
, SIGNAL(triggered()),
187 this, SLOT(openProject()));
190 void EditorWindow::addTab(TabContent
*doc
)
192 ui
->editorTabs
->addTab(doc
, doc
->title());
194 /* Connecting to title change events */
195 QObject::connect(doc
, SIGNAL(titleChanged(QString
)),
196 this, SLOT(tabTitleChanged(QString
)));
197 QObject::connect(doc
, SIGNAL(lineChanged(int)),
198 this, SLOT(lineChanged(int)));
200 /* Connecting to settings change events */
201 if(doc
->type() == TabContent::Skin
)
202 dynamic_cast<SkinDocument
*>(doc
)->connectPrefs(prefs
);
206 void EditorWindow::newTab()
208 SkinDocument
* doc
= new SkinDocument(parseStatus
, project
);
210 ui
->editorTabs
->setCurrentWidget(doc
);
213 void EditorWindow::shiftTab(int index
)
215 TabContent
* widget
= dynamic_cast<TabContent
*>
216 (ui
->editorTabs
->currentWidget());
219 ui
->parseTree
->setModel(0);
220 ui
->actionSave_Document
->setEnabled(false);
221 ui
->actionSave_Document_As
->setEnabled(false);
222 ui
->actionClose_Document
->setEnabled(false);
223 ui
->actionToolbarSave
->setEnabled(false);
224 ui
->fromTree
->setEnabled(false);
227 else if(widget
->type() == TabContent::Config
)
229 ui
->actionSave_Document
->setEnabled(true);
230 ui
->actionSave_Document_As
->setEnabled(true);
231 ui
->actionClose_Document
->setEnabled(true);
232 ui
->actionToolbarSave
->setEnabled(true);
235 else if(widget
->type() == TabContent::Skin
)
237 /* Syncing the tree view and the status bar */
238 SkinDocument
* doc
= dynamic_cast<SkinDocument
*>(widget
);
239 ui
->parseTree
->setModel(doc
->getModel());
240 parseStatus
->setText(doc
->getStatus());
242 ui
->actionSave_Document
->setEnabled(true);
243 ui
->actionSave_Document_As
->setEnabled(true);
244 ui
->actionClose_Document
->setEnabled(true);
245 ui
->actionToolbarSave
->setEnabled(true);
246 ui
->fromTree
->setEnabled(true);
250 /* Syncing the preview */
251 viewer
->setScene(doc
->scene());
256 bool EditorWindow::closeTab(int index
)
258 TabContent
* widget
= dynamic_cast<TabContent
*>
259 (ui
->editorTabs
->widget(index
));
260 if(widget
->requestClose())
262 ui
->editorTabs
->removeTab(index
);
263 widget
->deleteLater();
270 void EditorWindow::closeCurrent()
272 closeTab(ui
->editorTabs
->currentIndex());
275 void EditorWindow::saveCurrent()
277 if(ui
->editorTabs
->currentIndex() >= 0)
278 dynamic_cast<TabContent
*>(ui
->editorTabs
->currentWidget())->save();
281 void EditorWindow::saveCurrentAs()
283 if(ui
->editorTabs
->currentIndex() >= 0)
284 dynamic_cast<TabContent
*>(ui
->editorTabs
->currentWidget())->saveAs();
287 void EditorWindow::openFile()
289 QStringList fileNames
;
292 settings
.beginGroup("SkinDocument");
293 QString directory
= settings
.value("defaultDirectory", "").toString();
294 fileNames
= QFileDialog::getOpenFileNames(this, tr("Open Files"), directory
,
295 SkinDocument::fileFilter());
297 for(int i
= 0; i
< fileNames
.count(); i
++)
299 if(!QFile::exists(fileNames
[i
]))
302 QString current
= fileNames
[i
];
304 loadTabFromSkinFile(current
);
306 /* And setting the new default directory */
307 current
.chop(current
.length() - current
.lastIndexOf('/') - 1);
308 settings
.setValue("defaultDirectory", current
);
315 void EditorWindow::openProject()
320 settings
.beginGroup("ProjectModel");
321 QString directory
= settings
.value("defaultDirectory", "").toString();
322 fileName
= QFileDialog::getOpenFileName(this, tr("Open Project"), directory
,
323 ProjectModel::fileFilter());
325 if(QFile::exists(fileName
))
331 project
= new ProjectModel(fileName
, this);
332 ui
->projectTree
->setModel(project
);
334 QObject::connect(ui
->projectTree
, SIGNAL(activated(QModelIndex
)),
335 project
, SLOT(activated(QModelIndex
)));
337 fileName
.chop(fileName
.length() - fileName
.lastIndexOf('/') - 1);
338 settings
.setValue("defaultDirectory", fileName
);
340 for(int i
= 0; i
< ui
->editorTabs
->count(); i
++)
342 TabContent
* doc
= dynamic_cast<TabContent
*>
343 (ui
->editorTabs
->widget(i
));
344 if(doc
->type() == TabContent::Skin
)
346 dynamic_cast<SkinDocument
*>(doc
)->setProject(project
);
347 if(i
== ui
->editorTabs
->currentIndex())
349 viewer
->setScene(dynamic_cast<SkinDocument
*>(doc
)->scene());
360 void EditorWindow::configFileChanged(QString configFile
)
363 if(QFile::exists(configFile
))
369 project
= new ProjectModel(configFile
, this);
370 ui
->projectTree
->setModel(project
);
372 QObject::connect(ui
->projectTree
, SIGNAL(activated(QModelIndex
)),
373 project
, SLOT(activated(QModelIndex
)));
375 for(int i
= 0; i
< ui
->editorTabs
->count(); i
++)
377 TabContent
* doc
= dynamic_cast<TabContent
*>
378 (ui
->editorTabs
->widget(i
));
379 if(doc
->type() == TabContent::Skin
)
381 dynamic_cast<SkinDocument
*>(doc
)->setProject(project
);
382 if(i
== ui
->editorTabs
->currentIndex())
384 viewer
->setScene(dynamic_cast<SkinDocument
*>(doc
)->scene());
394 void EditorWindow::tabTitleChanged(QString title
)
396 TabContent
* sender
= dynamic_cast<TabContent
*>(QObject::sender());
397 ui
->editorTabs
->setTabText(ui
->editorTabs
->indexOf(sender
), title
);
400 void EditorWindow::showPanel()
402 if(sender() == ui
->actionFile_Panel
)
403 ui
->projectDock
->setVisible(true);
404 if(sender() == ui
->actionPreview_Panel
)
405 ui
->skinPreviewDock
->setVisible(true);
406 if(sender() == ui
->actionDisplay_Panel
)
407 ui
->parseTreeDock
->setVisible(true);
410 void EditorWindow::closeEvent(QCloseEvent
* event
)
415 /* Closing all the tabs */
416 for(int i
= 0; i
< ui
->editorTabs
->count(); i
++)
418 if(!dynamic_cast<TabContent
*>
419 (ui
->editorTabs
->widget(i
))->requestClose())
429 void EditorWindow::updateCurrent()
431 if(ui
->editorTabs
->currentIndex() < 0)
434 dynamic_cast<SkinDocument
*>
435 (ui
->editorTabs
->currentWidget())->genCode();
438 void EditorWindow::lineChanged(int line
)
440 ui
->parseTree
->collapseAll();
441 if(parseTreeSelection
)
442 parseTreeSelection
->deleteLater();
443 ParseTreeModel
* model
= dynamic_cast<ParseTreeModel
*>
444 (ui
->parseTree
->model());
445 parseTreeSelection
= new QItemSelectionModel(model
);
446 expandLine(model
, QModelIndex(), line
);
448 ui
->parseTree
->setSelectionModel(parseTreeSelection
);
452 void EditorWindow::expandLine(ParseTreeModel
* model
, QModelIndex parent
,
455 for(int i
= 0; i
< model
->rowCount(parent
); i
++)
457 QModelIndex dataType
= model
->index(i
, ParseTreeModel::typeColumn
,
459 QModelIndex dataVal
= model
->index(i
, ParseTreeModel::valueColumn
,
461 QModelIndex data
= model
->index(i
, ParseTreeModel::lineColumn
, parent
);
462 QModelIndex recurse
= model
->index(i
, 0, parent
);
464 expandLine(model
, recurse
, line
);
466 if(model
->data(data
, Qt::DisplayRole
) == line
)
468 ui
->parseTree
->expand(parent
);
469 ui
->parseTree
->expand(data
);
470 ui
->parseTree
->scrollTo(parent
, QAbstractItemView::PositionAtTop
);
472 parseTreeSelection
->select(data
, QItemSelectionModel::Select
);
473 parseTreeSelection
->select(dataType
, QItemSelectionModel::Select
);
474 parseTreeSelection
->select(dataVal
, QItemSelectionModel::Select
);
480 void EditorWindow::sizeColumns()
482 /* Setting the column widths */
483 ui
->parseTree
->resizeColumnToContents(ParseTreeModel::lineColumn
);
484 ui
->parseTree
->resizeColumnToContents(ParseTreeModel::typeColumn
);
485 ui
->parseTree
->resizeColumnToContents(ParseTreeModel::valueColumn
);
488 EditorWindow::~EditorWindow()