2 ******************************************************************************
4 * @file savedaction.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.
8 * @see The GNU Public License (GPL) Version 3
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
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 <utils/savedaction.h>
31 #include <utils/qtcassert.h>
32 #include <utils/pathchooser.h>
34 #include <QtCore/QDebug>
35 #include <QtCore/QSettings>
37 #include <QAbstractButton>
39 #include <QActionGroup>
42 #include <QRadioButton>
46 using namespace Utils
;
49 //////////////////////////////////////////////////////////////////////////
53 //////////////////////////////////////////////////////////////////////////
56 \class Utils::SavedAction
58 \brief The SavedAction class is a helper class for actions with persistent
65 SavedAction::SavedAction(QObject
*parent
)
69 connect(this, SIGNAL(triggered(bool)), this, SLOT(actionTriggered(bool)));
74 Returns the current value of the object.
78 QVariant
SavedAction::value() const
85 Sets the current value of the object. If the value changed and
86 \a doemit is true, the \c valueChanged() signal will be emitted.
90 void SavedAction::setValue(const QVariant
&value
, bool doemit
)
92 if (value
== m_value
) {
96 if (this->isCheckable()) {
97 this->setChecked(m_value
.toBool());
100 emit
valueChanged(m_value
);
106 Returns the default value to be used when the item does not exist yet
109 \sa setDefaultValue()
111 QVariant
SavedAction::defaultValue() const
113 return m_defaultValue
;
118 Sets the default value to be used when the item does not exist yet
123 void SavedAction::setDefaultValue(const QVariant
&value
)
125 m_defaultValue
= value
;
130 Returns the key to be used when accessing the settings.
134 QString
SavedAction::settingsKey() const
136 return m_settingsKey
;
141 Sets the key to be used when accessing the settings.
145 void SavedAction::setSettingsKey(const QString
&key
)
152 Sets the key and group to be used when accessing the settings.
156 void SavedAction::setSettingsKey(const QString
&group
, const QString
&key
)
159 m_settingsGroup
= group
;
164 Sets the key to be used when accessing the settings.
168 QString
SavedAction::settingsGroup() const
170 return m_settingsGroup
;
174 Sets the group to be used when accessing the settings.
178 void SavedAction::setSettingsGroup(const QString
&group
)
180 m_settingsGroup
= group
;
183 QString
SavedAction::textPattern() const
185 return m_textPattern
;
188 void SavedAction::setTextPattern(const QString
&value
)
190 m_textPattern
= value
;
193 QString
SavedAction::toString() const
195 return QLatin1String("value: ") + m_value
.toString()
196 + QLatin1String(" defaultvalue: ") + m_defaultValue
.toString()
197 + QLatin1String(" settingskey: ") + m_settingsGroup
198 + '/' + m_settingsKey
;
202 \fn QAction *SavedAction::updatedAction(const QString &text)
204 Adjust the \c text() of the underlying action.
206 This can be used to update the item shortly before e.g. a menu is shown.
208 If the item's \c textPattern() is empty the \a text will be used
211 Otherwise, the behaviour depends on \a text: if it is non-empty,
212 \c QString(textPattern()).arg(text), otherwise, \c textPattern()
213 with the "%1" placeholder removed will be used.
215 \sa textPattern(), setTextPattern()
217 QAction
*SavedAction::updatedAction(const QString
&text0
)
219 QString text
= text0
;
222 if (!m_textPattern
.isEmpty()) {
223 if (text
.isEmpty()) {
224 text
= m_textPattern
;
225 text
.remove("\"%1\"");
229 text
= m_textPattern
.arg(text0
);
232 this->setEnabled(enabled
);
233 this->setData(text0
);
239 Uses \c settingsGroup() and \c settingsKey() to restore the
240 item from \a settings,
242 \sa settingsKey(), settingsGroup(), writeSettings()
244 void SavedAction::readSettings(QSettings
*settings
)
246 if (m_settingsGroup
.isEmpty() || m_settingsKey
.isEmpty()) {
249 settings
->beginGroup(m_settingsGroup
);
250 QVariant var
= settings
->value(m_settingsKey
, m_defaultValue
);
251 // work around old ini files containing @Invalid() entries
252 if (isCheckable() && !var
.isValid()) {
256 // qDebug() << "READING: " << var.isValid() << m_settingsKey << " -> " << m_value
257 // << " (default: " << m_defaultValue << ")" << var;
258 settings
->endGroup();
262 Uses \c settingsGroup() and \c settingsKey() to write the
265 \sa settingsKey(), settingsGroup(), readSettings()
267 void SavedAction::writeSettings(QSettings
*settings
)
269 if (m_settingsGroup
.isEmpty() || m_settingsKey
.isEmpty()) {
272 settings
->beginGroup(m_settingsGroup
);
273 settings
->setValue(m_settingsKey
, m_value
);
274 // qDebug() << "WRITING: " << m_settingsKey << " -> " << toString();
275 settings
->endGroup();
279 A \c SavedAction can be connected to a widget, typically a
280 checkbox, radiobutton, or a lineedit in some configuration dialog.
282 The widget will retrieve its contents from the SavedAction's
283 value, and - depending on the \a ApplyMode - either write
284 changes back immediately, or when \s SavedAction::apply()
285 is called explicitly.
287 \sa apply(), disconnectWidget()
289 void SavedAction::connectWidget(QWidget
*widget
, ApplyMode applyMode
)
291 QTC_ASSERT(!m_widget
,
292 qDebug() << "ALREADY CONNECTED: " << widget
<< m_widget
<< toString(); return );
294 m_applyMode
= applyMode
;
296 if (QAbstractButton
* button
= qobject_cast
<QAbstractButton
*>(widget
)) {
297 if (button
->isCheckable()) {
298 button
->setChecked(m_value
.toBool());
299 connect(button
, SIGNAL(clicked(bool)),
300 this, SLOT(checkableButtonClicked(bool)));
302 connect(button
, SIGNAL(clicked()),
303 this, SLOT(uncheckableButtonClicked()));
305 } else if (QSpinBox
* spinBox
= qobject_cast
<QSpinBox
*>(widget
)) {
306 spinBox
->setValue(m_value
.toInt());
308 // qDebug() << "SETTING VALUE" << spinBox->value();
309 connect(spinBox
, SIGNAL(valueChanged(int)),
310 this, SLOT(spinBoxValueChanged(int)));
311 connect(spinBox
, SIGNAL(valueChanged(QString
)),
312 this, SLOT(spinBoxValueChanged(QString
)));
313 } else if (QDoubleSpinBox
* doubleSpinBox
= qobject_cast
<QDoubleSpinBox
*>(widget
)) {
314 doubleSpinBox
->setValue(m_value
.toDouble());
315 // qDebug() << "SETTING VALUE" << doubleSpinBox->value();
316 connect(doubleSpinBox
, SIGNAL(valueChanged(double)),
317 this, SLOT(doubleSpinBoxValueChanged(double)));
318 connect(doubleSpinBox
, SIGNAL(valueChanged(QString
)),
319 this, SLOT(doubleSpinBoxValueChanged(QString
)));
320 } else if (QLineEdit
* lineEdit
= qobject_cast
<QLineEdit
*>(widget
)) {
321 lineEdit
->setText(m_value
.toString());
322 // qDebug() << "SETTING TEXT" << lineEdit->text();
323 connect(lineEdit
, SIGNAL(editingFinished()),
324 this, SLOT(lineEditEditingFinished()));
325 } else if (PathChooser
* pathChooser
= qobject_cast
<PathChooser
*>(widget
)) {
326 pathChooser
->setPath(m_value
.toString());
327 connect(pathChooser
, SIGNAL(editingFinished()),
328 this, SLOT(pathChooserEditingFinished()));
329 connect(pathChooser
, SIGNAL(browsingFinished()),
330 this, SLOT(pathChooserEditingFinished()));
332 qDebug() << "Cannot connect widget " << widget
<< toString();
337 Disconnects the \c SavedAction from a widget.
339 \sa apply(), connectWidget()
341 void SavedAction::disconnectWidget()
346 void SavedAction::apply(QSettings
*s
)
348 if (QAbstractButton
* button
= qobject_cast
<QAbstractButton
*>(m_widget
)) {
349 setValue(button
->isChecked());
350 } else if (QLineEdit
* lineEdit
= qobject_cast
<QLineEdit
*>(m_widget
)) {
351 setValue(lineEdit
->text());
352 } else if (QSpinBox
* spinBox
= qobject_cast
<QSpinBox
*>(m_widget
)) {
353 setValue(spinBox
->value());
354 } else if (QDoubleSpinBox
* doubleSpinBox
= qobject_cast
<QDoubleSpinBox
*>(m_widget
)) {
355 setValue(doubleSpinBox
->value());
356 } else if (PathChooser
* pathChooser
= qobject_cast
<PathChooser
*>(m_widget
)) {
357 setValue(pathChooser
->path());
364 void SavedAction::uncheckableButtonClicked()
366 QAbstractButton
*button
= qobject_cast
<QAbstractButton
*>(sender());
368 QTC_ASSERT(button
, return );
369 // qDebug() << "UNCHECKABLE BUTTON: " << sender();
373 void SavedAction::checkableButtonClicked(bool)
375 QAbstractButton
*button
= qobject_cast
<QAbstractButton
*>(sender());
377 QTC_ASSERT(button
, return );
378 // qDebug() << "CHECKABLE BUTTON: " << sender();
379 if (m_applyMode
== ImmediateApply
) {
380 setValue(button
->isChecked());
384 void SavedAction::lineEditEditingFinished()
386 QLineEdit
*lineEdit
= qobject_cast
<QLineEdit
*>(sender());
388 QTC_ASSERT(lineEdit
, return );
389 if (m_applyMode
== ImmediateApply
) {
390 setValue(lineEdit
->text());
394 void SavedAction::spinBoxValueChanged(int value
)
396 QSpinBox
*spinBox
= qobject_cast
<QSpinBox
*>(sender());
398 QTC_ASSERT(spinBox
, return );
399 if (m_applyMode
== ImmediateApply
) {
404 void SavedAction::spinBoxValueChanged(QString value
)
406 QSpinBox
*spinBox
= qobject_cast
<QSpinBox
*>(sender());
408 QTC_ASSERT(spinBox
, return );
409 if (m_applyMode
== ImmediateApply
) {
414 void SavedAction::doubleSpinBoxValueChanged(double value
)
416 QDoubleSpinBox
*doubleSpinBox
= qobject_cast
<QDoubleSpinBox
*>(sender());
418 QTC_ASSERT(doubleSpinBox
, return );
419 if (m_applyMode
== ImmediateApply
) {
424 void SavedAction::doubleSpinBoxValueChanged(QString value
)
426 QDoubleSpinBox
*doubleSpinBox
= qobject_cast
<QDoubleSpinBox
*>(sender());
428 QTC_ASSERT(doubleSpinBox
, return );
429 if (m_applyMode
== ImmediateApply
) {
434 void SavedAction::pathChooserEditingFinished()
436 PathChooser
*pathChooser
= qobject_cast
<PathChooser
*>(sender());
438 QTC_ASSERT(pathChooser
, return );
439 if (m_applyMode
== ImmediateApply
) {
440 setValue(pathChooser
->path());
444 void SavedAction::actionTriggered(bool)
447 setValue(isChecked());
449 if (actionGroup() && actionGroup()->isExclusive()) {
450 // FIXME: should be taken care of more directly
451 foreach(QAction
* act
, actionGroup()->actions())
452 if (SavedAction
* dact
= qobject_cast
<SavedAction
*>(act
)) {
453 dact
->setValue(bool(act
== this));
458 void SavedAction::trigger(const QVariant
&data
)
465 //////////////////////////////////////////////////////////////////////////
469 //////////////////////////////////////////////////////////////////////////
471 void SavedActionSet::insert(SavedAction
*action
, QWidget
*widget
)
473 m_list
.append(action
);
475 action
->connectWidget(widget
);
479 void SavedActionSet::apply(QSettings
*settings
)
481 foreach(SavedAction
* action
, m_list
)
482 action
->apply(settings
);
485 void SavedActionSet::finish()
487 foreach(SavedAction
* action
, m_list
)
488 action
->disconnectWidget();