annotate src/multichoicedialog.cpp @ 571:012ba1b83328

Show cancel button with progress bar only when running an operation that it makes sense to cancel (we don't really want people cancelling e.g. initial folder scan because it would leave things in an inconsistent state)
author Chris Cannam
date Thu, 01 Mar 2012 22:53:54 +0000
parents c2e212ab0068
children 98f57888d893
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@560 8 Copyright (c) 2012 Chris Cannam
Chris@560 9 Copyright (c) 2012 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@72 30 #include <QUrl>
Chris@68 31
Chris@68 32 MultiChoiceDialog::MultiChoiceDialog(QString title, QString heading, QWidget *parent) :
Chris@67 33 QDialog(parent)
Chris@67 34 {
Chris@68 35 setModal(true);
Chris@68 36 setWindowTitle(title);
Chris@68 37
Chris@68 38 QGridLayout *outer = new QGridLayout;
Chris@68 39 setLayout(outer);
Chris@68 40
Chris@68 41 outer->addWidget(new QLabel(heading), 0, 0, 1, 3);
Chris@68 42
Chris@68 43 QWidget *innerWidget = new QWidget;
Chris@69 44 outer->addWidget(innerWidget, 1, 0, 1, 3);
Chris@69 45 m_choiceLayout = new QHBoxLayout;
Chris@68 46 innerWidget->setLayout(m_choiceLayout);
Chris@68 47
Chris@68 48 m_descriptionLabel = new QLabel;
Chris@68 49 outer->addWidget(m_descriptionLabel, 2, 0, 1, 3);
Chris@68 50
Chris@69 51 QFont f = m_descriptionLabel->font();
Chris@202 52 f.setPointSize(f.pointSize() * 0.95);
Chris@69 53 m_descriptionLabel->setFont(f);
Chris@69 54
Chris@74 55 m_urlLabel = new QLabel(tr("&URL:"));
Chris@72 56 outer->addWidget(m_urlLabel, 3, 0);
Chris@68 57
Chris@72 58 m_urlCombo = new QComboBox();
Chris@72 59 m_urlCombo->setEditable(true);
Chris@74 60 m_urlLabel->setBuddy(m_urlCombo);
Chris@72 61 connect(m_urlCombo, SIGNAL(editTextChanged(const QString &)),
Chris@72 62 this, SLOT(urlChanged(const QString &)));
Chris@72 63 outer->addWidget(m_urlCombo, 3, 1, 1, 2);
Chris@72 64
Chris@74 65 m_fileLabel = new QLabel(tr("&File:"));
Chris@72 66 outer->addWidget(m_fileLabel, 4, 0);
Chris@72 67
Chris@72 68 m_fileCombo = new QComboBox();
Chris@72 69 m_fileCombo->setEditable(true);
Chris@74 70 m_fileLabel->setBuddy(m_fileCombo);
Chris@74 71 connect(m_fileCombo, SIGNAL(editTextChanged(const QString &)),
Chris@74 72 this, SLOT(fileChanged(const QString &)));
Chris@72 73 outer->addWidget(m_fileCombo, 4, 1);
Chris@69 74 outer->setColumnStretch(1, 20);
Chris@68 75
Chris@68 76 m_browseButton = new QPushButton(tr("Browse..."));
Chris@72 77 outer->addWidget(m_browseButton, 4, 2);
Chris@69 78 connect(m_browseButton, SIGNAL(clicked()), this, SLOT(browse()));
Chris@68 79
Chris@68 80 QDialogButtonBox *bbox = new QDialogButtonBox(QDialogButtonBox::Ok |
Chris@68 81 QDialogButtonBox::Cancel);
Chris@68 82 connect(bbox, SIGNAL(accepted()), this, SLOT(accept()));
Chris@68 83 connect(bbox, SIGNAL(rejected()), this, SLOT(reject()));
Chris@72 84 outer->addWidget(bbox, 5, 0, 1, 3);
Chris@74 85
Chris@74 86 m_okButton = bbox->button(QDialogButtonBox::Ok);
Chris@199 87 updateOkButton();
Chris@74 88
Chris@69 89 setMinimumWidth(480);
Chris@67 90 }
Chris@68 91
Chris@69 92 QString
Chris@69 93 MultiChoiceDialog::getCurrentChoice()
Chris@69 94 {
Chris@69 95 return m_currentChoice;
Chris@69 96 }
Chris@69 97
Chris@69 98 void
Chris@69 99 MultiChoiceDialog::setCurrentChoice(QString c)
Chris@69 100 {
Chris@69 101 m_currentChoice = c;
Chris@69 102 choiceChanged();
Chris@69 103 }
Chris@69 104
Chris@69 105 QString
Chris@69 106 MultiChoiceDialog::getArgument()
Chris@69 107 {
Chris@72 108 if (m_argTypes[m_currentChoice] == UrlArg ||
Chris@72 109 m_argTypes[m_currentChoice] == UrlToDirectoryArg) {
Chris@72 110 return m_urlCombo->currentText();
Chris@72 111 } else {
Chris@72 112 return m_fileCombo->currentText();
Chris@72 113 }
Chris@72 114 }
Chris@72 115
Chris@72 116 QString
Chris@72 117 MultiChoiceDialog::getAdditionalArgument()
Chris@72 118 {
Chris@72 119 if (m_argTypes[m_currentChoice] == UrlToDirectoryArg) {
Chris@72 120 return m_fileCombo->currentText();
Chris@72 121 } else {
Chris@72 122 return "";
Chris@72 123 }
Chris@69 124 }
Chris@69 125
Chris@69 126 void
Chris@72 127 MultiChoiceDialog::addRecentArgument(QString id, QString arg,
Chris@72 128 bool additionalArgument)
Chris@69 129 {
Chris@72 130 if (additionalArgument) {
Chris@72 131 RecentFiles(QString("Recent-%1-add").arg(id)).addFile(arg);
Chris@72 132 } else {
Chris@72 133 RecentFiles(QString("Recent-%1").arg(id)).addFile(arg);
Chris@72 134 }
Chris@69 135 }
Chris@69 136
Chris@69 137 void
Chris@69 138 MultiChoiceDialog::addChoice(QString id, QString text,
Chris@553 139 QString description, ArgType arg,
Chris@553 140 bool defaultEmpty)
Chris@69 141 {
Chris@69 142 bool first = (m_texts.empty());
Chris@69 143
Chris@69 144 m_texts[id] = text;
Chris@69 145 m_descriptions[id] = description;
Chris@69 146 m_argTypes[id] = arg;
Chris@553 147 m_defaultEmpty[id] = defaultEmpty;
Chris@69 148
Chris@69 149 if (arg != NoArg) {
Chris@69 150 m_recentFiles[id] = QSharedPointer<RecentFiles>
Chris@69 151 (new RecentFiles(QString("Recent-%1").arg(id)));
Chris@69 152 }
Chris@69 153
Chris@69 154 SelectableLabel *cb = new SelectableLabel;
Chris@69 155 cb->setSelectedText(text);
Chris@69 156 cb->setUnselectedText(text);
Chris@183 157 cb->setMaximumWidth(270);
Chris@69 158
Chris@69 159 m_choiceLayout->addWidget(cb);
Chris@69 160 m_choiceButtons[cb] = id;
Chris@69 161
Chris@69 162 connect(cb, SIGNAL(selectionChanged()), this, SLOT(choiceChanged()));
Chris@69 163
Chris@69 164 if (first) {
Chris@69 165 m_currentChoice = id;
Chris@69 166 choiceChanged();
Chris@69 167 }
Chris@69 168 }
Chris@69 169
Chris@342 170 QString
Chris@342 171 MultiChoiceDialog::getDefaultPath() const
Chris@342 172 {
Chris@342 173 QDir home(QDir::home());
Chris@342 174 QDir dflt;
Chris@342 175
Chris@483 176 dflt = QDir(home.filePath(tr("Documents")));
Chris@483 177 DEBUG << "testing " << dflt << endl;
Chris@483 178 if (dflt.exists()) return dflt.canonicalPath();
Chris@483 179
Chris@342 180 dflt = QDir(home.filePath(tr("My Documents")));
Chris@342 181 DEBUG << "testing " << dflt << endl;
Chris@342 182 if (dflt.exists()) return dflt.canonicalPath();
Chris@342 183
Chris@483 184 dflt = QDir(home.filePath(tr("Desktop")));
Chris@342 185 DEBUG << "testing " << dflt << endl;
Chris@342 186 if (dflt.exists()) return dflt.canonicalPath();
Chris@342 187
Chris@342 188 DEBUG << "all failed, returning " << home << endl;
Chris@342 189 return home.canonicalPath();
Chris@342 190 }
Chris@342 191
Chris@69 192 void
Chris@69 193 MultiChoiceDialog::browse()
Chris@69 194 {
Chris@69 195 QString origin = getArgument();
Chris@69 196
Chris@69 197 if (origin == "") {
Chris@342 198 origin = getDefaultPath();
Chris@69 199 }
Chris@69 200
Chris@69 201 QString path = origin;
Chris@69 202
Chris@72 203 if (m_argTypes[m_currentChoice] == DirectoryArg ||
Chris@72 204 m_argTypes[m_currentChoice] == UrlToDirectoryArg) {
Chris@69 205
Chris@69 206 path = QFileDialog::getExistingDirectory
Chris@69 207 (this, tr("Open Directory"), origin,
Chris@69 208 QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
Chris@69 209 if (path != QString()) {
Chris@72 210 m_fileCombo->lineEdit()->setText(path + QDir::separator());
Chris@69 211 }
Chris@69 212
Chris@69 213 } else {
Chris@69 214
Chris@69 215 path = QFileDialog::getOpenFileName
Chris@69 216 (this, tr("Open File"), origin);
Chris@69 217 if (path != QString()) {
Chris@72 218 m_fileCombo->lineEdit()->setText(path);
Chris@69 219 }
Chris@69 220 }
Chris@69 221 }
Chris@69 222
Chris@69 223 void
Chris@72 224 MultiChoiceDialog::urlChanged(const QString &s)
Chris@72 225 {
Chris@199 226 updateOkButton();
Chris@483 227 updateFileComboFromURL();
Chris@199 228 }
Chris@199 229
Chris@199 230 void
Chris@199 231 MultiChoiceDialog::fileChanged(const QString &s)
Chris@199 232 {
Chris@199 233 updateOkButton();
Chris@199 234 }
Chris@199 235
Chris@199 236 void
Chris@483 237 MultiChoiceDialog::updateFileComboFromURL()
Chris@199 238 {
Chris@72 239 if (m_argTypes[m_currentChoice] != UrlToDirectoryArg) {
Chris@72 240 return;
Chris@72 241 }
Chris@72 242 QString url = m_urlCombo->currentText();
Chris@72 243 if (QRegExp("^\\w+://").indexIn(url) < 0) {
Chris@72 244 return;
Chris@72 245 }
Chris@72 246 QString urlDirName = url;
Chris@79 247 urlDirName.replace(QRegExp("^.*\\//.*\\/"), "");
Chris@72 248 if (urlDirName == "" || urlDirName == url) {
Chris@72 249 return;
Chris@72 250 }
Chris@483 251 QString dirPath = m_fileCombo->currentText();
Chris@483 252 QString defaultPath = getDefaultPath();
Chris@483 253 if (dirPath == defaultPath) {
Chris@483 254 dirPath += QDir::separator() + urlDirName;
Chris@483 255 } else if (dirPath == defaultPath + QDir::separator()) {
Chris@483 256 dirPath += urlDirName;
Chris@483 257 } else {
Chris@483 258 QDir d(dirPath);
Chris@483 259 d.cdUp();
Chris@483 260 dirPath = d.filePath(urlDirName);
Chris@483 261 }
Chris@483 262 m_fileCombo->lineEdit()->setText(dirPath);
Chris@483 263 }
Chris@483 264
Chris@483 265 void
Chris@483 266 MultiChoiceDialog::updateOkButton()
Chris@483 267 {
Chris@565 268 if (m_defaultEmpty[m_currentChoice]) {
Chris@565 269 m_okButton->setEnabled(true);
Chris@565 270 } else if (m_argTypes[m_currentChoice] == UrlToDirectoryArg) {
Chris@79 271 m_okButton->setEnabled(getArgument() != "" &&
Chris@79 272 getAdditionalArgument() != "");
Chris@79 273 } else {
Chris@79 274 m_okButton->setEnabled(getArgument() != "");
Chris@79 275 }
Chris@72 276 }
Chris@72 277
Chris@72 278 void
Chris@69 279 MultiChoiceDialog::choiceChanged()
Chris@69 280 {
Chris@69 281 DEBUG << "choiceChanged" << endl;
Chris@69 282
Chris@69 283 if (m_choiceButtons.empty()) return;
Chris@69 284
Chris@69 285 QString id = "";
Chris@69 286
Chris@69 287 QObject *s = sender();
Chris@69 288 QWidget *w = qobject_cast<QWidget *>(s);
Chris@69 289 if (w) id = m_choiceButtons[w];
Chris@69 290
Chris@69 291 if (id == m_currentChoice) return;
Chris@69 292 if (id == "") {
Chris@69 293 // Happens when this is called for the very first time, when
Chris@69 294 // m_currentChoice has been set to the intended ID but no
Chris@69 295 // button has actually been pressed -- then we need to
Chris@69 296 // initialise
Chris@69 297 id = m_currentChoice;
Chris@69 298 }
Chris@69 299
Chris@69 300 m_currentChoice = id;
Chris@69 301
Chris@69 302 foreach (QWidget *cw, m_choiceButtons.keys()) {
Chris@69 303 SelectableLabel *sl = qobject_cast<SelectableLabel *>(cw);
Chris@69 304 if (sl) {
Chris@69 305 sl->setSelected(m_choiceButtons[cw] == id);
Chris@69 306 }
Chris@69 307 }
Chris@69 308
Chris@69 309 m_descriptionLabel->setText(m_descriptions[id]);
Chris@69 310
Chris@72 311 m_browseButton->hide();
Chris@483 312
Chris@72 313 m_urlLabel->hide();
Chris@483 314 m_urlCombo->clear();
Chris@72 315 m_urlCombo->hide();
Chris@72 316
Chris@483 317 m_fileLabel->hide();
Chris@483 318 m_fileCombo->clear();
Chris@483 319 m_fileCombo->hide();
Chris@483 320
Chris@72 321 QSharedPointer<RecentFiles> rf = m_recentFiles[id];
Chris@72 322
Chris@69 323 switch (m_argTypes[id]) {
Chris@69 324
Chris@69 325 case NoArg:
Chris@69 326 break;
Chris@69 327
Chris@69 328 case FileArg:
Chris@74 329 m_fileLabel->setText(tr("&File:"));
Chris@72 330 m_fileLabel->show();
Chris@72 331 m_fileCombo->show();
Chris@72 332 m_fileCombo->addItems(rf->getRecent());
Chris@553 333 if (m_defaultEmpty[id]) m_fileCombo->lineEdit()->setText("");
Chris@69 334 m_browseButton->show();
Chris@69 335 break;
Chris@69 336
Chris@69 337 case DirectoryArg:
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->addItems(rf->getRecent());
Chris@553 342 if (m_defaultEmpty[id]) m_fileCombo->lineEdit()->setText("");
Chris@69 343 m_browseButton->show();
Chris@69 344 break;
Chris@69 345
Chris@69 346 case UrlArg:
Chris@72 347 m_urlLabel->show();
Chris@72 348 m_urlCombo->show();
Chris@183 349 m_urlCombo->addItems(rf->getRecent());
Chris@553 350 if (m_defaultEmpty[id]) m_urlCombo->lineEdit()->setText("");
Chris@69 351 break;
Chris@69 352
Chris@72 353 case UrlToDirectoryArg:
Chris@72 354 m_urlLabel->show();
Chris@72 355 m_urlCombo->show();
Chris@72 356 m_urlCombo->addItems(rf->getRecent());
Chris@553 357 if (m_defaultEmpty[id]) m_urlCombo->lineEdit()->setText("");
Chris@74 358 m_fileLabel->setText(tr("&Folder:"));
Chris@72 359 m_fileLabel->show();
Chris@72 360 m_fileCombo->show();
Chris@342 361 m_fileCombo->lineEdit()->setText(getDefaultPath());
Chris@483 362 updateFileComboFromURL();
Chris@69 363 m_browseButton->show();
Chris@69 364 break;
Chris@69 365 }
Chris@69 366
Chris@199 367 updateOkButton();
Chris@69 368 adjustSize();
Chris@69 369 }
Chris@69 370
Chris@69 371