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