# HG changeset patch # User Chris Cannam # Date 1173464310 0 # Node ID 6f46179086c0431c16d66168782861a2933118f4 # Parent 9465b5375235b323df6cc7857c28ad45bad0a94a * Basic beginnings of what will become a tip-of-the-day dialog diff -r 9465b5375235 -r 6f46179086c0 widgets/TipDialog.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/widgets/TipDialog.cpp Fri Mar 09 18:18:30 2007 +0000 @@ -0,0 +1,255 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Sonic Visualiser + An audio file viewer and annotation editor. + Centre for Digital Music, Queen Mary, University of London. + This file copyright 2007 QMUL. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#include "TipDialog.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +TipDialog::TipDialog(QWidget *parent, Qt::WFlags flags) : + QDialog(parent, flags), + m_tipNumber(0), + m_label(0), + m_caption(tr("Tip of the Day")) +{ + readTips(); + + QSettings settings; + settings.beginGroup("TipOfTheDay"); + + if (!settings.value("showonstartup", true).toBool()) return; + + m_tipNumber = settings.value("nexttip", 0).toInt(); + + setWindowTitle(m_caption); + + QGridLayout *grid = new QGridLayout; + setLayout(grid); + + QGroupBox *groupBox = new QGroupBox; + groupBox->setTitle(m_caption); + grid->addWidget(groupBox, 0, 0); + + QGridLayout *subgrid = new QGridLayout; + groupBox->setLayout(subgrid); + + m_label = new QLabel; + subgrid->addWidget(m_label, 0, 0); + + QHBoxLayout *hbox = new QHBoxLayout; + grid->addLayout(hbox, 1, 0); + + QPushButton *close = new QPushButton(tr("Close")); + hbox->addStretch(10); + hbox->addWidget(close); + connect(close, SIGNAL(clicked()), this, SLOT(accept())); + + showTip(); +} + +TipDialog::~TipDialog() +{ +} + +void +TipDialog::next() +{ + if (++m_tipNumber >= int(m_tips.size())) { + //!!! The tips file should define where we loop back to -- the + // first one at least is likely to be a generic welcome message + m_tipNumber = 0; + } + + showTip(); +} + +void +TipDialog::previous() +{ + if (--m_tipNumber < 0) { + m_tipNumber = m_tips.size() - 1; + } + + showTip(); +} + +void +TipDialog::readTips() +{ + std::cerr << "TipDialog::readTips" << std::endl; + + QString language = QLocale::system().name(); + QString filename = QString(":i18n/tips_%1.xml").arg(language); + + if (!QFileInfo(filename).exists()) { + + QString base = language.section('_', 0, 0); + filename = QString(":i18n/tips_%1.xml").arg(base); + + if (!QFileInfo(filename).exists()) { + + filename = QString(":i18n/tips.xml"); + + if (!QFileInfo(filename).exists()) return; + } + } + + QFile file(filename); + + std::cerr << "TipDialog::readTips from " << filename.toStdString() << std::endl; + + QXmlInputSource source(&file); + + TipFileParser parser(this); + parser.parse(source); +} + +void +TipDialog::showTip() +{ + if (m_tipNumber < int(m_tips.size())) { + std::cerr << "Tip " << m_tipNumber << " is: " << m_tips[m_tipNumber].toStdString() << std::endl; + m_label->setText(m_tips[m_tipNumber]); + } else { + accept(); + } + + int tn = m_tipNumber; + if (++tn >= int(m_tips.size())) tn = 0; //!!! as above + + QSettings settings; + settings.beginGroup("TipOfTheDay"); + settings.setValue("nexttip", tn); +} + +TipDialog::TipFileParser::TipFileParser(TipDialog *dialog) : + m_dialog(dialog), + m_inTip(false), + m_inText(false) +{ +} + +TipDialog::TipFileParser::~TipFileParser() +{ +} + +void +TipDialog::TipFileParser::parse(QXmlInputSource &source) +{ + QXmlSimpleReader reader; + reader.setContentHandler(this); + reader.setErrorHandler(this); + reader.parse(source); +} + +bool +TipDialog::TipFileParser::startElement(const QString &, const QString &, + const QString &qName, + const QXmlAttributes &attributes) +{ + QString name = qName.toLower(); + + std::cerr << "TipFileParser::startElement(" << name.toStdString() << ")" << std::endl; + + if (name == "tips") { + QString caption = attributes.value("caption"); + std::cerr << "TipFileParser::caption = " << caption.toStdString() << std::endl; + if (caption != "") m_dialog->m_caption = caption; + } else if (name == "tip") { + if (m_inTip) { + std::cerr << "WARNING: TipFileParser: nested elements" << std::endl; + } + m_inTip = true; + } else if (name == "text") { + if (m_inTip) { + m_inText = true; + std::cerr << "TipFileParser: adding new tip" << std::endl; + m_dialog->m_tips.push_back(""); + } else { + std::cerr << "WARNING: TipFileParser: outside element" << std::endl; + } + } + + std::cerr << "TipFileParser::startElement done" << std::endl; + return true; +} + +bool +TipDialog::TipFileParser::endElement(const QString &, const QString &, + const QString &qName) +{ + QString name = qName.toLower(); + + if (name == "text") { + if (m_inText) { + std::cerr << "WARNING: TipFileParser: without " << std::endl; + } + m_inText = false; + } else if (name == "tip") { + if (m_inText) { + std::cerr << "WARNING: TipFileParser: without " << std::endl; + } else if (!m_inTip) { + std::cerr << "WARNING: TipFileParser: without " << std::endl; + } + m_inTip = false; + } + + return true; +} + +bool +TipDialog::TipFileParser::characters(const QString &text) +{ + std::cerr << "TipFileParser::characters(" << text.toStdString() << ")" << std::endl; + + if (m_inText) { + m_dialog->m_tips[m_dialog->m_tips.size()-1] += text; + } + + return true; +} + +bool +TipDialog::TipFileParser::error(const QXmlParseException &exception) +{ + QString errorString = + QString("ERROR: TipFileParser: %1 at line %2, column %3") + .arg(exception.message()) + .arg(exception.lineNumber()) + .arg(exception.columnNumber()); + std::cerr << errorString.toStdString() << std::endl; + return QXmlDefaultHandler::error(exception); +} + +bool +TipDialog::TipFileParser::fatalError(const QXmlParseException &exception) +{ + QString errorString = + QString("FATAL ERROR: TipFileParser: %1 at line %2, column %3") + .arg(exception.message()) + .arg(exception.lineNumber()) + .arg(exception.columnNumber()); + std::cerr << errorString.toStdString() << std::endl; + return QXmlDefaultHandler::fatalError(exception); +} diff -r 9465b5375235 -r 6f46179086c0 widgets/TipDialog.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/widgets/TipDialog.h Fri Mar 09 18:18:30 2007 +0000 @@ -0,0 +1,82 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Sonic Visualiser + An audio file viewer and annotation editor. + Centre for Digital Music, Queen Mary, University of London. + This file copyright 2007 QMUL. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#ifndef _TIP_DIALOG_H_ +#define _TIP_DIALOG_H_ + +#include +#include +#include + +#include + +class QLabel; +class QXmlInputSource; + +class TipDialog : public QDialog +{ + Q_OBJECT + +public: + TipDialog(QWidget *parent = 0, Qt::WFlags flags = 0); + virtual ~TipDialog(); + + bool isOK() { return !m_tips.empty(); } + +protected slots: + void previous(); + void next(); + +protected: + int m_tipNumber; + QLabel *m_label; + QString m_caption; + + std::vector m_tips; + + void readTips(); + void showTip(); + + class TipFileParser : public QXmlDefaultHandler + { + public: + TipFileParser(TipDialog *dialog); + virtual ~TipFileParser(); + + void parse(QXmlInputSource &source); + + virtual bool startElement(const QString &namespaceURI, + const QString &localName, + const QString &qName, + const QXmlAttributes& atts); + + virtual bool characters(const QString &); + + virtual bool endElement(const QString &namespaceURI, + const QString &localName, + const QString &qName); + + bool error(const QXmlParseException &exception); + bool fatalError(const QXmlParseException &exception); + + protected: + TipDialog *m_dialog; + + bool m_inTip; + bool m_inText; + }; +}; + +#endif diff -r 9465b5375235 -r 6f46179086c0 widgets/widgets.pro --- a/widgets/widgets.pro Thu Mar 08 16:53:08 2007 +0000 +++ b/widgets/widgets.pro Fri Mar 09 18:18:30 2007 +0000 @@ -32,6 +32,7 @@ RangeInputDialog.h \ SubdividingMenu.h \ Thumbwheel.h \ + TipDialog.h \ WindowShapePreview.h \ WindowTypeSelector.h SOURCES += AudioDial.cpp \ @@ -52,5 +53,6 @@ RangeInputDialog.cpp \ SubdividingMenu.cpp \ Thumbwheel.cpp \ + TipDialog.cpp \ WindowShapePreview.cpp \ WindowTypeSelector.cpp