savedaction.cpp 12.5 KB
Newer Older
1
2
3
4
5
6
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
7
** Contact: Nokia Corporation (qt-info@nokia.com)
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
hjk's avatar
hjk committed
26
** contact the sales department at http://qt.nokia.com/contact.
27
28
29
30
31
32
33
34
35
36
37
**
**************************************************************************/

#include <utils/savedaction.h>

#include <utils/qtcassert.h>
#include <utils/pathchooser.h>

#include <QtCore/QDebug>
#include <QtCore/QSettings>

38
#include <QtGui/QAbstractButton>
39
40
41
42
#include <QtGui/QAction>
#include <QtGui/QActionGroup>
#include <QtGui/QCheckBox>
#include <QtGui/QLineEdit>
43
44
#include <QtGui/QRadioButton>
#include <QtGui/QSpinBox>
45
#include <QtGui/QGroupBox>
46
47


48
using namespace Utils;
49
50
51
52
53
54
55
56


//////////////////////////////////////////////////////////////////////////
//
// SavedAction
//
//////////////////////////////////////////////////////////////////////////

hjk's avatar
hjk committed
57
/*!
58
    \class Utils::SavedAction
hjk's avatar
hjk committed
59
60
61
62
63
64
65
66
    
    \brief The SavedAction class is a helper class for actions with persistent
    state.

    \ingroup utils

*/

67
68
69
70
71
72
73
SavedAction::SavedAction(QObject *parent)
  : QAction(parent)
{
    m_widget = 0;
    connect(this, SIGNAL(triggered(bool)), this, SLOT(actionTriggered(bool)));
}

hjk's avatar
hjk committed
74
75
76
77
78
79

/*!
    Returns the current value of the object.

    \sa setValue()
*/
80
81
82
83
84
QVariant SavedAction::value() const
{
    return m_value;
}

hjk's avatar
hjk committed
85
86
87
88
89
90
91

/*!
    Sets the current value of the object. If the value changed and
    \a doemit is true, the \c valueChanged() signal will be emitted.

    \sa value()
*/
92
93
94
95
96
97
98
99
100
101
102
void SavedAction::setValue(const QVariant &value, bool doemit)
{
    if (value == m_value)
        return;
    m_value = value;
    if (this->isCheckable())
        this->setChecked(m_value.toBool());
    if (doemit)
        emit valueChanged(m_value);
}

hjk's avatar
hjk committed
103
104
105
106
107
108
109

/*!
    Returns the default value to be used when the item does not exist yet
    in the settings.

    \sa setDefaultValue()
*/
110
111
112
113
114
QVariant SavedAction::defaultValue() const
{
    return m_defaultValue;
}

hjk's avatar
hjk committed
115
116
117
118
119
120
121

/*!
    Sets the default value to be used when the item does not exist yet
    in the settings.

    \sa defaultValue()
*/
122
123
124
125
126
void SavedAction::setDefaultValue(const QVariant &value)
{
    m_defaultValue = value;
}

hjk's avatar
hjk committed
127
128
129
130
131
132

/*!
    Returns the key to be used when accessing the settings.

    \sa settingsKey()
*/
133
134
135
136
137
QString SavedAction::settingsKey() const
{
    return m_settingsKey;
}

hjk's avatar
hjk committed
138
139
140
141
142
143

/*!
    Sets the key to be used when accessing the settings.

    \sa settingsKey()
*/
144
145
146
147
148
void SavedAction::setSettingsKey(const QString &key)
{
    m_settingsKey = key;
}

hjk's avatar
hjk committed
149
150
151
152
153
154

/*!
    Sets the key and group to be used when accessing the settings.

    \sa settingsKey()
*/
155
156
157
158
159
160
void SavedAction::setSettingsKey(const QString &group, const QString &key)
{
    m_settingsKey = key;
    m_settingsGroup = group;
}

hjk's avatar
hjk committed
161
162
163
164
165
166

/*!
    Sets the key to be used when accessing the settings.

    \sa settingsKey()
*/
167
168
169
170
171
QString SavedAction::settingsGroup() const
{
    return m_settingsGroup;
}

hjk's avatar
hjk committed
172
173
174
175
176
/*!
    Sets the group to be used when accessing the settings.

    \sa settingsGroup()
*/
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
void SavedAction::setSettingsGroup(const QString &group)
{
    m_settingsGroup = group;
}

QString SavedAction::textPattern() const
{
    return m_textPattern;
}

void SavedAction::setTextPattern(const QString &value)
{
    m_textPattern = value;
}

QString SavedAction::toString() const
{
hjk's avatar
hjk committed
194
195
196
197
    return QLatin1String("value: ") + m_value.toString()
        + QLatin1String("  defaultvalue: ") + m_defaultValue.toString()
        + QLatin1String("  settingskey: ") + m_settingsGroup
        + '/' + m_settingsKey;
198
199
}

