annotate src/multichoicedialog.cpp @ 634:58ac1b197666

* Added setting to show history automatically when it changes (defaults to true)
author Sam Izzo <sam@humbug.net>
date Mon, 27 Aug 2012 01:45:26 +1000
parents 98f57888d893
children ae67ea0af696
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@604 278 bool
Chris@604 279 MultiChoiceDialog::urlComboNotUrl() const
Chris@604 280 {
Chris@604 281 QString url = m_urlCombo->currentText();
Chris@604 282 if (QRegExp("^\\w+://").indexIn(url) < 0) {
Chris@604 283 return true;
Chris@604 284 } else {
Chris@604 285 return false;
Chris@604 286 }
Chris@604 287 }
Chris@604 288
Chris@72 289 void
Chris@69 290 MultiChoiceDialog::choiceChanged()
Chris@69 291 {
Chris@69 292 DEBUG << "choiceChanged" << endl;
Chris@69 293
Chris@69 294 if (m_choiceButtons.empty()) return;
Chris@69 295
Chris@69 296 QString id = "";
Chris@69 297
Chris@69 298 QObject *s = sender();
Chris@69 299 QWidget *w = qobject_cast<QWidget *>(s);
Chris@69 300 if (w) id = m_choiceButtons[w];
Chris@69 301
Chris@69 302 if (id == m_currentChoice) return;
Chris@69 303 if (id == "") {
Chris@69 304 // Happens when this is called for the very first time, when
Chris@69 305 // m_currentChoice has been set to the intended ID but no
Chris@69 306 // button has actually been pressed -- then we need to
Chris@69 307 // initialise
Chris@69 308 id = m_currentChoice;
Chris@69 309 }
Chris@69 310
Chris@69 311 m_currentChoice = id;
Chris@69 312
Chris@69 313 foreach (QWidget *cw, m_choiceButtons.keys()) {
Chris@69 314 SelectableLabel *sl = qobject_cast<SelectableLabel *>(cw);
Chris@69 315 if (sl) {
Chris@69 316 sl->setSelected(m_choiceButtons[cw] == id);
Chris@69 317 }
Chris@69 318 }
Chris@69 319
Chris@69 320 m_descriptionLabel->setText(m_descriptions[id]);
Chris@69 321
Chris@72 322 m_browseButton->hide();
Chris@483 323
Chris@72 324 m_urlLabel->hide();
Chris@483 325 m_urlCombo->clear();
Chris@72 326 m_urlCombo->hide();
Chris@72 327
Chris@483 328 m_fileLabel->hide();
Chris@483 329 m_fileCombo->clear();
Chris@483 330 m_fileCombo->hide();
Chris@483 331
Chris@72 332 QSharedPointer<RecentFiles> rf = m_recentFiles[id];
Chris@72 333
Chris@69 334 switch (m_argTypes[id]) {
Chris@69 335
Chris@69 336 case NoArg:
Chris@69 337 break;
Chris@69 338
Chris@69 339 case FileArg:
Chris@74 340 m_fileLabel->setText(tr("&File:"));
Chris@72 341 m_fileLabel->show();
Chris@72 342 m_fileCombo->show();
Chris@72 343 m_fileCombo->addItems(rf->getRecent());
Chris@553 344 if (m_defaultEmpty[id]) m_fileCombo->lineEdit()->setText("");
Chris@69 345 m_browseButton->show();
Chris@69 346 break;
Chris@69 347
Chris@69 348 case DirectoryArg:
Chris@74 349 m_fileLabel->setText(tr("&Folder:"));
Chris@72 350 m_fileLabel->show();
Chris@72 351 m_fileCombo->show();
Chris@72 352 m_fileCombo->addItems(rf->getRecent());
Chris@553 353 if (m_defaultEmpty[id]) m_fileCombo->lineEdit()->setText("");
Chris@69 354 m_browseButton->show();
Chris@69 355 break;
Chris@69 356
Chris@69 357 case UrlArg:
Chris@72 358 m_urlLabel->show();
Chris@72 359 m_urlCombo->show();
Chris@183 360 m_urlCombo->addItems(rf->getRecent());
Chris@604 361 if (m_defaultEmpty[id] || urlComboNotUrl()) {
Chris@604 362 m_urlCombo->lineEdit()->setText("");
Chris@604 363 }
Chris@69 364 break;
Chris@69 365
Chris@72 366 case UrlToDirectoryArg:
Chris@72 367 m_urlLabel->show();
Chris@72 368 m_urlCombo->show();
Chris@72 369 m_urlCombo->addItems(rf->getRecent());
Chris@604 370 if (m_defaultEmpty[id] || urlComboNotUrl()) {
Chris@604 371 m_urlCombo->lineEdit()->setText("");
Chris@604 372 }
Chris@74 373 m_fileLabel->setText(tr("&Folder:"));
Chris@72 374 m_fileLabel->show();
Chris@72 375 m_fileCombo->show();
Chris@342 376 m_fileCombo->lineEdit()->setText(getDefaultPath());
Chris@483 377 updateFileComboFromURL();
Chris@69 378 m_browseButton->show();
Chris@69 379 break;
Chris@69 380 }
Chris@69 381
Chris@199 382 updateOkButton();
Chris@69 383 adjustSize();
Chris@69 384 }
Chris@69 385
Chris@69 386