summaryrefslogtreecommitdiff
path: root/utils/themeeditor/gui/skindocument.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/themeeditor/gui/skindocument.cpp')
-rw-r--r--utils/themeeditor/gui/skindocument.cpp311
1 files changed, 311 insertions, 0 deletions
diff --git a/utils/themeeditor/gui/skindocument.cpp b/utils/themeeditor/gui/skindocument.cpp
new file mode 100644
index 0000000000..82c7106051
--- /dev/null
+++ b/utils/themeeditor/gui/skindocument.cpp
@@ -0,0 +1,311 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2010 Robert Bieber
11 *
12 * This program is free software; 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 optiyouon) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "skindocument.h"
23
24#include <QFile>
25#include <QSettings>
26#include <QColor>
27#include <QMessageBox>
28#include <QFileDialog>
29
30#include <iostream>
31
32SkinDocument::SkinDocument(QLabel* statusLabel, QWidget *parent) :
33 TabContent(parent), statusLabel(statusLabel)
34{
35 setupUI();
36
37 titleText = "Untitled";
38 fileName = "";
39 saved = "";
40 parseStatus = tr("Empty document");
41 blockUpdate = false;
42}
43
44SkinDocument::SkinDocument(QLabel* statusLabel, QString file, QWidget *parent):
45 TabContent(parent), fileName(file), statusLabel(statusLabel)
46{
47 setupUI();
48 blockUpdate = false;
49
50 /* Loading the file */
51 if(QFile::exists(fileName))
52 {
53 QFile fin(fileName);
54 fin.open(QFile::ReadOnly);
55 editor->document()->setPlainText(QString(fin.readAll()));
56 saved = editor->document()->toPlainText();
57 editor->setTextCursor(QTextCursor(editor->document()->begin()));
58 fin.close();
59 }
60
61 /* Setting the title */
62 QStringList decomposed = fileName.split('/');
63 titleText = decomposed.last();
64}
65
66SkinDocument::~SkinDocument()
67{
68 delete highlighter;
69 delete model;
70}
71
72void SkinDocument::connectPrefs(PreferencesDialog* prefs)
73{
74 QObject::connect(prefs, SIGNAL(accepted()),
75 this, SLOT(settingsChanged()));
76 QObject::connect(prefs, SIGNAL(accepted()),
77 highlighter, SLOT(loadSettings()));
78}
79
80bool SkinDocument::requestClose()
81{
82 /* Storing the response in blockUpdate will also block updates to the
83 status bar if the tab is being closed */
84 if(editor->document()->toPlainText() != saved)
85 {
86 /* Spawning the "Are you sure?" dialog */
87 QMessageBox confirm(this);
88 confirm.setWindowTitle(tr("Confirm Close"));
89 confirm.setText(titleText + tr(" has been modified."));
90 confirm.setInformativeText(tr("Do you want to save your changes?"));
91 confirm.setStandardButtons(QMessageBox::Save | QMessageBox::Discard
92 | QMessageBox::Cancel);
93 confirm.setDefaultButton(QMessageBox::Save);
94 int confirmation = confirm.exec();
95
96 switch(confirmation)
97 {
98 case QMessageBox::Save:
99 save();
100 /* After calling save, make sure the user actually went through */
101 if(editor->document()->toPlainText() != saved)
102 blockUpdate = false;
103 else
104 blockUpdate = true;
105 break;
106
107 case QMessageBox::Discard:
108 blockUpdate = true;
109 break;
110
111 case QMessageBox::Cancel:
112 blockUpdate = false;
113 break;
114 }
115 }
116 else
117 blockUpdate = true;
118
119 return blockUpdate;
120}
121
122void SkinDocument::setupUI()
123{
124 /* Setting up the text edit */
125 layout = new QHBoxLayout;
126 editor = new CodeEditor(this);
127 editor->setLineWrapMode(QPlainTextEdit::NoWrap);
128 layout->addWidget(editor);
129
130 setLayout(layout);
131
132 /* Attaching the syntax highlighter */
133 highlighter = new SkinHighlighter(editor->document());
134
135 /* Setting up the model */
136 model = new ParseTreeModel("");
137
138 /* Connecting the editor's signal */
139 QObject::connect(editor, SIGNAL(textChanged()),
140 this, SLOT(codeChanged()));
141 QObject::connect(editor, SIGNAL(cursorPositionChanged()),
142 this, SLOT(cursorChanged()));
143
144 settingsChanged();
145}
146
147void SkinDocument::settingsChanged()
148{
149 /* Setting the editor colors */
150 QSettings settings;
151 settings.beginGroup("SkinDocument");
152
153 QColor fg = settings.value("fgColor", Qt::black).value<QColor>();
154 QColor bg = settings.value("bgColor", Qt::white).value<QColor>();
155 QPalette palette;
156 palette.setColor(QPalette::All, QPalette::Base, bg);
157 palette.setColor(QPalette::All, QPalette::Text, fg);
158 editor->setPalette(palette);
159
160 QColor highlight = settings.value("errorColor", Qt::red).value<QColor>();
161 editor->setErrorColor(highlight);
162
163 /* Setting the font */
164 QFont def("Monospace");
165 def.setStyleHint(QFont::TypeWriter);
166 QFont family = settings.value("fontFamily", def).value<QFont>();
167 family.setPointSize(settings.value("fontSize", 12).toInt());
168 editor->setFont(family);
169
170 editor->repaint();
171
172 settings.endGroup();
173
174}
175
176void SkinDocument::cursorChanged()
177{
178 if(editor->isError(editor->textCursor().blockNumber() + 1))
179 {
180 QTextCursor line = editor->textCursor();
181 line.movePosition(QTextCursor::StartOfLine);
182 line.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor);
183 skin_parse(line.selectedText().toAscii());
184 if(skin_error_line() > 0)
185 parseStatus = tr("Error on line ") +
186 QString::number(line.blockNumber() + 1) + tr(": ") +
187 skin_error_message();
188 statusLabel->setText(parseStatus);
189 }
190 else if(editor->hasErrors())
191 {
192 parseStatus = tr("Errors in document");
193 statusLabel->setText(parseStatus);
194 }
195 else
196 {
197 emit lineChanged(editor->textCursor().blockNumber() + 1);
198 }
199
200}
201
202void SkinDocument::codeChanged()
203{
204 if(blockUpdate)
205 return;
206
207 if(editor->document()->isEmpty())
208 {
209 parseStatus = tr("Empty document");
210 statusLabel->setText(parseStatus);
211 return;
212 }
213
214 editor->clearErrors();
215 parseStatus = model->changeTree(editor->document()->
216 toPlainText().toAscii());
217 if(skin_error_line() > 0)
218 parseStatus = tr("Errors in document");
219 statusLabel->setText(parseStatus);
220
221 /* Highlighting if an error was found */
222 if(skin_error_line() > 0)
223 {
224 editor->addError(skin_error_line());
225
226 /* Now we're going to attempt parsing again at each line, until we find
227 one that won't error out*/
228 QTextDocument doc(editor->document()->toPlainText());
229 int base = 0;
230 while(skin_error_line() > 0 && !doc.isEmpty())
231 {
232 QTextCursor rest(&doc);
233
234 for(int i = 0; i < skin_error_line(); i++)
235 rest.movePosition(QTextCursor::NextBlock,
236 QTextCursor::KeepAnchor);
237 if(skin_error_line() == doc.blockCount())
238 rest.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
239
240 rest.removeSelectedText();
241 base += skin_error_line();
242
243 skin_parse(doc.toPlainText().toAscii());
244
245 if(skin_error_line() > 0)
246 editor->addError(base + skin_error_line());
247
248 }
249 }
250
251 if(editor->document()->toPlainText() != saved)
252 emit titleChanged(titleText + QChar('*'));
253 else
254 emit titleChanged(titleText);
255
256 cursorChanged();
257
258}
259
260void SkinDocument::save()
261{
262 QFile fout(fileName);
263
264 if(!fout.exists())
265 {
266 saveAs();
267 return;
268 }
269
270 fout.open(QFile::WriteOnly);
271 fout.write(editor->document()->toPlainText().toAscii());
272 fout.close();
273
274 saved = editor->document()->toPlainText();
275 QStringList decompose = fileName.split('/');
276 titleText = decompose.last();
277 emit titleChanged(titleText);
278
279}
280
281void SkinDocument::saveAs()
282{
283 /* Determining the directory to open */
284 QString directory = fileName;
285
286 QSettings settings;
287 settings.beginGroup("SkinDocument");
288 if(directory == "")
289 directory = settings.value("defaultDirectory", "").toString();
290
291 fileName = QFileDialog::getSaveFileName(this, tr("Save Document"),
292 directory, fileFilter());
293 directory = fileName;
294 if(fileName == "")
295 return;
296
297 directory.chop(fileName.length() - fileName.lastIndexOf('/') - 1);
298 settings.setValue("defaultDirectory", directory);
299 settings.endGroup();
300
301 QFile fout(fileName);
302 fout.open(QFile::WriteOnly);
303 fout.write(editor->document()->toPlainText().toAscii());
304 fout.close();
305
306 saved = editor->document()->toPlainText();
307 QStringList decompose = fileName.split('/');
308 titleText = decompose[decompose.count() - 1];
309 emit titleChanged(titleText);
310
311}