annotate multichoicedialog.cpp @ 341:1fc2e0269ae0 help

Add Help button to multi-choice dialog
author Chris Cannam
date Tue, 15 Mar 2011 12:36:26 +0000
parents 8fd71f570884
children
rev   line source
Chris@67 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@67 2
Chris@67 3 /*
Chris@67 4 EasyMercurial
Chris@67 5
Chris@67 6 Based on HgExplorer by Jari Korhonen
Chris@67 7 Copyright (c) 2010 Jari Korhonen
Chris@244 8 Copyright (c) 2011 Chris Cannam
Chris@244 9 Copyright (c) 2011 Queen Mary, University of London
Chris@67 10
Chris@67 11 This program is free software; you can redistribute it and/or
Chris@67 12 modify it under the terms of the GNU General Public License as
Chris@67 13 published by the Free Software Foundation; either version 2 of the
Chris@67 14 License, or (at your option) any later version. See the file
Chris@67 15 COPYING included with this distribution for more information.
Chris@67 16 */
Chris@67 17
Chris@67 18 #include "multichoicedialog.h"
Chris@67 19
Chris@69 20 #include "selectablelabel.h"
Chris@69 21
Chris@69 22 #include "debug.h"
Chris@69 23
Chris@68 24 #include <QDialogButtonBox>
Chris@69 25 #include <QToolButton>
Chris@69 26 #include <QPushButton>
Chris@69 27 #include <QFont>
Chris@69 28 #include <QDir>
Chris@69 29 #include <QFileDialog>
Chris@341 30 #include <QDesktopServices>
Chris@72 31 #include <QUrl>
Chris@68 32
Chris@341 33 MultiChoiceDialog::MultiChoiceDialog(QString title, QString heading,
Chris@341 34 QString helpUrl, QWidget *parent) :
Chris@341 35 QDialog(parent),
Chris@341 36 m_helpUrl(helpUrl)
Chris@67 37 {
Chris@68 38 setModal(true);
Chris@68 39 setWindowTitle(title);
Chris@68 40
Chris@68 41 QGridLayout *outer = new QGridLayout;
Chris@68 42 setLayout(outer);
Chris@68 43
Chris@68 44 outer->addWidget(new QLabel(heading), 0, 0, 1, 3);
Chris@68 45
Chris@68 46 QWidget *innerWidget = new QWidget;
Chris@69 47 outer->addWidget(innerWidget, 1, 0, 1, 3);
Chris@69 48 m_choiceLayout = new QHBoxLayout;
Chris@68 49 innerWidget->setLayout(m_choiceLayout);
Chris@68 50
Chris@68 51 m_descriptionLabel = new QLabel;
Chris@68 52 outer->addWidget(m_descriptionLabel, 2, 0, 1, 3);
Chris@68 53
Chris@69 54 QFont f = m_descriptionLabel->font();
Chris@202 55 f.setPointSize(f.pointSize() * 0.95);
Chris@69 56 m_descriptionLabel->setFont(f);
Chris@69 57
Chris@74 58 m_urlLabel = new QLabel(tr("&URL:"));
Chris@72 59 outer->addWidget(m_urlLabel, 3, 0);
Chris@68 60
Chris@72 61 m_urlCombo = new QComboBox();
Chris@72 62 m_urlCombo->setEditable(true);
Chris@74 63 m_urlLabel->setBuddy(m_urlCombo);
Chris@72 64 connect(m_urlCombo, SIGNAL(editTextChanged(const QString &)),
Chris@72 65 this, SLOT(urlChanged(const QString &)));
Chris@72 66 outer->addWidget(m_urlCombo, 3, 1, 1, 2);
Chris@72 67
Chris@74 68 m_fileLabel = new QLabel(tr("&File:"));
Chris@72 69 outer->addWidget(m_fileLabel, 4, 0);
Chris@72 70
Chris@72 71 m_fileCombo = new QComboBox();
Chris@72 72 m_fileCombo->setEditable(true);
Chris@74 73 m_fileLabel->setBuddy(m_fileCombo);
Chris@74 74 connect(m_fileCombo, SIGNAL(editTextChanged(const QString &)),
Chris@74 75 this, SLOT(fileChanged(const QString &)));
Chris@72 76 outer->addWidget(m_fileCombo, 4, 1);
Chris@69 77 outer->setColumnStretch(1, 20);
Chris@68 78
Chris@68 79 m_browseButton = new QPushButton(tr("Browse..."));
Chris@72 80 outer->addWidget(m_browseButton, 4, 2);
Chris@69 81 connect(m_browseButton, SIGNAL(clicked()), this, SLOT(browse()));
Chris@68 82
Chris@341 83 outer->addItem(new QSpacerItem(2, 12), 5, 0);
Chris@341 84
Chris@341 85 QDialogButtonBox *bbox;
Chris@341 86 if (helpUrl != "") {
Chris@341 87 bbox = new QDialogButtonBox(QDialogButtonBox::Help |
Chris@341 88 QDialogButtonBox::Ok |
Chris@341 89 QDialogButtonBox::Cancel);
Chris@341 90 } else {
Chris@341 91 bbox = new QDialogButtonBox(QDialogButtonBox::Ok |
Chris@341 92 QDialogButtonBox::Cancel);
Chris@341 93 }
Chris@68 94 connect(bbox, SIGNAL(accepted()), this, SLOT(accept()));
Chris@68 95 connect(bbox, SIGNAL(rejected()), this, SLOT(reject()));
Chris@341 96 connect(bbox, SIGNAL(helpRequested()), this, SLOT(helpRequested()));
Chris@341 97 outer->addWidget(bbox, 6, 0, 1, 3);
Chris@74 98
Chris@74 99 m_okButton = bbox->button(QDialogButtonBox::Ok);
Chris@199 100 updateOkButton();
Chris@74 101
Chris@69 102 setMinimumWidth(480);
Chris@67 103 }
Chris@68 104
Chris@341 105 void
Chris@341 106 MultiChoiceDialog::helpRequested()
Chris@341 107 {
Chris@341 108 QDesktopServices::openUrl(m_helpUrl);
Chris@341 109 }
Chris@341 110
Chris@69 111 QString
Chris@69 112 MultiChoiceDialog::getCurrentChoice()
Chris@69 113 {
Chris@69 114 return m_currentChoice;
Chris@69 115 }
Chris@69 116
Chris@69 117 void
Chris@69 118 MultiChoiceDialog::setCurrentChoice(QString c)
Chris@69 119 {
Chris@69 120 m_currentChoice = c;
Chris@69 121 choiceChanged();
Chris@69 122 }
Chris@69 123
Chris@69 124 QString
Chris@69 125 MultiChoiceDialog::getArgument()
Chris@69 126 {
Chris@72 127 if (m_argTypes[m_currentChoice] == UrlArg ||
Chris@72 128 m_argTypes[m_currentChoice] == UrlToDirectoryArg) {
Chris@72 129 return m_urlCombo->currentText();
Chris@72 130 } else {
Chris@72 131 return m_fileCombo->currentText();
Chris@72 132 }
Chris@72 133 }
Chris@72 134
Chris@72 135 QString
Chris@72 136 MultiChoiceDialog::getAdditionalArgument()
Chris@72 137 {
Chris@72 138 if (m_argTypes[m_currentChoice] == UrlToDirectoryArg) {
Chris@72 139 return m_fileCombo->currentText();
Chris@72 140 } else {
Chris@72 141 return "";
Chris@72 142 }
Chris@69 143 }
Chris@69 144
Chris@69 145 void
Chris@72 146 MultiChoiceDialog::addRecentArgument(QString id, QString arg,
Chris@72 147 bool additionalArgument)
Chris@69 148 {
Chris@72 149 if (additionalArgument) {
Chris@72 150 RecentFiles(QString("Recent-%1-add").arg(id)).addFile(arg);
Chris@72 151 } else {
Chris@72 152 RecentFiles(QString("Recent-%1").arg(id)).addFile(arg);
Chris@72 153 }
Chris@69 154 }
Chris@69 155
Chris@69 156 void
Chris@69 157 MultiChoiceDialog::addChoice(QString id, QString text,
Chris@69 158 QString description, ArgType arg)
Chris@69 159 {
Chris@69 160 bool first = (m_texts.empty());
Chris@69 161
Chris@69 162 m_texts[id] = text;
Chris@69 163 m_descriptions[id] = description;
Chris@69 164 m_argTypes[id] = arg;
Chris@69 165
Chris@69 166 if (arg != NoArg) {
Chris@69 167 m_recentFiles[id] = QSharedPointer<RecentFiles>
Chris@69 168 (new RecentFiles(QString("Recent-%1").arg(id)));
Chris@69 169 }
Chris@69 170
Chris@69 171 SelectableLabel *cb = new SelectableLabel;
Chris@69 172 cb->setSelectedText(text);
Chris@69 173 cb->setUnselectedText(text);
Chris@183 174 cb->setMaximumWidth(270);
Chris@69 175
Chris@69 176 m_choiceLayout->addWidget(cb);
Chris@69 177 m_choiceButtons[cb] = id;
Chris@69 178
Chris@69 179 connect(cb, SIGNAL(selectionChanged()), this, SLOT(choiceChanged()));
Chris@69 180
Chris@69 181 if (first) {
Chris@69 182 m_currentChoice = id;
Chris@69 183 choiceChanged();
Chris@69 184 }
Chris@69 185 }
Chris@69 186
Chris@69 187 void
Chris@69 188 MultiChoiceDialog::browse()
Chris@69 189 {
Chris@69 190 QString origin = getArgument();
Chris@69 191
Chris@69 192 if (origin == "") {
Chris@69 193 #ifdef Q_OS_WIN32
Chris@69 194 origin = "c:";
Chris@69 195 #else
Chris@69 196 origin = QDir::homePath();
Chris@69 197 #endif
Chris@69 198 }
Chris@69 199
Chris@69 200 QString path = origin;
Chris@69 201
Chris@72 202 if (m_argTypes[m_currentChoice] == DirectoryArg ||
Chris@72 203 m_argTypes[m_currentChoice] == UrlToDirectoryArg) {
Chris@69 204
Chris@69 205 path = QFileDialog::getExistingDirectory
Chris@69 206 (this, tr("Open Directory"), origin,
Chris@69 207 QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
Chris@69 208 if (path != QString()) {
Chris@72 209 m_fileCombo->lineEdit()->setText(path + QDir::separator());
Chris@69 210 }
Chris@69 211
Chris@69 212 } else {
Chris@69 213
Chris@69 214 path = QFileDialog::getOpenFileName
Chris@69 215 (this, tr("Open File"), origin);
Chris@69 216 if (path != QString()) {
Chris@72 217 m_fileCombo->lineEdit()->setText(path);
Chris@69 218 }
Chris@69 219 }
Chris@69 220 }
Chris@69 221
Chris@69 222 void
Chris@72 223 MultiChoiceDialog::urlChanged(const QString &s)
Chris@72 224 {
Chris@199 225 updateOkButton();
Chris@199 226 }
Chris@199 227
Chris@199 228 void
Chris@199 229 MultiChoiceDialog::fileChanged(const QString &s)
Chris@199 230 {
Chris@199 231 updateOkButton();
Chris@199 232 }
Chris@199 233
Chris@199 234 void
Chris@199 235 MultiChoiceDialog::updateOkButton()
Chris@199 236 {
Chris@79 237 /* This doesn't work well
Chris@72 238 if (m_argTypes[m_currentChoice] != UrlToDirectoryArg) {
Chris@72 239 return;
Chris@72 240 }
Chris@72 241 QDir dirPath(m_fileCombo->currentText());
Chris@72 242 if (!dirPath.exists()) {
Chris@72 243 if (!dirPath.cdUp()) return;
Chris@72 244 }
Chris@72 245 QString url = m_urlCombo->currentText();
Chris@72 246 if (QRegExp("^\\w+://").indexIn(url) < 0) {
Chris@72 247 return;
Chris@72 248 }
Chris@72 249 QString urlDirName = url;
Chris@79 250 urlDirName.replace(QRegExp("^.*\\//.*\\/"), "");
Chris@72 251 if (urlDirName == "" || urlDirName == url) {
Chris@72 252 return;
Chris@72 253 }
Chris@72 254 m_fileCombo->lineEdit()->setText(dirPath.filePath(urlDirName));
Chris@79 255 */
Chris@79 256 if (m_argTypes[m_currentChoice] == UrlToDirectoryArg) {
Chris@79 257 m_okButton->setEnabled(getArgument() != "" &&
Chris@79 258 getAdditionalArgument() != "");
Chris@79 259 } else {
Chris@79 260 m_okButton->setEnabled(getArgument() != "");
Chris@79 261 }
Chris@72 262 }
Chris@72 263
Chris@72 264 void
Chris@69 265 MultiChoiceDialog::choiceChanged()
Chris@69 266 {
Chris@69 267 DEBUG << "choiceChanged" << endl;
Chris@69 268
Chris@69 269 if (m_choiceButtons.empty()) return;
Chris@69 270
Chris@69 271 QString id = "";
Chris@69 272
Chris@69 273 QObject *s = sender();
Chris@69 274 QWidget *w = qobject_cast<QWidget *>(s);
Chris@69 275 if (w) id = m_choiceButtons[w];
Chris@69 276
Chris@69 277 if (id == m_currentChoice) return;
Chris@69 278 if (id == "") {
Chris@69 279 // Happens when this is called for the very first time, when
Chris@69 280 // m_currentChoice has been set to the intended ID but no
Chris@69 281 // button has actually been pressed -- then we need to
Chris@69 282 // initialise
Chris@69 283 id = m_currentChoice;
Chris@69 284 }
Chris@69 285
Chris@69 286 m_currentChoice = id;
Chris@69 287
Chris@69 288 foreach (QWidget *cw, m_choiceButtons.keys()) {
Chris@69 289 SelectableLabel *sl = qobject_cast<SelectableLabel *>(cw);
Chris@69 290 if (sl) {
Chris@69 291 sl->setSelected(m_choiceButtons[cw] == id);
Chris@69 292 }
Chris@69 293 }
Chris@69 294
Chris@69 295 m_descriptionLabel->setText(m_descriptions[id]);
Chris@69 296
Chris@72 297 m_fileLabel->hide();
Chris@72 298 m_fileCombo->hide();
Chris@72 299 m_browseButton->hide();
Chris@72 300 m_urlLabel->hide();
Chris@72 301 m_urlCombo->hide();
Chris@72 302
Chris@72 303 QSharedPointer<RecentFiles> rf = m_recentFiles[id];
Chris@72 304 m_fileCombo->clear();
Chris@72 305 m_urlCombo->clear();
Chris@72 306
Chris@69 307 switch (m_argTypes[id]) {
Chris@69 308
Chris@69 309 case NoArg:
Chris@69 310 break;
Chris@69 311
Chris@69 312 case FileArg:
Chris@74 313 m_fileLabel->setText(tr("&File:"));
Chris@72 314 m_fileLabel->show();
Chris@72 315 m_fileCombo->show();
Chris@72 316 m_fileCombo->addItems(rf->getRecent());
Chris@69 317 m_browseButton->show();
Chris@69 318 break;
Chris@69 319
Chris@69 320 case DirectoryArg:
Chris@74 321 m_fileLabel->setText(tr("&Folder:"));
Chris@72 322 m_fileLabel->show();
Chris@72 323 m_fileCombo->show();
Chris@72 324 m_fileCombo->addItems(rf->getRecent());
Chris@69 325 m_browseButton->show();
Chris@69 326 break;
Chris@69 327
Chris@69 328 case UrlArg:
Chris@72 329 m_urlLabel->show();
Chris@72 330 m_urlCombo->show();
Chris@183 331 m_urlCombo->addItems(rf->getRecent());
Chris@69 332 break;
Chris@69 333
Chris@72 334 case UrlToDirectoryArg:
Chris@72 335 m_urlLabel->show();
Chris@72 336 m_urlCombo->show();
Chris@72 337 m_urlCombo->addItems(rf->getRecent());
Chris@74 338 m_fileLabel->setText(tr("&Folder:"));
Chris@72 339 m_fileLabel->show();
Chris@72 340 m_fileCombo->show();
Chris@72 341 m_fileCombo->lineEdit()->setText(QDir::homePath());
Chris@69 342 m_browseButton->show();
Chris@69 343 break;
Chris@69 344 }
Chris@69 345
Chris@199 346 updateOkButton();
Chris@69 347 adjustSize();
Chris@69 348 }
Chris@69 349
Chris@69 350