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@69
|
139 QString description, ArgType arg)
|
Chris@69
|
140 {
|
Chris@69
|
141 bool first = (m_texts.empty());
|
Chris@69
|
142
|
Chris@69
|
143 m_texts[id] = text;
|
Chris@69
|
144 m_descriptions[id] = description;
|
Chris@69
|
145 m_argTypes[id] = arg;
|
Chris@69
|
146
|
Chris@69
|
147 if (arg != NoArg) {
|
Chris@69
|
148 m_recentFiles[id] = QSharedPointer<RecentFiles>
|
Chris@69
|
149 (new RecentFiles(QString("Recent-%1").arg(id)));
|
Chris@69
|
150 }
|
Chris@69
|
151
|
Chris@69
|
152 SelectableLabel *cb = new SelectableLabel;
|
Chris@69
|
153 cb->setSelectedText(text);
|
Chris@69
|
154 cb->setUnselectedText(text);
|
Chris@183
|
155 cb->setMaximumWidth(270);
|
Chris@69
|
156
|
Chris@69
|
157 m_choiceLayout->addWidget(cb);
|
Chris@69
|
158 m_choiceButtons[cb] = id;
|
Chris@69
|
159
|
Chris@69
|
160 connect(cb, SIGNAL(selectionChanged()), this, SLOT(choiceChanged()));
|
Chris@69
|
161
|
Chris@69
|
162 if (first) {
|
Chris@69
|
163 m_currentChoice = id;
|
Chris@69
|
164 choiceChanged();
|
Chris@69
|
165 }
|
Chris@69
|
166 }
|
Chris@69
|
167
|
Chris@342
|
168 QString
|
Chris@342
|
169 MultiChoiceDialog::getDefaultPath() const
|
Chris@342
|
170 {
|
Chris@342
|
171 QDir home(QDir::home());
|
Chris@342
|
172 QDir dflt;
|
Chris@342
|
173
|
Chris@342
|
174 dflt = QDir(home.filePath(tr("My Documents")));
|
Chris@342
|
175 DEBUG << "testing " << dflt << endl;
|
Chris@342
|
176 if (dflt.exists()) return dflt.canonicalPath();
|
Chris@342
|
177
|
Chris@342
|
178 dflt = QDir(home.filePath(tr("Documents")));
|
Chris@342
|
179 DEBUG << "testing " << dflt << endl;
|
Chris@342
|
180 if (dflt.exists()) return dflt.canonicalPath();
|
Chris@342
|
181
|
Chris@342
|
182 DEBUG << "all failed, returning " << home << endl;
|
Chris@342
|
183 return home.canonicalPath();
|
Chris@342
|
184 }
|
Chris@342
|
185
|
Chris@69
|
186 void
|
Chris@69
|
187 MultiChoiceDialog::browse()
|
Chris@69
|
188 {
|
Chris@69
|
189 QString origin = getArgument();
|
Chris@69
|
190
|
Chris@69
|
191 if (origin == "") {
|
Chris@342
|
192 origin = getDefaultPath();
|
Chris@69
|
193 }
|
Chris@69
|
194
|
Chris@69
|
195 QString path = origin;
|
Chris@69
|
196
|
Chris@72
|
197 if (m_argTypes[m_currentChoice] == DirectoryArg ||
|
Chris@72
|
198 m_argTypes[m_currentChoice] == UrlToDirectoryArg) {
|
Chris@69
|
199
|
Chris@69
|
200 path = QFileDialog::getExistingDirectory
|
Chris@69
|
201 (this, tr("Open Directory"), origin,
|
Chris@69
|
202 QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
|
Chris@69
|
203 if (path != QString()) {
|
Chris@72
|
204 m_fileCombo->lineEdit()->setText(path + QDir::separator());
|
Chris@69
|
205 }
|
Chris@69
|
206
|
Chris@69
|
207 } else {
|
Chris@69
|
208
|
Chris@69
|
209 path = QFileDialog::getOpenFileName
|
Chris@69
|
210 (this, tr("Open File"), origin);
|
Chris@69
|
211 if (path != QString()) {
|
Chris@72
|
212 m_fileCombo->lineEdit()->setText(path);
|
Chris@69
|
213 }
|
Chris@69
|
214 }
|
Chris@69
|
215 }
|
Chris@69
|
216
|
Chris@69
|
217 void
|
Chris@72
|
218 MultiChoiceDialog::urlChanged(const QString &s)
|
Chris@72
|
219 {
|
Chris@199
|
220 updateOkButton();
|
Chris@199
|
221 }
|
Chris@199
|
222
|
Chris@199
|
223 void
|
Chris@199
|
224 MultiChoiceDialog::fileChanged(const QString &s)
|
Chris@199
|
225 {
|
Chris@199
|
226 updateOkButton();
|
Chris@199
|
227 }
|
Chris@199
|
228
|
Chris@199
|
229 void
|
Chris@199
|
230 MultiChoiceDialog::updateOkButton()
|
Chris@199
|
231 {
|
Chris@79
|
232 /* This doesn't work well
|
Chris@72
|
233 if (m_argTypes[m_currentChoice] != UrlToDirectoryArg) {
|
Chris@72
|
234 return;
|
Chris@72
|
235 }
|
Chris@72
|
236 QDir dirPath(m_fileCombo->currentText());
|
Chris@72
|
237 if (!dirPath.exists()) {
|
Chris@72
|
238 if (!dirPath.cdUp()) return;
|
Chris@72
|
239 }
|
Chris@72
|
240 QString url = m_urlCombo->currentText();
|
Chris@72
|
241 if (QRegExp("^\\w+://").indexIn(url) < 0) {
|
Chris@72
|
242 return;
|
Chris@72
|
243 }
|
Chris@72
|
244 QString urlDirName = url;
|
Chris@79
|
245 urlDirName.replace(QRegExp("^.*\\//.*\\/"), "");
|
Chris@72
|
246 if (urlDirName == "" || urlDirName == url) {
|
Chris@72
|
247 return;
|
Chris@72
|
248 }
|
Chris@72
|
249 m_fileCombo->lineEdit()->setText(dirPath.filePath(urlDirName));
|
Chris@79
|
250 */
|
Chris@79
|
251 if (m_argTypes[m_currentChoice] == UrlToDirectoryArg) {
|
Chris@79
|
252 m_okButton->setEnabled(getArgument() != "" &&
|
Chris@79
|
253 getAdditionalArgument() != "");
|
Chris@79
|
254 } else {
|
Chris@79
|
255 m_okButton->setEnabled(getArgument() != "");
|
Chris@79
|
256 }
|
Chris@72
|
257 }
|
Chris@72
|
258
|
Chris@72
|
259 void
|
Chris@69
|
260 MultiChoiceDialog::choiceChanged()
|
Chris@69
|
261 {
|
Chris@69
|
262 DEBUG << "choiceChanged" << endl;
|
Chris@69
|
263
|
Chris@69
|
264 if (m_choiceButtons.empty()) return;
|
Chris@69
|
265
|
Chris@69
|
266 QString id = "";
|
Chris@69
|
267
|
Chris@69
|
268 QObject *s = sender();
|
Chris@69
|
269 QWidget *w = qobject_cast<QWidget *>(s);
|
Chris@69
|
270 if (w) id = m_choiceButtons[w];
|
Chris@69
|
271
|
Chris@69
|
272 if (id == m_currentChoice) return;
|
Chris@69
|
273 if (id == "") {
|
Chris@69
|
274 // Happens when this is called for the very first time, when
|
Chris@69
|
275 // m_currentChoice has been set to the intended ID but no
|
Chris@69
|
276 // button has actually been pressed -- then we need to
|
Chris@69
|
277 // initialise
|
Chris@69
|
278 id = m_currentChoice;
|
Chris@69
|
279 }
|
Chris@69
|
280
|
Chris@69
|
281 m_currentChoice = id;
|
Chris@69
|
282
|
Chris@69
|
283 foreach (QWidget *cw, m_choiceButtons.keys()) {
|
Chris@69
|
284 SelectableLabel *sl = qobject_cast<SelectableLabel *>(cw);
|
Chris@69
|
285 if (sl) {
|
Chris@69
|
286 sl->setSelected(m_choiceButtons[cw] == id);
|
Chris@69
|
287 }
|
Chris@69
|
288 }
|
Chris@69
|
289
|
Chris@69
|
290 m_descriptionLabel->setText(m_descriptions[id]);
|
Chris@69
|
291
|
Chris@72
|
292 m_fileLabel->hide();
|
Chris@72
|
293 m_fileCombo->hide();
|
Chris@72
|
294 m_browseButton->hide();
|
Chris@72
|
295 m_urlLabel->hide();
|
Chris@72
|
296 m_urlCombo->hide();
|
Chris@72
|
297
|
Chris@72
|
298 QSharedPointer<RecentFiles> rf = m_recentFiles[id];
|
Chris@72
|
299 m_fileCombo->clear();
|
Chris@72
|
300 m_urlCombo->clear();
|
Chris@72
|
301
|
Chris@69
|
302 switch (m_argTypes[id]) {
|
Chris@69
|
303
|
Chris@69
|
304 case NoArg:
|
Chris@69
|
305 break;
|
Chris@69
|
306
|
Chris@69
|
307 case FileArg:
|
Chris@74
|
308 m_fileLabel->setText(tr("&File:"));
|
Chris@72
|
309 m_fileLabel->show();
|
Chris@72
|
310 m_fileCombo->show();
|
Chris@72
|
311 m_fileCombo->addItems(rf->getRecent());
|
Chris@69
|
312 m_browseButton->show();
|
Chris@69
|
313 break;
|
Chris@69
|
314
|
Chris@69
|
315 case DirectoryArg:
|
Chris@74
|
316 m_fileLabel->setText(tr("&Folder:"));
|
Chris@72
|
317 m_fileLabel->show();
|
Chris@72
|
318 m_fileCombo->show();
|
Chris@72
|
319 m_fileCombo->addItems(rf->getRecent());
|
Chris@69
|
320 m_browseButton->show();
|
Chris@69
|
321 break;
|
Chris@69
|
322
|
Chris@69
|
323 case UrlArg:
|
Chris@72
|
324 m_urlLabel->show();
|
Chris@72
|
325 m_urlCombo->show();
|
Chris@183
|
326 m_urlCombo->addItems(rf->getRecent());
|
Chris@69
|
327 break;
|
Chris@69
|
328
|
Chris@72
|
329 case UrlToDirectoryArg:
|
Chris@72
|
330 m_urlLabel->show();
|
Chris@72
|
331 m_urlCombo->show();
|
Chris@72
|
332 m_urlCombo->addItems(rf->getRecent());
|
Chris@74
|
333 m_fileLabel->setText(tr("&Folder:"));
|
Chris@72
|
334 m_fileLabel->show();
|
Chris@72
|
335 m_fileCombo->show();
|
Chris@342
|
336 m_fileCombo->lineEdit()->setText(getDefaultPath());
|
Chris@69
|
337 m_browseButton->show();
|
Chris@69
|
338 break;
|
Chris@69
|
339 }
|
Chris@69
|
340
|
Chris@199
|
341 updateOkButton();
|
Chris@69
|
342 adjustSize();
|
Chris@69
|
343 }
|
Chris@69
|
344
|
Chris@69
|
345
|