svgui  1.9
TipDialog.cpp
Go to the documentation of this file.
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
00002 
00003 /*
00004     Sonic Visualiser
00005     An audio file viewer and annotation editor.
00006     Centre for Digital Music, Queen Mary, University of London.
00007     This file copyright 2007 QMUL.
00008     
00009     This program is free software; you can redistribute it and/or
00010     modify it under the terms of the GNU General Public License as
00011     published by the Free Software Foundation; either version 2 of the
00012     License, or (at your option) any later version.  See the file
00013     COPYING included with this distribution for more information.
00014 */
00015 
00016 #include "TipDialog.h"
00017 
00018 #include <QLabel>
00019 #include <QPushButton>
00020 #include <QSettings>
00021 #include <QLabel>
00022 #include <QLocale>
00023 #include <QXmlInputSource>
00024 #include <QFileInfo>
00025 #include <QGridLayout>
00026 #include <QGroupBox>
00027 #include <QCheckBox>
00028 
00029 #include <iostream>
00030 
00031 TipDialog::TipDialog(QWidget *parent) :
00032     QDialog(parent),
00033     m_tipNumber(0),
00034     m_label(0),
00035     m_caption(tr("Tip of the Day"))
00036 {
00037     readTips();
00038 
00039     QSettings settings;
00040     settings.beginGroup("TipOfTheDay");
00041 
00042     if (!settings.value("showonstartup", true).toBool()) return;
00043 
00044     m_tipNumber = settings.value("nexttip", 0).toInt();
00045 
00046     setWindowTitle(m_caption);
00047 
00048     QGridLayout *grid = new QGridLayout;
00049     setLayout(grid);
00050     
00051     QGroupBox *groupBox = new QGroupBox;
00052 //    groupBox->setTitle(m_caption);
00053     grid->addWidget(groupBox, 0, 0);
00054     
00055     QGridLayout *subgrid = new QGridLayout;
00056     groupBox->setLayout(subgrid);
00057 
00058     m_label = new QLabel;
00059     subgrid->addWidget(m_label, 0, 0);
00060     m_label->setWordWrap(true);
00061 
00062     QHBoxLayout *hbox = new QHBoxLayout;
00063     grid->addLayout(hbox, 1, 0);
00064 
00065     QCheckBox *show = new QCheckBox(tr("Show tip on startup"));
00066     hbox->addWidget(show);
00067 
00068     hbox->addSpacing(20);
00069     hbox->addStretch(10);
00070     
00071     QPushButton *prev = new QPushButton(tr("<< Previous"));
00072     hbox->addWidget(prev);
00073     connect(prev, SIGNAL(clicked()), this, SLOT(previous()));
00074     
00075     QPushButton *next = new QPushButton(tr("Next >>"));
00076     hbox->addWidget(next);
00077     connect(next, SIGNAL(clicked()), this, SLOT(next()));
00078     
00079     QPushButton *close = new QPushButton(tr("Close"));
00080     hbox->addWidget(close);
00081     connect(close, SIGNAL(clicked()), this, SLOT(accept()));
00082     
00083     close->setDefault(true);
00084 
00085     showTip();
00086 }
00087 
00088 TipDialog::~TipDialog()
00089 {
00090 }
00091 
00092 void
00093 TipDialog::next()
00094 {
00095     if (++m_tipNumber >= int(m_tips.size())) {
00097         // first one at least is likely to be a generic welcome message
00098         m_tipNumber = 0;
00099     }
00100 
00101     showTip();
00102 }
00103 
00104 void
00105 TipDialog::previous()
00106 {
00107     if (--m_tipNumber < 0) {
00108         m_tipNumber = m_tips.size() - 1;
00109     }
00110 
00111     showTip();
00112 }
00113 
00114 void
00115 TipDialog::readTips()
00116 {
00117     SVDEBUG << "TipDialog::readTips" << endl;
00118 
00119     QString language = QLocale::system().name();
00120     QString filename = QString(":i18n/tips_%1.xml").arg(language);
00121 
00122     if (!QFileInfo(filename).exists()) {
00123 
00124         QString base = language.section('_', 0, 0);
00125         filename = QString(":i18n/tips_%1.xml").arg(base);
00126 
00127         if (!QFileInfo(filename).exists()) {
00128 
00129             filename = QString(":i18n/tips.xml");
00130 
00131             if (!QFileInfo(filename).exists()) return;
00132         }
00133     }
00134 
00135     QFile file(filename);
00136 
00137     SVDEBUG << "TipDialog::readTips from " << filename << endl;
00138 
00139     QXmlInputSource source(&file);
00140     
00141     TipFileParser parser(this);
00142     parser.parse(source);
00143 }
00144 
00145 void
00146 TipDialog::showTip()
00147 {
00148     if (m_tipNumber < int(m_tips.size())) {
00149         cerr << "Tip " << m_tipNumber << " is: " << m_tips[m_tipNumber] << endl;
00150         m_label->setText(m_tips[m_tipNumber]);
00151     } else {
00152         accept();
00153     }
00154 
00155     int tn = m_tipNumber;
00156     if (++tn >= int(m_tips.size())) tn = 0; 
00157 
00158     QSettings settings;
00159     settings.beginGroup("TipOfTheDay");
00160     settings.setValue("nexttip", tn);
00161 }
00162 
00163 TipDialog::TipFileParser::TipFileParser(TipDialog *dialog) :
00164     m_dialog(dialog),
00165     m_inTip(false),
00166     m_inText(false),
00167     m_inHtml(false)
00168 {
00169 }
00170 
00171 TipDialog::TipFileParser::~TipFileParser()
00172 {
00173 }
00174 
00175 void
00176 TipDialog::TipFileParser::parse(QXmlInputSource &source)
00177 {
00178     QXmlSimpleReader reader;
00179     reader.setContentHandler(this);
00180     reader.setErrorHandler(this);
00181     reader.parse(source);
00182 }
00183 
00184 bool
00185 TipDialog::TipFileParser::startElement(const QString &, const QString &,
00186                                        const QString &qName,
00187                                        const QXmlAttributes &attributes)
00188 {
00189     QString name = qName.toLower();
00190 
00191     SVDEBUG << "TipFileParser::startElement(" << name << ")" << endl;
00192 
00193     if (name == "tips") {
00194         QString caption = attributes.value("caption");
00195         SVDEBUG << "TipFileParser::caption = " << caption << endl;
00196         if (caption != "") m_dialog->m_caption = caption;
00197     } else if (name == "tip") {
00198         if (m_inTip) {
00199             cerr << "WARNING: TipFileParser: nested <tip> elements" << endl;
00200         }
00201         m_inTip = true;
00202     } else if (name == "text") {
00203         if (m_inTip) {
00204             m_inText = true;
00205             cerr << "TipFileParser: adding new tip" << endl;
00206             m_dialog->m_tips.push_back("");
00207         } else {
00208             cerr << "WARNING: TipFileParser: <text> outside <tip> element" << endl;
00209         }
00210     } else if (name == "html") {
00211         if (m_inTip) {
00212             m_inHtml = true;
00213             cerr << "TipFileParser: adding new tip" << endl;
00214             m_dialog->m_tips.push_back("");
00215         } else {
00216             cerr << "WARNING: TipFileParser: <html> outside <tip> element" << endl;
00217         }
00218     } else if (m_inHtml) {
00219         m_dialog->m_tips[m_dialog->m_tips.size()-1] += "<" + qName;
00220         for (int i = 0; i < attributes.count(); ++i) {
00221             m_dialog->m_tips[m_dialog->m_tips.size()-1] += 
00222                 " " + attributes.qName(i) + "=\"" + attributes.value(i) + "\"";
00223         }
00224         m_dialog->m_tips[m_dialog->m_tips.size()-1] += ">";
00225     }
00226     
00227     SVDEBUG << "TipFileParser::startElement done" << endl;
00228     return true;
00229 }
00230 
00231 bool
00232 TipDialog::TipFileParser::endElement(const QString &, const QString &,
00233                                      const QString &qName)
00234 {
00235     QString name = qName.toLower();
00236 
00237     if (name == "text") {
00238         if (!m_inText) {
00239             cerr << "WARNING: TipFileParser: </text> without <text>" << endl;
00240         }
00241         m_inText = false;
00242     } else if (name == "html") {
00243         if (!m_inHtml) {
00244             cerr << "WARNING: TipFileParser: </html> without <html>" << endl;
00245         }
00246         m_inHtml = false;
00247     } else if (name == "tip") {
00248         if (m_inText) {
00249             cerr << "WARNING: TipFileParser: <text> without </text>" << endl;
00250         } else if (m_inHtml) {
00251             cerr << "WARNING: TipFileParser: <html> without </html>" << endl;
00252         } else if (!m_inTip) {
00253             cerr << "WARNING: TipFileParser: </tip> without <tip>" << endl;
00254         }
00255         m_inTip = false;
00256     } else if (m_inHtml) {
00257         m_dialog->m_tips[m_dialog->m_tips.size()-1] += "</" + qName + ">";
00258     }
00259 
00260     return true;
00261 }
00262 
00263 bool
00264 TipDialog::TipFileParser::characters(const QString &text)
00265 {
00266     SVDEBUG << "TipFileParser::characters(" << text << ")" << endl;
00267 
00268     if (m_inText || m_inHtml) {
00269         m_dialog->m_tips[m_dialog->m_tips.size()-1] += text;
00270     }
00271 
00272     return true;
00273 }
00274 
00275 bool
00276 TipDialog::TipFileParser::error(const QXmlParseException &exception)
00277 {
00278     QString errorString =
00279         QString("ERROR: TipFileParser: %1 at line %2, column %3")
00280         .arg(exception.message())
00281         .arg(exception.lineNumber())
00282         .arg(exception.columnNumber());
00283     cerr << errorString << endl;
00284     return QXmlDefaultHandler::error(exception);
00285 }
00286 
00287 bool
00288 TipDialog::TipFileParser::fatalError(const QXmlParseException &exception)
00289 {
00290     QString errorString =
00291         QString("FATAL ERROR: TipFileParser: %1 at line %2, column %3")
00292         .arg(exception.message())
00293         .arg(exception.lineNumber())
00294         .arg(exception.columnNumber());
00295     cerr << errorString << endl;
00296     return QXmlDefaultHandler::fatalError(exception);
00297 }