annotate src/multichoicedialog.cpp @ 558:d932ce55c364 find

Remove the single find widget from top, add one to each tab at the bottom instead. (Turns out you don't usually want to search for the same text in both types of widget.) Also provide sensible no-results text.
author Chris Cannam
date Mon, 27 Feb 2012 17:08:26 +0000
parents 9c8147c9f245
children 533519ebc0cb
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@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@79 268 if (m_argTypes[m_currentChoice] == UrlToDirectoryArg) {
Chris@79 269 m_okButton->setEnabled(getArgument() != "" &&
Chris@79 270 getAdditionalArgument() != "");
Chris@79 271 } else {
Chris@79 272 m_okButton->setEnabled(getArgument() != "");
Chris@79 273 }
Chris@72 274 }
Chris@72 275
Chris@72 276 void
Chris@69 277 MultiChoiceDialog::choiceChanged()
Chris@69 278 {
Chris@69 279 DEBUG << "choiceChanged" << endl;
Chris@69 280
Chris@69 281 if (m_choiceButtons.empty()) return;
Chris@69 282
Chris@69 283 QString id = "";
Chris@69 284
Chris@69 285 QObject *s = sender();
Chris@69 286 QWidget *w = qobject_cast<QWidget *>(s);
Chris@69 287 if (w) id = m_choiceButtons[w];
Chris@69 288
Chris@69 289 if (id == m_currentChoice) return;
Chris@69 290 if (id == "") {
Chris@69 291 // Happens when this is called for the very first time, when
Chris@69 292 // m_currentChoice has been set to the intended ID but no
Chris@69 293 // button has actually been pressed -- then we need to
Chris@69 294 // initialise
Chris@69 295 id = m_currentChoice;
Chris@69 296 }
Chris@69 297
Chris@69 298 m_currentChoice = id;
Chris@69 299
Chris@69 300 foreach (QWidget *cw, m_choiceButtons.keys()) {
Chris@69 301 SelectableLabel *sl = qobject_cast<SelectableLabel *>(cw);
Chris@69 302 if (sl) {
Chris@69 303 sl->setSelected(m_choiceButtons[cw] == id);
Chris@69 304 }
Chris@69 305 }
Chris@69 306
Chris@69 307 m_descriptionLabel->setText(m_descriptions[id]);
Chris@69 308
Chris@72 309 m_browseButton->hide();
Chris@483 310
Chris@72 311 m_urlLabel->hide();
Chris@483 312 m_urlCombo->clear();
Chris@72 313 m_urlCombo->hide();
Chris@72 314
Chris@483 315 m_fileLabel->hide();
Chris@483 316 m_fileCombo->clear();
Chris@483 317 m_fileCombo->hide();
Chris@483 318
Chris@72 319 QSharedPointer<RecentFiles> rf = m_recentFiles[id];
Chris@72 320
Chris@69 321 switch (m_argTypes[id]) {
Chris@69 322
Chris@69 323 case NoArg:
Chris@69 324 break;
Chris@69 325
Chris@69 326 case FileArg:
Chris@74 327 m_fileLabel->setText(tr("&File:"));
Chris@72 328 m_fileLabel->show();
Chris@72 329 m_fileCombo->show();
Chris@72 330 m_fileCombo->addItems(rf->getRecent());
Chris@553 331 if (m_defaultEmpty[id]) m_fileCombo->lineEdit()->setText("");
Chris@69 332 m_browseButton->show();
Chris@69 333 break;
Chris@69 334
Chris@69 335 case DirectoryArg:
Chris@74 336 m_fileLabel->setText(tr("&Folder:"));
Chris@72 337 m_fileLabel->show();
Chris@72 338 m_fileCombo->show();
Chris@72 339 m_fileCombo->addItems(rf->getRecent());
Chris@553 340 if (m_defaultEmpty[id]) m_fileCombo->lineEdit()->setText("");
Chris@69 341 m_browseButton->show();
Chris@69 342 break;
Chris@69 343
Chris@69 344 case UrlArg:
Chris@72 345 m_urlLabel->show();
Chris@72 346 m_urlCombo->show();
Chris@183 347 m_urlCombo->addItems(rf->getRecent());
Chris@553 348 if (m_defaultEmpty[id]) m_urlCombo->lineEdit()->setText("");
Chris@69 349 break;
Chris@69 350
Chris@72 351 case UrlToDirectoryArg:
Chris@72 352 m_urlLabel->show();
Chris@72 353 m_urlCombo->show();
Chris@72 354 m_urlCombo->addItems(rf->getRecent());
Chris@553 355 if (m_defaultEmpty[id]) m_urlCombo->lineEdit()->setText("");
Chris@74 356 m_fileLabel->setText(tr("&Folder:"));
Chris@72 357 m_fileLabel->show();
Chris@72 358 m_fileCombo->show();
Chris@342 359 m_fileCombo->lineEdit()->setText(getDefaultPath());
Chris@483 360 updateFileComboFromURL();
Chris@69 361 m_browseButton->show();
Chris@69 362 break;
Chris@69 363 }
Chris@69 364
Chris@199 365 updateOkButton();
Chris@69 366 adjustSize();
Chris@69 367 }
Chris@69 368
Chris@69 369