annotate widgets/TipDialog.cpp @ 1447:8afea53332f3 single-point

Add option to make pane sizes auto-resize-only (i.e. remove user control via a splitter); also place alignment views above panes instead of below, meaning the extra bit of space that we currently have for the pane without one at least goes to the primary pane
author Chris Cannam
date Tue, 30 Apr 2019 15:53:21 +0100
parents c8a6fd3f9dff
children
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@616 31 TipDialog::TipDialog(QWidget *parent) :
Chris@616 32 QDialog(parent),
Chris@225 33 m_tipNumber(0),
Chris@1408 34 m_label(nullptr),
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@229 65 QCheckBox *show = new QCheckBox(tr("Show tip on startup"));
Chris@228 66 hbox->addWidget(show);
Chris@228 67
Chris@229 68 hbox->addSpacing(20);
Chris@228 69 hbox->addStretch(10);
Chris@228 70
Chris@228 71 QPushButton *prev = new QPushButton(tr("<< Previous"));
Chris@228 72 hbox->addWidget(prev);
Chris@228 73 connect(prev, SIGNAL(clicked()), this, SLOT(previous()));
Chris@228 74
Chris@228 75 QPushButton *next = new QPushButton(tr("Next >>"));
Chris@228 76 hbox->addWidget(next);
Chris@228 77 connect(next, SIGNAL(clicked()), this, SLOT(next()));
Chris@225 78
Chris@225 79 QPushButton *close = new QPushButton(tr("Close"));
Chris@225 80 hbox->addWidget(close);
Chris@225 81 connect(close, SIGNAL(clicked()), this, SLOT(accept()));
Chris@225 82
Chris@228 83 close->setDefault(true);
Chris@228 84
Chris@225 85 showTip();
Chris@225 86 }
Chris@225 87
Chris@225 88 TipDialog::~TipDialog()
Chris@225 89 {
Chris@225 90 }
Chris@225 91
Chris@225 92 void
Chris@225 93 TipDialog::next()
Chris@225 94 {
Chris@225 95 if (++m_tipNumber >= int(m_tips.size())) {
Chris@225 96 //!!! The tips file should define where we loop back to -- the
Chris@225 97 // first one at least is likely to be a generic welcome message
Chris@225 98 m_tipNumber = 0;
Chris@225 99 }
Chris@225 100
Chris@225 101 showTip();
Chris@225 102 }
Chris@225 103
Chris@225 104 void
Chris@225 105 TipDialog::previous()
Chris@225 106 {
Chris@225 107 if (--m_tipNumber < 0) {
Chris@908 108 m_tipNumber = int(m_tips.size()) - 1;
Chris@225 109 }
Chris@225 110
Chris@225 111 showTip();
Chris@225 112 }
Chris@225 113
Chris@225 114 void
Chris@225 115 TipDialog::readTips()
Chris@225 116 {
Chris@587 117 SVDEBUG << "TipDialog::readTips" << endl;
Chris@225 118
Chris@225 119 QString language = QLocale::system().name();
Chris@225 120 QString filename = QString(":i18n/tips_%1.xml").arg(language);
Chris@225 121
Chris@225 122 if (!QFileInfo(filename).exists()) {
Chris@225 123
Chris@225 124 QString base = language.section('_', 0, 0);
Chris@225 125 filename = QString(":i18n/tips_%1.xml").arg(base);
Chris@225 126
Chris@225 127 if (!QFileInfo(filename).exists()) {
Chris@225 128
Chris@225 129 filename = QString(":i18n/tips.xml");
Chris@225 130
Chris@225 131 if (!QFileInfo(filename).exists()) return;
Chris@225 132 }
Chris@225 133 }
Chris@225 134
Chris@225 135 QFile file(filename);
Chris@225 136
Chris@587 137 SVDEBUG << "TipDialog::readTips from " << filename << endl;
Chris@225 138
Chris@225 139 QXmlInputSource source(&file);
Chris@225 140
Chris@225 141 TipFileParser parser(this);
Chris@225 142 parser.parse(source);
Chris@225 143 }
Chris@225 144
Chris@225 145 void
Chris@225 146 TipDialog::showTip()
Chris@225 147 {
Chris@225 148 if (m_tipNumber < int(m_tips.size())) {
Chris@682 149 cerr << "Tip " << m_tipNumber << " is: " << m_tips[m_tipNumber] << endl;
Chris@225 150 m_label->setText(m_tips[m_tipNumber]);
Chris@225 151 } else {
Chris@225 152 accept();
Chris@225 153 }
Chris@225 154
Chris@225 155 int tn = m_tipNumber;
Chris@225 156 if (++tn >= int(m_tips.size())) tn = 0; //!!! as above
Chris@225 157
Chris@225 158 QSettings settings;
Chris@225 159 settings.beginGroup("TipOfTheDay");
Chris@225 160 settings.setValue("nexttip", tn);
Chris@225 161 }
Chris@225 162
Chris@225 163 TipDialog::TipFileParser::TipFileParser(TipDialog *dialog) :
Chris@225 164 m_dialog(dialog),
Chris@225 165 m_inTip(false),
Chris@228 166 m_inText(false),
Chris@228 167 m_inHtml(false)
Chris@225 168 {
Chris@225 169 }
Chris@225 170
Chris@225 171 TipDialog::TipFileParser::~TipFileParser()
Chris@225 172 {
Chris@225 173 }
Chris@225 174
Chris@225 175 void
Chris@225 176 TipDialog::TipFileParser::parse(QXmlInputSource &source)
Chris@225 177 {
Chris@225 178 QXmlSimpleReader reader;
Chris@225 179 reader.setContentHandler(this);
Chris@225 180 reader.setErrorHandler(this);
Chris@225 181 reader.parse(source);
Chris@225 182 }
Chris@225 183
Chris@225 184 bool
Chris@225 185 TipDialog::TipFileParser::startElement(const QString &, const QString &,
Chris@225 186 const QString &qName,
Chris@225 187 const QXmlAttributes &attributes)
Chris@225 188 {
Chris@225 189 QString name = qName.toLower();
Chris@225 190
Chris@587 191 SVDEBUG << "TipFileParser::startElement(" << name << ")" << endl;
Chris@225 192
Chris@225 193 if (name == "tips") {
Chris@225 194 QString caption = attributes.value("caption");
Chris@587 195 SVDEBUG << "TipFileParser::caption = " << caption << endl;
Chris@225 196 if (caption != "") m_dialog->m_caption = caption;
Chris@225 197 } else if (name == "tip") {
Chris@225 198 if (m_inTip) {
Chris@682 199 cerr << "WARNING: TipFileParser: nested <tip> elements" << endl;
Chris@225 200 }
Chris@225 201 m_inTip = true;
Chris@225 202 } else if (name == "text") {
Chris@225 203 if (m_inTip) {
Chris@225 204 m_inText = true;
Chris@682 205 cerr << "TipFileParser: adding new tip" << endl;
Chris@225 206 m_dialog->m_tips.push_back("");
Chris@225 207 } else {
Chris@682 208 cerr << "WARNING: TipFileParser: <text> outside <tip> element" << endl;
Chris@225 209 }
Chris@228 210 } else if (name == "html") {
Chris@228 211 if (m_inTip) {
Chris@228 212 m_inHtml = true;
Chris@682 213 cerr << "TipFileParser: adding new tip" << endl;
Chris@228 214 m_dialog->m_tips.push_back("");
Chris@228 215 } else {
Chris@682 216 cerr << "WARNING: TipFileParser: <html> outside <tip> element" << endl;
Chris@228 217 }
Chris@228 218 } else if (m_inHtml) {
Chris@228 219 m_dialog->m_tips[m_dialog->m_tips.size()-1] += "<" + qName;
Chris@228 220 for (int i = 0; i < attributes.count(); ++i) {
Chris@228 221 m_dialog->m_tips[m_dialog->m_tips.size()-1] +=
Chris@228 222 " " + attributes.qName(i) + "=\"" + attributes.value(i) + "\"";
Chris@228 223 }
Chris@228 224 m_dialog->m_tips[m_dialog->m_tips.size()-1] += ">";
Chris@225 225 }
Chris@225 226
Chris@587 227 SVDEBUG << "TipFileParser::startElement done" << endl;
Chris@225 228 return true;
Chris@225 229 }
Chris@225 230
Chris@225 231 bool
Chris@225 232 TipDialog::TipFileParser::endElement(const QString &, const QString &,
Chris@225 233 const QString &qName)
Chris@225 234 {
Chris@225 235 QString name = qName.toLower();
Chris@225 236
Chris@225 237 if (name == "text") {
Chris@228 238 if (!m_inText) {
Chris@682 239 cerr << "WARNING: TipFileParser: </text> without <text>" << endl;
Chris@225 240 }
Chris@225 241 m_inText = false;
Chris@228 242 } else if (name == "html") {
Chris@228 243 if (!m_inHtml) {
Chris@682 244 cerr << "WARNING: TipFileParser: </html> without <html>" << endl;
Chris@228 245 }
Chris@228 246 m_inHtml = false;
Chris@225 247 } else if (name == "tip") {
Chris@225 248 if (m_inText) {
Chris@682 249 cerr << "WARNING: TipFileParser: <text> without </text>" << endl;
Chris@228 250 } else if (m_inHtml) {
Chris@682 251 cerr << "WARNING: TipFileParser: <html> without </html>" << endl;
Chris@225 252 } else if (!m_inTip) {
Chris@682 253 cerr << "WARNING: TipFileParser: </tip> without <tip>" << endl;
Chris@225 254 }
Chris@225 255 m_inTip = false;
Chris@228 256 } else if (m_inHtml) {
Chris@228 257 m_dialog->m_tips[m_dialog->m_tips.size()-1] += "</" + qName + ">";
Chris@225 258 }
Chris@225 259
Chris@225 260 return true;
Chris@225 261 }
Chris@225 262
Chris@225 263 bool
Chris@225 264 TipDialog::TipFileParser::characters(const QString &text)
Chris@225 265 {
Chris@587 266 SVDEBUG << "TipFileParser::characters(" << text << ")" << endl;
Chris@225 267
Chris@228 268 if (m_inText || m_inHtml) {
Chris@225 269 m_dialog->m_tips[m_dialog->m_tips.size()-1] += text;
Chris@225 270 }
Chris@225 271
Chris@225 272 return true;
Chris@225 273 }
Chris@225 274
Chris@225 275 bool
Chris@225 276 TipDialog::TipFileParser::error(const QXmlParseException &exception)
Chris@225 277 {
Chris@225 278 QString errorString =
Chris@1266 279 QString("ERROR: TipFileParser: %1 at line %2, column %3")
Chris@1266 280 .arg(exception.message())
Chris@1266 281 .arg(exception.lineNumber())
Chris@1266 282 .arg(exception.columnNumber());
Chris@682 283 cerr << errorString << endl;
Chris@225 284 return QXmlDefaultHandler::error(exception);
Chris@225 285 }
Chris@225 286
Chris@225 287 bool
Chris@225 288 TipDialog::TipFileParser::fatalError(const QXmlParseException &exception)
Chris@225 289 {
Chris@225 290 QString errorString =
Chris@1266 291 QString("FATAL ERROR: TipFileParser: %1 at line %2, column %3")
Chris@1266 292 .arg(exception.message())
Chris@1266 293 .arg(exception.lineNumber())
Chris@1266 294 .arg(exception.columnNumber());
Chris@682 295 cerr << errorString << endl;
Chris@225 296 return QXmlDefaultHandler::fatalError(exception);
Chris@225 297 }