2 * specialactions.cpp - widget to specify special alarm actions
4 * Copyright © 2004-2009,2012 by David Jarvie <djarvie@kde.org>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 #include "specialactions.h"
24 #include "autoqpointer.h"
26 #include "functions.h"
27 #include "shellprocess.h"
29 #include <KLocalizedString>
30 #include <KConfigGroup>
34 #include <QHBoxLayout>
35 #include <QVBoxLayout>
36 #include <QResizeEvent>
37 #include <QDialogButtonBox>
38 #include <QPushButton>
40 #include "kalarm_debug.h"
43 /*=============================================================================
44 = Class SpecialActionsButton
45 = Button to display the Special Alarm Actions dialog.
46 =============================================================================*/
48 SpecialActionsButton::SpecialActionsButton(bool enableCheckboxes
, QWidget
* parent
)
49 : QPushButton(i18nc("@action:button", "Special Actions..."), parent
),
51 mEnableCheckboxes(enableCheckboxes
),
56 connect(this, &SpecialActionsButton::clicked
, this, &SpecialActionsButton::slotButtonPressed
);
57 setWhatsThis(i18nc("@info:whatsthis", "Specify actions to execute before and after the alarm is displayed."));
60 /******************************************************************************
61 * Set the pre- and post-alarm actions.
62 * The button's pressed state is set to reflect whether any actions are set.
64 void SpecialActionsButton::setActions(const QString
& pre
, const QString
& post
, KAEvent::ExtraActionOptions options
)
69 setChecked(!mPreAction
.isEmpty() || !mPostAction
.isEmpty());
72 /******************************************************************************
73 * Called when the OK button is clicked.
74 * Display a font and colour selection dialog and get the selections.
76 void SpecialActionsButton::slotButtonPressed()
78 // Use AutoQPointer to guard against crash on application exit while
79 // the dialogue is still open. It prevents double deletion (both on
80 // deletion of SpecialActionsButton, and on return from this function).
81 AutoQPointer
<SpecialActionsDlg
> dlg
= new SpecialActionsDlg(mPreAction
, mPostAction
, mOptions
, mEnableCheckboxes
, this);
82 dlg
->setReadOnly(mReadOnly
);
83 if (dlg
->exec() == QDialog::Accepted
)
85 mPreAction
= dlg
->preAction();
86 mPostAction
= dlg
->postAction();
87 mOptions
= dlg
->options();
91 setChecked(!mPreAction
.isEmpty() || !mPostAction
.isEmpty());
95 /*=============================================================================
96 = Class SpecialActionsDlg
97 = Pre- and post-alarm actions dialog.
98 =============================================================================*/
100 static const char SPEC_ACT_DIALOG_NAME
[] = "SpecialActionsDialog";
103 SpecialActionsDlg::SpecialActionsDlg(const QString
& preAction
, const QString
& postAction
,
104 KAEvent::ExtraActionOptions options
, bool enableCheckboxes
,
108 setWindowTitle(i18nc("@title:window", "Special Alarm Actions"));
109 QVBoxLayout
* mainLayout
= new QVBoxLayout
;
110 setLayout(mainLayout
);
112 QWidget
* page
= new QWidget(this);
113 mainLayout
->addWidget(page
);
114 QVBoxLayout
* layout
= new QVBoxLayout(page
);
115 layout
->setMargin(0);
117 mActions
= new SpecialActions(enableCheckboxes
, page
);
118 layout
->addWidget(mActions
);
119 mActions
->setActions(preAction
, postAction
, options
);
121 QDialogButtonBox
* buttonBox
= new QDialogButtonBox(QDialogButtonBox::Ok
|QDialogButtonBox::Cancel
);
122 mainLayout
->addWidget(buttonBox
);
123 QPushButton
* okButton
= buttonBox
->button(QDialogButtonBox::Ok
);
124 okButton
->setDefault(true);
125 okButton
->setShortcut(Qt::CTRL
| Qt::Key_Return
);
126 connect(buttonBox
, &QDialogButtonBox::rejected
, this, &SpecialActionsDlg::reject
);
127 connect(okButton
, &QPushButton::clicked
, this, &SpecialActionsDlg::slotOk
);
130 if (KAlarm::readConfigWindowSize(SPEC_ACT_DIALOG_NAME
, s
))
134 /******************************************************************************
135 * Called when the OK button is clicked.
137 void SpecialActionsDlg::slotOk()
139 if (mActions
->isReadOnly())
144 /******************************************************************************
145 * Called when the dialog's size has changed.
146 * Records the new size in the config file.
148 void SpecialActionsDlg::resizeEvent(QResizeEvent
* re
)
151 KAlarm::writeConfigWindowSize(SPEC_ACT_DIALOG_NAME
, re
->size());
152 QDialog::resizeEvent(re
);
156 /*=============================================================================
157 = Class SpecialActions
158 = Pre- and post-alarm actions widget.
159 =============================================================================*/
161 SpecialActions::SpecialActions(bool enableCheckboxes
, QWidget
* parent
)
163 mEnableCheckboxes(enableCheckboxes
),
166 QVBoxLayout
* topLayout
= new QVBoxLayout(this);
167 topLayout
->setMargin(0);
170 QGroupBox
* group
= new QGroupBox(i18nc("@title:group", "Pre-Alarm Action"), this);
171 topLayout
->addWidget(group
);
172 QVBoxLayout
* vlayout
= new QVBoxLayout(group
);
174 QWidget
* box
= new QWidget(group
); // this is to control the QWhatsThis text display area
175 vlayout
->addWidget(box
);
176 QHBoxLayout
* boxLayout
= new QHBoxLayout(box
);
177 boxLayout
->setMargin(0);
178 QLabel
* label
= new QLabel(i18nc("@label:textbox", "Command:"), box
);
179 boxLayout
->addWidget(label
);
180 mPreAction
= new QLineEdit(box
);
181 boxLayout
->addWidget(mPreAction
);
182 label
->setBuddy(mPreAction
);
183 connect(mPreAction
, &QLineEdit::textChanged
, this, &SpecialActions::slotPreActionChanged
);
184 box
->setWhatsThis(xi18nc("@info:whatsthis",
185 "<para>Enter a shell command to execute before the alarm is displayed.</para>"
186 "<para>Note that it is executed only when the alarm proper is displayed, not when a reminder or deferred alarm is displayed.</para>"
187 "<para><note>KAlarm will wait for the command to complete before displaying the alarm.</note></para>"));
188 boxLayout
->setStretchFactor(mPreAction
, 1);
190 // Cancel if error in pre-alarm action
191 mExecOnDeferral
= new CheckBox(i18nc("@option:check", "Execute for deferred alarms"), group
);
192 mExecOnDeferral
->setWhatsThis(xi18nc("@info:whatsthis", "<para>If unchecked, the command is only executed before the alarm proper is displayed.</para>"
193 "<para>If checked, the pre-alarm command is also executed before a deferred alarm is displayed.</para>"));
194 vlayout
->addWidget(mExecOnDeferral
, 0, Qt::AlignLeft
);
196 mCancelOnError
= new CheckBox(i18nc("@option:check", "Cancel alarm on error"), group
);
197 mCancelOnError
->setWhatsThis(i18nc("@info:whatsthis", "Cancel the alarm if the pre-alarm command fails, i.e. do not display the alarm or execute any post-alarm action command."));
198 vlayout
->addWidget(mCancelOnError
, 0, Qt::AlignLeft
);
200 mDontShowError
= new CheckBox(i18nc("@option:check", "Do not notify errors"), group
);
201 mDontShowError
->setWhatsThis(i18nc("@info:whatsthis", "Do not show error status or error message if the pre-alarm command fails."));
202 vlayout
->addWidget(mDontShowError
, 0, Qt::AlignLeft
);
205 group
= new QGroupBox(i18nc("@title:group", "Post-Alarm Action"), this);
206 topLayout
->addWidget(group
);
207 vlayout
= new QVBoxLayout(group
);
209 box
= new QWidget(group
); // this is to control the QWhatsThis text display area
210 vlayout
->addWidget(box
);
211 boxLayout
= new QHBoxLayout(box
);
212 boxLayout
->setMargin(0);
213 label
= new QLabel(i18nc("@label:textbox", "Command:"), box
);
214 boxLayout
->addWidget(label
);
215 mPostAction
= new QLineEdit(box
);
216 boxLayout
->addWidget(mPostAction
);
217 label
->setBuddy(mPostAction
);
218 box
->setWhatsThis(xi18nc("@info:whatsthis",
219 "<para>Enter a shell command to execute after the alarm window is closed.</para>"
220 "<para>Note that it is not executed after closing a reminder window. If you defer "
221 "the alarm, it is not executed until the alarm is finally acknowledged or closed.</para>"));
222 boxLayout
->setStretchFactor(mPostAction
, 1);
224 mExecOnDeferral
->setEnabled(enableCheckboxes
);
225 mCancelOnError
->setEnabled(enableCheckboxes
);
226 mDontShowError
->setEnabled(enableCheckboxes
);
229 void SpecialActions::setActions(const QString
& pre
, const QString
& post
, KAEvent::ExtraActionOptions options
)
231 mPreAction
->setText(pre
);
232 mPostAction
->setText(post
);
233 mExecOnDeferral
->setChecked(options
& KAEvent::ExecPreActOnDeferral
);
234 mCancelOnError
->setChecked(options
& KAEvent::CancelOnPreActError
);
235 mDontShowError
->setChecked(options
& KAEvent::DontShowPreActError
);
238 QString
SpecialActions::preAction() const
240 return mPreAction
->text();
243 QString
SpecialActions::postAction() const
245 return mPostAction
->text();
248 KAEvent::ExtraActionOptions
SpecialActions::options() const
250 KAEvent::ExtraActionOptions opts
= 0;
251 if (mExecOnDeferral
->isChecked()) opts
|= KAEvent::ExecPreActOnDeferral
;
252 if (mCancelOnError
->isChecked()) opts
|= KAEvent::CancelOnPreActError
;
253 if (mDontShowError
->isChecked()) opts
|= KAEvent::DontShowPreActError
;
257 void SpecialActions::setReadOnly(bool ro
)
260 mPreAction
->setReadOnly(mReadOnly
);
261 mPostAction
->setReadOnly(mReadOnly
);
262 mExecOnDeferral
->setReadOnly(mReadOnly
);
263 mCancelOnError
->setReadOnly(mReadOnly
);
264 mDontShowError
->setReadOnly(mReadOnly
);
267 void SpecialActions::slotPreActionChanged(const QString
& text
)
269 if (!mEnableCheckboxes
)
271 bool textValid
= !text
.isEmpty();
272 mExecOnDeferral
->setEnabled(textValid
);
273 mCancelOnError
->setEnabled(textValid
);
274 mDontShowError
->setEnabled(textValid
);