2 * editdlgtypes.cpp - dialogs to create or edit alarm or alarm template types
4 * Copyright © 2001-2014 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 "editdlgtypes.h"
23 #include "editdlg_p.h"
25 #include "autoqpointer.h"
26 #include "buttongroup.h"
28 #include "colourbutton.h"
29 #include "emailidcombo.h"
30 #include "fontcolourbutton.h"
31 #include "functions.h"
32 #include "kalarmapp.h"
34 #include "latecancel.h"
36 #include "mainwindow.h"
37 #include "messagebox.h"
38 #include "messagewin.h"
39 #include "pickfileradio.h"
40 #include "preferences.h"
41 #include "radiobutton.h"
43 #include "shellprocess.h"
44 #include "soundpicker.h"
46 #include "specialactions.h"
47 #include "templatepickdlg.h"
48 #include "timespinbox.h"
50 #include <kalarmcal/identities.h>
52 #include <Akonadi/Contact/EmailAddressSelectionDialog>
53 #include <KCalCore/Person>
54 #include <KCalUtils/kcalutils/icaldrag.h>
55 using namespace KCalCore
;
57 #include <KLocalizedString>
58 #include <kfileitem.h>
65 #include <QGridLayout>
66 #include <QHBoxLayout>
67 #include <QVBoxLayout>
68 #include <QDragEnterEvent>
69 #include <QStandardItemModel>
70 #include "kalarm_debug.h"
72 using namespace KAlarmCal
;
74 enum { tTEXT
, tFILE
, tCOMMAND
}; // order of mTypeCombo items
77 /*=============================================================================
78 = Class PickLogFileRadio
79 =============================================================================*/
80 class PickLogFileRadio
: public PickFileRadio
83 PickLogFileRadio(QPushButton
* b
, LineEdit
* e
, const QString
& text
, ButtonGroup
* group
, QWidget
* parent
)
84 : PickFileRadio(b
, e
, text
, group
, parent
) { }
85 QString
pickFile() Q_DECL_OVERRIDE
// called when browse button is pressed to select a log file
87 return KAlarm::browseFile(i18nc("@title:window", "Choose Log File"), mDefaultDir
, fileEdit()->text(), QString(),
88 KFile::LocalOnly
, parentWidget());
91 QString mDefaultDir
; // default directory for log file browse button
95 /*=============================================================================
96 = Class EditDisplayAlarmDlg
97 = Dialog to edit display alarms.
98 =============================================================================*/
100 QString
EditDisplayAlarmDlg::i18n_chk_ConfirmAck() { return i18nc("@option:check", "Confirm acknowledgment"); }
103 /******************************************************************************
106 * Template = true to edit/create an alarm template
107 * = false to edit/create an alarm.
108 * event != to initialise the dialog to show the specified event's data.
110 EditDisplayAlarmDlg::EditDisplayAlarmDlg(bool Template
, QWidget
* parent
, GetResourceType getResource
)
111 : EditAlarmDlg(Template
, KAEvent::MESSAGE
, parent
, getResource
),
112 mSpecialActionsButton(Q_NULLPTR
),
113 mReminderDeferral(false),
114 mReminderArchived(false)
116 qCDebug(KALARM_LOG
) << "New";
120 EditDisplayAlarmDlg::EditDisplayAlarmDlg(bool Template
, const KAEvent
* event
, bool newAlarm
, QWidget
* parent
,
121 GetResourceType getResource
, bool readOnly
)
122 : EditAlarmDlg(Template
, event
, newAlarm
, parent
, getResource
, readOnly
),
123 mSpecialActionsButton(Q_NULLPTR
),
124 mReminderDeferral(false),
125 mReminderArchived(false)
127 qCDebug(KALARM_LOG
) << "Event.id()";
131 /******************************************************************************
132 * Return the window caption.
134 QString
EditDisplayAlarmDlg::type_caption() const
136 return isTemplate() ? (isNewAlarm() ? i18nc("@title:window", "New Display Alarm Template") : i18nc("@title:window", "Edit Display Alarm Template"))
137 : (isNewAlarm() ? i18nc("@title:window", "New Display Alarm") : i18nc("@title:window", "Edit Display Alarm"));
140 /******************************************************************************
141 * Set up the dialog controls common to display alarms.
143 void EditDisplayAlarmDlg::type_init(QWidget
* parent
, QVBoxLayout
* frameLayout
)
145 // Display type combo box
146 QWidget
* box
= new QWidget(parent
); // to group widgets for QWhatsThis text
148 QHBoxLayout
* boxHLayout
= new QHBoxLayout(box
);
149 boxHLayout
->setMargin(0);
150 QLabel
* label
= new QLabel(i18nc("@label:listbox", "Display type:"), box
);
151 boxHLayout
->addWidget(label
);
152 label
->setFixedSize(label
->sizeHint());
153 mTypeCombo
= new ComboBox(box
);
154 boxHLayout
->addWidget(mTypeCombo
);
155 QString textItem
= i18nc("@item:inlistbox", "Text message");
156 QString fileItem
= i18nc("@item:inlistbox", "File contents");
157 QString commandItem
= i18nc("@item:inlistbox", "Command output");
158 mTypeCombo
->addItem(textItem
); // index = tTEXT
159 mTypeCombo
->addItem(fileItem
); // index = tFILE
160 mTypeCombo
->addItem(commandItem
); // index = tCOMMAND
161 mTypeCombo
->setFixedSize(mTypeCombo
->sizeHint());
162 mTypeCombo
->setCurrentIndex(-1); // ensure slotAlarmTypeChanged() is called when index is set
163 if (!ShellProcess::authorised())
165 // User not authorised to issue shell commands - disable Command Output option
166 QStandardItemModel
* model
= qobject_cast
<QStandardItemModel
*>(mTypeCombo
->model());
169 QModelIndex index
= model
->index(2, mTypeCombo
->modelColumn(), mTypeCombo
->rootModelIndex());
170 QStandardItem
* item
= model
->itemFromIndex(index
);
172 item
->setEnabled(false);
175 connect(mTypeCombo
, static_cast<void (ComboBox::*)(int)>(&ComboBox::currentIndexChanged
), this, &EditDisplayAlarmDlg::slotAlarmTypeChanged
);
176 connect(mTypeCombo
, static_cast<void (ComboBox::*)(int)>(&ComboBox::currentIndexChanged
), this, &EditDisplayAlarmDlg::contentsChanged
);
177 label
->setBuddy(mTypeCombo
);
178 box
->setWhatsThis(xi18nc("@info:whatsthis", "<para>Select what the alarm should display:"
179 "<list><item><interface>%1</interface>: the alarm will display the text message you type in.</item>"
180 "<item><interface>%2</interface>: the alarm will display the contents of a text or image file.</item>"
181 "<item><interface>%3</interface>: the alarm will display the output from a command.</item></list></para>",
182 textItem
, fileItem
, commandItem
));
183 boxHLayout
->setStretchFactor(new QWidget(box
), 1); // left adjust the control
184 frameLayout
->addWidget(box
);
186 // Text message edit box
187 mTextMessageEdit
= new TextEdit(parent
);
188 mTextMessageEdit
->setLineWrapMode(KTextEdit::NoWrap
);
189 mTextMessageEdit
->setWhatsThis(i18nc("@info:whatsthis", "Enter the text of the alarm message. It may be multi-line."));
190 connect(mTextMessageEdit
, &TextEdit::textChanged
, this, &EditDisplayAlarmDlg::contentsChanged
);
191 frameLayout
->addWidget(mTextMessageEdit
);
193 // File name edit box
194 mFileBox
= new QWidget(parent
);
195 frameLayout
->addWidget(mFileBox
);
196 QHBoxLayout
* fileBoxHLayout
= new QHBoxLayout(mFileBox
);
197 fileBoxHLayout
->setMargin(0);
198 fileBoxHLayout
->setSpacing(0);
199 mFileMessageEdit
= new LineEdit(LineEdit::Url
, mFileBox
);
200 fileBoxHLayout
->addWidget(mFileMessageEdit
);
201 mFileMessageEdit
->setAcceptDrops(true);
202 mFileMessageEdit
->setWhatsThis(i18nc("@info:whatsthis", "Enter the name or URL of a text or image file to display."));
203 connect(mFileMessageEdit
, &LineEdit::textChanged
, this, &EditDisplayAlarmDlg::contentsChanged
);
205 // File browse button
206 mFileBrowseButton
= new QPushButton(mFileBox
);
207 fileBoxHLayout
->addWidget(mFileBrowseButton
);
208 mFileBrowseButton
->setIcon(QIcon::fromTheme(QStringLiteral("document-open")));
209 int size
= mFileBrowseButton
->sizeHint().height();
210 mFileBrowseButton
->setFixedSize(size
, size
);
211 mFileBrowseButton
->setToolTip(i18nc("@info:tooltip", "Choose a file"));
212 mFileBrowseButton
->setWhatsThis(i18nc("@info:whatsthis", "Select a text or image file to display."));
213 connect(mFileBrowseButton
, &QPushButton::clicked
, this, &EditDisplayAlarmDlg::slotPickFile
);
215 // Command type checkbox and edit box
216 mCmdEdit
= new CommandEdit(parent
);
217 connect(mCmdEdit
, &CommandEdit::scriptToggled
, this, &EditDisplayAlarmDlg::slotCmdScriptToggled
);
218 connect(mCmdEdit
, &CommandEdit::changed
, this, &EditDisplayAlarmDlg::contentsChanged
);
219 frameLayout
->addWidget(mCmdEdit
);
221 // Sound checkbox and file selector
222 QHBoxLayout
* hlayout
= new QHBoxLayout();
223 hlayout
->setMargin(0);
224 frameLayout
->addLayout(hlayout
);
225 mSoundPicker
= new SoundPicker(parent
);
226 mSoundPicker
->setFixedSize(mSoundPicker
->sizeHint());
227 connect(mSoundPicker
, &SoundPicker::changed
, this, &EditDisplayAlarmDlg::contentsChanged
);
228 hlayout
->addWidget(mSoundPicker
);
229 hlayout
->addSpacing(2 * style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing
));
230 hlayout
->addStretch();
232 // Font and colour choice button and sample text
233 mFontColourButton
= new FontColourButton(parent
);
234 mFontColourButton
->setMaximumHeight(mFontColourButton
->sizeHint().height() * 3/2);
235 hlayout
->addWidget(mFontColourButton
);
236 connect(mFontColourButton
, &FontColourButton::selected
, this, &EditDisplayAlarmDlg::setColours
);
237 connect(mFontColourButton
, &FontColourButton::selected
, this, &EditDisplayAlarmDlg::contentsChanged
);
239 if (ShellProcess::authorised()) // don't display if shell commands not allowed (e.g. kiosk mode)
241 // Special actions button
242 mSpecialActionsButton
= new SpecialActionsButton(false, parent
);
243 mSpecialActionsButton
->setFixedSize(mSpecialActionsButton
->sizeHint());
244 connect(mSpecialActionsButton
, &SpecialActionsButton::selected
, this, &EditDisplayAlarmDlg::contentsChanged
);
245 frameLayout
->addWidget(mSpecialActionsButton
, 0, Qt::AlignRight
);
248 // Top-adjust the controls
249 mFilePadding
= new QWidget(parent
);
250 hlayout
= new QHBoxLayout(mFilePadding
);
251 hlayout
->setMargin(0);
252 hlayout
->setSpacing(0);
253 frameLayout
->addWidget(mFilePadding
);
254 frameLayout
->setStretchFactor(mFilePadding
, 1);
257 /******************************************************************************
258 * Create a reminder control.
260 Reminder
* EditDisplayAlarmDlg::createReminder(QWidget
* parent
)
262 static const QString reminderText
= i18nc("@info:whatsthis", "Enter how long in advance of or after the main alarm to display a reminder alarm.");
263 return new Reminder(i18nc("@info:whatsthis", "Check to additionally display a reminder in advance of or after the main alarm time(s)."),
264 xi18nc("@info:whatsthis", "<para>Enter how long in advance of or after the main alarm to display a reminder alarm.</para><para>%1</para>", TimeSpinBox::shiftWhatsThis()),
265 i18nc("@info:whatsthis", "Select whether the reminder should be triggered before or after the main alarm"),
269 /******************************************************************************
270 * Create an "acknowledgement confirmation required" checkbox.
272 CheckBox
* EditDisplayAlarmDlg::createConfirmAckCheckbox(QWidget
* parent
)
274 CheckBox
* confirmAck
= new CheckBox(i18n_chk_ConfirmAck(), parent
);
275 confirmAck
->setWhatsThis(i18nc("@info:whatsthis", "Check to be prompted for confirmation when you acknowledge the alarm."));
279 /******************************************************************************
280 * Initialise the dialog controls from the specified event.
282 void EditDisplayAlarmDlg::type_initValues(const KAEvent
* event
)
284 mKMailSerialNumber
= 0;
285 lateCancel()->showAutoClose(true);
288 if (mAlarmType
== KAEvent::MESSAGE
&& event
->kmailSerialNumber()
289 && AlarmText::checkIfEmail(event
->cleanText()))
290 mKMailSerialNumber
= event
->kmailSerialNumber();
291 lateCancel()->setAutoClose(event
->autoClose());
292 if (event
->useDefaultFont())
293 mFontColourButton
->setDefaultFont();
295 mFontColourButton
->setFont(event
->font());
296 mFontColourButton
->setBgColour(event
->bgColour());
297 mFontColourButton
->setFgColour(event
->fgColour());
298 setColours(event
->fgColour(), event
->bgColour());
299 mConfirmAck
->setChecked(event
->confirmAck());
300 bool recurs
= event
->recurs();
301 int reminderMins
= event
->reminderMinutes();
302 if (reminderMins
> 0 && !event
->reminderActive())
303 reminderMins
= 0; // don't show advance reminder which has already passed
306 if (event
->reminderDeferral() && !recurs
)
308 reminderMins
= event
->deferDateTime().minsTo(event
->mainDateTime());
309 mReminderDeferral
= true;
311 else if (event
->reminderMinutes() && recurs
)
313 reminderMins
= event
->reminderMinutes();
314 mReminderArchived
= true;
317 reminder()->setMinutes(reminderMins
, dateOnly());
318 reminder()->setOnceOnly(event
->reminderOnceOnly());
319 reminder()->enableOnceOnly(recurs
);
320 if (mSpecialActionsButton
)
321 mSpecialActionsButton
->setActions(event
->preAction(), event
->postAction(), event
->extraActionOptions());
322 Preferences::SoundType soundType
= event
->speak() ? Preferences::Sound_Speak
323 : event
->beep() ? Preferences::Sound_Beep
324 : !event
->audioFile().isEmpty() ? Preferences::Sound_File
325 : Preferences::Sound_None
;
326 mSoundPicker
->set(soundType
, event
->audioFile(), event
->soundVolume(),
327 event
->fadeVolume(), event
->fadeSeconds(), event
->repeatSoundPause());
331 // Set the values to their defaults
332 if (!ShellProcess::authorised())
334 // Don't allow shell commands in kiosk mode
335 if (mSpecialActionsButton
)
336 mSpecialActionsButton
->setEnabled(false);
338 lateCancel()->setAutoClose(Preferences::defaultAutoClose());
339 mTypeCombo
->setCurrentIndex(0);
340 mFontColourButton
->setDefaultFont();
341 mFontColourButton
->setBgColour(Preferences::defaultBgColour());
342 mFontColourButton
->setFgColour(Preferences::defaultFgColour());
343 setColours(Preferences::defaultFgColour(), Preferences::defaultBgColour());
344 mConfirmAck
->setChecked(Preferences::defaultConfirmAck());
345 reminder()->setMinutes(0, false);
346 reminder()->enableOnceOnly(isTimedRecurrence()); // must be called after mRecurrenceEdit is set up
347 if (mSpecialActionsButton
)
349 KAEvent::ExtraActionOptions
opts(Q_NULLPTR
);
350 if (Preferences::defaultExecPreActionOnDeferral())
351 opts
|= KAEvent::ExecPreActOnDeferral
;
352 if (Preferences::defaultCancelOnPreActionError())
353 opts
|= KAEvent::CancelOnPreActError
;
354 if (Preferences::defaultDontShowPreActionError())
355 opts
|= KAEvent::DontShowPreActError
;
356 mSpecialActionsButton
->setActions(Preferences::defaultPreAction(), Preferences::defaultPostAction(), opts
);
358 mSoundPicker
->set(Preferences::defaultSoundType(), Preferences::defaultSoundFile(),
359 Preferences::defaultSoundVolume(), -1, 0, (Preferences::defaultSoundRepeat() ? 0 : -1));
363 /******************************************************************************
364 * Called when the More/Less Options button is clicked.
365 * Show/hide the optional options.
367 void EditDisplayAlarmDlg::type_showOptions(bool more
)
369 if (mSpecialActionsButton
)
372 mSpecialActionsButton
->show();
374 mSpecialActionsButton
->hide();
378 /******************************************************************************
379 * Called when the font/color button has been clicked.
380 * Set the colors in the message text entry control.
382 void EditDisplayAlarmDlg::setColours(const QColor
& fgColour
, const QColor
& bgColour
)
384 QPalette pal
= mTextMessageEdit
->palette();
385 pal
.setColor(mTextMessageEdit
->backgroundRole(), bgColour
);
386 pal
.setColor(QPalette::Text
, fgColour
);
387 mTextMessageEdit
->setPalette(pal
);
388 pal
= mTextMessageEdit
->viewport()->palette();
389 pal
.setColor(mTextMessageEdit
->viewport()->backgroundRole(), bgColour
);
390 pal
.setColor(QPalette::Text
, fgColour
);
391 mTextMessageEdit
->viewport()->setPalette(pal
);
392 // Change the color of existing text
393 QTextCursor cursor
= mTextMessageEdit
->textCursor();
394 mTextMessageEdit
->selectAll();
395 mTextMessageEdit
->setTextColor(fgColour
);
396 mTextMessageEdit
->setTextCursor(cursor
);
399 /******************************************************************************
400 * Set the dialog's action and the action's text.
402 void EditDisplayAlarmDlg::setAction(KAEvent::SubAction action
, const AlarmText
& alarmText
)
404 QString text
= alarmText
.displayText();
407 case KAEvent::MESSAGE
:
408 mTypeCombo
->setCurrentIndex(tTEXT
);
409 mTextMessageEdit
->setPlainText(text
);
410 mKMailSerialNumber
= alarmText
.isEmail() ? alarmText
.kmailSerialNumber() : 0;
413 mTypeCombo
->setCurrentIndex(tFILE
);
414 mFileMessageEdit
->setText(text
);
416 case KAEvent::COMMAND
:
417 mTypeCombo
->setCurrentIndex(tCOMMAND
);
418 mCmdEdit
->setText(alarmText
);
426 /******************************************************************************
427 * Initialise various values in the New Alarm dialogue.
429 void EditDisplayAlarmDlg::setBgColour(const QColor
& colour
)
431 mFontColourButton
->setBgColour(colour
);
432 setColours(mFontColourButton
->fgColour(), colour
);
434 void EditDisplayAlarmDlg::setFgColour(const QColor
& colour
)
436 mFontColourButton
->setFgColour(colour
);
437 setColours(colour
, mFontColourButton
->bgColour());
439 void EditDisplayAlarmDlg::setConfirmAck(bool confirm
)
441 mConfirmAck
->setChecked(confirm
);
443 void EditDisplayAlarmDlg::setAutoClose(bool close
)
445 lateCancel()->setAutoClose(close
);
447 void EditDisplayAlarmDlg::setAudio(Preferences::SoundType type
, const QString
& file
, float volume
, int repeatPause
)
449 mSoundPicker
->set(type
, file
, volume
, -1, 0, repeatPause
);
451 void EditDisplayAlarmDlg::setReminder(int minutes
, bool onceOnly
)
453 reminder()->setMinutes(minutes
, dateOnly());
454 reminder()->setOnceOnly(onceOnly
);
455 reminder()->enableOnceOnly(isTimedRecurrence());
458 /******************************************************************************
459 * Set the read-only status of all non-template controls.
461 void EditDisplayAlarmDlg::setReadOnly(bool readOnly
)
463 mTypeCombo
->setReadOnly(readOnly
);
464 mTextMessageEdit
->setReadOnly(readOnly
);
465 mFileMessageEdit
->setReadOnly(readOnly
);
466 mCmdEdit
->setReadOnly(readOnly
);
467 mFontColourButton
->setReadOnly(readOnly
);
468 mSoundPicker
->setReadOnly(readOnly
);
469 mConfirmAck
->setReadOnly(readOnly
);
470 reminder()->setReadOnly(readOnly
);
471 if (mSpecialActionsButton
)
472 mSpecialActionsButton
->setReadOnly(readOnly
);
474 mFileBrowseButton
->hide();
476 mFileBrowseButton
->show();
477 EditAlarmDlg::setReadOnly(readOnly
);
480 /******************************************************************************
481 * Save the state of all controls.
483 void EditDisplayAlarmDlg::saveState(const KAEvent
* event
)
485 EditAlarmDlg::saveState(event
);
486 mSavedType
= mTypeCombo
->currentIndex();
487 mSavedCmdScript
= mCmdEdit
->isScript();
488 mSavedSoundType
= mSoundPicker
->sound();
489 mSavedSoundFile
= mSoundPicker
->file();
490 mSavedSoundVolume
= mSoundPicker
->volume(mSavedSoundFadeVolume
, mSavedSoundFadeSeconds
);
491 mSavedRepeatPause
= mSoundPicker
->repeatPause();
492 mSavedConfirmAck
= mConfirmAck
->isChecked();
493 mSavedFont
= mFontColourButton
->font();
494 mSavedFgColour
= mFontColourButton
->fgColour();
495 mSavedBgColour
= mFontColourButton
->bgColour();
496 mSavedReminder
= reminder()->minutes();
497 mSavedOnceOnly
= reminder()->isOnceOnly();
498 mSavedAutoClose
= lateCancel()->isAutoClose();
499 if (mSpecialActionsButton
)
501 mSavedPreAction
= mSpecialActionsButton
->preAction();
502 mSavedPostAction
= mSpecialActionsButton
->postAction();
503 mSavedPreActionOptions
= mSpecialActionsButton
->options();
507 /******************************************************************************
508 * Check whether any of the controls has changed state since the dialog was
510 * Reply = true if any controls have changed, or if it's a new event.
511 * = false if no controls have changed.
513 bool EditDisplayAlarmDlg::type_stateChanged() const
515 if (mSavedType
!= mTypeCombo
->currentIndex()
516 || mSavedCmdScript
!= mCmdEdit
->isScript()
517 || mSavedSoundType
!= mSoundPicker
->sound()
518 || mSavedConfirmAck
!= mConfirmAck
->isChecked()
519 || mSavedFont
!= mFontColourButton
->font()
520 || mSavedFgColour
!= mFontColourButton
->fgColour()
521 || mSavedBgColour
!= mFontColourButton
->bgColour()
522 || mSavedReminder
!= reminder()->minutes()
523 || mSavedOnceOnly
!= reminder()->isOnceOnly()
524 || mSavedAutoClose
!= lateCancel()->isAutoClose())
526 if (mSpecialActionsButton
)
528 if (mSavedPreAction
!= mSpecialActionsButton
->preAction()
529 || mSavedPostAction
!= mSpecialActionsButton
->postAction()
530 || mSavedPreActionOptions
!= mSpecialActionsButton
->options())
533 if (mSavedSoundType
== Preferences::Sound_File
)
535 if (mSavedSoundFile
!= mSoundPicker
->file())
537 if (!mSavedSoundFile
.isEmpty())
541 if (mSavedRepeatPause
!= mSoundPicker
->repeatPause()
542 || mSavedSoundVolume
!= mSoundPicker
->volume(fadeVolume
, fadeSecs
)
543 || mSavedSoundFadeVolume
!= fadeVolume
544 || mSavedSoundFadeSeconds
!= fadeSecs
)
551 /******************************************************************************
552 * Extract the data in the dialog specific to the alarm type and set up a
555 void EditDisplayAlarmDlg::type_setEvent(KAEvent
& event
, const KDateTime
& dt
, const QString
& text
, int lateCancel
, bool trial
)
557 KAEvent::SubAction type
;
558 switch (mTypeCombo
->currentIndex())
560 case tFILE
: type
= KAEvent::FILE; break;
561 case tCOMMAND
: type
= KAEvent::COMMAND
; break;
563 case tTEXT
: type
= KAEvent::MESSAGE
; break;
565 event
.set(dt
, text
, mFontColourButton
->bgColour(), mFontColourButton
->fgColour(), mFontColourButton
->font(),
566 type
, lateCancel
, getAlarmFlags());
567 if (type
== KAEvent::MESSAGE
)
569 if (AlarmText::checkIfEmail(text
))
570 event
.setKMailSerialNumber(mKMailSerialNumber
);
574 float volume
= mSoundPicker
->volume(fadeVolume
, fadeSecs
);
575 int repeatPause
= mSoundPicker
->repeatPause();
576 event
.setAudioFile(mSoundPicker
->file().toDisplayString(), volume
, fadeVolume
, fadeSecs
, repeatPause
);
577 if (!trial
&& reminder()->isEnabled())
578 event
.setReminder(reminder()->minutes(), reminder()->isOnceOnly());
579 if (mSpecialActionsButton
&& mSpecialActionsButton
->isEnabled())
580 event
.setActions(mSpecialActionsButton
->preAction(), mSpecialActionsButton
->postAction(),
581 mSpecialActionsButton
->options());
584 /******************************************************************************
585 * Get the currently specified alarm flag bits.
587 KAEvent::Flags
EditDisplayAlarmDlg::getAlarmFlags() const
589 bool cmd
= (mTypeCombo
->currentIndex() == tCOMMAND
);
590 KAEvent::Flags flags
= EditAlarmDlg::getAlarmFlags();
591 if (mSoundPicker
->sound() == Preferences::Sound_Beep
) flags
|= KAEvent::BEEP
;
592 if (mSoundPicker
->sound() == Preferences::Sound_Speak
) flags
|= KAEvent::SPEAK
;
593 if (mSoundPicker
->repeatPause() >= 0) flags
|= KAEvent::REPEAT_SOUND
;
594 if (mConfirmAck
->isChecked()) flags
|= KAEvent::CONFIRM_ACK
;
595 if (lateCancel()->isAutoClose()) flags
|= KAEvent::AUTO_CLOSE
;
596 if (mFontColourButton
->defaultFont()) flags
|= KAEvent::DEFAULT_FONT
;
597 if (cmd
) flags
|= KAEvent::DISPLAY_COMMAND
;
598 if (cmd
&& mCmdEdit
->isScript()) flags
|= KAEvent::SCRIPT
;
602 /******************************************************************************
603 * Called when one of the alarm display type combo box is changed, to display
604 * the appropriate set of controls for that action type.
606 void EditDisplayAlarmDlg::slotAlarmTypeChanged(int index
)
608 QWidget
* focus
= Q_NULLPTR
;
611 case tTEXT
: // text message
613 mFilePadding
->hide();
615 mTextMessageEdit
->show();
616 mSoundPicker
->showSpeak(true);
617 mTryButton
->setWhatsThis(i18nc("@info:whatsthis", "Display the alarm message now"));
618 focus
= mTextMessageEdit
;
620 case tFILE
: // file contents
621 mTextMessageEdit
->hide();
623 mFilePadding
->show();
625 mSoundPicker
->showSpeak(false);
626 mTryButton
->setWhatsThis(i18nc("@info:whatsthis", "Display the file now"));
627 mFileMessageEdit
->setNoSelect();
628 focus
= mFileMessageEdit
;
630 case tCOMMAND
: // command output
631 mTextMessageEdit
->hide();
633 slotCmdScriptToggled(mCmdEdit
->isScript()); // show/hide mFilePadding
635 mSoundPicker
->showSpeak(true);
636 mTryButton
->setWhatsThis(i18nc("@info:whatsthis", "Display the command output now"));
644 /******************************************************************************
645 * Called when the file browse button is pressed to select a file to display.
647 void EditDisplayAlarmDlg::slotPickFile()
649 static QString defaultDir
; // default directory for file browse button
650 QString file
= KAlarm::browseFile(i18nc("@title:window", "Choose Text or Image File to Display"),
651 defaultDir
, mFileMessageEdit
->text(), QString(), KFile::ExistingOnly
, this);
654 mFileMessageEdit
->setText(KAlarm::pathOrUrl(file
));
659 /******************************************************************************
660 * Called when one of the command type radio buttons is clicked,
661 * to display the appropriate edit field.
663 void EditDisplayAlarmDlg::slotCmdScriptToggled(bool on
)
666 mFilePadding
->hide();
668 mFilePadding
->show();
671 /******************************************************************************
672 * Clean up the alarm text, and if it's a file, check whether it's valid.
674 bool EditDisplayAlarmDlg::checkText(QString
& result
, bool showErrorMessage
) const
676 switch (mTypeCombo
->currentIndex())
679 result
= mTextMessageEdit
->toPlainText();
684 QString alarmtext
= mFileMessageEdit
->text().trimmed();
686 KAlarm::FileErr err
= KAlarm::checkFileExists(alarmtext
, url
);
687 if (err
== KAlarm::FileErr_None
)
690 switch (KAlarm::fileType(fi
.currentMimeType()))
692 case KAlarm::TextFormatted
:
693 case KAlarm::TextPlain
:
694 case KAlarm::TextApplication
:
698 err
= KAlarm::FileErr_NotTextImage
;
702 if (err
!= KAlarm::FileErr_None
&& showErrorMessage
)
704 mFileMessageEdit
->setFocus();
705 if (!KAlarm::showFileErrMessage(alarmtext
, err
, KAlarm::FileErr_BlankDisplay
, const_cast<EditDisplayAlarmDlg
*>(this)))
712 result
= mCmdEdit
->text(const_cast<EditDisplayAlarmDlg
*>(this), showErrorMessage
);
713 if (result
.isEmpty())
721 /*=============================================================================
722 = Class EditCommandAlarmDlg
723 = Dialog to edit command alarms.
724 =============================================================================*/
726 QString
EditCommandAlarmDlg::i18n_chk_EnterScript() { return i18nc("@option:check", "Enter a script"); }
727 QString
EditCommandAlarmDlg::i18n_radio_ExecInTermWindow() { return i18nc("@option:radio", "Execute in terminal window"); }
728 QString
EditCommandAlarmDlg::i18n_chk_ExecInTermWindow() { return i18nc("@option:check", "Execute in terminal window"); }
731 /******************************************************************************
734 * Template = true to edit/create an alarm template
735 * = false to edit/create an alarm.
736 * event != to initialise the dialog to show the specified event's data.
738 EditCommandAlarmDlg::EditCommandAlarmDlg(bool Template
, QWidget
* parent
, GetResourceType getResource
)
739 : EditAlarmDlg(Template
, KAEvent::COMMAND
, parent
, getResource
)
741 qCDebug(KALARM_LOG
) << "New";
745 EditCommandAlarmDlg::EditCommandAlarmDlg(bool Template
, const KAEvent
* event
, bool newAlarm
, QWidget
* parent
,
746 GetResourceType getResource
, bool readOnly
)
747 : EditAlarmDlg(Template
, event
, newAlarm
, parent
, getResource
, readOnly
)
749 qCDebug(KALARM_LOG
) << "Event.id()";
753 /******************************************************************************
754 * Return the window caption.
756 QString
EditCommandAlarmDlg::type_caption() const
758 return isTemplate() ? (isNewAlarm() ? i18nc("@title:window", "New Command Alarm Template") : i18nc("@title:window", "Edit Command Alarm Template"))
759 : (isNewAlarm() ? i18nc("@title:window", "New Command Alarm") : i18nc("@title:window", "Edit Command Alarm"));
762 /******************************************************************************
763 * Set up the command alarm dialog controls.
765 void EditCommandAlarmDlg::type_init(QWidget
* parent
, QVBoxLayout
* frameLayout
)
767 mTryButton
->setWhatsThis(i18nc("@info:whatsthis", "Execute the specified command now"));
769 mCmdEdit
= new CommandEdit(parent
);
770 connect(mCmdEdit
, &CommandEdit::scriptToggled
, this, &EditCommandAlarmDlg::slotCmdScriptToggled
);
771 connect(mCmdEdit
, &CommandEdit::changed
, this, &EditCommandAlarmDlg::contentsChanged
);
772 frameLayout
->addWidget(mCmdEdit
);
774 // What to do with command output
776 mCmdOutputBox
= new QGroupBox(i18nc("@title:group", "Command Output"), parent
);
777 frameLayout
->addWidget(mCmdOutputBox
);
778 QVBoxLayout
* vlayout
= new QVBoxLayout(mCmdOutputBox
);
779 vlayout
->setMargin(style()->pixelMetric(QStyle::PM_DefaultChildMargin
));
780 vlayout
->setSpacing(style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing
));
781 mCmdOutputGroup
= new ButtonGroup(mCmdOutputBox
);
782 connect(mCmdOutputGroup
, &ButtonGroup::buttonSet
, this, &EditCommandAlarmDlg::contentsChanged
);
784 // Execute in terminal window
785 mCmdExecInTerm
= new RadioButton(i18n_radio_ExecInTermWindow(), mCmdOutputBox
);
786 mCmdExecInTerm
->setFixedSize(mCmdExecInTerm
->sizeHint());
787 mCmdExecInTerm
->setWhatsThis(i18nc("@info:whatsthis", "Check to execute the command in a terminal window"));
788 mCmdOutputGroup
->addButton(mCmdExecInTerm
, Preferences::Log_Terminal
);
789 vlayout
->addWidget(mCmdExecInTerm
, 0, Qt::AlignLeft
);
791 // Log file name edit box
792 QWidget
* box
= new QWidget(mCmdOutputBox
);
793 QHBoxLayout
* boxHLayout
= new QHBoxLayout(box
);
794 boxHLayout
->setMargin(0);
795 boxHLayout
->setSpacing(0);
796 (new QWidget(box
))->setFixedWidth(mCmdExecInTerm
->style()->pixelMetric(QStyle::PM_ExclusiveIndicatorWidth
)); // indent the edit box
797 mCmdLogFileEdit
= new LineEdit(LineEdit::Url
, box
);
798 boxHLayout
->addWidget(mCmdLogFileEdit
);
799 mCmdLogFileEdit
->setAcceptDrops(true);
800 mCmdLogFileEdit
->setWhatsThis(i18nc("@info:whatsthis", "Enter the name or path of the log file."));
801 connect(mCmdLogFileEdit
, &LineEdit::textChanged
, this, &EditCommandAlarmDlg::contentsChanged
);
803 // Log file browse button.
804 // The file browser dialog is activated by the PickLogFileRadio class.
805 QPushButton
* browseButton
= new QPushButton(box
);
806 boxHLayout
->addWidget(browseButton
);
807 browseButton
->setIcon(QIcon::fromTheme(QStringLiteral("document-open")));
808 int size
= browseButton
->sizeHint().height();
809 browseButton
->setFixedSize(size
, size
);
810 browseButton
->setToolTip(i18nc("@info:tooltip", "Choose a file"));
811 browseButton
->setWhatsThis(i18nc("@info:whatsthis", "Select a log file."));
813 // Log output to file
814 mCmdLogToFile
= new PickLogFileRadio(browseButton
, mCmdLogFileEdit
, i18nc("@option:radio", "Log to file"), mCmdOutputGroup
, mCmdOutputBox
);
815 mCmdLogToFile
->setFixedSize(mCmdLogToFile
->sizeHint());
816 mCmdLogToFile
->setWhatsThis(i18nc("@info:whatsthis", "Check to log the command output to a local file. The output will be appended to any existing contents of the file."));
817 connect(mCmdLogToFile
, &PickLogFileRadio::fileChanged
, this, &EditCommandAlarmDlg::contentsChanged
);
818 mCmdOutputGroup
->addButton(mCmdLogToFile
, Preferences::Log_File
);
819 vlayout
->addWidget(mCmdLogToFile
, 0, Qt::AlignLeft
);
820 vlayout
->addWidget(box
);
823 mCmdDiscardOutput
= new RadioButton(i18nc("@option:radio", "Discard"), mCmdOutputBox
);
824 mCmdDiscardOutput
->setFixedSize(mCmdDiscardOutput
->sizeHint());
825 mCmdDiscardOutput
->setWhatsThis(i18nc("@info:whatsthis", "Check to discard command output."));
826 mCmdOutputGroup
->addButton(mCmdDiscardOutput
, Preferences::Log_Discard
);
827 vlayout
->addWidget(mCmdDiscardOutput
, 0, Qt::AlignLeft
);
829 // Top-adjust the controls
830 mCmdPadding
= new QWidget(parent
);
831 QHBoxLayout
* hlayout
= new QHBoxLayout(mCmdPadding
);
832 hlayout
->setMargin(0);
833 hlayout
->setSpacing(0);
834 frameLayout
->addWidget(mCmdPadding
);
835 frameLayout
->setStretchFactor(mCmdPadding
, 1);
838 /******************************************************************************
839 * Initialise the dialog controls from the specified event.
841 void EditCommandAlarmDlg::type_initValues(const KAEvent
* event
)
845 // Set the values to those for the specified event
846 RadioButton
* logType
= event
->commandXterm() ? mCmdExecInTerm
847 : !event
->logFile().isEmpty() ? mCmdLogToFile
849 if (logType
== mCmdLogToFile
)
850 mCmdLogFileEdit
->setText(event
->logFile()); // set file name before setting radio button
851 logType
->setChecked(true);
855 // Set the values to their defaults
856 mCmdEdit
->setScript(Preferences::defaultCmdScript());
857 mCmdLogFileEdit
->setText(Preferences::defaultCmdLogFile()); // set file name before setting radio button
858 mCmdOutputGroup
->setButton(Preferences::defaultCmdLogType());
860 slotCmdScriptToggled(mCmdEdit
->isScript());
863 /******************************************************************************
864 * Called when the More/Less Options button is clicked.
865 * Show/hide the optional options.
867 void EditCommandAlarmDlg::type_showOptions(bool more
)
870 mCmdOutputBox
->show();
872 mCmdOutputBox
->hide();
875 /******************************************************************************
876 * Set the dialog's action and the action's text.
878 void EditCommandAlarmDlg::setAction(KAEvent::SubAction action
, const AlarmText
& alarmText
)
881 Q_ASSERT(action
== KAEvent::COMMAND
);
882 mCmdEdit
->setText(alarmText
);
885 /******************************************************************************
886 * Set the read-only status of all non-template controls.
888 void EditCommandAlarmDlg::setReadOnly(bool readOnly
)
890 if (!isTemplate() && !ShellProcess::authorised())
891 readOnly
= true; // don't allow editing of existing command alarms in kiosk mode
892 mCmdEdit
->setReadOnly(readOnly
);
893 mCmdExecInTerm
->setReadOnly(readOnly
);
894 mCmdLogToFile
->setReadOnly(readOnly
);
895 mCmdDiscardOutput
->setReadOnly(readOnly
);
896 EditAlarmDlg::setReadOnly(readOnly
);
899 /******************************************************************************
900 * Save the state of all controls.
902 void EditCommandAlarmDlg::saveState(const KAEvent
* event
)
904 EditAlarmDlg::saveState(event
);
905 mSavedCmdScript
= mCmdEdit
->isScript();
906 mSavedCmdOutputRadio
= mCmdOutputGroup
->checkedButton();
907 mSavedCmdLogFile
= mCmdLogFileEdit
->text();
910 /******************************************************************************
911 * Check whether any of the controls has changed state since the dialog was
913 * Reply = true if any controls have changed, or if it's a new event.
914 * = false if no controls have changed.
916 bool EditCommandAlarmDlg::type_stateChanged() const
918 if (mSavedCmdScript
!= mCmdEdit
->isScript()
919 || mSavedCmdOutputRadio
!= mCmdOutputGroup
->checkedButton())
921 if (mCmdOutputGroup
->checkedButton() == mCmdLogToFile
)
923 if (mSavedCmdLogFile
!= mCmdLogFileEdit
->text())
929 /******************************************************************************
930 * Extract the data in the dialog specific to the alarm type and set up a
933 void EditCommandAlarmDlg::type_setEvent(KAEvent
& event
, const KDateTime
& dt
, const QString
& text
, int lateCancel
, bool trial
)
936 event
.set(dt
, text
, QColor(), QColor(), QFont(), KAEvent::COMMAND
, lateCancel
, getAlarmFlags());
937 if (mCmdOutputGroup
->checkedButton() == mCmdLogToFile
)
938 event
.setLogFile(mCmdLogFileEdit
->text());
941 /******************************************************************************
942 * Get the currently specified alarm flag bits.
944 KAEvent::Flags
EditCommandAlarmDlg::getAlarmFlags() const
946 KAEvent::Flags flags
= EditAlarmDlg::getAlarmFlags();
947 if (mCmdEdit
->isScript()) flags
|= KAEvent::SCRIPT
;
948 if (mCmdOutputGroup
->checkedButton() == mCmdExecInTerm
) flags
|= KAEvent::EXEC_IN_XTERM
;
952 /******************************************************************************
953 * Validate and convert command alarm data.
955 bool EditCommandAlarmDlg::type_validate(bool trial
)
958 if (mCmdOutputGroup
->checkedButton() == mCmdLogToFile
)
960 // Validate the log file name
961 QString file
= mCmdLogFileEdit
->text();
962 QFileInfo
info(file
);
963 QDir::setCurrent(QDir::homePath());
964 bool err
= file
.isEmpty() || info
.isDir();
969 err
= !info
.isWritable();
973 QFileInfo
dirinfo(info
.absolutePath()); // get absolute directory path
974 err
= (!dirinfo
.isDir() || !dirinfo
.isWritable());
980 mCmdLogFileEdit
->setFocus();
981 KAMessageBox::sorry(this, i18nc("@info", "Log file must be the name or path of a local file, with write permission."));
984 // Convert the log file to an absolute path
985 mCmdLogFileEdit
->setText(info
.absoluteFilePath());
990 /******************************************************************************
991 * Called when the Try action has been executed.
992 * Tell the user the result of the Try action.
994 void EditCommandAlarmDlg::type_executedTry(const QString
& text
, void* result
)
996 ShellProcess
* proc
= (ShellProcess
*)result
;
997 if (proc
&& proc
!= (void*)-1
998 && mCmdOutputGroup
->checkedButton() != mCmdExecInTerm
)
1000 theApp()->commandMessage(proc
, this);
1001 KAMessageBox::information(this, xi18nc("@info", "Command executed: <icode>%1</icode>", text
));
1002 theApp()->commandMessage(proc
, Q_NULLPTR
);
1006 /******************************************************************************
1007 * Called when one of the command type radio buttons is clicked,
1008 * to display the appropriate edit field.
1010 void EditCommandAlarmDlg::slotCmdScriptToggled(bool on
)
1013 mCmdPadding
->hide();
1015 mCmdPadding
->show();
1018 /******************************************************************************
1019 * Clean up the alarm text.
1021 bool EditCommandAlarmDlg::checkText(QString
& result
, bool showErrorMessage
) const
1023 result
= mCmdEdit
->text(const_cast<EditCommandAlarmDlg
*>(this), showErrorMessage
);
1024 if (result
.isEmpty())
1030 /*=============================================================================
1031 = Class EditEmailAlarmDlg
1032 = Dialog to edit email alarms.
1033 =============================================================================*/
1035 QString
EditEmailAlarmDlg::i18n_chk_CopyEmailToSelf() { return i18nc("@option:check", "Copy email to self"); }
1038 /******************************************************************************
1041 * Template = true to edit/create an alarm template
1042 * = false to edit/create an alarm.
1043 * event != to initialise the dialog to show the specified event's data.
1045 EditEmailAlarmDlg::EditEmailAlarmDlg(bool Template
, QWidget
* parent
, GetResourceType getResource
)
1046 : EditAlarmDlg(Template
, KAEvent::EMAIL
, parent
, getResource
),
1047 mEmailRemoveButton(Q_NULLPTR
)
1049 qCDebug(KALARM_LOG
) << "New";
1053 EditEmailAlarmDlg::EditEmailAlarmDlg(bool Template
, const KAEvent
* event
, bool newAlarm
, QWidget
* parent
,
1054 GetResourceType getResource
, bool readOnly
)
1055 : EditAlarmDlg(Template
, event
, newAlarm
, parent
, getResource
, readOnly
),
1056 mEmailRemoveButton(Q_NULLPTR
)
1058 qCDebug(KALARM_LOG
) << "Event.id()";
1062 /******************************************************************************
1063 * Return the window caption.
1065 QString
EditEmailAlarmDlg::type_caption() const
1067 return isTemplate() ? (isNewAlarm() ? i18nc("@title:window", "New Email Alarm Template") : i18nc("@title:window", "Edit Email Alarm Template"))
1068 : (isNewAlarm() ? i18nc("@title:window", "New Email Alarm") : i18nc("@title:window", "Edit Email Alarm"));
1071 /******************************************************************************
1072 * Set up the email alarm dialog controls.
1074 void EditEmailAlarmDlg::type_init(QWidget
* parent
, QVBoxLayout
* frameLayout
)
1076 mTryButton
->setWhatsThis(i18nc("@info:whatsthis", "Send the email to the specified addressees now"));
1078 QGridLayout
* grid
= new QGridLayout();
1080 grid
->setColumnStretch(1, 1);
1081 frameLayout
->addLayout(grid
);
1083 mEmailFromList
= Q_NULLPTR
;
1084 if (Preferences::emailFrom() == Preferences::MAIL_FROM_KMAIL
)
1086 // Email sender identity
1087 QLabel
* label
= new QLabel(i18nc("@label:listbox 'From' email address", "From:"), parent
);
1088 label
->setFixedSize(label
->sizeHint());
1089 grid
->addWidget(label
, 0, 0);
1091 mEmailFromList
= new EmailIdCombo(Identities::identityManager(), parent
);
1092 mEmailFromList
->setMinimumSize(mEmailFromList
->sizeHint());
1093 label
->setBuddy(mEmailFromList
);
1094 mEmailFromList
->setWhatsThis(i18nc("@info:whatsthis", "Your email identity, used to identify you as the sender when sending email alarms."));
1095 connect(mEmailFromList
, &EmailIdCombo::identityChanged
, this, &EditEmailAlarmDlg::contentsChanged
);
1096 grid
->addWidget(mEmailFromList
, 0, 1, 1, 2);
1100 QLabel
* label
= new QLabel(i18nc("@label:textbox Email addressee", "To:"), parent
);
1101 label
->setFixedSize(label
->sizeHint());
1102 grid
->addWidget(label
, 1, 0);
1104 mEmailToEdit
= new LineEdit(LineEdit::Emails
, parent
);
1105 mEmailToEdit
->setMinimumSize(mEmailToEdit
->sizeHint());
1106 mEmailToEdit
->setWhatsThis(i18nc("@info:whatsthis", "Enter the addresses of the email recipients. Separate multiple addresses by "
1107 "commas or semicolons."));
1108 connect(mEmailToEdit
, &LineEdit::textChanged
, this, &EditEmailAlarmDlg::contentsChanged
);
1109 grid
->addWidget(mEmailToEdit
, 1, 1);
1111 mEmailAddressButton
= new QPushButton(parent
);
1112 mEmailAddressButton
->setIcon(QIcon::fromTheme(QStringLiteral("help-contents")));
1113 int size
= mEmailAddressButton
->sizeHint().height();
1114 mEmailAddressButton
->setFixedSize(size
, size
);
1115 connect(mEmailAddressButton
, &QPushButton::clicked
, this, &EditEmailAlarmDlg::openAddressBook
);
1116 mEmailAddressButton
->setToolTip(i18nc("@info:tooltip", "Open address book"));
1117 mEmailAddressButton
->setWhatsThis(i18nc("@info:whatsthis", "Select email addresses from your address book."));
1118 grid
->addWidget(mEmailAddressButton
, 1, 2);
1121 label
= new QLabel(i18nc("@label:textbox Email subject", "Subject:"), parent
);
1122 label
->setFixedSize(label
->sizeHint());
1123 grid
->addWidget(label
, 2, 0);
1125 mEmailSubjectEdit
= new LineEdit(parent
);
1126 mEmailSubjectEdit
->setMinimumSize(mEmailSubjectEdit
->sizeHint());
1127 label
->setBuddy(mEmailSubjectEdit
);
1128 mEmailSubjectEdit
->setWhatsThis(i18nc("@info:whatsthis", "Enter the email subject."));
1129 connect(mEmailSubjectEdit
, &LineEdit::textChanged
, this, &EditEmailAlarmDlg::contentsChanged
);
1130 grid
->addWidget(mEmailSubjectEdit
, 2, 1, 1, 2);
1133 mEmailMessageEdit
= new TextEdit(parent
);
1134 mEmailMessageEdit
->setWhatsThis(i18nc("@info:whatsthis", "Enter the email message."));
1135 connect(mEmailMessageEdit
, &TextEdit::textChanged
, this, &EditEmailAlarmDlg::contentsChanged
);
1136 frameLayout
->addWidget(mEmailMessageEdit
);
1138 // Email attachments
1139 grid
= new QGridLayout();
1141 frameLayout
->addLayout(grid
);
1142 label
= new QLabel(i18nc("@label:listbox", "Attachments:"), parent
);
1143 label
->setFixedSize(label
->sizeHint());
1144 grid
->addWidget(label
, 0, 0);
1146 mEmailAttachList
= new QComboBox(parent
);
1147 mEmailAttachList
->setEditable(true);
1148 mEmailAttachList
->setMinimumSize(mEmailAttachList
->sizeHint());
1149 if (mEmailAttachList
->lineEdit())
1150 mEmailAttachList
->lineEdit()->setReadOnly(true);
1151 label
->setBuddy(mEmailAttachList
);
1152 mEmailAttachList
->setWhatsThis(i18nc("@info:whatsthis", "Files to send as attachments to the email."));
1153 grid
->addWidget(mEmailAttachList
, 0, 1);
1154 grid
->setColumnStretch(1, 1);
1156 mEmailAddAttachButton
= new QPushButton(i18nc("@action:button", "Add..."), parent
);
1157 connect(mEmailAddAttachButton
, &QPushButton::clicked
, this, &EditEmailAlarmDlg::slotAddAttachment
);
1158 mEmailAddAttachButton
->setWhatsThis(i18nc("@info:whatsthis", "Add an attachment to the email."));
1159 grid
->addWidget(mEmailAddAttachButton
, 0, 2);
1161 mEmailRemoveButton
= new QPushButton(i18nc("@action:button", "Remove"), parent
);
1162 connect(mEmailRemoveButton
, &QPushButton::clicked
, this, &EditEmailAlarmDlg::slotRemoveAttachment
);
1163 mEmailRemoveButton
->setWhatsThis(i18nc("@info:whatsthis", "Remove the highlighted attachment from the email."));
1164 grid
->addWidget(mEmailRemoveButton
, 1, 2);
1166 // BCC email to sender
1167 mEmailBcc
= new CheckBox(i18n_chk_CopyEmailToSelf(), parent
);
1168 mEmailBcc
->setFixedSize(mEmailBcc
->sizeHint());
1169 mEmailBcc
->setWhatsThis(i18nc("@info:whatsthis", "If checked, the email will be blind copied to you."));
1170 connect(mEmailBcc
, &CheckBox::toggled
, this, &EditEmailAlarmDlg::contentsChanged
);
1171 grid
->addWidget(mEmailBcc
, 1, 0, 1, 2, Qt::AlignLeft
);
1174 /******************************************************************************
1175 * Initialise the dialog controls from the specified event.
1177 void EditEmailAlarmDlg::type_initValues(const KAEvent
* event
)
1181 // Set the values to those for the specified event
1182 mEmailAttachList
->addItems(event
->emailAttachments());
1183 mEmailToEdit
->setText(event
->emailAddresses(QStringLiteral(", ")));
1184 mEmailSubjectEdit
->setText(event
->emailSubject());
1185 mEmailBcc
->setChecked(event
->emailBcc());
1187 mEmailFromList
->setCurrentIdentity(event
->emailFromId());
1191 // Set the values to their defaults
1192 mEmailBcc
->setChecked(Preferences::defaultEmailBcc());
1197 /******************************************************************************
1198 * Enable/disable controls depending on whether any attachments are entered.
1200 void EditEmailAlarmDlg::attachmentEnable()
1202 bool enable
= mEmailAttachList
->count();
1203 mEmailAttachList
->setEnabled(enable
);
1204 if (mEmailRemoveButton
)
1205 mEmailRemoveButton
->setEnabled(enable
);
1208 /******************************************************************************
1209 * Set the dialog's action and the action's text.
1211 void EditEmailAlarmDlg::setAction(KAEvent::SubAction action
, const AlarmText
& alarmText
)
1214 Q_ASSERT(action
== KAEvent::EMAIL
);
1215 if (alarmText
.isEmail())
1217 mEmailToEdit
->setText(alarmText
.to());
1218 mEmailSubjectEdit
->setText(alarmText
.subject());
1219 mEmailMessageEdit
->setPlainText(alarmText
.body());
1222 mEmailMessageEdit
->setPlainText(alarmText
.displayText());
1225 /******************************************************************************
1226 * Initialise various values in the New Alarm dialogue.
1228 void EditEmailAlarmDlg::setEmailFields(uint fromID
, const KCalCore::Person::List
& addresses
,
1229 const QString
& subject
, const QStringList
& attachments
)
1232 mEmailFromList
->setCurrentIdentity(fromID
);
1233 if (!addresses
.isEmpty())
1234 mEmailToEdit
->setText(KAEvent::joinEmailAddresses(addresses
, QStringLiteral(", ")));
1235 if (!subject
.isEmpty())
1236 mEmailSubjectEdit
->setText(subject
);
1237 if (!attachments
.isEmpty())
1239 mEmailAttachList
->addItems(attachments
);
1243 void EditEmailAlarmDlg::setBcc(bool bcc
)
1245 mEmailBcc
->setChecked(bcc
);
1248 /******************************************************************************
1249 * Set the read-only status of all non-template controls.
1251 void EditEmailAlarmDlg::setReadOnly(bool readOnly
)
1253 mEmailToEdit
->setReadOnly(readOnly
);
1254 mEmailSubjectEdit
->setReadOnly(readOnly
);
1255 mEmailMessageEdit
->setReadOnly(readOnly
);
1256 mEmailBcc
->setReadOnly(readOnly
);
1258 mEmailFromList
->setReadOnly(readOnly
);
1261 mEmailAddressButton
->hide();
1262 mEmailAddAttachButton
->hide();
1263 mEmailRemoveButton
->hide();
1267 mEmailAddressButton
->show();
1268 mEmailAddAttachButton
->show();
1269 mEmailRemoveButton
->show();
1271 EditAlarmDlg::setReadOnly(readOnly
);
1274 /******************************************************************************
1275 * Save the state of all controls.
1277 void EditEmailAlarmDlg::saveState(const KAEvent
* event
)
1279 EditAlarmDlg::saveState(event
);
1281 mSavedEmailFrom
= mEmailFromList
->currentIdentityName();
1282 mSavedEmailTo
= mEmailToEdit
->text();
1283 mSavedEmailSubject
= mEmailSubjectEdit
->text();
1284 mSavedEmailAttach
.clear();
1285 for (int i
= 0, end
= mEmailAttachList
->count(); i
< end
; ++i
)
1286 mSavedEmailAttach
+= mEmailAttachList
->itemText(i
);
1287 mSavedEmailBcc
= mEmailBcc
->isChecked();
1290 /******************************************************************************
1291 * Check whether any of the controls has changed state since the dialog was
1293 * Reply = true if any controls have changed, or if it's a new event.
1294 * = false if no controls have changed.
1296 bool EditEmailAlarmDlg::type_stateChanged() const
1298 QStringList emailAttach
;
1299 for (int i
= 0, end
= mEmailAttachList
->count(); i
< end
; ++i
)
1300 emailAttach
+= mEmailAttachList
->itemText(i
);
1301 if ((mEmailFromList
&& mSavedEmailFrom
!= mEmailFromList
->currentIdentityName())
1302 || mSavedEmailTo
!= mEmailToEdit
->text()
1303 || mSavedEmailSubject
!= mEmailSubjectEdit
->text()
1304 || mSavedEmailAttach
!= emailAttach
1305 || mSavedEmailBcc
!= mEmailBcc
->isChecked())
1310 /******************************************************************************
1311 * Extract the data in the dialog specific to the alarm type and set up a
1314 void EditEmailAlarmDlg::type_setEvent(KAEvent
& event
, const KDateTime
& dt
, const QString
& text
, int lateCancel
, bool trial
)
1317 event
.set(dt
, text
, QColor(), QColor(), QFont(), KAEvent::EMAIL
, lateCancel
, getAlarmFlags());
1318 uint from
= mEmailFromList
? mEmailFromList
->currentIdentity() : 0;
1319 event
.setEmail(from
, mEmailAddresses
, mEmailSubjectEdit
->text(), mEmailAttachments
);
1322 /******************************************************************************
1323 * Get the currently specified alarm flag bits.
1325 KAEvent::Flags
EditEmailAlarmDlg::getAlarmFlags() const
1327 KAEvent::Flags flags
= EditAlarmDlg::getAlarmFlags();
1328 if (mEmailBcc
->isChecked()) flags
|= KAEvent::EMAIL_BCC
;
1332 /******************************************************************************
1333 * Convert the email addresses to a list, and validate them. Convert the email
1334 * attachments to a list.
1336 bool EditEmailAlarmDlg::type_validate(bool trial
)
1338 QString addrs
= mEmailToEdit
->text();
1339 if (addrs
.isEmpty())
1340 mEmailAddresses
.clear();
1343 QString bad
= KAMail::convertAddresses(addrs
, mEmailAddresses
);
1346 mEmailToEdit
->setFocus();
1347 KAMessageBox::error(this, xi18nc("@info", "Invalid email address: <email>%1</email>", bad
));
1351 if (mEmailAddresses
.isEmpty())
1353 mEmailToEdit
->setFocus();
1354 KAMessageBox::error(this, i18nc("@info", "No email address specified"));
1358 mEmailAttachments
.clear();
1359 for (int i
= 0, end
= mEmailAttachList
->count(); i
< end
; ++i
)
1361 QString att
= mEmailAttachList
->itemText(i
);
1362 switch (KAMail::checkAttachment(att
))
1365 mEmailAttachments
.append(att
);
1370 mEmailAttachList
->setFocus();
1371 KAMessageBox::error(this, xi18nc("@info", "Invalid email attachment: <filename>%1</filename>", att
));
1375 if (trial
&& KAMessageBox::warningContinueCancel(this, i18nc("@info", "Do you really want to send the email now to the specified recipient(s)?"),
1376 i18nc("@action:button", "Confirm Email"), KGuiItem(i18nc("@action:button", "Send"))) != KMessageBox::Continue
)
1381 /******************************************************************************
1382 * Called when the Try action is about to be executed.
1384 void EditEmailAlarmDlg::type_aboutToTry()
1386 // Disconnect any previous connections, to prevent multiple messages being output
1387 disconnect(theApp(), &KAlarmApp::execAlarmSuccess
, this, &EditEmailAlarmDlg::slotTrySuccess
);
1388 connect(theApp(), &KAlarmApp::execAlarmSuccess
, this, &EditEmailAlarmDlg::slotTrySuccess
);
1391 /******************************************************************************
1392 * Tell the user the result of the Try action.
1394 void EditEmailAlarmDlg::slotTrySuccess()
1396 disconnect(theApp(), &KAlarmApp::execAlarmSuccess
, this, &EditEmailAlarmDlg::slotTrySuccess
);
1398 QString to
= KAEvent::joinEmailAddresses(mEmailAddresses
, QStringLiteral("<nl/>"));
1399 to
.replace(QLatin1Char('<'), QStringLiteral("<"));
1400 to
.replace(QLatin1Char('>'), QStringLiteral(">"));
1401 if (mEmailBcc
->isChecked())
1402 msg
= QLatin1String("<qt>") + xi18nc("@info", "Email sent to:<nl/>%1<nl/>Bcc: <email>%2</email>",
1403 to
, Preferences::emailBccAddress()) + QLatin1String("</qt>");
1405 msg
= QLatin1String("<qt>") + xi18nc("@info", "Email sent to:<nl/>%1", to
) + QLatin1String("</qt>");
1406 KAMessageBox::information(this, msg
);
1409 /******************************************************************************
1410 * Get a selection from the Address Book.
1412 void EditEmailAlarmDlg::openAddressBook()
1414 // Use AutoQPointer to guard against crash on application exit while
1415 // the dialogue is still open. It prevents double deletion (both on
1416 // deletion of MainWindow, and on return from this function).
1417 AutoQPointer
<Akonadi::EmailAddressSelectionDialog
> dlg
= new Akonadi::EmailAddressSelectionDialog(this);
1418 if (dlg
->exec() != QDialog::Accepted
)
1421 Akonadi::EmailAddressSelection::List selections
= dlg
->selectedAddresses();
1422 if (selections
.isEmpty())
1424 Person
person(selections
.first().name(), selections
.first().email());
1425 QString addrs
= mEmailToEdit
->text().trimmed();
1426 if (!addrs
.isEmpty())
1427 addrs
+= QLatin1String(", ");
1428 addrs
+= person
.fullName();
1429 mEmailToEdit
->setText(addrs
);
1432 /******************************************************************************
1433 * Select a file to attach to the email.
1435 void EditEmailAlarmDlg::slotAddAttachment()
1437 QString url
= KAlarm::browseFile(i18nc("@title:window", "Choose File to Attach"), mAttachDefaultDir
, QString(),
1438 QString(), KFile::ExistingOnly
, this);
1441 mEmailAttachList
->addItem(url
);
1442 mEmailAttachList
->setCurrentIndex(mEmailAttachList
->count() - 1); // select the new item
1443 mEmailRemoveButton
->setEnabled(true);
1444 mEmailAttachList
->setEnabled(true);
1449 /******************************************************************************
1450 * Remove the currently selected attachment from the email.
1452 void EditEmailAlarmDlg::slotRemoveAttachment()
1454 int item
= mEmailAttachList
->currentIndex();
1455 mEmailAttachList
->removeItem(item
);
1456 int count
= mEmailAttachList
->count();
1458 mEmailAttachList
->setCurrentIndex(count
- 1);
1461 mEmailRemoveButton
->setEnabled(false);
1462 mEmailAttachList
->setEnabled(false);
1467 /******************************************************************************
1468 * Clean up the alarm text.
1470 bool EditEmailAlarmDlg::checkText(QString
& result
, bool showErrorMessage
) const
1472 Q_UNUSED(showErrorMessage
);
1473 result
= mEmailMessageEdit
->toPlainText();
1478 /*=============================================================================
1479 = Class EditAudioAlarmDlg
1480 = Dialog to edit audio alarms with no display window.
1481 =============================================================================*/
1483 /******************************************************************************
1486 * Template = true to edit/create an alarm template
1487 * = false to edit/create an alarm.
1488 * event != to initialise the dialog to show the specified event's data.
1490 EditAudioAlarmDlg::EditAudioAlarmDlg(bool Template
, QWidget
* parent
, GetResourceType getResource
)
1491 : EditAlarmDlg(Template
, KAEvent::AUDIO
, parent
, getResource
),
1492 mMessageWin(Q_NULLPTR
)
1494 qCDebug(KALARM_LOG
) << "New";
1498 EditAudioAlarmDlg::EditAudioAlarmDlg(bool Template
, const KAEvent
* event
, bool newAlarm
, QWidget
* parent
,
1499 GetResourceType getResource
, bool readOnly
)
1500 : EditAlarmDlg(Template
, event
, newAlarm
, parent
, getResource
, readOnly
),
1501 mMessageWin(Q_NULLPTR
)
1503 qCDebug(KALARM_LOG
) << "Event.id()";
1505 mTryButton
->setEnabled(!MessageWin::isAudioPlaying());
1506 connect(theApp(), &KAlarmApp::audioPlaying
, this, &EditAudioAlarmDlg::slotAudioPlaying
);
1509 /******************************************************************************
1510 * Return the window caption.
1512 QString
EditAudioAlarmDlg::type_caption() const
1514 return isTemplate() ? (isNewAlarm() ? i18nc("@title:window", "New Audio Alarm Template") : i18nc("@title:window", "Edit Audio Alarm Template"))
1515 : (isNewAlarm() ? i18nc("@title:window", "New Audio Alarm") : i18nc("@title:window", "Edit Audio Alarm"));
1518 /******************************************************************************
1519 * Set up the dialog controls common to display alarms.
1521 void EditAudioAlarmDlg::type_init(QWidget
* parent
, QVBoxLayout
* frameLayout
)
1523 // File name edit box
1524 mSoundConfig
= new SoundWidget(false, true, parent
);
1526 mSoundConfig
->setAllowEmptyFile();
1527 connect(mSoundConfig
, &SoundWidget::changed
, this, &EditAudioAlarmDlg::contentsChanged
);
1528 frameLayout
->addWidget(mSoundConfig
);
1530 // Top-adjust the controls
1531 mPadding
= new QWidget(parent
);
1532 QHBoxLayout
* hlayout
= new QHBoxLayout(mPadding
);
1533 hlayout
->setMargin(0);
1534 hlayout
->setSpacing(0);
1535 frameLayout
->addWidget(mPadding
);
1536 frameLayout
->setStretchFactor(mPadding
, 1);
1539 /******************************************************************************
1540 * Initialise the dialog controls from the specified event.
1542 void EditAudioAlarmDlg::type_initValues(const KAEvent
* event
)
1546 mSoundConfig
->set(event
->audioFile(), event
->soundVolume(), event
->fadeVolume(), event
->fadeSeconds(),
1547 (event
->flags() & KAEvent::REPEAT_SOUND
) ? event
->repeatSoundPause() : -1);
1551 // Set the values to their defaults
1552 mSoundConfig
->set(Preferences::defaultSoundFile(), Preferences::defaultSoundVolume(),
1553 -1, 0, (Preferences::defaultSoundRepeat() ? 0 : -1));
1557 /******************************************************************************
1558 * Initialise various values in the New Alarm dialogue.
1560 void EditAudioAlarmDlg::setAudio(const QString
& file
, float volume
)
1562 mSoundConfig
->set(file
, volume
);
1565 /******************************************************************************
1566 * Set the dialog's action and the action's text.
1568 void EditAudioAlarmDlg::setAction(KAEvent::SubAction action
, const AlarmText
& alarmText
)
1571 Q_ASSERT(action
== KAEvent::AUDIO
);
1572 mSoundConfig
->set(alarmText
.displayText(), Preferences::defaultSoundVolume());
1575 /******************************************************************************
1576 * Set the read-only status of all non-template controls.
1578 void EditAudioAlarmDlg::setReadOnly(bool readOnly
)
1580 mSoundConfig
->setReadOnly(readOnly
);
1581 EditAlarmDlg::setReadOnly(readOnly
);
1584 /******************************************************************************
1585 * Save the state of all controls.
1587 void EditAudioAlarmDlg::saveState(const KAEvent
* event
)
1589 EditAlarmDlg::saveState(event
);
1590 mSavedFile
= mSoundConfig
->fileName();
1591 mSoundConfig
->getVolume(mSavedVolume
, mSavedFadeVolume
, mSavedFadeSeconds
);
1592 mSavedRepeatPause
= mSoundConfig
->repeatPause();
1595 /******************************************************************************
1596 * Check whether any of the controls has changed state since the dialog was
1598 * Reply = true if any controls have changed, or if it's a new event.
1599 * = false if no controls have changed.
1601 bool EditAudioAlarmDlg::type_stateChanged() const
1603 if (mSavedFile
!= mSoundConfig
->fileName())
1605 if (!mSavedFile
.isEmpty() || isTemplate())
1607 float volume
, fadeVolume
;
1609 mSoundConfig
->getVolume(volume
, fadeVolume
, fadeSecs
);
1610 if (mSavedRepeatPause
!= mSoundConfig
->repeatPause()
1611 || mSavedVolume
!= volume
1612 || mSavedFadeVolume
!= fadeVolume
1613 || mSavedFadeSeconds
!= fadeSecs
)
1619 /******************************************************************************
1620 * Extract the data in the dialog specific to the alarm type and set up a
1623 void EditAudioAlarmDlg::type_setEvent(KAEvent
& event
, const KDateTime
& dt
, const QString
& text
, int lateCancel
, bool trial
)
1627 event
.set(dt
, QString(), QColor(), QColor(), QFont(), KAEvent::AUDIO
, lateCancel
, getAlarmFlags());
1628 float volume
, fadeVolume
;
1630 mSoundConfig
->getVolume(volume
, fadeVolume
, fadeSecs
);
1631 int repeatPause
= mSoundConfig
->repeatPause();
1633 mSoundConfig
->file(url
, false);
1634 event
.setAudioFile(url
.toString(), volume
, fadeVolume
, fadeSecs
, repeatPause
, isTemplate());
1637 /******************************************************************************
1638 * Get the currently specified alarm flag bits.
1640 KAEvent::Flags
EditAudioAlarmDlg::getAlarmFlags() const
1642 KAEvent::Flags flags
= EditAlarmDlg::getAlarmFlags();
1643 if (mSoundConfig
->repeatPause() >= 0) flags
|= KAEvent::REPEAT_SOUND
;
1647 /******************************************************************************
1648 * Check whether the file name is valid.
1650 bool EditAudioAlarmDlg::checkText(QString
& result
, bool showErrorMessage
) const
1653 if (!mSoundConfig
->file(url
, showErrorMessage
))
1658 result
= url
.isLocalFile() ? url
.toLocalFile() : url
.toString();
1662 /******************************************************************************
1663 * Called when the Try button is clicked.
1664 * If the audio file is currently playing (as a result of previously clicking
1665 * the Try button), cancel playback. Otherwise, play the audio file.
1667 void EditAudioAlarmDlg::slotTry()
1669 if (!MessageWin::isAudioPlaying())
1670 EditAlarmDlg::slotTry(); // play the audio file
1671 else if (mMessageWin
)
1673 mMessageWin
->stopAudio();
1674 mMessageWin
= Q_NULLPTR
;
1678 /******************************************************************************
1679 * Called when the Try action has been executed.
1681 void EditAudioAlarmDlg::type_executedTry(const QString
&, void* result
)
1683 mMessageWin
= (MessageWin
*)result
; // note which MessageWin controls the audio playback
1686 slotAudioPlaying(true);
1687 connect(mMessageWin
, &MessageWin::destroyed
, this, &EditAudioAlarmDlg::audioWinDestroyed
);
1691 /******************************************************************************
1692 * Called when audio playing starts or stops.
1693 * Enable/disable/toggle the Try button.
1695 void EditAudioAlarmDlg::slotAudioPlaying(bool playing
)
1699 // Nothing is playing, so enable the Try button
1700 mTryButton
->setEnabled(true);
1701 mTryButton
->setCheckable(false);
1702 mTryButton
->setChecked(false);
1703 mMessageWin
= Q_NULLPTR
;
1705 else if (mMessageWin
)
1707 // The test sound file is playing, so enable the Try button and depress it
1708 mTryButton
->setEnabled(true);
1709 mTryButton
->setCheckable(true);
1710 mTryButton
->setChecked(true);
1714 // An alarm is playing, so disable the Try button
1715 mTryButton
->setEnabled(false);
1716 mTryButton
->setCheckable(false);
1717 mTryButton
->setChecked(false);
1722 /*=============================================================================
1724 = A widget to allow entry of a command or a command script.
1725 =============================================================================*/
1726 CommandEdit::CommandEdit(QWidget
* parent
)
1729 QVBoxLayout
* vlayout
= new QVBoxLayout(this);
1730 vlayout
->setMargin(0);
1731 vlayout
->setSpacing(style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing
));
1732 mTypeScript
= new CheckBox(EditCommandAlarmDlg::i18n_chk_EnterScript(), this);
1733 mTypeScript
->setFixedSize(mTypeScript
->sizeHint());
1734 mTypeScript
->setWhatsThis(i18nc("@info:whatsthis", "Check to enter the contents of a script instead of a shell command line"));
1735 connect(mTypeScript
, &CheckBox::toggled
, this, &CommandEdit::slotCmdScriptToggled
);
1736 connect(mTypeScript
, &CheckBox::toggled
, this, &CommandEdit::changed
);
1737 vlayout
->addWidget(mTypeScript
, 0, Qt::AlignLeft
);
1739 mCommandEdit
= new LineEdit(LineEdit::Url
, this);
1740 mCommandEdit
->setWhatsThis(i18nc("@info:whatsthis", "Enter a shell command to execute."));
1741 connect(mCommandEdit
, &LineEdit::textChanged
, this, &CommandEdit::changed
);
1742 vlayout
->addWidget(mCommandEdit
);
1744 mScriptEdit
= new TextEdit(this);
1745 mScriptEdit
->setWhatsThis(i18nc("@info:whatsthis", "Enter the contents of a script to execute"));
1746 connect(mScriptEdit
, &TextEdit::textChanged
, this, &CommandEdit::changed
);
1747 vlayout
->addWidget(mScriptEdit
);
1749 slotCmdScriptToggled(mTypeScript
->isChecked());
1752 /******************************************************************************
1753 * Initialise the widget controls from the specified event.
1755 void CommandEdit::setScript(bool script
)
1757 mTypeScript
->setChecked(script
);
1760 bool CommandEdit::isScript() const
1762 return mTypeScript
->isChecked();
1765 /******************************************************************************
1766 * Set the widget's text.
1768 void CommandEdit::setText(const AlarmText
& alarmText
)
1770 QString text
= alarmText
.displayText();
1771 bool script
= alarmText
.isScript();
1772 mTypeScript
->setChecked(script
);
1774 mScriptEdit
->setPlainText(text
);
1776 mCommandEdit
->setText(KAlarm::pathOrUrl(text
));
1779 /******************************************************************************
1780 * Return the widget's text.
1782 QString
CommandEdit::text() const
1785 if (mTypeScript
->isChecked())
1786 result
= mScriptEdit
->toPlainText();
1788 result
= mCommandEdit
->text();
1789 return result
.trimmed();
1792 /******************************************************************************
1793 * Return the alarm text.
1794 * If 'showErrorMessage' is true and the text is empty, an error message is
1797 QString
CommandEdit::text(EditAlarmDlg
* dlg
, bool showErrorMessage
) const
1799 QString result
= text();
1800 if (showErrorMessage
&& result
.isEmpty())
1801 KAMessageBox::sorry(dlg
, i18nc("@info", "Please enter a command or script to execute"));
1805 /******************************************************************************
1806 * Set the read-only status of all controls.
1808 void CommandEdit::setReadOnly(bool readOnly
)
1810 mTypeScript
->setReadOnly(readOnly
);
1811 mCommandEdit
->setReadOnly(readOnly
);
1812 mScriptEdit
->setReadOnly(readOnly
);
1815 /******************************************************************************
1816 * Called when one of the command type radio buttons is clicked,
1817 * to display the appropriate edit field.
1819 void CommandEdit::slotCmdScriptToggled(bool on
)
1823 mCommandEdit
->hide();
1824 mScriptEdit
->show();
1825 mScriptEdit
->setFocus();
1829 mScriptEdit
->hide();
1830 mCommandEdit
->show();
1831 mCommandEdit
->setFocus();
1833 Q_EMIT
scriptToggled(on
);
1836 /******************************************************************************
1837 * Returns the minimum size of the widget.
1839 QSize
CommandEdit::minimumSizeHint() const
1841 QSize
t(mTypeScript
->minimumSizeHint());
1842 QSize
s(mCommandEdit
->minimumSizeHint().expandedTo(mScriptEdit
->minimumSizeHint()));
1843 s
.setHeight(s
.height() + style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing
) + t
.height());
1844 if (s
.width() < t
.width())
1845 s
.setWidth(t
.width());
1851 /*=============================================================================
1853 = A text edit field with a minimum height of 3 text lines.
1854 =============================================================================*/
1855 TextEdit::TextEdit(QWidget
* parent
)
1858 QSize tsize
= sizeHint();
1859 tsize
.setHeight(fontMetrics().lineSpacing()*13/4 + 2*frameWidth());
1860 setMinimumSize(tsize
);
1863 void TextEdit::dragEnterEvent(QDragEnterEvent
* e
)
1865 if (KCalUtils::ICalDrag::canDecode(e
->mimeData()))
1866 e
->ignore(); // don't accept "text/calendar" objects
1867 KTextEdit::dragEnterEvent(e
);