hjk's avatar
hjk committed
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
/*!
    \fn QAction *SavedAction::updatedAction(const QString &text)

    Adjust the \c text() of the underlying action.

    This can be used to update the item shortly before e.g. a menu is shown.

    If the item's \c textPattern() is empty the \a text will be used
    verbatim.

    Otherwise, the behaviour depends on \a text: if it is non-empty,
    \c QString(textPattern()).arg(text), otherwise, \c textPattern()
    with the "%1" placeholder removed will be used.

    \sa textPattern(), setTextPattern()
*/
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
QAction *SavedAction::updatedAction(const QString &text0)
{
    QString text = text0;
    bool enabled = true;
    if (!m_textPattern.isEmpty()) {
        if (text.isEmpty()) {
            text = m_textPattern;
            text.remove("\"%1\"");
            text.remove("%1");
            enabled = false;
        } else {
            text = m_textPattern.arg(text0);
        }
    }
    this->setEnabled(enabled);
    this->setData(text0);
    this->setText(text);
    return this;
}

hjk's avatar
hjk committed
236
237
238
239
240
241
/*
    Uses \c settingsGroup() and \c settingsKey() to restore the 
    item from \a settings,

    \sa settingsKey(), settingsGroup(), writeSettings()
*/
242
void SavedAction::readSettings(const QSettings *settings)
243
244
245
{
    if (m_settingsGroup.isEmpty() || m_settingsKey.isEmpty())
        return;
246
    QVariant var = settings->value(m_settingsGroup + QLatin1Char('/') + m_settingsKey, m_defaultValue);
247
248
249
250
251
252
    // work around old ini files containing @Invalid() entries
    if (isCheckable() && !var.isValid())
        var = false;
    setValue(var);
    //qDebug() << "READING: " << var.isValid() << m_settingsKey << " -> " << m_value
    //    << " (default: " << m_defaultValue << ")" << var;
253
254
}

hjk's avatar
hjk committed
255
256
257
258
259
260
/*
    Uses \c settingsGroup() and \c settingsKey() to write the 
    item to \a settings,

    \sa settingsKey(), settingsGroup(), readSettings()
*/
261
262
263
264
265
266
267
268
269
270
void SavedAction::writeSettings(QSettings *settings)
{
    if (m_settingsGroup.isEmpty() || m_settingsKey.isEmpty())
        return;
    settings->beginGroup(m_settingsGroup);
    settings->setValue(m_settingsKey, m_value);
    //qDebug() << "WRITING: " << m_settingsKey << " -> " << toString();
    settings->endGroup();
}
   
hjk's avatar
hjk committed
271
272
273
274
275
276
277
278
279
280
281
/*
    A \c SavedAction can be connected to a widget, typically a
    checkbox, radiobutton, or a lineedit in some configuration dialog.

    The widget will retrieve its contents from the SavedAction's 
    value, and - depending on the \a ApplyMode - either write
    changes back immediately, or when \s SavedAction::apply()
    is called explicitly.

    \sa apply(), disconnectWidget()
*/
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
void SavedAction::connectWidget(QWidget *widget, ApplyMode applyMode)
{
    QTC_ASSERT(!m_widget,
        qDebug() << "ALREADY CONNECTED: " << widget << m_widget << toString(); return);
    m_widget = widget;
    m_applyMode = applyMode;
    
    if (QAbstractButton *button = qobject_cast<QAbstractButton *>(widget)) {
        if (button->isCheckable()) {
            button->setChecked(m_value.toBool());
            connect(button, SIGNAL(clicked(bool)),
                this, SLOT(checkableButtonClicked(bool)));
        } else {
            connect(button, SIGNAL(clicked()),
                this, SLOT(uncheckableButtonClicked()));
        }
298
299
300
301
302
303
304
    } else if (QSpinBox *spinBox = qobject_cast<QSpinBox *>(widget)) {
        spinBox->setValue(m_value.toInt());
        //qDebug() << "SETTING VALUE" << spinBox->value(); 
        connect(spinBox, SIGNAL(valueChanged(int)),
            this, SLOT(spinBoxValueChanged(int)));
        connect(spinBox, SIGNAL(valueChanged(QString)),
            this, SLOT(spinBoxValueChanged(QString)));
305
306
307
308
309
310
311
312
313
314
315
    } else if (QLineEdit *lineEdit = qobject_cast<QLineEdit *>(widget)) {
        lineEdit->setText(m_value.toString());
        //qDebug() << "SETTING TEXT" << lineEdit->text(); 
        connect(lineEdit, SIGNAL(editingFinished()),
            this, SLOT(lineEditEditingFinished()));
    } else if (PathChooser *pathChooser = qobject_cast<PathChooser *>(widget)) {
        pathChooser->setPath(m_value.toString());
        connect(pathChooser, SIGNAL(editingFinished()),
            this, SLOT(pathChooserEditingFinished()));
        connect(pathChooser, SIGNAL(browsingFinished()),
            this, SLOT(pathChooserEditingFinished()));
316
317
318
319
320
    } else if (QGroupBox *groupBox= qobject_cast<QGroupBox *>(widget)) {
        if (!groupBox->isCheckable())
            qDebug() << "connectWidget to non-checkable group box" << widget << toString();
        groupBox->setChecked(m_value.toBool());
        connect(groupBox, SIGNAL(toggled(bool)), this, SLOT(groupBoxToggled(bool)));
321
322
323
324
325
    } else {
        qDebug() << "Cannot connect widget " << widget << toString();
    }
}

