lbajardsilogic@0: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ lbajardsilogic@0: lbajardsilogic@0: /* lbajardsilogic@0: Sonic Visualiser lbajardsilogic@0: An audio file viewer and annotation editor. lbajardsilogic@0: Centre for Digital Music, Queen Mary, University of London. lbajardsilogic@0: This file copyright 2007 QMUL. lbajardsilogic@0: lbajardsilogic@0: This program is free software; you can redistribute it and/or lbajardsilogic@0: modify it under the terms of the GNU General Public License as lbajardsilogic@0: published by the Free Software Foundation; either version 2 of the lbajardsilogic@0: License, or (at your option) any later version. See the file lbajardsilogic@0: COPYING included with this distribution for more information. lbajardsilogic@0: */ lbajardsilogic@0: lbajardsilogic@0: #include "TipDialog.h" lbajardsilogic@0: lbajardsilogic@0: #include lbajardsilogic@0: #include lbajardsilogic@0: #include lbajardsilogic@0: #include lbajardsilogic@0: #include lbajardsilogic@0: #include lbajardsilogic@0: #include lbajardsilogic@0: #include lbajardsilogic@0: #include lbajardsilogic@0: #include lbajardsilogic@0: lbajardsilogic@0: #include lbajardsilogic@0: lbajardsilogic@0: TipDialog::TipDialog(QWidget *parent, Qt::WFlags flags) : lbajardsilogic@0: QDialog(parent, flags), lbajardsilogic@0: m_tipNumber(0), lbajardsilogic@0: m_label(0), lbajardsilogic@0: m_caption(tr("Tip of the Day")) lbajardsilogic@0: { lbajardsilogic@0: readTips(); lbajardsilogic@0: lbajardsilogic@0: QSettings settings; lbajardsilogic@0: settings.beginGroup("TipOfTheDay"); lbajardsilogic@0: lbajardsilogic@0: if (!settings.value("showonstartup", true).toBool()) return; lbajardsilogic@0: lbajardsilogic@0: m_tipNumber = settings.value("nexttip", 0).toInt(); lbajardsilogic@0: lbajardsilogic@0: setWindowTitle(m_caption); lbajardsilogic@0: lbajardsilogic@0: QGridLayout *grid = new QGridLayout; lbajardsilogic@0: setLayout(grid); lbajardsilogic@0: lbajardsilogic@0: QGroupBox *groupBox = new QGroupBox; lbajardsilogic@0: // groupBox->setTitle(m_caption); lbajardsilogic@0: grid->addWidget(groupBox, 0, 0); lbajardsilogic@0: lbajardsilogic@0: QGridLayout *subgrid = new QGridLayout; lbajardsilogic@0: groupBox->setLayout(subgrid); lbajardsilogic@0: lbajardsilogic@0: m_label = new QLabel; lbajardsilogic@0: subgrid->addWidget(m_label, 0, 0); lbajardsilogic@0: m_label->setWordWrap(true); lbajardsilogic@0: lbajardsilogic@0: QHBoxLayout *hbox = new QHBoxLayout; lbajardsilogic@0: grid->addLayout(hbox, 1, 0); lbajardsilogic@0: lbajardsilogic@0: QCheckBox *show = new QCheckBox(tr("Show tip on startup")); lbajardsilogic@0: hbox->addWidget(show); lbajardsilogic@0: lbajardsilogic@0: hbox->addSpacing(20); lbajardsilogic@0: hbox->addStretch(10); lbajardsilogic@0: lbajardsilogic@0: QPushButton *prev = new QPushButton(tr("<< Previous")); lbajardsilogic@0: hbox->addWidget(prev); lbajardsilogic@0: connect(prev, SIGNAL(clicked()), this, SLOT(previous())); lbajardsilogic@0: lbajardsilogic@0: QPushButton *next = new QPushButton(tr("Next >>")); lbajardsilogic@0: hbox->addWidget(next); lbajardsilogic@0: connect(next, SIGNAL(clicked()), this, SLOT(next())); lbajardsilogic@0: lbajardsilogic@0: QPushButton *close = new QPushButton(tr("Close")); lbajardsilogic@0: hbox->addWidget(close); lbajardsilogic@0: connect(close, SIGNAL(clicked()), this, SLOT(accept())); lbajardsilogic@0: lbajardsilogic@0: close->setDefault(true); lbajardsilogic@0: lbajardsilogic@0: showTip(); lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: TipDialog::~TipDialog() lbajardsilogic@0: { lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: void lbajardsilogic@0: TipDialog::next() lbajardsilogic@0: { lbajardsilogic@0: if (++m_tipNumber >= int(m_tips.size())) { lbajardsilogic@0: //!!! The tips file should define where we loop back to -- the lbajardsilogic@0: // first one at least is likely to be a generic welcome message lbajardsilogic@0: m_tipNumber = 0; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: showTip(); lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: void lbajardsilogic@0: TipDialog::previous() lbajardsilogic@0: { lbajardsilogic@0: if (--m_tipNumber < 0) { lbajardsilogic@0: m_tipNumber = m_tips.size() - 1; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: showTip(); lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: void lbajardsilogic@0: TipDialog::readTips() lbajardsilogic@0: { lbajardsilogic@0: std::cerr << "TipDialog::readTips" << std::endl; lbajardsilogic@0: lbajardsilogic@0: QString language = QLocale::system().name(); lbajardsilogic@0: QString filename = QString(":i18n/tips_%1.xml").arg(language); lbajardsilogic@0: lbajardsilogic@0: if (!QFileInfo(filename).exists()) { lbajardsilogic@0: lbajardsilogic@0: QString base = language.section('_', 0, 0); lbajardsilogic@0: filename = QString(":i18n/tips_%1.xml").arg(base); lbajardsilogic@0: lbajardsilogic@0: if (!QFileInfo(filename).exists()) { lbajardsilogic@0: lbajardsilogic@0: filename = QString(":i18n/tips.xml"); lbajardsilogic@0: lbajardsilogic@0: if (!QFileInfo(filename).exists()) return; lbajardsilogic@0: } lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: QFile file(filename); lbajardsilogic@0: lbajardsilogic@0: std::cerr << "TipDialog::readTips from " << filename.toStdString() << std::endl; lbajardsilogic@0: lbajardsilogic@0: QXmlInputSource source(&file); lbajardsilogic@0: lbajardsilogic@0: TipFileParser parser(this); lbajardsilogic@0: parser.parse(source); lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: void lbajardsilogic@0: TipDialog::showTip() lbajardsilogic@0: { lbajardsilogic@0: if (m_tipNumber < int(m_tips.size())) { lbajardsilogic@0: std::cerr << "Tip " << m_tipNumber << " is: " << m_tips[m_tipNumber].toStdString() << std::endl; lbajardsilogic@0: m_label->setText(m_tips[m_tipNumber]); lbajardsilogic@0: } else { lbajardsilogic@0: accept(); lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: int tn = m_tipNumber; lbajardsilogic@0: if (++tn >= int(m_tips.size())) tn = 0; //!!! as above lbajardsilogic@0: lbajardsilogic@0: QSettings settings; lbajardsilogic@0: settings.beginGroup("TipOfTheDay"); lbajardsilogic@0: settings.setValue("nexttip", tn); lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: TipDialog::TipFileParser::TipFileParser(TipDialog *dialog) : lbajardsilogic@0: m_dialog(dialog), lbajardsilogic@0: m_inTip(false), lbajardsilogic@0: m_inText(false), lbajardsilogic@0: m_inHtml(false) lbajardsilogic@0: { lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: TipDialog::TipFileParser::~TipFileParser() lbajardsilogic@0: { lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: void lbajardsilogic@0: TipDialog::TipFileParser::parse(QXmlInputSource &source) lbajardsilogic@0: { lbajardsilogic@0: QXmlSimpleReader reader; lbajardsilogic@0: reader.setContentHandler(this); lbajardsilogic@0: reader.setErrorHandler(this); lbajardsilogic@0: reader.parse(source); lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: bool lbajardsilogic@0: TipDialog::TipFileParser::startElement(const QString &, const QString &, lbajardsilogic@0: const QString &qName, lbajardsilogic@0: const QXmlAttributes &attributes) lbajardsilogic@0: { lbajardsilogic@0: QString name = qName.toLower(); lbajardsilogic@0: lbajardsilogic@0: std::cerr << "TipFileParser::startElement(" << name.toStdString() << ")" << std::endl; lbajardsilogic@0: lbajardsilogic@0: if (name == "tips") { lbajardsilogic@0: QString caption = attributes.value("caption"); lbajardsilogic@0: std::cerr << "TipFileParser::caption = " << caption.toStdString() << std::endl; lbajardsilogic@0: if (caption != "") m_dialog->m_caption = caption; lbajardsilogic@0: } else if (name == "tip") { lbajardsilogic@0: if (m_inTip) { lbajardsilogic@0: std::cerr << "WARNING: TipFileParser: nested elements" << std::endl; lbajardsilogic@0: } lbajardsilogic@0: m_inTip = true; lbajardsilogic@0: } else if (name == "text") { lbajardsilogic@0: if (m_inTip) { lbajardsilogic@0: m_inText = true; lbajardsilogic@0: std::cerr << "TipFileParser: adding new tip" << std::endl; lbajardsilogic@0: m_dialog->m_tips.push_back(""); lbajardsilogic@0: } else { lbajardsilogic@0: std::cerr << "WARNING: TipFileParser: outside element" << std::endl; lbajardsilogic@0: } lbajardsilogic@0: } else if (name == "html") { lbajardsilogic@0: if (m_inTip) { lbajardsilogic@0: m_inHtml = true; lbajardsilogic@0: std::cerr << "TipFileParser: adding new tip" << std::endl; lbajardsilogic@0: m_dialog->m_tips.push_back(""); lbajardsilogic@0: } else { lbajardsilogic@0: std::cerr << "WARNING: TipFileParser: outside element" << std::endl; lbajardsilogic@0: } lbajardsilogic@0: } else if (m_inHtml) { lbajardsilogic@0: m_dialog->m_tips[m_dialog->m_tips.size()-1] += "<" + qName; lbajardsilogic@0: for (int i = 0; i < attributes.count(); ++i) { lbajardsilogic@0: m_dialog->m_tips[m_dialog->m_tips.size()-1] += lbajardsilogic@0: " " + attributes.qName(i) + "=\"" + attributes.value(i) + "\""; lbajardsilogic@0: } lbajardsilogic@0: m_dialog->m_tips[m_dialog->m_tips.size()-1] += ">"; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: std::cerr << "TipFileParser::startElement done" << std::endl; lbajardsilogic@0: return true; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: bool lbajardsilogic@0: TipDialog::TipFileParser::endElement(const QString &, const QString &, lbajardsilogic@0: const QString &qName) lbajardsilogic@0: { lbajardsilogic@0: QString name = qName.toLower(); lbajardsilogic@0: lbajardsilogic@0: if (name == "text") { lbajardsilogic@0: if (!m_inText) { lbajardsilogic@0: std::cerr << "WARNING: TipFileParser: without " << std::endl; lbajardsilogic@0: } lbajardsilogic@0: m_inText = false; lbajardsilogic@0: } else if (name == "html") { lbajardsilogic@0: if (!m_inHtml) { lbajardsilogic@0: std::cerr << "WARNING: TipFileParser: without " << std::endl; lbajardsilogic@0: } lbajardsilogic@0: m_inHtml = false; lbajardsilogic@0: } else if (name == "tip") { lbajardsilogic@0: if (m_inText) { lbajardsilogic@0: std::cerr << "WARNING: TipFileParser: without " << std::endl; lbajardsilogic@0: } else if (m_inHtml) { lbajardsilogic@0: std::cerr << "WARNING: TipFileParser: without " << std::endl; lbajardsilogic@0: } else if (!m_inTip) { lbajardsilogic@0: std::cerr << "WARNING: TipFileParser: without " << std::endl; lbajardsilogic@0: } lbajardsilogic@0: m_inTip = false; lbajardsilogic@0: } else if (m_inHtml) { lbajardsilogic@0: m_dialog->m_tips[m_dialog->m_tips.size()-1] += ""; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: return true; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: bool lbajardsilogic@0: TipDialog::TipFileParser::characters(const QString &text) lbajardsilogic@0: { lbajardsilogic@0: std::cerr << "TipFileParser::characters(" << text.toStdString() << ")" << std::endl; lbajardsilogic@0: lbajardsilogic@0: if (m_inText || m_inHtml) { lbajardsilogic@0: m_dialog->m_tips[m_dialog->m_tips.size()-1] += text; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: return true; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: bool lbajardsilogic@0: TipDialog::TipFileParser::error(const QXmlParseException &exception) lbajardsilogic@0: { lbajardsilogic@0: QString errorString = lbajardsilogic@0: QString("ERROR: TipFileParser: %1 at line %2, column %3") lbajardsilogic@0: .arg(exception.message()) lbajardsilogic@0: .arg(exception.lineNumber()) lbajardsilogic@0: .arg(exception.columnNumber()); lbajardsilogic@0: std::cerr << errorString.toStdString() << std::endl; lbajardsilogic@0: return QXmlDefaultHandler::error(exception); lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: bool lbajardsilogic@0: TipDialog::TipFileParser::fatalError(const QXmlParseException &exception) lbajardsilogic@0: { lbajardsilogic@0: QString errorString = lbajardsilogic@0: QString("FATAL ERROR: TipFileParser: %1 at line %2, column %3") lbajardsilogic@0: .arg(exception.message()) lbajardsilogic@0: .arg(exception.lineNumber()) lbajardsilogic@0: .arg(exception.columnNumber()); lbajardsilogic@0: std::cerr << errorString.toStdString() << std::endl; lbajardsilogic@0: return QXmlDefaultHandler::fatalError(exception); lbajardsilogic@0: }