LP-311 Remove basic/advanced stabilization tab auto-switch (autotune/txpid lock issues)
[librepilot.git] / ground / gcs / src / libs / utils / newclasswidget.cpp
blob74152983b77c330e9eb0fc1c44feab2ff3b422e5
1 /**
2 ******************************************************************************
4 * @file newclasswidget.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 "newclasswidget.h"
30 #include "ui_newclasswidget.h"
32 #include <utils/filewizardpage.h>
34 #include <QFileDialog>
35 #include <QtCore/QFileInfo>
36 #include <QtCore/QStringList>
37 #include <QtCore/QDir>
38 #include <QtCore/QDebug>
39 #include <QtCore/QRegExp>
41 enum { debugNewClassWidget = 0 };
43 namespace Utils {
44 struct NewClassWidgetPrivate {
45 NewClassWidgetPrivate();
47 Ui::NewClassWidget m_ui;
48 QString m_headerExtension;
49 QString m_sourceExtension;
50 QString m_formExtension;
51 bool m_valid;
52 bool m_classEdited;
53 // Store the "visible" values to prevent the READ accessors from being
54 // fooled by a temporarily hidden widget
55 bool m_baseClassInputVisible;
56 bool m_formInputVisible;
57 bool m_pathInputVisible;
58 bool m_qobjectCheckBoxVisible;
59 bool m_formInputCheckable;
62 NewClassWidgetPrivate::NewClassWidgetPrivate() :
63 m_headerExtension(QLatin1String("h")),
64 m_sourceExtension(QLatin1String("cpp")),
65 m_formExtension(QLatin1String("ui")),
66 m_valid(false),
67 m_classEdited(false),
68 m_baseClassInputVisible(true),
69 m_formInputVisible(true),
70 m_pathInputVisible(true),
71 m_qobjectCheckBoxVisible(false),
72 m_formInputCheckable(false)
76 // --------------------- NewClassWidget
77 NewClassWidget::NewClassWidget(QWidget *parent) :
78 QWidget(parent),
79 m_d(new NewClassWidgetPrivate)
81 m_d->m_ui.setupUi(this);
83 m_d->m_ui.baseClassComboBox->setEditable(false);
85 connect(m_d->m_ui.classLineEdit, SIGNAL(updateFileName(QString)),
86 this, SLOT(slotUpdateFileNames(QString)));
87 connect(m_d->m_ui.classLineEdit, SIGNAL(textEdited(QString)),
88 this, SLOT(classNameEdited()));
89 connect(m_d->m_ui.baseClassComboBox, SIGNAL(currentIndexChanged(int)),
90 this, SLOT(suggestClassNameFromBase()));
91 connect(m_d->m_ui.baseClassComboBox, SIGNAL(editTextChanged(QString)),
92 this, SLOT(slotValidChanged()));
93 connect(m_d->m_ui.classLineEdit, SIGNAL(validChanged()),
94 this, SLOT(slotValidChanged()));
95 connect(m_d->m_ui.headerFileLineEdit, SIGNAL(validChanged()),
96 this, SLOT(slotValidChanged()));
97 connect(m_d->m_ui.sourceFileLineEdit, SIGNAL(validChanged()),
98 this, SLOT(slotValidChanged()));
99 connect(m_d->m_ui.formFileLineEdit, SIGNAL(validChanged()),
100 this, SLOT(slotValidChanged()));
101 connect(m_d->m_ui.pathChooser, SIGNAL(validChanged()),
102 this, SLOT(slotValidChanged()));
104 connect(m_d->m_ui.classLineEdit, SIGNAL(validReturnPressed()),
105 this, SLOT(slotActivated()));
106 connect(m_d->m_ui.headerFileLineEdit, SIGNAL(validReturnPressed()),
107 this, SLOT(slotActivated()));
108 connect(m_d->m_ui.sourceFileLineEdit, SIGNAL(validReturnPressed()),
109 this, SLOT(slotActivated()));
110 connect(m_d->m_ui.formFileLineEdit, SIGNAL(validReturnPressed()),
111 this, SLOT(slotActivated()));
112 connect(m_d->m_ui.formFileLineEdit, SIGNAL(validReturnPressed()),
113 this, SLOT(slotActivated()));
114 connect(m_d->m_ui.pathChooser, SIGNAL(returnPressed()),
115 this, SLOT(slotActivated()));
117 connect(m_d->m_ui.generateFormCheckBox, SIGNAL(stateChanged(int)),
118 this, SLOT(slotFormInputChecked()));
120 m_d->m_ui.generateFormCheckBox->setChecked(true);
121 setFormInputCheckable(false, true);
122 setClassType(NoClassType);
125 NewClassWidget::~NewClassWidget()
127 delete m_d;
130 void NewClassWidget::classNameEdited()
132 if (debugNewClassWidget) {
133 qDebug() << Q_FUNC_INFO << m_d->m_headerExtension << m_d->m_sourceExtension;
135 m_d->m_classEdited = true;
138 void NewClassWidget::suggestClassNameFromBase()
140 if (debugNewClassWidget) {
141 qDebug() << Q_FUNC_INFO << m_d->m_headerExtension << m_d->m_sourceExtension;
143 if (m_d->m_classEdited) {
144 return;
146 // Suggest a class unless edited ("QMainWindow"->"MainWindow")
147 QString base = baseClassName();
148 if (base.startsWith(QLatin1Char('Q'))) {
149 base.remove(0, 1);
150 setClassName(base);
154 QStringList NewClassWidget::baseClassChoices() const
156 QStringList rc;
157 const int count = m_d->m_ui.baseClassComboBox->count();
159 for (int i = 0; i < count; i++) {
160 rc.push_back(m_d->m_ui.baseClassComboBox->itemText(i));
162 return rc;
165 void NewClassWidget::setBaseClassChoices(const QStringList &choices)
167 m_d->m_ui.baseClassComboBox->clear();
168 m_d->m_ui.baseClassComboBox->addItems(choices);
171 void NewClassWidget::setBaseClassInputVisible(bool visible)
173 m_d->m_baseClassInputVisible = visible;
174 m_d->m_ui.baseClassLabel->setVisible(visible);
175 m_d->m_ui.baseClassComboBox->setVisible(visible);
178 void NewClassWidget::setBaseClassEditable(bool editable)
180 m_d->m_ui.baseClassComboBox->setEditable(editable);
183 bool NewClassWidget::isBaseClassInputVisible() const
185 return m_d->m_baseClassInputVisible;
188 bool NewClassWidget::isBaseClassEditable() const
190 return m_d->m_ui.baseClassComboBox->isEditable();
193 void NewClassWidget::setFormInputVisible(bool visible)
195 m_d->m_formInputVisible = visible;
196 m_d->m_ui.formLabel->setVisible(visible);
197 m_d->m_ui.formFileLineEdit->setVisible(visible);
200 bool NewClassWidget::isFormInputVisible() const
202 return m_d->m_formInputVisible;
205 void NewClassWidget::setFormInputCheckable(bool checkable)
207 setFormInputCheckable(checkable, false);
210 void NewClassWidget::setFormInputCheckable(bool checkable, bool force)
212 if (!force && checkable == m_d->m_formInputCheckable) {
213 return;
215 m_d->m_formInputCheckable = checkable;
216 m_d->m_ui.generateFormLabel->setVisible(checkable);
217 m_d->m_ui.generateFormCheckBox->setVisible(checkable);
220 void NewClassWidget::setFormInputChecked(bool v)
222 m_d->m_ui.generateFormCheckBox->setChecked(v);
225 bool NewClassWidget::formInputCheckable() const
227 return m_d->m_formInputCheckable;
230 bool NewClassWidget::formInputChecked() const
232 return m_d->m_ui.generateFormCheckBox->isChecked();
235 void NewClassWidget::slotFormInputChecked()
237 const bool checked = formInputChecked();
239 m_d->m_ui.formLabel->setEnabled(checked);
240 m_d->m_ui.formFileLineEdit->setEnabled(checked);
243 void NewClassWidget::setPathInputVisible(bool visible)
245 m_d->m_pathInputVisible = visible;
246 m_d->m_ui.pathLabel->setVisible(visible);
247 m_d->m_ui.pathChooser->setVisible(visible);
250 bool NewClassWidget::isPathInputVisible() const
252 return m_d->m_pathInputVisible;
255 void NewClassWidget::setClassName(const QString &suggestedName)
257 if (debugNewClassWidget) {
258 qDebug() << Q_FUNC_INFO << suggestedName << m_d->m_headerExtension << m_d->m_sourceExtension;
260 m_d->m_ui.classLineEdit->setText(ClassNameValidatingLineEdit::createClassName(suggestedName));
263 QString NewClassWidget::className() const
265 return m_d->m_ui.classLineEdit->text();
268 QString NewClassWidget::baseClassName() const
270 return m_d->m_ui.baseClassComboBox->currentText();
273 void NewClassWidget::setBaseClassName(const QString &c)
275 const int index = m_d->m_ui.baseClassComboBox->findText(c);
277 if (index != -1) {
278 m_d->m_ui.baseClassComboBox->setCurrentIndex(index);
279 suggestClassNameFromBase();
283 QString NewClassWidget::sourceFileName() const
285 return m_d->m_ui.sourceFileLineEdit->text();
288 QString NewClassWidget::headerFileName() const
290 return m_d->m_ui.headerFileLineEdit->text();
293 QString NewClassWidget::formFileName() const
295 return m_d->m_ui.formFileLineEdit->text();
298 QString NewClassWidget::path() const
300 return m_d->m_ui.pathChooser->path();
303 void NewClassWidget::setPath(const QString &path)
305 m_d->m_ui.pathChooser->setPath(path);
308 bool NewClassWidget::namespacesEnabled() const
310 return m_d->m_ui.classLineEdit->namespacesEnabled();
313 void NewClassWidget::setNamespacesEnabled(bool b)
315 m_d->m_ui.classLineEdit->setNamespacesEnabled(b);
318 QString NewClassWidget::sourceExtension() const
320 return m_d->m_sourceExtension;
323 void NewClassWidget::setSourceExtension(const QString &e)
325 if (debugNewClassWidget) {
326 qDebug() << Q_FUNC_INFO << e;
328 m_d->m_sourceExtension = fixSuffix(e);
331 QString NewClassWidget::headerExtension() const
333 return m_d->m_headerExtension;
336 void NewClassWidget::setHeaderExtension(const QString &e)
338 if (debugNewClassWidget) {
339 qDebug() << Q_FUNC_INFO << e;
341 m_d->m_headerExtension = fixSuffix(e);
344 QString NewClassWidget::formExtension() const
346 return m_d->m_formExtension;
349 void NewClassWidget::setFormExtension(const QString &e)
351 if (debugNewClassWidget) {
352 qDebug() << Q_FUNC_INFO << e;
354 m_d->m_formExtension = fixSuffix(e);
357 bool NewClassWidget::allowDirectories() const
359 return m_d->m_ui.headerFileLineEdit->allowDirectories();
362 void NewClassWidget::setAllowDirectories(bool v)
364 // We keep all in sync
365 if (allowDirectories() != v) {
366 m_d->m_ui.sourceFileLineEdit->setAllowDirectories(v);
367 m_d->m_ui.headerFileLineEdit->setAllowDirectories(v);
368 m_d->m_ui.formFileLineEdit->setAllowDirectories(v);
372 bool NewClassWidget::lowerCaseFiles() const
374 return m_d->m_ui.classLineEdit->lowerCaseFileName();
377 void NewClassWidget::setLowerCaseFiles(bool v)
379 m_d->m_ui.classLineEdit->setLowerCaseFileName(v);
382 NewClassWidget::ClassType NewClassWidget::classType() const
384 return static_cast<ClassType>(m_d->m_ui.classTypeComboBox->currentIndex());
387 void NewClassWidget::setClassType(ClassType ct)
389 m_d->m_ui.classTypeComboBox->setCurrentIndex(ct);
392 bool NewClassWidget::isClassTypeComboVisible() const
394 return m_d->m_ui.classTypeLabel->isVisible();
397 void NewClassWidget::setClassTypeComboVisible(bool v)
399 m_d->m_ui.classTypeLabel->setVisible(v);
400 m_d->m_ui.classTypeComboBox->setVisible(v);
403 void NewClassWidget::slotValidChanged()
405 const bool newValid = isValid();
407 if (newValid != m_d->m_valid) {
408 m_d->m_valid = newValid;
409 emit validChanged();
413 bool NewClassWidget::isValid(QString *error) const
415 if (!m_d->m_ui.classLineEdit->isValid()) {
416 if (error) {
417 *error = m_d->m_ui.classLineEdit->errorMessage();
419 return false;
422 if (isBaseClassInputVisible() && isBaseClassEditable()) {
423 // TODO: Should this be a ClassNameValidatingComboBox?
424 QRegExp classNameValidator(QLatin1String("[a-zA-Z_][a-zA-Z0-9_]*(::[a-zA-Z_][a-zA-Z0-9_]*)*"));
425 const QString baseClass = m_d->m_ui.baseClassComboBox->currentText().trimmed();
426 if (!baseClass.isEmpty() && !classNameValidator.exactMatch(baseClass)) {
427 if (error) {
428 *error = tr("Invalid base class name");
430 return false;
434 if (!m_d->m_ui.headerFileLineEdit->isValid()) {
435 if (error) {
436 *error = tr("Invalid header file name: '%1'").arg(m_d->m_ui.headerFileLineEdit->errorMessage());
438 return false;
441 if (!m_d->m_ui.sourceFileLineEdit->isValid()) {
442 if (error) {
443 *error = tr("Invalid source file name: '%1'").arg(m_d->m_ui.sourceFileLineEdit->errorMessage());
445 return false;
448 if (isFormInputVisible()) {
449 if (!m_d->m_ui.formFileLineEdit->isValid()) {
450 if (error) {
451 *error = tr("Invalid form file name: '%1'").arg(m_d->m_ui.formFileLineEdit->errorMessage());
453 return false;
457 if (isPathInputVisible()) {
458 if (!m_d->m_ui.pathChooser->isValid()) {
459 if (error) {
460 *error = m_d->m_ui.pathChooser->errorMessage();
462 return false;
465 return true;
468 void NewClassWidget::triggerUpdateFileNames()
470 m_d->m_ui.classLineEdit->triggerChanged();
473 void NewClassWidget::slotUpdateFileNames(const QString &baseName)
475 if (debugNewClassWidget) {
476 qDebug() << Q_FUNC_INFO << baseName << m_d->m_headerExtension << m_d->m_sourceExtension;
478 const QChar dot = QLatin1Char('.');
479 m_d->m_ui.sourceFileLineEdit->setText(baseName + dot + m_d->m_sourceExtension);
480 m_d->m_ui.headerFileLineEdit->setText(baseName + dot + m_d->m_headerExtension);
481 m_d->m_ui.formFileLineEdit->setText(baseName + dot + m_d->m_formExtension);
484 void NewClassWidget::slotActivated()
486 if (m_d->m_valid) {
487 emit activated();
491 QString NewClassWidget::fixSuffix(const QString &suffix)
493 QString s = suffix;
495 if (s.startsWith(QLatin1Char('.'))) {
496 s.remove(0, 1);
498 return s;
501 // Utility to add a suffix to a file unless the user specified one
502 static QString ensureSuffix(QString f, const QString &extension)
504 const QChar dot = QLatin1Char('.');
506 if (f.contains(dot)) {
507 return f;
509 f += dot;
510 f += extension;
511 return f;
514 // If a non-empty name was passed, expand to directory and suffix
515 static QString expandFileName(const QDir &dir, const QString name, const QString &extension)
517 if (name.isEmpty()) {
518 return QString();
520 return dir.absoluteFilePath(ensureSuffix(name, extension));
523 QStringList NewClassWidget::files() const
525 QStringList rc;
526 const QDir dir = QDir(path());
528 rc.push_back(expandFileName(dir, headerFileName(), headerExtension()));
529 rc.push_back(expandFileName(dir, sourceFileName(), sourceExtension()));
530 if (isFormInputVisible()) {
531 rc.push_back(expandFileName(dir, formFileName(), formExtension()));
533 return rc;
535 } // namespace Utils