LP-311 Remove basic/advanced stabilization tab auto-switch (autotune/txpid lock issues)
[librepilot.git] / ground / gcs / src / libs / utils / pathchooser.cpp
blob18e420c0185a13a0491052a6e7995e2c5e7e2c5e
1 /**
2 ******************************************************************************
4 * @file pathchooser.cpp
5 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
6 * Parts by Nokia Corporation (qt-info@nokia.com) Copyright (C) 2009.
7 * @brief
8 * @see The GNU Public License (GPL) Version 3
9 * @defgroup
10 * @{
12 *****************************************************************************/
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 3 of the License, or
17 * (at your option) any later version.
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 * for more details.
24 * You should have received a copy of the GNU General Public License along
25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 #include "pathchooser.h"
31 #include "basevalidatinglineedit.h"
32 #include "qtcassert.h"
34 #include <QtCore/QDebug>
35 #include <QtCore/QDir>
36 #include <QtCore/QFileInfo>
37 #include <QtCore/QSettings>
39 #include <QDesktopServices>
40 #include <QFileDialog>
41 #include <QHBoxLayout>
42 #include <QLineEdit>
43 #include <QToolButton>
44 #include <QPushButton>
46 /*static*/ const char *const Utils::PathChooser::browseButtonLabel =
47 #ifdef Q_WS_MAC
48 QT_TRANSLATE_NOOP("Utils::PathChooser", "Choose...");
49 #else
50 QT_TRANSLATE_NOOP("Utils::PathChooser", "Browse...");
51 #endif
53 namespace Utils {
54 // ------------------ PathValidatingLineEdit
55 class PathValidatingLineEdit : public BaseValidatingLineEdit {
56 public:
57 explicit PathValidatingLineEdit(PathChooser *chooser, QWidget *parent = 0);
59 protected:
60 virtual bool validate(const QString &value, QString *errorMessage) const;
62 private:
63 PathChooser *m_chooser;
66 PathValidatingLineEdit::PathValidatingLineEdit(PathChooser *chooser, QWidget *parent) :
67 BaseValidatingLineEdit(parent),
68 m_chooser(chooser)
70 QTC_ASSERT(chooser, return );
73 bool PathValidatingLineEdit::validate(const QString &value, QString *errorMessage) const
75 return m_chooser->validatePath(value, errorMessage);
78 // ------------------ PathChooserPrivate
79 struct PathChooserPrivate {
80 PathChooserPrivate(PathChooser *chooser);
82 QHBoxLayout *m_hLayout;
83 PathValidatingLineEdit *m_lineEdit;
84 PathChooser::Kind m_acceptingKind;
85 QString m_dialogTitleOverride;
86 QString m_dialogFilter;
87 QString m_initialBrowsePathOverride;
90 PathChooserPrivate::PathChooserPrivate(PathChooser *chooser) :
91 m_hLayout(new QHBoxLayout),
92 m_lineEdit(new PathValidatingLineEdit(chooser)),
93 m_acceptingKind(PathChooser::Directory)
96 PathChooser::PathChooser(QWidget *parent) :
97 QWidget(parent),
98 m_d(new PathChooserPrivate(this))
100 m_d->m_hLayout->setContentsMargins(0, 0, 0, 0);
102 connect(m_d->m_lineEdit, SIGNAL(validReturnPressed()), this, SIGNAL(returnPressed()));
103 connect(m_d->m_lineEdit, SIGNAL(textChanged(QString)), this, SIGNAL(changed(QString)));
104 connect(m_d->m_lineEdit, SIGNAL(validChanged()), this, SIGNAL(validChanged()));
105 connect(m_d->m_lineEdit, SIGNAL(validChanged(bool)), this, SIGNAL(validChanged(bool)));
106 connect(m_d->m_lineEdit, SIGNAL(editingFinished()), this, SIGNAL(editingFinished()));
108 m_d->m_lineEdit->setMinimumWidth(50);
109 m_d->m_hLayout->addWidget(m_d->m_lineEdit);
110 m_d->m_hLayout->setSizeConstraint(QLayout::SetMinimumSize);
112 addButton(tr(browseButtonLabel), this, SLOT(slotBrowse()));
114 setLayout(m_d->m_hLayout);
115 setFocusProxy(m_d->m_lineEdit);
118 PathChooser::~PathChooser()
120 delete m_d;
123 void PathChooser::addButton(const QString &text, QObject *receiver, const char *slotFunc)
125 #ifdef Q_WS_MAC
126 QPushButton *button = new QPushButton;
127 #else
128 QToolButton *button = new QToolButton;
129 #endif
130 button->setText(text);
131 connect(button, SIGNAL(clicked()), receiver, slotFunc);
132 m_d->m_hLayout->addWidget(button);
135 QAbstractButton *PathChooser::buttonAtIndex(int index) const
137 return findChildren<QAbstractButton *>().at(index);
140 QString PathChooser::path() const
142 return m_d->m_lineEdit->text();
145 void PathChooser::setPath(const QString &path)
147 m_d->m_lineEdit->setText(QDir::toNativeSeparators(path));
150 void PathChooser::slotBrowse()
152 emit beforeBrowsing();
154 QString predefined = path();
156 if ((predefined.isEmpty() || !QFileInfo(predefined).isDir())
157 && !m_d->m_initialBrowsePathOverride.isNull()) {
158 predefined = m_d->m_initialBrowsePathOverride;
160 if (!QFileInfo(predefined).isDir()) {
161 predefined.clear();
165 if (predefined.startsWith(":")) {
166 predefined.clear();
169 // Prompt for a file/dir
170 QString dialogTitle;
171 QString newPath;
172 switch (m_d->m_acceptingKind) {
173 case PathChooser::Directory:
174 newPath = QFileDialog::getExistingDirectory(this,
175 makeDialogTitle(tr("Choose a directory")), predefined);
176 break;
178 case PathChooser::File: // fall through
179 case PathChooser::Command:
180 newPath = QFileDialog::getOpenFileName(this,
181 makeDialogTitle(tr("Choose a file")), predefined,
182 m_d->m_dialogFilter);
183 break;
185 default:
189 // Delete trailing slashes unless it is "/"|"\\", only
190 if (!newPath.isEmpty()) {
191 newPath = QDir::toNativeSeparators(newPath);
192 if (newPath.size() > 1 && newPath.endsWith(QDir::separator())) {
193 newPath.truncate(newPath.size() - 1);
195 setPath(newPath);
198 emit browsingFinished();
201 bool PathChooser::isValid() const
203 return m_d->m_lineEdit->isValid();
206 QString PathChooser::errorMessage() const
208 return m_d->m_lineEdit->errorMessage();
211 bool PathChooser::validatePath(const QString &path, QString *errorMessage)
213 if (path.isEmpty()) {
214 if (errorMessage) {
215 *errorMessage = tr("The path must not be empty.");
217 return false;
220 const QFileInfo fi(path);
221 const bool isDir = fi.isDir();
223 // Check if existing
224 switch (m_d->m_acceptingKind) {
225 case PathChooser::Directory: // fall through
226 case PathChooser::File:
227 if (!fi.exists()) {
228 if (errorMessage) {
229 *errorMessage = tr("The path '%1' does not exist.").arg(path);
231 return false;
233 break;
235 case PathChooser::Command: // fall through
236 default:
240 // Check expected kind
241 switch (m_d->m_acceptingKind) {
242 case PathChooser::Directory:
243 if (!isDir) {
244 if (errorMessage) {
245 *errorMessage = tr("The path '%1' is not a directory.").arg(path);
247 return false;
249 break;
251 case PathChooser::File:
252 if (isDir) {
253 if (errorMessage) {
254 *errorMessage = tr("The path '%1' is not a file.").arg(path);
256 return false;
258 break;
260 case PathChooser::Command:
261 // TODO do proper command validation
262 // i.e. search $PATH for a matching file
263 break;
265 default:
269 return true;
272 QString PathChooser::label()
274 return tr("Path:");
277 QString PathChooser::homePath()
279 #ifdef Q_OS_WIN
280 // Return 'users/<name>/Documents' on Windows, since Windows explorer
281 // does not let people actually display the contents of their home
282 // directory. Alternatively, create a QtCreator-specific directory?
283 return QStandardPaths::displayName(QStandardPaths::DocumentsLocation);
285 #else
286 return QDir::homePath();
288 #endif
291 void PathChooser::setExpectedKind(Kind expected)
293 m_d->m_acceptingKind = expected;
296 PathChooser::Kind PathChooser::expectedKind() const
298 return m_d->m_acceptingKind;
301 void PathChooser::setPromptDialogTitle(const QString &title)
303 m_d->m_dialogTitleOverride = title;
306 QString PathChooser::promptDialogTitle() const
308 return m_d->m_dialogTitleOverride;
311 void PathChooser::setPromptDialogFilter(const QString &filter)
313 m_d->m_dialogFilter = filter;
316 QString PathChooser::promptDialogFilter() const
318 return m_d->m_dialogFilter;
321 void PathChooser::setInitialBrowsePathBackup(const QString &path)
323 m_d->m_initialBrowsePathOverride = path;
326 QString PathChooser::makeDialogTitle(const QString &title)
328 if (m_d->m_dialogTitleOverride.isNull()) {
329 return title;
330 } else {
331 return m_d->m_dialogTitleOverride;
334 } // namespace Utils