8c98255cca111c7b7c22f5094a872f5315462407
[kugel-rb.git] / utils / themeeditor / gui / skindocument.cpp
blob8c98255cca111c7b7c22f5094a872f5315462407
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; 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.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include "skindocument.h"
24 #include <QFile>
25 #include <QSettings>
26 #include <QColor>
27 #include <QMessageBox>
28 #include <QFileDialog>
30 #include <iostream>
32 SkinDocument::SkinDocument(QLabel* statusLabel, ProjectModel* project,
33 QWidget *parent)
34 :TabContent(parent), statusLabel(statusLabel),
35 project(project)
37 setupUI();
39 titleText = "Untitled";
40 fileName = "";
41 saved = "";
42 parseStatus = tr("Empty document");
43 blockUpdate = false;
46 SkinDocument::SkinDocument(QLabel* statusLabel, QString file,
47 ProjectModel* project, QWidget *parent)
48 :TabContent(parent), fileName(file),
49 statusLabel(statusLabel), project(project)
51 setupUI();
52 blockUpdate = false;
54 /* Loading the file */
55 if(QFile::exists(fileName))
57 QFile fin(fileName);
58 fin.open(QFile::ReadOnly);
59 editor->document()->setPlainText(QString(fin.readAll()));
60 saved = editor->document()->toPlainText();
61 editor->setTextCursor(QTextCursor(editor->document()->begin()));
62 fin.close();
65 /* Setting the title */
66 QStringList decomposed = fileName.split('/');
67 titleText = decomposed.last();
70 SkinDocument::~SkinDocument()
72 highlighter->deleteLater();
73 model->deleteLater();
76 void SkinDocument::connectPrefs(PreferencesDialog* prefs)
78 QObject::connect(prefs, SIGNAL(accepted()),
79 this, SLOT(settingsChanged()));
80 QObject::connect(prefs, SIGNAL(accepted()),
81 highlighter, SLOT(loadSettings()));
84 bool SkinDocument::requestClose()
86 /* Storing the response in blockUpdate will also block updates to the
87 status bar if the tab is being closed */
88 if(editor->document()->toPlainText() != saved)
90 /* Spawning the "Are you sure?" dialog */
91 QMessageBox confirm(this);
92 confirm.setWindowTitle(tr("Confirm Close"));
93 confirm.setText(titleText + tr(" has been modified."));
94 confirm.setInformativeText(tr("Do you want to save your changes?"));
95 confirm.setStandardButtons(QMessageBox::Save | QMessageBox::Discard
96 | QMessageBox::Cancel);
97 confirm.setDefaultButton(QMessageBox::Save);
98 int confirmation = confirm.exec();
100 switch(confirmation)
102 case QMessageBox::Save:
103 save();
104 /* After calling save, make sure the user actually went through */
105 if(editor->document()->toPlainText() != saved)
106 blockUpdate = false;
107 else
108 blockUpdate = true;
109 break;
111 case QMessageBox::Discard:
112 blockUpdate = true;
113 break;
115 case QMessageBox::Cancel:
116 blockUpdate = false;
117 break;
120 else
121 blockUpdate = true;
123 return blockUpdate;
126 void SkinDocument::setupUI()
128 /* Setting up the text edit */
129 layout = new QHBoxLayout;
130 editor = new CodeEditor(this);
131 editor->setLineWrapMode(QPlainTextEdit::NoWrap);
132 layout->addWidget(editor);
134 setLayout(layout);
136 /* Attaching the syntax highlighter */
137 highlighter = new SkinHighlighter(editor->document());
139 /* Setting up the model */
140 model = new ParseTreeModel("");
142 /* Connecting the editor's signal */
143 QObject::connect(editor, SIGNAL(textChanged()),
144 this, SLOT(codeChanged()));
145 QObject::connect(editor, SIGNAL(cursorPositionChanged()),
146 this, SLOT(cursorChanged()));
148 settingsChanged();
151 void SkinDocument::settingsChanged()
153 /* Setting the editor colors */
154 QSettings settings;
155 settings.beginGroup("SkinDocument");
157 QColor fg = settings.value("fgColor", Qt::black).value<QColor>();
158 QColor bg = settings.value("bgColor", Qt::white).value<QColor>();
159 QPalette palette;
160 palette.setColor(QPalette::All, QPalette::Base, bg);
161 palette.setColor(QPalette::All, QPalette::Text, fg);
162 editor->setPalette(palette);
164 QColor highlight = settings.value("errorColor", Qt::red).value<QColor>();
165 editor->setErrorColor(highlight);
167 /* Setting the font */
168 QFont def("Monospace");
169 def.setStyleHint(QFont::TypeWriter);
170 QFont family = settings.value("fontFamily", def).value<QFont>();
171 family.setPointSize(settings.value("fontSize", 12).toInt());
172 editor->setFont(family);
174 editor->repaint();
176 settings.endGroup();
180 void SkinDocument::cursorChanged()
182 if(editor->isError(editor->textCursor().blockNumber() + 1))
184 QTextCursor line = editor->textCursor();
185 line.movePosition(QTextCursor::StartOfLine);
186 line.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor);
187 skin_parse(line.selectedText().toAscii());
188 if(skin_error_line() > 0)
189 parseStatus = tr("Error on line ") +
190 QString::number(line.blockNumber() + 1) + tr(": ") +
191 skin_error_message();
192 statusLabel->setText(parseStatus);
194 else if(editor->hasErrors())
196 parseStatus = tr("Errors in document");
197 statusLabel->setText(parseStatus);
199 else
201 emit lineChanged(editor->textCursor().blockNumber() + 1);
206 void SkinDocument::codeChanged()
208 if(blockUpdate)
209 return;
211 if(editor->document()->isEmpty())
213 parseStatus = tr("Empty document");
214 statusLabel->setText(parseStatus);
215 return;
218 editor->clearErrors();
219 parseStatus = model->changeTree(editor->document()->
220 toPlainText().toAscii());
221 if(skin_error_line() > 0)
222 parseStatus = tr("Errors in document");
223 statusLabel->setText(parseStatus);
225 /* Highlighting if an error was found */
226 if(skin_error_line() > 0)
228 editor->addError(skin_error_line());
230 /* Now we're going to attempt parsing again at each line, until we find
231 one that won't error out*/
232 QTextDocument doc(editor->document()->toPlainText());
233 int base = 0;
234 while(skin_error_line() > 0 && !doc.isEmpty())
236 QTextCursor rest(&doc);
238 for(int i = 0; i < skin_error_line(); i++)
239 rest.movePosition(QTextCursor::NextBlock,
240 QTextCursor::KeepAnchor);
241 if(skin_error_line() == doc.blockCount())
242 rest.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
244 rest.removeSelectedText();
245 base += skin_error_line();
247 skin_parse(doc.toPlainText().toAscii());
249 if(skin_error_line() > 0)
250 editor->addError(base + skin_error_line());
255 if(editor->document()->toPlainText() != saved)
256 emit titleChanged(titleText + QChar('*'));
257 else
258 emit titleChanged(titleText);
260 model->render(project, &fileName);
262 cursorChanged();
266 void SkinDocument::save()
268 QFile fout(fileName);
270 if(!fout.exists())
272 saveAs();
273 return;
276 fout.open(QFile::WriteOnly);
277 fout.write(editor->document()->toPlainText().toAscii());
278 fout.close();
280 saved = editor->document()->toPlainText();
281 QStringList decompose = fileName.split('/');
282 titleText = decompose.last();
283 emit titleChanged(titleText);
287 void SkinDocument::saveAs()
289 /* Determining the directory to open */
290 QString directory = fileName;
292 QSettings settings;
293 settings.beginGroup("SkinDocument");
294 if(directory == "")
295 directory = settings.value("defaultDirectory", "").toString();
297 fileName = QFileDialog::getSaveFileName(this, tr("Save Document"),
298 directory, fileFilter());
299 directory = fileName;
300 if(fileName == "")
301 return;
303 directory.chop(fileName.length() - fileName.lastIndexOf('/') - 1);
304 settings.setValue("defaultDirectory", directory);
305 settings.endGroup();
307 QFile fout(fileName);
308 fout.open(QFile::WriteOnly);
309 fout.write(editor->document()->toPlainText().toAscii());
310 fout.close();
312 saved = editor->document()->toPlainText();
313 QStringList decompose = fileName.split('/');
314 titleText = decompose[decompose.count() - 1];
315 emit titleChanged(titleText);
319 QString SkinDocument::findSetting(QString key, QString fallback)
321 if(!project)
322 return fallback;
323 else
324 return project->getSetting(key, fallback);