annotate widgets/TipDialog.cpp @ 228:1c4c9e3e44e6

* updates to tip dialog
author Chris Cannam
date Tue, 13 Mar 2007 19:51:09 +0000
parents 6f46179086c0
children 387f2f6fc333
rev   line source
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@228 27 #include <QCheckBox>
Chris@225 28
Chris@225 29 #include <iostream>
Chris@225 30
Chris@225 31 TipDialog::TipDialog(QWidget *parent, Qt::WFlags flags) :
Chris@225 32 QDialog(parent, flags),
Chris@225 33 m_tipNumber(0),
Chris@225 34 m_label(0),
Chris@225 35 m_caption(tr("Tip of the Day"))
Chris@225 36 {
Chris@225 37 readTips();
Chris@225 38
Chris@225 39 QSettings settings;
Chris@225 40 settings.beginGroup("TipOfTheDay");
Chris@225 41
Chris@225 42 if (!settings.value("showonstartup", true).toBool()) return;
Chris@225 43
Chris@225 44 m_tipNumber = settings.value("nexttip", 0).toInt();
Chris@225 45
Chris@225 46 setWindowTitle(m_caption);
Chris@225 47
Chris@225 48 QGridLayout *grid = new QGridLayout;
Chris@225 49 setLayout(grid);
Chris@225 50
Chris@225 51 QGroupBox *groupBox = new QGroupBox;
Chris@228 52 // groupBox->setTitle(m_caption);
Chris@225 53 grid->addWidget(groupBox, 0, 0);
Chris@225 54
Chris@225 55 QGridLayout *subgrid = new QGridLayout;
Chris@225 56 groupBox->setLayout(subgrid);
Chris@225 57
Chris@225 58 m_label = new QLabel;
Chris@225 59 subgrid->addWidget(m_label, 0, 0);
Chris@228 60 m_label->setWordWrap(true);
Chris@225 61
Chris@225 62 QHBoxLayout *hbox = new QHBoxLayout;
Chris@225 63 grid->addLayout(hbox, 1, 0);
Chris@228 64
Chris@228 65 QCheckBox *show = new QCheckBox(tr("Show tips on startup"));
Chris@228 66 hbox->addWidget(show);
Chris@228 67
Chris@228 68 hbox->addStretch(10);
Chris@228 69
Chris@228 70 QPushButton *prev = new QPushButton(tr("<< Previous"));
Chris@228 71 hbox->addWidget(prev);
Chris@228 72 connect(prev, SIGNAL(clicked()), this, SLOT(previous()));
Chris@228 73
Chris@228 74 QPushButton *next = new QPushButton(tr("Next >>"));
Chris@228 75 hbox->addWidget(next);
Chris@228 76 connect(next, SIGNAL(clicked()), this, SLOT(next()));
Chris@225 77
Chris@225 78 QPushButton *close = new QPushButton(tr("Close"));
Chris@225 79 hbox->addWidget(close);
Chris@225 80 connect(close, SIGNAL(clicked()), this, SLOT(accept()));
Chris@225 81
Chris@228 82 close->setDefault(true);
Chris@228 83
Chris@225 84 showTip();
Chris@225 85 }
Chris@225 86
Chris@225 87 TipDialog::~TipDialog()
Chris@225 88 {
Chris@225 89 }
Chris@225 90
Chris@225 91 void
Chris@225 92 TipDialog::next()
Chris@225 93 {
Chris@225 94 if (++m_tipNumber >= int(m_tips.size())) {
Chris@225 95 //!!! The tips file should define where we loop back to -- the
Chris@225 96 // first one at least is likely to be a generic welcome message
Chris@225 97 m_tipNumber = 0;
Chris@225 98 }
Chris@225 99
Chris@225 100 showTip();
Chris@225 101 }
Chris@225 102
Chris@225 103 void
Chris@225 104 TipDialog::previous()
Chris@225 105 {
Chris@225 106 if (--m_tipNumber < 0) {
Chris@225 107 m_tipNumber = m_tips.size() - 1;
Chris@225 108 }
Chris@225 109
Chris@225 110 showTip();
Chris@225 111 }
Chris@225 112
Chris@225 113 void
Chris@225 114 TipDialog::readTips()
Chris@225 115 {
Chris@225 116 std::cerr << "TipDialog::readTips" << std::endl;
Chris@225 117
Chris@225 118 QString language = QLocale::system().name();
Chris@225 119 QString filename = QString(":i18n/tips_%1.xml").arg(language);
Chris@225 120
Chris@225 121 if (!QFileInfo(filename).exists()) {
Chris@225 122
Chris@225 123 QString base = language.section('_', 0, 0);
Chris@225 124 filename = QString(":i18n/tips_%1.xml").arg(base);
Chris@225 125
Chris@225 126 if (!QFileInfo(filename).exists()) {
Chris@225 127
Chris@225 128 filename = QString(":i18n/tips.xml");
Chris@225 129
Chris@225 130 if (!QFileInfo(filename).exists()) return;
Chris@225 131 }
Chris@225 132 }
Chris@225 133
Chris@225 134 QFile file(filename);
Chris@225 135
Chris@225 136 std::cerr << "TipDialog::readTips from " << filename.toStdString() << std::endl;
Chris@225 137
Chris@225 138 QXmlInputSource source(&file);
Chris@225 139
Chris@225 140 TipFileParser parser(this);
Chris@225 141 parser.parse(source);
Chris@225 142 }
Chris@225 143
Chris@225 144 void
Chris@225 145 TipDialog::showTip()
Chris@225 146 {
Chris@225 147 if (m_tipNumber < int(m_tips.size())) {
Chris@225 148 std::cerr << "Tip " << m_tipNumber << " is: " << m_tips[m_tipNumber].toStdString() << std::endl;
Chris@225 149 m_label->setText(m_tips[m_tipNumber]);
Chris@225 150 } else {
Chris@225 151 accept();
Chris@225 152 }
Chris@225 153
Chris@225 154 int tn = m_tipNumber;
Chris@225 155 if (++tn >= int(m_tips.size())) tn = 0; //!!! as above
Chris@225 156
Chris@225 157 QSettings settings;
Chris@225 158 settings.beginGroup("TipOfTheDay");
Chris@225 159 settings.setValue("nexttip", tn);
Chris@225 160 }
Chris@225 161
Chris@225 162 TipDialog::TipFileParser::TipFileParser(TipDialog *dialog) :
Chris@225 163 m_dialog(dialog),
Chris@225 164 m_inTip(false),
Chris@228 165 m_inText(false),
Chris@228 166 m_inHtml(false)
Chris@225 167 {
Chris@225 168 }
Chris@225 169
Chris@225 170 TipDialog::TipFileParser::~TipFileParser()
Chris@225 171 {
Chris@225 172 }
Chris@225 173
Chris@225 174 void
Chris@225 175 TipDialog::TipFileParser::parse(QXmlInputSource &source)
Chris@225 176 {
Chris@225 177 QXmlSimpleReader reader;
Chris@225 178 reader.setContentHandler(this);
Chris@225 179 reader.setErrorHandler(this);
Chris@225 180 reader.parse(source);
Chris@225 181 }
Chris@225 182
Chris@225 183 bool
Chris@225 184 TipDialog::TipFileParser::startElement(const QString &, const QString &,
Chris@225 185 const QString &qName,
Chris@225 186 const QXmlAttributes &attributes)
Chris@225 187 {
Chris@225 188 QString name = qName.toLower();
Chris@225 189
Chris@225 190 std::cerr << "TipFileParser::startElement(" << name.toStdString() << ")" << std::endl;
Chris@225 191
Chris@225 192 if (name == "tips") {
Chris@225 193 QString caption = attributes.value("caption");
Chris@225 194 std::cerr << "TipFileParser::caption = " << caption.toStdString() << std::endl;
Chris@225 195 if (caption != "") m_dialog->m_caption = caption;
Chris@225 196 } else if (name == "tip") {
Chris@225 197 if (m_inTip) {
Chris@225 198 std::cerr << "WARNING: TipFileParser: nested <tip> elements" << std::endl;
Chris@225 199 }
Chris@225 200 m_inTip = true;
Chris@225 201 } else if (name == "text") {
Chris@225 202 if (m_inTip) {
Chris@225 203 m_inText = true;
Chris@225 204 std::cerr << "TipFileParser: adding new tip" << std::endl;
Chris@225 205 m_dialog->m_tips.push_back("");
Chris@225 206 } else {
Chris@225 207 std::cerr << "WARNING: TipFileParser: <text> outside <tip> element" << std::endl;
Chris@225 208 }
Chris@228 209 } else if (name == "html") {
Chris@228 210 if (m_inTip) {
Chris@228 211 m_inHtml = true;
Chris@228 212 std::cerr << "TipFileParser: adding new tip" << std::endl;
Chris@228 213 m_dialog->m_tips.push_back("");
Chris@228 214 } else {
Chris@228 215 std::cerr << "WARNING: TipFileParser: <html> outside <tip> element" << std::endl;
Chris@228 216 }
Chris@228 217 } else if (m_inHtml) {
Chris@228 218 m_dialog->m_tips[m_dialog->m_tips.size()-1] += "<" + qName;
Chris@228 219 for (int i = 0; i < attributes.count(); ++i) {
Chris@228 220 m_dialog->m_tips[m_dialog->m_tips.size()-1] +=
Chris@228 221 " " + attributes.qName(i) + "=\"" + attributes.value(i) + "\"";
Chris@228 222 }
Chris@228 223 m_dialog->m_tips[m_dialog->m_tips.size()-1] += ">";
Chris@225 224 }
Chris@225 225
Chris@225 226 std::cerr << "TipFileParser::startElement done" << std::endl;
Chris@225 227 return true;
Chris@225 228 }
Chris@225 229
Chris@225 230 bool
Chris@225 231 TipDialog::TipFileParser::endElement(const QString &, const QString &,
Chris@225 232 const QString &qName)
Chris@225 233 {
Chris@225 234 QString name = qName.toLower();
Chris@225 235
Chris@225 236 if (name == "text") {
Chris@228 237 if (!m_inText) {
Chris@225 238 std::cerr << "WARNING: TipFileParser: </text> without <text>" << std::endl;
Chris@225 239 }
Chris@225 240 m_inText = false;
Chris@228 241 } else if (name == "html") {
Chris@228 242 if (!m_inHtml) {
Chris@228 243 std::cerr << "WARNING: TipFileParser: </html> without <html>" << std::endl;
Chris@228 244 }
Chris@228 245 m_inHtml = false;
Chris@225 246 } else if (name == "tip") {
Chris@225 247 if (m_inText) {
Chris@225 248 std::cerr << "WARNING: TipFileParser: <text> without </text>" << std::endl;
Chris@228 249 } else if (m_inHtml) {
Chris@228 250 std::cerr << "WARNING: TipFileParser: <html> without </html>" << std::endl;
Chris@225 251 } else if (!m_inTip) {
Chris@225 252 std::cerr << "WARNING: TipFileParser: </tip> without <tip>" << std::endl;
Chris@225 253 }
Chris@225 254 m_inTip = false;
Chris@228 255 } else if (m_inHtml) {
Chris@228 256 m_dialog->m_tips[m_dialog->m_tips.size()-1] += "</" + qName + ">";
Chris@225 257 }
Chris@225 258
Chris@225 259 return true;
Chris@225 260 }
Chris@225 261
Chris@225 262 bool
Chris@225 263 TipDialog::TipFileParser::characters(const QString &text)
Chris@225 264 {
Chris@225 265 std::cerr << "TipFileParser::characters(" << text.toStdString() << ")" << std::endl;
Chris@225 266
Chris@228 267 if (m_inText || m_inHtml) {
Chris@225 268 m_dialog->m_tips[m_dialog->m_tips.size()-1] += text;
Chris@225 269 }
Chris@225 270
Chris@225 271 return true;
Chris@225 272 }
Chris@225 273
Chris@225 274 bool
Chris@225 275 TipDialog::TipFileParser::error(const QXmlParseException &exception)
Chris@225 276 {
Chris@225 277 QString errorString =
Chris@225 278 QString("ERROR: TipFileParser: %1 at line %2, column %3")
Chris@225 279 .arg(exception.message())
Chris@225 280 .arg(exception.lineNumber())
Chris@225 281 .arg(exception.columnNumber());
Chris@225 282 std::cerr << errorString.toStdString() << std::endl;
Chris@225 283 return QXmlDefaultHandler::error(exception);
Chris@225 284 }
Chris@225 285
Chris@225 286 bool
Chris@225 287 TipDialog::TipFileParser::fatalError(const QXmlParseException &exception)
Chris@225 288 {
Chris@225 289 QString errorString =
Chris@225 290 QString("FATAL ERROR: TipFileParser: %1 at line %2, column %3")
Chris@225 291 .arg(exception.message())
Chris@225 292 .arg(exception.lineNumber())
Chris@225 293 .arg(exception.columnNumber());
Chris@225 294 std::cerr << errorString.toStdString() << std::endl;
Chris@225 295 return QXmlDefaultHandler::fatalError(exception);
Chris@225 296 }