hjk's avatar
hjk committed
326
327
328
329
330
/*
    Disconnects the \c SavedAction from a widget.

    \sa apply(), connectWidget()
*/
331
332
333
334
void SavedAction::disconnectWidget()
{
    m_widget = 0;
}
335

336
337
338
339
340
341
void SavedAction::apply(QSettings *s)
{
    if (QAbstractButton *button = qobject_cast<QAbstractButton *>(m_widget))
        setValue(button->isChecked());
    else if (QLineEdit *lineEdit = qobject_cast<QLineEdit *>(m_widget))
        setValue(lineEdit->text());
342
343
    else if (QSpinBox *spinBox = qobject_cast<QSpinBox *>(m_widget))
        setValue(spinBox->value());
344
345
    else if (PathChooser *pathChooser = qobject_cast<PathChooser *>(m_widget))
        setValue(pathChooser->path());
346
347
    else if (const QGroupBox *groupBox= qobject_cast<QGroupBox *>(m_widget))
        setValue(groupBox->isChecked());
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
    if (s)
       writeSettings(s);
}

void SavedAction::uncheckableButtonClicked()
{
    QAbstractButton *button = qobject_cast<QAbstractButton *>(sender());
    QTC_ASSERT(button, return);
    //qDebug() << "UNCHECKABLE BUTTON: " << sender();
    QAction::trigger();
}

void SavedAction::checkableButtonClicked(bool)
{
    QAbstractButton *button = qobject_cast<QAbstractButton *>(sender());
    QTC_ASSERT(button, return);
    //qDebug() << "CHECKABLE BUTTON: " << sender();
    if (m_applyMode == ImmediateApply)
        setValue(button->isChecked());
}

void SavedAction::lineEditEditingFinished()
{
    QLineEdit *lineEdit = qobject_cast<QLineEdit *>(sender());
    QTC_ASSERT(lineEdit, return);
    if (m_applyMode == ImmediateApply)
        setValue(lineEdit->text());
}

377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
void SavedAction::spinBoxValueChanged(int value)
{
    QSpinBox *spinBox = qobject_cast<QSpinBox *>(sender());
    QTC_ASSERT(spinBox, return);
    if (m_applyMode == ImmediateApply)
        setValue(value);
}

void SavedAction::spinBoxValueChanged(QString value)
{
    QSpinBox *spinBox = qobject_cast<QSpinBox *>(sender());
    QTC_ASSERT(spinBox, return);
    if (m_applyMode == ImmediateApply)
        setValue(value);
}

393
394
395
396
397
398
399
400
void SavedAction::pathChooserEditingFinished()
{
    PathChooser *pathChooser = qobject_cast<PathChooser *>(sender());
    QTC_ASSERT(pathChooser, return);
    if (m_applyMode == ImmediateApply)
        setValue(pathChooser->path());
}

401
402
403
404
405
406
void SavedAction::groupBoxToggled(bool checked)
{
    if (m_applyMode == ImmediateApply)
        setValue(QVariant(checked));
}

407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
void SavedAction::actionTriggered(bool)
{
    if (isCheckable())
        setValue(isChecked());
    if (actionGroup() && actionGroup()->isExclusive()) {
        // FIXME: should be taken care of more directly
        foreach (QAction *act, actionGroup()->actions())
            if (SavedAction *dact = qobject_cast<SavedAction *>(act))
                dact->setValue(bool(act == this));
    }
}

void SavedAction::trigger(const QVariant &data)
{
    setData(data);
    QAction::trigger();
}


//////////////////////////////////////////////////////////////////////////
//
// SavedActionSet
//
//////////////////////////////////////////////////////////////////////////

void SavedActionSet::insert(SavedAction *action, QWidget *widget)
{
    m_list.append(action);
435
436
    if (widget)
        action->connectWidget(widget);
437
438
439
440
441
442
443
444
445
446
447
448
449
450
}

void SavedActionSet::apply(QSettings *settings)
{
    foreach (SavedAction *action, m_list)
        action->apply(settings);
}

void SavedActionSet::finish()
{
    foreach (SavedAction *action, m_list)
        action->disconnectWidget();
}

451
452
453
454
455
456
457
458
459
460
461
462
463
QString SavedActionSet::searchKeyWords() const
{
    const QChar blank = QLatin1Char(' ');
    QString rc;
    foreach (SavedAction *action, m_list) {
        if (!rc.isEmpty())
            rc += blank;
        rc += action->text();
    }
    rc.remove(QLatin1Char('&'));
    return rc;
}