Chris@225
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@225
|
2
|
Chris@225
|
3 /*
|
Chris@225
|
4 Sonic Visualiser
|
Chris@225
|
5 An audio file viewer and annotation editor.
|
Chris@225
|
6 Centre for Digital Music, Queen Mary, University of London.
|
Chris@225
|
7 This file copyright 2007 QMUL.
|
Chris@225
|
8
|
Chris@225
|
9 This program is free software; you can redistribute it and/or
|
Chris@225
|
10 modify it under the terms of the GNU General Public License as
|
Chris@225
|
11 published by the Free Software Foundation; either version 2 of the
|
Chris@225
|
12 License, or (at your option) any later version. See the file
|
Chris@225
|
13 COPYING included with this distribution for more information.
|
Chris@225
|
14 */
|
Chris@225
|
15
|
Chris@225
|
16 #include "TipDialog.h"
|
Chris@225
|
17
|
Chris@225
|
18 #include <QLabel>
|
Chris@225
|
19 #include <QPushButton>
|
Chris@225
|
20 #include <QSettings>
|
Chris@225
|
21 #include <QLabel>
|
Chris@225
|
22 #include <QLocale>
|
Chris@225
|
23 #include <QXmlInputSource>
|
Chris@225
|
24 #include <QFileInfo>
|
Chris@225
|
25 #include <QGridLayout>
|
Chris@225
|
26 #include <QGroupBox>
|
Chris@225
|
27
|
Chris@225
|
28 #include <iostream>
|
Chris@225
|
29
|
Chris@225
|
30 TipDialog::TipDialog(QWidget *parent, Qt::WFlags flags) :
|
Chris@225
|
31 QDialog(parent, flags),
|
Chris@225
|
32 m_tipNumber(0),
|
Chris@225
|
33 m_label(0),
|
Chris@225
|
34 m_caption(tr("Tip of the Day"))
|
Chris@225
|
35 {
|
Chris@225
|
36 readTips();
|
Chris@225
|
37
|
Chris@225
|
38 QSettings settings;
|
Chris@225
|
39 settings.beginGroup("TipOfTheDay");
|
Chris@225
|
40
|
Chris@225
|
41 if (!settings.value("showonstartup", true).toBool()) return;
|
Chris@225
|
42
|
Chris@225
|
43 m_tipNumber = settings.value("nexttip", 0).toInt();
|
Chris@225
|
44
|
Chris@225
|
45 setWindowTitle(m_caption);
|
Chris@225
|
46
|
Chris@225
|
47 QGridLayout *grid = new QGridLayout;
|
Chris@225
|
48 setLayout(grid);
|
Chris@225
|
49
|
Chris@225
|
50 QGroupBox *groupBox = new QGroupBox;
|
Chris@225
|
51 groupBox->setTitle(m_caption);
|
Chris@225
|
52 grid->addWidget(groupBox, 0, 0);
|
Chris@225
|
53
|
Chris@225
|
54 QGridLayout *subgrid = new QGridLayout;
|
Chris@225
|
55 groupBox->setLayout(subgrid);
|
Chris@225
|
56
|
Chris@225
|
57 m_label = new QLabel;
|
Chris@225
|
58 subgrid->addWidget(m_label, 0, 0);
|
Chris@225
|
59
|
Chris@225
|
60 QHBoxLayout *hbox = new QHBoxLayout;
|
Chris@225
|
61 grid->addLayout(hbox, 1, 0);
|
Chris@225
|
62
|
Chris@225
|
63 QPushButton *close = new QPushButton(tr("Close"));
|
Chris@225
|
64 hbox->addStretch(10);
|
Chris@225
|
65 hbox->addWidget(close);
|
Chris@225
|
66 connect(close, SIGNAL(clicked()), this, SLOT(accept()));
|
Chris@225
|
67
|
Chris@225
|
68 showTip();
|
Chris@225
|
69 }
|
Chris@225
|
70
|
Chris@225
|
71 TipDialog::~TipDialog()
|
Chris@225
|
72 {
|
Chris@225
|
73 }
|
Chris@225
|
74
|
Chris@225
|
75 void
|
Chris@225
|
76 TipDialog::next()
|
Chris@225
|
77 {
|
Chris@225
|
78 if (++m_tipNumber >= int(m_tips.size())) {
|
Chris@225
|
79 //!!! The tips file should define where we loop back to -- the
|
Chris@225
|
80 // first one at least is likely to be a generic welcome message
|
Chris@225
|
81 m_tipNumber = 0;
|
Chris@225
|
82 }
|
Chris@225
|
83
|
Chris@225
|
84 showTip();
|
Chris@225
|
85 }
|
Chris@225
|
86
|
Chris@225
|
87 void
|
Chris@225
|
88 TipDialog::previous()
|
Chris@225
|
89 {
|
Chris@225
|
90 if (--m_tipNumber < 0) {
|
Chris@225
|
91 m_tipNumber = m_tips.size() - 1;
|
Chris@225
|
92 }
|
Chris@225
|
93
|
Chris@225
|
94 showTip();
|
Chris@225
|
95 }
|
Chris@225
|
96
|
Chris@225
|
97 void
|
Chris@225
|
98 TipDialog::readTips()
|
Chris@225
|
99 {
|
Chris@225
|
100 std::cerr << "TipDialog::readTips" << std::endl;
|
Chris@225
|
101
|
Chris@225
|
102 QString language = QLocale::system().name();
|
Chris@225
|
103 QString filename = QString(":i18n/tips_%1.xml").arg(language);
|
Chris@225
|
104
|
Chris@225
|
105 if (!QFileInfo(filename).exists()) {
|
Chris@225
|
106
|
Chris@225
|
107 QString base = language.section('_', 0, 0);
|
Chris@225
|
108 filename = QString(":i18n/tips_%1.xml").arg(base);
|
Chris@225
|
109
|
Chris@225
|
110 if (!QFileInfo(filename).exists()) {
|
Chris@225
|
111
|
Chris@225
|
112 filename = QString(":i18n/tips.xml");
|
Chris@225
|
113
|
Chris@225
|
114 if (!QFileInfo(filename).exists()) return;
|
Chris@225
|
115 }
|
Chris@225
|
116 }
|
Chris@225
|
117
|
Chris@225
|
118 QFile file(filename);
|
Chris@225
|
119
|
Chris@225
|
120 std::cerr << "TipDialog::readTips from " << filename.toStdString() << std::endl;
|
Chris@225
|
121
|
Chris@225
|
122 QXmlInputSource source(&file);
|
Chris@225
|
123
|
Chris@225
|
124 TipFileParser parser(this);
|
Chris@225
|
125 parser.parse(source);
|
Chris@225
|
126 }
|
Chris@225
|
127
|
Chris@225
|
128 void
|
Chris@225
|
129 TipDialog::showTip()
|
Chris@225
|
130 {
|
Chris@225
|
131 if (m_tipNumber < int(m_tips.size())) {
|
Chris@225
|
132 std::cerr << "Tip " << m_tipNumber << " is: " << m_tips[m_tipNumber].toStdString() << std::endl;
|
Chris@225
|
133 m_label->setText(m_tips[m_tipNumber]);
|
Chris@225
|
134 } else {
|
Chris@225
|
135 accept();
|
Chris@225
|
136 }
|
Chris@225
|
137
|
Chris@225
|
138 int tn = m_tipNumber;
|
Chris@225
|
139 if (++tn >= int(m_tips.size())) tn = 0; //!!! as above
|
Chris@225
|
140
|
Chris@225
|
141 QSettings settings;
|
Chris@225
|
142 settings.beginGroup("TipOfTheDay");
|
Chris@225
|
143 settings.setValue("nexttip", tn);
|
Chris@225
|
144 }
|
Chris@225
|
145
|
Chris@225
|
146 TipDialog::TipFileParser::TipFileParser(TipDialog *dialog) :
|
Chris@225
|
147 m_dialog(dialog),
|
Chris@225
|
148 m_inTip(false),
|
Chris@225
|
149 m_inText(false)
|
Chris@225
|
150 {
|
Chris@225
|
151 }
|
Chris@225
|
152
|
Chris@225
|
153 TipDialog::TipFileParser::~TipFileParser()
|
Chris@225
|
154 {
|
Chris@225
|
155 }
|
Chris@225
|
156
|
Chris@225
|
157 void
|
Chris@225
|
158 TipDialog::TipFileParser::parse(QXmlInputSource &source)
|
Chris@225
|
159 {
|
Chris@225
|
160 QXmlSimpleReader reader;
|
Chris@225
|
161 reader.setContentHandler(this);
|
Chris@225
|
162 reader.setErrorHandler(this);
|
Chris@225
|
163 reader.parse(source);
|
Chris@225
|
164 }
|
Chris@225
|
165
|
Chris@225
|
166 bool
|
Chris@225
|
167 TipDialog::TipFileParser::startElement(const QString &, const QString &,
|
Chris@225
|
168 const QString &qName,
|
Chris@225
|
169 const QXmlAttributes &attributes)
|
Chris@225
|
170 {
|
Chris@225
|
171 QString name = qName.toLower();
|
Chris@225
|
172
|
Chris@225
|
173 std::cerr << "TipFileParser::startElement(" << name.toStdString() << ")" << std::endl;
|
Chris@225
|
174
|
Chris@225
|
175 if (name == "tips") {
|
Chris@225
|
176 QString caption = attributes.value("caption");
|
Chris@225
|
177 std::cerr << "TipFileParser::caption = " << caption.toStdString() << std::endl;
|
Chris@225
|
178 if (caption != "") m_dialog->m_caption = caption;
|
Chris@225
|
179 } else if (name == "tip") {
|
Chris@225
|
180 if (m_inTip) {
|
Chris@225
|
181 std::cerr << "WARNING: TipFileParser: nested <tip> elements" << std::endl;
|
Chris@225
|
182 }
|
Chris@225
|
183 m_inTip = true;
|
Chris@225
|
184 } else if (name == "text") {
|
Chris@225
|
185 if (m_inTip) {
|
Chris@225
|
186 m_inText = true;
|
Chris@225
|
187 std::cerr << "TipFileParser: adding new tip" << std::endl;
|
Chris@225
|
188 m_dialog->m_tips.push_back("");
|
Chris@225
|
189 } else {
|
Chris@225
|
190 std::cerr << "WARNING: TipFileParser: <text> outside <tip> element" << std::endl;
|
Chris@225
|
191 }
|
Chris@225
|
192 }
|
Chris@225
|
193
|
Chris@225
|
194 std::cerr << "TipFileParser::startElement done" << std::endl;
|
Chris@225
|
195 return true;
|
Chris@225
|
196 }
|
Chris@225
|
197
|
Chris@225
|
198 bool
|
Chris@225
|
199 TipDialog::TipFileParser::endElement(const QString &, const QString &,
|
Chris@225
|
200 const QString &qName)
|
Chris@225
|
201 {
|
Chris@225
|
202 QString name = qName.toLower();
|
Chris@225
|
203
|
Chris@225
|
204 if (name == "text") {
|
Chris@225
|
205 if (m_inText) {
|
Chris@225
|
206 std::cerr << "WARNING: TipFileParser: </text> without <text>" << std::endl;
|
Chris@225
|
207 }
|
Chris@225
|
208 m_inText = false;
|
Chris@225
|
209 } else if (name == "tip") {
|
Chris@225
|
210 if (m_inText) {
|
Chris@225
|
211 std::cerr << "WARNING: TipFileParser: <text> without </text>" << std::endl;
|
Chris@225
|
212 } else if (!m_inTip) {
|
Chris@225
|
213 std::cerr << "WARNING: TipFileParser: </tip> without <tip>" << std::endl;
|
Chris@225
|
214 }
|
Chris@225
|
215 m_inTip = false;
|
Chris@225
|
216 }
|
Chris@225
|
217
|
Chris@225
|
218 return true;
|
Chris@225
|
219 }
|
Chris@225
|
220
|
Chris@225
|
221 bool
|
Chris@225
|
222 TipDialog::TipFileParser::characters(const QString &text)
|
Chris@225
|
223 {
|
Chris@225
|
224 std::cerr << "TipFileParser::characters(" << text.toStdString() << ")" << std::endl;
|
Chris@225
|
225
|
Chris@225
|
226 if (m_inText) {
|
Chris@225
|
227 m_dialog->m_tips[m_dialog->m_tips.size()-1] += text;
|
Chris@225
|
228 }
|
Chris@225
|
229
|
Chris@225
|
230 return true;
|
Chris@225
|
231 }
|
Chris@225
|
232
|
Chris@225
|
233 bool
|
Chris@225
|
234 TipDialog::TipFileParser::error(const QXmlParseException &exception)
|
Chris@225
|
235 {
|
Chris@225
|
236 QString errorString =
|
Chris@225
|
237 QString("ERROR: TipFileParser: %1 at line %2, column %3")
|
Chris@225
|
238 .arg(exception.message())
|
Chris@225
|
239 .arg(exception.lineNumber())
|
Chris@225
|
240 .arg(exception.columnNumber());
|
Chris@225
|
241 std::cerr << errorString.toStdString() << std::endl;
|
Chris@225
|
242 return QXmlDefaultHandler::error(exception);
|
Chris@225
|
243 }
|
Chris@225
|
244
|
Chris@225
|
245 bool
|
Chris@225
|
246 TipDialog::TipFileParser::fatalError(const QXmlParseException &exception)
|
Chris@225
|
247 {
|
Chris@225
|
248 QString errorString =
|
Chris@225
|
249 QString("FATAL ERROR: TipFileParser: %1 at line %2, column %3")
|
Chris@225
|
250 .arg(exception.message())
|
Chris@225
|
251 .arg(exception.lineNumber())
|
Chris@225
|
252 .arg(exception.columnNumber());
|
Chris@225
|
253 std::cerr << errorString.toStdString() << std::endl;
|
Chris@225
|
254 return QXmlDefaultHandler::fatalError(exception);
|
Chris@225
|
255 }
|