00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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, Qt::WFlags flags) :
00032 QDialog(parent, flags),
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
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
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 std::cerr << "TipDialog::readTips" << std::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 std::cerr << "TipDialog::readTips from " << filename.toStdString() << std::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 std::cerr << "Tip " << m_tipNumber << " is: " << m_tips[m_tipNumber].toStdString() << std::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 std::cerr << "TipFileParser::startElement(" << name.toStdString() << ")" << std::endl;
00192
00193 if (name == "tips") {
00194 QString caption = attributes.value("caption");
00195 std::cerr << "TipFileParser::caption = " << caption.toStdString() << std::endl;
00196 if (caption != "") m_dialog->m_caption = caption;
00197 } else if (name == "tip") {
00198 if (m_inTip) {
00199 std::cerr << "WARNING: TipFileParser: nested <tip> elements" << std::endl;
00200 }
00201 m_inTip = true;
00202 } else if (name == "text") {
00203 if (m_inTip) {
00204 m_inText = true;
00205 std::cerr << "TipFileParser: adding new tip" << std::endl;
00206 m_dialog->m_tips.push_back("");
00207 } else {
00208 std::cerr << "WARNING: TipFileParser: <text> outside <tip> element" << std::endl;
00209 }
00210 } else if (name == "html") {
00211 if (m_inTip) {
00212 m_inHtml = true;
00213 std::cerr << "TipFileParser: adding new tip" << std::endl;
00214 m_dialog->m_tips.push_back("");
00215 } else {
00216 std::cerr << "WARNING: TipFileParser: <html> outside <tip> element" << std::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 std::cerr << "TipFileParser::startElement done" << std::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 std::cerr << "WARNING: TipFileParser: </text> without <text>" << std::endl;
00240 }
00241 m_inText = false;
00242 } else if (name == "html") {
00243 if (!m_inHtml) {
00244 std::cerr << "WARNING: TipFileParser: </html> without <html>" << std::endl;
00245 }
00246 m_inHtml = false;
00247 } else if (name == "tip") {
00248 if (m_inText) {
00249 std::cerr << "WARNING: TipFileParser: <text> without </text>" << std::endl;
00250 } else if (m_inHtml) {
00251 std::cerr << "WARNING: TipFileParser: <html> without </html>" << std::endl;
00252 } else if (!m_inTip) {
00253 std::cerr << "WARNING: TipFileParser: </tip> without <tip>" << std::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 std::cerr << "TipFileParser::characters(" << text.toStdString() << ")" << std::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 std::cerr << errorString.toStdString() << std::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 std::cerr << errorString.toStdString() << std::endl;
00296 return QXmlDefaultHandler::fatalError(exception);
00297 }