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 <kiconloader.h>
59 #include <kfileitem.h>
66 #include <QGridLayout>
67 #include <QHBoxLayout>
68 #include <QVBoxLayout>
69 #include <QDragEnterEvent>
70 #include <QStandardItemModel>
71 #include "kalarm_debug.h"
73 using namespace KAlarmCal
;
75 enum { tTEXT
, tFILE
, tCOMMAND
}; // order of mTypeCombo items
78 /*=============================================================================
79 = Class PickLogFileRadio
80 =============================================================================*/
81 class PickLogFileRadio
: public PickFileRadio
84 PickLogFileRadio(QPushButton
* b
, LineEdit
* e
, const QString
& text
, ButtonGroup
* group
, QWidget
* parent
)
85 : PickFileRadio(b
, e
, text
, group
, parent
) { }
86 QString
pickFile() Q_DECL_OVERRIDE
// called when browse button is pressed to select a log file
88 return KAlarm::browseFile(i18nc("@title:window", "Choose Log File"), mDefaultDir
, fileEdit()->text(), QString(),
89 KFile::LocalOnly
, parentWidget());
92 QString mDefaultDir
; // default directory for log file browse button
96 /*=============================================================================
97 = Class EditDisplayAlarmDlg
98 = Dialog to edit display alarms.
99 =============================================================================*/
101 QString
EditDisplayAlarmDlg::i18n_chk_ConfirmAck() { return i18nc("@option:check", "Confirm acknowledgment"); }
104 /******************************************************************************
107 * Template = true to edit/create an alarm template
108 * = false to edit/create an alarm.
109 * event != to initialise the dialog to show the specified event's data.
111 EditDisplayAlarmDlg::EditDisplayAlarmDlg(bool Template
, QWidget
* parent
, GetResourceType getResource
)
112 : EditAlarmDlg(Template
, KAEvent::MESSAGE
, parent
, getResource
),
113 mSpecialActionsButton(Q_NULLPTR
),
114 mReminderDeferral(false),
115 mReminderArchived(false)
117 qCDebug(KALARM_LOG
) << "New";
121 EditDisplayAlarmDlg::EditDisplayAlarmDlg(bool Template
, const KAEvent
* event
, bool newAlarm
, QWidget
* parent
,
122 GetResourceType getResource
, bool readOnly
)
123 : EditAlarmDlg(Template
, event
, newAlarm
, parent
, getResource
, readOnly
),
124 mSpecialActionsButton(Q_NULLPTR
),
125 mReminderDeferral(false),
126 mReminderArchived(false)
128 qCDebug(KALARM_LOG
) << "Event.id()";
132 /******************************************************************************
133 * Return the window caption.
135 QString
EditDisplayAlarmDlg::type_caption() const
137 return isTemplate() ? (isNewAlarm() ? i18nc("@title:window", "New Display Alarm Template") : i18nc("@title:window", "Edit Display Alarm Template"))
138 : (isNewAlarm() ? i18nc("@title:window", "New Display Alarm") : i18nc("@title:window", "Edit Display Alarm"));
141 /******************************************************************************
142 * Set up the dialog controls common to display alarms.
144 void EditDisplayAlarmDlg::type_init(QWidget
* parent
, QVBoxLayout
* frameLayout
)
146 // Display type combo box
147 QWidget
* box
= new QWidget(parent
); // to group widgets for QWhatsThis text
149 QHBoxLayout
* boxHLayout
= new QHBoxLayout(box
);
150 boxHLayout
->setMargin(0);
151 QLabel
* label
= new QLabel(i18nc("@label:listbox", "Display type:"), box
);
152 boxHLayout
->addWidget(label
);
153 label
->setFixedSize(label
->sizeHint());
154 mTypeCombo
= new ComboBox(box
);
155 boxHLayout
->addWidget(mTypeCombo
);
156 QString textItem
= i18nc("@item:inlistbox", "Text message");
157 QString fileItem
= i18nc("@item:inlistbox", "File contents");
158 QString commandItem
= i18nc("@item:inlistbox", "Command output");
159 mTypeCombo
->addItem(textItem
); // index = tTEXT
160 mTypeCombo
->addItem(fileItem
); // index = tFILE
161 mTypeCombo
->addItem(commandItem
); // index = tCOMMAND
162 mTypeCombo
->setFixedSize(mTypeCombo
->sizeHint());
163 mTypeCombo
->setCurrentIndex(-1); // ensure slotAlarmTypeChanged() is called when index is set
164 if (!ShellProcess::authorised())
166 // User not authorised to issue shell commands - disable Command Output option
167 QStandardItemModel
* model
= qobject_cast
<QStandardItemModel
*>(mTypeCombo
->model());
170 QModelIndex index
= model
->index(2, mTypeCombo
->modelColumn(), mTypeCombo
->rootModelIndex());
171 QStandardItem
* item
= model
->itemFromIndex(index
);
173 item
->setEnabled(false);
176 connect(mTypeCombo
, static_cast<void (ComboBox::*)(int)>(&ComboBox::currentIndexChanged
), this, &EditDisplayAlarmDlg::slotAlarmTypeChanged
);
177 connect(mTypeCombo
, static_cast<void (ComboBox::*)(int)>(&ComboBox::currentIndexChanged
), this, &EditDisplayAlarmDlg::contentsChanged
);
178 label
->setBuddy(mTypeCombo
);
179 box
->setWhatsThis(xi18nc("@info:whatsthis", "<para>Select what the alarm should display:"
180 "<list><item><interface>%1</interface>: the alarm will display the text message you type in.</item>"
181 "<item><interface>%2</interface>: the alarm will display the contents of a text or image file.</item>"
182 "<item><interface>%3</interface>: the alarm will display the output from a command.</item></list></para>",
183 textItem
, fileItem
, commandItem
));
184 boxHLayout
->setStretchFactor(new QWidget(box
), 1); // left adjust the control
185 frameLayout
->addWidget(box
);
187 // Text message edit box
188 mTextMessageEdit
= new TextEdit(parent
);
189 mTextMessageEdit
->setLineWrapMode(KTextEdit::NoWrap
);
190 mTextMessageEdit
->setWhatsThis(i18nc("@info:whatsthis", "Enter the text of the alarm message. It may be multi-line."));
191 connect(mTextMessageEdit
, &TextEdit::textChanged
, this, &EditDisplayAlarmDlg::contentsChanged
);
192 frameLayout
->addWidget(mTextMessageEdit
);
194 // File name edit box
195 mFileBox
= new QWidget(parent
);
196 frameLayout
->addWidget(mFileBox
);
197 QHBoxLayout
* fileBoxHLayout
= new QHBoxLayout(mFileBox
);
198 fileBoxHLayout
->setMargin(0);
199 fileBoxHLayout
->setSpacing(0);
200 mFileMessageEdit
= new LineEdit(LineEdit::Url
, mFileBox
);
201 fileBoxHLayout
->addWidget(mFileMessageEdit
);
202 mFileMessageEdit
->setAcceptDrops(true);
203 mFileMessageEdit
->setWhatsThis(i18nc("@info:whatsthis", "Enter the name or URL of a text or image file to display."));
204 connect(mFileMessageEdit
, &LineEdit::textChanged
, this, &EditDisplayAlarmDlg::contentsChanged
);
206 // File browse button
207 mFileBrowseButton
= new QPushButton(mFileBox
);
208 fileBoxHLayout
->addWidget(mFileBrowseButton
);
209 mFileBrowseButton
->setIcon(QIcon::fromTheme(QStringLiteral("document-open")));
210 int size
= mFileBrowseButton
->sizeHint().height();
211 mFileBrowseButton
->setFixedSize(size
, size
);
212 mFileBrowseButton
->setToolTip(i18nc("@info:tooltip", "Choose a file"));
213 mFileBrowseButton
->setWhatsThis(i18nc("@info:whatsthis", "Select a text or image file to display."));
214 connect(mFileBrowseButton
, &QPushButton::clicked
, this, &EditDisplayAlarmDlg::slotPickFile
);
216 // Command type checkbox and edit box
217 mCmdEdit
= new CommandEdit(parent
);
218 connect(mCmdEdit
, &CommandEdit::scriptToggled
, this, &EditDisplayAlarmDlg::slotCmdScriptToggled
);
219 connect(mCmdEdit
, &CommandEdit::changed
, this, &EditDisplayAlarmDlg::contentsChanged
);
220 frameLayout
->addWidget(mCmdEdit
);
222 // Sound checkbox and file selector
223 QHBoxLayout
* hlayout
= new QHBoxLayout();
224 hlayout
->setMargin(0);
225 frameLayout
->addLayout(hlayout
);
226 mSoundPicker
= new SoundPicker(parent
);
227 mSoundPicker
->setFixedSize(mSoundPicker
->sizeHint());
228 connect(mSoundPicker
, &SoundPicker::changed
, this, &EditDisplayAlarmDlg::contentsChanged
);
229 hlayout
->addWidget(mSoundPicker
);
230 hlayout
->addSpacing(2 * style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing
));
231 hlayout
->addStretch();
233 // Font and colour choice button and sample text
234 mFontColourButton
= new FontColourButton(parent
);
235 mFontColourButton
->setMaximumHeight(mFontColourButton
->sizeHint().height() * 3/2);
236 hlayout
->addWidget(mFontColourButton
);
237 connect(mFontColourButton
, &FontColourButton::selected
, this, &EditDisplayAlarmDlg::setColours
);
238 connect(mFontColourButton
, &FontColourButton::selected
, this, &EditDisplayAlarmDlg::contentsChanged
);
240 if (ShellProcess::authorised()) // don't display if shell commands not allowed (e.g. kiosk mode)
242 // Special actions button
243 mSpecialActionsButton
= new SpecialActionsButton(false, parent
);
244 mSpecialActionsButton
->setFixedSize(mSpecialActionsButton
->sizeHint());
245 connect(mSpecialActionsButton
, &SpecialActionsButton::selected
, this, &EditDisplayAlarmDlg::contentsChanged
);
246 frameLayout
->addWidget(mSpecialActionsButton
, 0, Qt::AlignRight
);
249 // Top-adjust the controls
250 mFilePadding
= new QWidget(parent
);
251 hlayout
= new QHBoxLayout(mFilePadding
);
252 hlayout
->setMargin(0);
253 hlayout
->setSpacing(0);
254 frameLayout
->addWidget(mFilePadding
);
255 frameLayout
->setStretchFactor(mFilePadding
, 1);
258 /******************************************************************************
259 * Create a reminder control.
261 Reminder
* EditDisplayAlarmDlg::createReminder(QWidget
* parent
)
263 static const QString reminderText
= i18nc("@info:whatsthis", "Enter how long in advance of or after the main alarm to display a reminder alarm.");
264 return new Reminder(i18nc("@info:whatsthis", "Check to additionally display a reminder in advance of or after the main alarm time(s)."),
265 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()),
266 i18nc("@info:whatsthis", "Select whether the reminder should be triggered before or after the main alarm"),
270 /******************************************************************************
271 * Create an "acknowledgement confirmation required" checkbox.
273 CheckBox
* EditDisplayAlarmDlg::createConfirmAckCheckbox(QWidget
* parent
)
275 CheckBox
* confirmAck
= new CheckBox(i18n_chk_ConfirmAck(), parent
);
276 confirmAck
->setWhatsThis(i18nc("@info:whatsthis", "Check to be prompted for confirmation when you acknowledge the alarm."));
280 /******************************************************************************
281 * Initialise the dialog controls from the specified event.
283 void EditDisplayAlarmDlg::type_initValues(const KAEvent
* event
)
285 mKMailSerialNumber
= 0;
286 lateCancel()->showAutoClose(true);
289 if (mAlarmType
== KAEvent::MESSAGE
&& event
->kmailSerialNumber()
290 && AlarmText::checkIfEmail(event
->cleanText()))
291 mKMailSerialNumber
= event
->kmailSerialNumber();
292 lateCancel()->setAutoClose(event
->autoClose());
293 if (event
->useDefaultFont())
294 mFontColourButton
->setDefaultFont();
296 mFontColourButton
->setFont(event
->font());
297 mFontColourButton
->setBgColour(event
->bgColour());
298 mFontColourButton
->setFgColour(event
->fgColour());
299 setColours(event
->fgColour(), event
->bgColour());
300 mConfirmAck
->setChecked(event
->confirmAck());
301 bool recurs
= event
->recurs();
302 int reminderMins
= event
->reminderMinutes();
303 if (reminderMins
> 0 && !event
->reminderActive())
304 reminderMins
= 0; // don't show advance reminder which has already passed
307 if (event
->reminderDeferral() && !recurs
)
309 reminderMins
= event
->deferDateTime().minsTo(event
->mainDateTime());
310 mReminderDeferral
= true;
312 else if (event
->reminderMinutes() && recurs
)
314 reminderMins
= event
->reminderMinutes();
315 mReminderArchived
= true;
318 reminder()->setMinutes(reminderMins
, dateOnly());
319 reminder()->setOnceOnly(event
->reminderOnceOnly());
320 reminder()->enableOnceOnly(recurs
);
321 if (mSpecialActionsButton
)
322 mSpecialActionsButton
->setActions(event
->preAction(), event
->postAction(), event
->extraActionOptions());
323 Preferences::SoundType soundType
= event
->speak() ? Preferences::Sound_Speak
324 : event
->beep() ? Preferences::Sound_Beep
325 : !event
->audioFile().isEmpty() ? Preferences::Sound_File
326 : Preferences::Sound_None
;
327 mSoundPicker
->set(soundType
, event
->audioFile(), event
->soundVolume(),
328 event
->fadeVolume(), event
->fadeSeconds(), event
->repeatSoundPause());
332 // Set the values to their defaults
333 if (!ShellProcess::authorised())
335 // Don't allow shell commands in kiosk mode
336 if (mSpecialActionsButton
)
337 mSpecialActionsButton
->setEnabled(false);
339 lateCancel()->setAutoClose(Preferences::defaultAutoClose());
340 mTypeCombo
->setCurrentIndex(0);
341 mFontColourButton
->setDefaultFont();
342 mFontColourButton
->setBgColour(Preferences::defaultBgColour());
343 mFontColourButton
->setFgColour(Preferences::defaultFgColour());
344 setColours(Preferences::defaultFgColour(), Preferences::defaultBgColour());
345 mConfirmAck
->setChecked(Preferences::defaultConfirmAck());
346 reminder()->setMinutes(0, false);
347 reminder()->enableOnceOnly(isTimedRecurrence()); // must be called after mRecurrenceEdit is set up
348 if (mSpecialActionsButton
)
350 KAEvent::ExtraActionOptions
opts(Q_NULLPTR
);
351 if (Preferences::defaultExecPreActionOnDeferral())
352 opts
|= KAEvent::ExecPreActOnDeferral
;
353 if (Preferences::defaultCancelOnPreActionError())
354 opts
|= KAEvent::CancelOnPreActError
;
355 if (Preferences::defaultDontShowPreActionError())
356 opts
|= KAEvent::DontShowPreActError
;
357 mSpecialActionsButton
->setActions(Preferences::defaultPreAction(), Preferences::defaultPostAction(), opts
);
359 mSoundPicker
->set(Preferences::defaultSoundType(), Preferences::defaultSoundFile(),
360 Preferences::defaultSoundVolume(), -1, 0, (Preferences::defaultSoundRepeat() ? 0 : -1));
364 /******************************************************************************
365 * Called when the More/Less Options button is clicked.
366 * Show/hide the optional options.
368 void EditDisplayAlarmDlg::type_showOptions(bool more
)
370 if (mSpecialActionsButton
)
373 mSpecialActionsButton
->show();
375 mSpecialActionsButton
->hide();
379 /******************************************************************************
380 * Called when the font/color button has been clicked.
381 * Set the colors in the message text entry control.
383 void EditDisplayAlarmDlg::setColours(const QColor
& fgColour
, const QColor
& bgColour
)
385 QPalette pal
= mTextMessageEdit
->palette();
386 pal
.setColor(mTextMessageEdit
->backgroundRole(), bgColour
);
387 pal
.setColor(QPalette::Text
, fgColour
);
388 mTextMessageEdit
->setPalette(pal
);
389 pal
= mTextMessageEdit
->viewport()->palette();
390 pal
.setColor(mTextMessageEdit
->viewport()->backgroundRole(), bgColour
);
391 pal
.setColor(QPalette::Text
, fgColour
);
392 mTextMessageEdit
->viewport()->setPalette(pal
);
393 // Change the color of existing text
394 QTextCursor cursor
= mTextMessageEdit
->textCursor();
395 mTextMessageEdit
->selectAll();
396 mTextMessageEdit
->setTextColor(fgColour
);
397 mTextMessageEdit
->setTextCursor(cursor
);
400 /******************************************************************************
401 * Set the dialog's action and the action's text.
403 void EditDisplayAlarmDlg::setAction(KAEvent::SubAction action
, const AlarmText
& alarmText
)
405 QString text
= alarmText
.displayText();
408 case KAEvent::MESSAGE
:
409 mTypeCombo
->setCurrentIndex(tTEXT
);
410 mTextMessageEdit
->setPlainText(text
);
411 mKMailSerialNumber
= alarmText
.isEmail() ? alarmText
.kmailSerialNumber() : 0;
414 mTypeCombo
->setCurrentIndex(tFILE
);
415 mFileMessageEdit
->setText(text
);
417 case KAEvent::COMMAND
:
418 mTypeCombo
->setCurrentIndex(tCOMMAND
);
419 mCmdEdit
->setText(alarmText
);
427 /******************************************************************************
428 * Initialise various values in the New Alarm dialogue.
430 void EditDisplayAlarmDlg::setBgColour(const QColor
& colour
)
432 mFontColourButton
->setBgColour(colour
);
433 setColours(mFontColourButton
->fgColour(), colour
);
435 void EditDisplayAlarmDlg::setFgColour(const QColor
& colour
)
437 mFontColourButton
->setFgColour(colour
);
438 setColours(colour
, mFontColourButton
->bgColour());
440 void EditDisplayAlarmDlg::setConfirmAck(bool confirm
)
442 mConfirmAck
->setChecked(confirm
);
444 void EditDisplayAlarmDlg::setAutoClose(bool close
)
446 lateCancel()->setAutoClose(close
);
448 void EditDisplayAlarmDlg::setAudio(Preferences::SoundType type
, const QString
& file
, float volume
, int repeatPause
)
450 mSoundPicker
->set(type
, file
, volume
, -1, 0, repeatPause
);
452 void EditDisplayAlarmDlg::setReminder(int minutes
, bool onceOnly
)
454 reminder()->setMinutes(minutes
, dateOnly());
455 reminder()->setOnceOnly(onceOnly
);
456 reminder()->enableOnceOnly(isTimedRecurrence());
459 /******************************************************************************
460 * Set the read-only status of all non-template controls.
462 void EditDisplayAlarmDlg::setReadOnly(bool readOnly
)
464 mTypeCombo
->setReadOnly(readOnly
);
465 mTextMessageEdit
->setReadOnly(readOnly
);
466 mFileMessageEdit
->setReadOnly(readOnly
);
467 mCmdEdit
->setReadOnly(readOnly
);
468 mFontColourButton
->setReadOnly(readOnly
);
469 mSoundPicker
->setReadOnly(readOnly
);
470 mConfirmAck
->setReadOnly(readOnly
);
471 reminder()->setReadOnly(readOnly
);
472 if (mSpecialActionsButton
)
473 mSpecialActionsButton
->setReadOnly(readOnly
);
475 mFileBrowseButton
->hide();
477 mFileBrowseButton
->show();
478 EditAlarmDlg::setReadOnly(readOnly
);
481 /******************************************************************************
482 * Save the state of all controls.
484 void EditDisplayAlarmDlg::saveState(const KAEvent
* event
)
486 EditAlarmDlg::saveState(event
);
487 mSavedType
= mTypeCombo
->currentIndex();
488 mSavedCmdScript
= mCmdEdit
->isScript();
489 mSavedSoundType
= mSoundPicker
->sound();
490 mSavedSoundFile
= mSoundPicker
->file();
491 mSavedSoundVolume
= mSoundPicker
->volume(mSavedSoundFadeVolume
, mSavedSoundFadeSeconds
);
492 mSavedRepeatPause
= mSoundPicker
->repeatPause();
493 mSavedConfirmAck
= mConfirmAck
->isChecked();
494 mSavedFont
= mFontColourButton
->font();
495 mSavedFgColour
= mFontColourButton
->fgColour();
496 mSavedBgColour
= mFontColourButton
->bgColour();
497 mSavedReminder
= reminder()->minutes();
498 mSavedOnceOnly
= reminder()->isOnceOnly();
499 mSavedAutoClose
= lateCancel()->isAutoClose();
500 if (mSpecialActionsButton
)
502 mSavedPreAction
= mSpecialActionsButton
->preAction();
503 mSavedPostAction
= mSpecialActionsButton
->postAction();
504 mSavedPreActionOptions
= mSpecialActionsButton
->options();
508 /******************************************************************************
509 * Check whether any of the controls has changed state since the dialog was
511 * Reply = true if any controls have changed, or if it's a new event.
512 * = false if no controls have changed.
514 bool EditDisplayAlarmDlg::type_stateChanged() const
516 if (mSavedType
!= mTypeCombo
->currentIndex()
517 || mSavedCmdScript
!= mCmdEdit
->isScript()
518 || mSavedSoundType
!= mSoundPicker
->sound()
519 || mSavedConfirmAck
!= mConfirmAck
->isChecked()
520 || mSavedFont
!= mFontColourButton
->font()
521 || mSavedFgColour
!= mFontColourButton
->fgColour()
522 || mSavedBgColour
!= mFontColourButton
->bgColour()
523 || mSavedReminder
!= reminder()->minutes()
524 || mSavedOnceOnly
!= reminder()->isOnceOnly()
525 || mSavedAutoClose
!= lateCancel()->isAutoClose())
527 if (mSpecialActionsButton
)
529 if (mSavedPreAction
!= mSpecialActionsButton
->preAction()
530 || mSavedPostAction
!= mSpecialActionsButton
->postAction()
531 || mSavedPreActionOptions
!= mSpecialActionsButton
->options())
534 if (mSavedSoundType
== Preferences::Sound_File
)
536 if (mSavedSoundFile
!= mSoundPicker
->file())
538 if (!mSavedSoundFile
.isEmpty())
542 if (mSavedRepeatPause
!= mSoundPicker
->repeatPause()
543 || mSavedSoundVolume
!= mSoundPicker
->volume(fadeVolume
, fadeSecs
)
544 || mSavedSoundFadeVolume
!= fadeVolume
545 || mSavedSoundFadeSeconds
!= fadeSecs
)
552 /******************************************************************************
553 * Extract the data in the dialog specific to the alarm type and set up a
556 void EditDisplayAlarmDlg::type_setEvent(KAEvent
& event
, const KDateTime
& dt
, const QString
& text
, int lateCancel
, bool trial
)
558 KAEvent::SubAction type
;
559 switch (mTypeCombo
->currentIndex())
561 case tFILE
: type
= KAEvent::FILE; break;
562 case tCOMMAND
: type
= KAEvent::COMMAND
; break;
564 case tTEXT
: type
= KAEvent::MESSAGE
; break;
566 event
.set(dt
, text
, mFontColourButton
->bgColour(), mFontColourButton
->fgColour(), mFontColourButton
->font(),
567 type
, lateCancel
, getAlarmFlags());
568 if (type
== KAEvent::MESSAGE
)
570 if (AlarmText::checkIfEmail(text
))
571 event
.setKMailSerialNumber(mKMailSerialNumber
);
575 float volume
= mSoundPicker
->volume(fadeVolume
, fadeSecs
);
576 int repeatPause
= mSoundPicker
->repeatPause();
577 event
.setAudioFile(mSoundPicker
->file().toDisplayString(), volume
, fadeVolume
, fadeSecs
, repeatPause
);
578 if (!trial
&& reminder()->isEnabled())
579 event
.setReminder(reminder()->minutes(), reminder()->isOnceOnly());
580 if (mSpecialActionsButton
&& mSpecialActionsButton
->isEnabled())
581 event
.setActions(mSpecialActionsButton
->preAction(), mSpecialActionsButton
->postAction(),
582 mSpecialActionsButton
->options());
585 /******************************************************************************
586 * Get the currently specified alarm flag bits.
588 KAEvent::Flags
EditDisplayAlarmDlg::getAlarmFlags() const
590 bool cmd
= (mTypeCombo
->currentIndex() == tCOMMAND
);
591 KAEvent::Flags flags
= EditAlarmDlg::getAlarmFlags();
592 if (mSoundPicker
->sound() == Preferences::Sound_Beep
) flags
|= KAEvent::BEEP
;
593 if (mSoundPicker
->sound() == Preferences::Sound_Speak
) flags
|= KAEvent::SPEAK
;
594 if (mSoundPicker
->repeatPause() >= 0) flags
|= KAEvent::REPEAT_SOUND
;
595 if (mConfirmAck
->isChecked()) flags
|= KAEvent::CONFIRM_ACK
;
596 if (lateCancel()->isAutoClose()) flags
|= KAEvent::AUTO_CLOSE
;
597 if (mFontColourButton
->defaultFont()) flags
|= KAEvent::DEFAULT_FONT
;
598 if (cmd
) flags
|= KAEvent::DISPLAY_COMMAND
;
599 if (cmd
&& mCmdEdit
->isScript()) flags
|= KAEvent::SCRIPT
;
603 /******************************************************************************
604 * Called when one of the alarm display type combo box is changed, to display
605 * the appropriate set of controls for that action type.
607 void EditDisplayAlarmDlg::slotAlarmTypeChanged(int index
)
609 QWidget
* focus
= Q_NULLPTR
;
612 case tTEXT
: // text message
614 mFilePadding
->hide();
616 mTextMessageEdit
->show();
617 mSoundPicker
->showSpeak(true);
618 mTryButton
->setWhatsThis(i18nc("@info:whatsthis", "Display the alarm message now"));
619 focus
= mTextMessageEdit
;
621 case tFILE
: // file contents
622 mTextMessageEdit
->hide();
624 mFilePadding
->show();
626 mSoundPicker
->showSpeak(false);
627 mTryButton
->setWhatsThis(i18nc("@info:whatsthis", "Display the file now"));
628 mFileMessageEdit
->setNoSelect();
629 focus
= mFileMessageEdit
;
631 case tCOMMAND
: // command output
632 mTextMessageEdit
->hide();
634 slotCmdScriptToggled(mCmdEdit
->isScript()); // show/hide mFilePadding
636 mSoundPicker
->showSpeak(true);
637 mTryButton
->setWhatsThis(i18nc("@info:whatsthis", "Display the command output now"));
645 /******************************************************************************
646 * Called when the file browse button is pressed to select a file to display.
648 void EditDisplayAlarmDlg::slotPickFile()
650 static QString defaultDir
; // default directory for file browse button
651 QString file
= KAlarm::browseFile(i18nc("@title:window", "Choose Text or Image File to Display"),
652 defaultDir
, mFileMessageEdit
->text(), QString(), KFile::ExistingOnly
, this);
655 mFileMessageEdit
->setText(KAlarm::pathOrUrl(file
));
660 /******************************************************************************
661 * Called when one of the command type radio buttons is clicked,
662 * to display the appropriate edit field.
664 void EditDisplayAlarmDlg::slotCmdScriptToggled(bool on
)
667 mFilePadding
->hide();
669 mFilePadding
->show();
672 /******************************************************************************
673 * Clean up the alarm text, and if it's a file, check whether it's valid.
675 bool EditDisplayAlarmDlg::checkText(QString
& result
, bool showErrorMessage
) const
677 switch (mTypeCombo
->currentIndex())
680 result
= mTextMessageEdit
->toPlainText();
685 QString alarmtext
= mFileMessageEdit
->text().trimmed();
687 KAlarm::FileErr err
= KAlarm::checkFileExists(alarmtext
, url
);
688 if (err
== KAlarm::FileErr_None
)
691 switch (KAlarm::fileType(fi
.currentMimeType()))
693 case KAlarm::TextFormatted
:
694 case KAlarm::TextPlain
:
695 case KAlarm::TextApplication
:
699 err
= KAlarm::FileErr_NotTextImage
;
703 if (err
!= KAlarm::FileErr_None
&& showErrorMessage
)
705 mFileMessageEdit
->setFocus();
706 if (!KAlarm::showFileErrMessage(alarmtext
, err
, KAlarm::FileErr_BlankDisplay
, const_cast<EditDisplayAlarmDlg
*>(this)))
713 result
= mCmdEdit
->text(const_cast<EditDisplayAlarmDlg
*>(this), showErrorMessage
);
714 if (result
.isEmpty())
722 /*=============================================================================
723 = Class EditCommandAlarmDlg
724 = Dialog to edit command alarms.
725 =============================================================================*/
727 QString
EditCommandAlarmDlg::i18n_chk_EnterScript() { return i18nc("@option:check", "Enter a script"); }
728 QString
EditCommandAlarmDlg::i18n_radio_ExecInTermWindow() { return i18nc("@option:radio", "Execute in terminal window"); }
729 QString
EditCommandAlarmDlg::i18n_chk_ExecInTermWindow() { return i18nc("@option:check", "Execute in terminal window"); }
732 /******************************************************************************
735 * Template = true to edit/create an alarm template
736 * = false to edit/create an alarm.
737 * event != to initialise the dialog to show the specified event's data.
739 EditCommandAlarmDlg::EditCommandAlarmDlg(bool Template
, QWidget
* parent
, GetResourceType getResource
)
740 : EditAlarmDlg(Template
, KAEvent::COMMAND
, parent
, getResource
)
742 qCDebug(KALARM_LOG
) << "New";
746 EditCommandAlarmDlg::EditCommandAlarmDlg(bool Template
, const KAEvent
* event
, bool newAlarm
, QWidget
* parent
,
747 GetResourceType getResource
, bool readOnly
)
748 : EditAlarmDlg(Template
, event
, newAlarm
, parent
, getResource
, readOnly
)
750 qCDebug(KALARM_LOG
) << "Event.id()";
754 /******************************************************************************
755 * Return the window caption.
757 QString
EditCommandAlarmDlg::type_caption() const
759 return isTemplate() ? (isNewAlarm() ? i18nc("@title:window", "New Command Alarm Template") : i18nc("@title:window", "Edit Command Alarm Template"))
760 : (isNewAlarm() ? i18nc("@title:window", "New Command Alarm") : i18nc("@title:window", "Edit Command Alarm"));
763 /******************************************************************************
764 * Set up the command alarm dialog controls.
766 void EditCommandAlarmDlg::type_init(QWidget
* parent
, QVBoxLayout
* frameLayout
)
768 mTryButton
->setWhatsThis(i18nc("@info:whatsthis", "Execute the specified command now"));
770 mCmdEdit
= new CommandEdit(parent
);
771 connect(mCmdEdit
, &CommandEdit::scriptToggled
, this, &EditCommandAlarmDlg::slotCmdScriptToggled
);
772 connect(mCmdEdit
, &CommandEdit::changed
, this, &EditCommandAlarmDlg::contentsChanged
);
773 frameLayout
->addWidget(mCmdEdit
);
775 // What to do with command output
777 mCmdOutputBox
= new QGroupBox(i18nc("@title:group", "Command Output"), parent
);
778 frameLayout
->addWidget(mCmdOutputBox
);
779 QVBoxLayout
* vlayout
= new QVBoxLayout(mCmdOutputBox
);
780 vlayout
->setMargin(style()->pixelMetric(QStyle::PM_DefaultChildMargin
));
781 vlayout
->setSpacing(style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing
));
782 mCmdOutputGroup
= new ButtonGroup(mCmdOutputBox
);
783 connect(mCmdOutputGroup
, &ButtonGroup::buttonSet
, this, &EditCommandAlarmDlg::contentsChanged
);
785 // Execute in terminal window
786 mCmdExecInTerm
= new RadioButton(i18n_radio_ExecInTermWindow(), mCmdOutputBox
);
787 mCmdExecInTerm
->setFixedSize(mCmdExecInTerm
->sizeHint());
788 mCmdExecInTerm
->setWhatsThis(i18nc("@info:whatsthis", "Check to execute the command in a terminal window"));
789 mCmdOutputGroup
->addButton(mCmdExecInTerm
, Preferences::Log_Terminal
);
790 vlayout
->addWidget(mCmdExecInTerm
, 0, Qt::AlignLeft
);
792 // Log file name edit box
793 QWidget
* box
= new QWidget(mCmdOutputBox
);
794 QHBoxLayout
* boxHLayout
= new QHBoxLayout(box
);
795 boxHLayout
->setMargin(0);
796 boxHLayout
->setSpacing(0);
797 (new QWidget(box
))->setFixedWidth(mCmdExecInTerm
->style()->pixelMetric(QStyle::PM_ExclusiveIndicatorWidth
)); // indent the edit box
798 mCmdLogFileEdit
= new LineEdit(LineEdit::Url
, box
);
799 boxHLayout
->addWidget(mCmdLogFileEdit
);
800 mCmdLogFileEdit
->setAcceptDrops(true);
801 mCmdLogFileEdit
->setWhatsThis(i18nc("@info:whatsthis", "Enter the name or path of the log file."));
802 connect(mCmdLogFileEdit
, &LineEdit::textChanged
, this, &EditCommandAlarmDlg::contentsChanged
);
804 // Log file browse button.
805 // The file browser dialog is activated by the PickLogFileRadio class.
806 QPushButton
* browseButton
= new QPushButton(box
);
807 boxHLayout
->addWidget(browseButton
);
808 browseButton
->setIcon(QIcon::fromTheme(QStringLiteral("document-open")));
809 int size
= browseButton
->sizeHint().height();
810 browseButton
->setFixedSize(size
, size
);
811 browseButton
->setToolTip(i18nc("@info:tooltip", "Choose a file"));
812 browseButton
->setWhatsThis(i18nc("@info:whatsthis", "Select a log file."));
814 // Log output to file
815 mCmdLogToFile
= new PickLogFileRadio(browseButton
, mCmdLogFileEdit
, i18nc("@option:radio", "Log to file"), mCmdOutputGroup
, mCmdOutputBox
);
816 mCmdLogToFile
->setFixedSize(mCmdLogToFile
->sizeHint());
817 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."));
818 connect(mCmdLogToFile
, &PickLogFileRadio::fileChanged
, this, &EditCommandAlarmDlg::contentsChanged
);
819 mCmdOutputGroup
->addButton(mCmdLogToFile
, Preferences::Log_File
);
820 vlayout
->addWidget(mCmdLogToFile
, 0, Qt::AlignLeft
);
821 vlayout
->addWidget(box
);
824 mCmdDiscardOutput
= new RadioButton(i18nc("@option:radio", "Discard"), mCmdOutputBox
);
825 mCmdDiscardOutput
->setFixedSize(mCmdDiscardOutput
->sizeHint());
826 mCmdDiscardOutput
->setWhatsThis(i18nc("@info:whatsthis", "Check to discard command output."));
827 mCmdOutputGroup
->addButton(mCmdDiscardOutput
, Preferences::Log_Discard
);
828 vlayout
->addWidget(mCmdDiscardOutput
, 0, Qt::AlignLeft
);
830 // Top-adjust the controls
831 mCmdPadding
= new QWidget(parent
);
832 QHBoxLayout
* hlayout
= new QHBoxLayout(mCmdPadding
);
833 hlayout
->setMargin(0);
834 hlayout
->setSpacing(0);
835 frameLayout
->addWidget(mCmdPadding
);
836 frameLayout
->setStretchFactor(mCmdPadding
, 1);
839 /******************************************************************************
840 * Initialise the dialog controls from the specified event.
842 void EditCommandAlarmDlg::type_initValues(const KAEvent
* event
)
846 // Set the values to those for the specified event
847 RadioButton
* logType
= event
->commandXterm() ? mCmdExecInTerm
848 : !event
->logFile().isEmpty() ? mCmdLogToFile
850 if (logType
== mCmdLogToFile
)
851 mCmdLogFileEdit
->setText(event
->logFile()); // set file name before setting radio button
852 logType
->setChecked(true);
856 // Set the values to their defaults
857 mCmdEdit
->setScript(Preferences::defaultCmdScript());
858 mCmdLogFileEdit
->setText(Preferences::defaultCmdLogFile()); // set file name before setting radio button
859 mCmdOutputGroup
->setButton(Preferences::defaultCmdLogType());
861 slotCmdScriptToggled(mCmdEdit
->isScript());
864 /******************************************************************************
865 * Called when the More/Less Options button is clicked.
866 * Show/hide the optional options.
868 void EditCommandAlarmDlg::type_showOptions(bool more
)
871 mCmdOutputBox
->show();
873 mCmdOutputBox
->hide();
876 /******************************************************************************
877 * Set the dialog's action and the action's text.
879 void EditCommandAlarmDlg::setAction(KAEvent::SubAction action
, const AlarmText
& alarmText
)
882 Q_ASSERT(action
== KAEvent::COMMAND
);
883 mCmdEdit
->setText(alarmText
);
886 /******************************************************************************
887 * Set the read-only status of all non-template controls.
889 void EditCommandAlarmDlg::setReadOnly(bool readOnly
)
891 if (!isTemplate() && !ShellProcess::authorised())
892 readOnly
= true; // don't allow editing of existing command alarms in kiosk mode
893 mCmdEdit
->setReadOnly(readOnly
);
894 mCmdExecInTerm
->setReadOnly(readOnly
);
895 mCmdLogToFile
->setReadOnly(readOnly
);
896 mCmdDiscardOutput
->setReadOnly(readOnly
);
897 EditAlarmDlg::setReadOnly(readOnly
);
900 /******************************************************************************
901 * Save the state of all controls.
903 void EditCommandAlarmDlg::saveState(const KAEvent
* event
)
905 EditAlarmDlg::saveState(event
);
906 mSavedCmdScript
= mCmdEdit
->isScript();
907 mSavedCmdOutputRadio
= mCmdOutputGroup
->checkedButton();
908 mSavedCmdLogFile
= mCmdLogFileEdit
->text();
911 /******************************************************************************
912 * Check whether any of the controls has changed state since the dialog was
914 * Reply = true if any controls have changed, or if it's a new event.
915 * = false if no controls have changed.
917 bool EditCommandAlarmDlg::type_stateChanged() const
919 if (mSavedCmdScript
!= mCmdEdit
->isScript()
920 || mSavedCmdOutputRadio
!= mCmdOutputGroup
->checkedButton())
922 if (mCmdOutputGroup
->checkedButton() == mCmdLogToFile
)
924 if (mSavedCmdLogFile
!= mCmdLogFileEdit
->text())
930 /******************************************************************************
931 * Extract the data in the dialog specific to the alarm type and set up a
934 void EditCommandAlarmDlg::type_setEvent(KAEvent
& event
, const KDateTime
& dt
, const QString
& text
, int lateCancel
, bool trial
)
937 event
.set(dt
, text
, QColor(), QColor(), QFont(), KAEvent::COMMAND
, lateCancel
, getAlarmFlags());
938 if (mCmdOutputGroup
->checkedButton() == mCmdLogToFile
)
939 event
.setLogFile(mCmdLogFileEdit
->text());
942 /******************************************************************************
943 * Get the currently specified alarm flag bits.
945 KAEvent::Flags
EditCommandAlarmDlg::getAlarmFlags() const
947 KAEvent::Flags flags
= EditAlarmDlg::getAlarmFlags();
948 if (mCmdEdit
->isScript()) flags
|= KAEvent::SCRIPT
;
949 if (mCmdOutputGroup
->checkedButton() == mCmdExecInTerm
) flags
|= KAEvent::EXEC_IN_XTERM
;
953 /******************************************************************************
954 * Validate and convert command alarm data.
956 bool EditCommandAlarmDlg::type_validate(bool trial
)
959 if (mCmdOutputGroup
->checkedButton() == mCmdLogToFile
)
961 // Validate the log file name
962 QString file
= mCmdLogFileEdit
->text();
963 QFileInfo
info(file
);
964 QDir::setCurrent(QDir::homePath());
965 bool err
= file
.isEmpty() || info
.isDir();
970 err
= !info
.isWritable();
974 QFileInfo
dirinfo(info
.absolutePath()); // get absolute directory path
975 err
= (!dirinfo
.isDir() || !dirinfo
.isWritable());
981 mCmdLogFileEdit
->setFocus();
982 KAMessageBox::sorry(this, i18nc("@info", "Log file must be the name or path of a local file, with write permission."));
985 // Convert the log file to an absolute path
986 mCmdLogFileEdit
->setText(info
.absoluteFilePath());
991 /******************************************************************************
992 * Called when the Try action has been executed.
993 * Tell the user the result of the Try action.
995 void EditCommandAlarmDlg::type_executedTry(const QString
& text
, void* result
)
997 ShellProcess
* proc
= (ShellProcess
*)result
;
998 if (proc
&& proc
!= (void*)-1
999 && mCmdOutputGroup
->checkedButton() != mCmdExecInTerm
)
1001 theApp()->commandMessage(proc
, this);
1002 KAMessageBox::information(this, xi18nc("@info", "Command executed: <icode>%1</icode>", text
));
1003 theApp()->commandMessage(proc
, Q_NULLPTR
);
1007 /******************************************************************************
1008 * Called when one of the command type radio buttons is clicked,
1009 * to display the appropriate edit field.
1011 void EditCommandAlarmDlg::slotCmdScriptToggled(bool on
)
1014 mCmdPadding
->hide();
1016 mCmdPadding
->show();
1019 /******************************************************************************
1020 * Clean up the alarm text.
1022 bool EditCommandAlarmDlg::checkText(QString
& result
, bool showErrorMessage
) const
1024 result
= mCmdEdit
->text(const_cast<EditCommandAlarmDlg
*>(this), showErrorMessage
);
1025 if (result
.isEmpty())
1031 /*=============================================================================
1032 = Class EditEmailAlarmDlg
1033 = Dialog to edit email alarms.
1034 =============================================================================*/
1036 QString
EditEmailAlarmDlg::i18n_chk_CopyEmailToSelf() { return i18nc("@option:check", "Copy email to self"); }
1039 /******************************************************************************
1042 * Template = true to edit/create an alarm template
1043 * = false to edit/create an alarm.
1044 * event != to initialise the dialog to show the specified event's data.
1046 EditEmailAlarmDlg::EditEmailAlarmDlg(bool Template
, QWidget
* parent
, GetResourceType getResource
)
1047 : EditAlarmDlg(Template
, KAEvent::EMAIL
, parent
, getResource
),
1048 mEmailRemoveButton(Q_NULLPTR
)
1050 qCDebug(KALARM_LOG
) << "New";
1054 EditEmailAlarmDlg::EditEmailAlarmDlg(bool Template
, const KAEvent
* event
, bool newAlarm
, QWidget
* parent
,
1055 GetResourceType getResource
, bool readOnly
)
1056 : EditAlarmDlg(Template
, event
, newAlarm
, parent
, getResource
, readOnly
),
1057 mEmailRemoveButton(Q_NULLPTR
)
1059 qCDebug(KALARM_LOG
) << "Event.id()";
1063 /******************************************************************************
1064 * Return the window caption.
1066 QString
EditEmailAlarmDlg::type_caption() const
1068 return isTemplate() ? (isNewAlarm() ? i18nc("@title:window", "New Email Alarm Template") : i18nc("@title:window", "Edit Email Alarm Template"))
1069 : (isNewAlarm() ? i18nc("@title:window", "New Email Alarm") : i18nc("@title:window", "Edit Email Alarm"));
1072 /******************************************************************************
1073 * Set up the email alarm dialog controls.
1075 void EditEmailAlarmDlg::type_init(QWidget
* parent
, QVBoxLayout
* frameLayout
)
1077 mTryButton
->setWhatsThis(i18nc("@info:whatsthis", "Send the email to the specified addressees now"));
1079 QGridLayout
* grid
= new QGridLayout();
1081 grid
->setColumnStretch(1, 1);
1082 frameLayout
->addLayout(grid
);
1084 mEmailFromList
= Q_NULLPTR
;
1085 if (Preferences::emailFrom() == Preferences::MAIL_FROM_KMAIL
)
1087 // Email sender identity
1088 QLabel
* label
= new QLabel(i18nc("@label:listbox 'From' email address", "From:"), parent
);
1089 label
->setFixedSize(label
->sizeHint());
1090 grid
->addWidget(label
, 0, 0);
1092 mEmailFromList
= new EmailIdCombo(Identities::identityManager(), parent
);
1093 mEmailFromList
->setMinimumSize(mEmailFromList
->sizeHint());
1094 label
->setBuddy(mEmailFromList
);
1095 mEmailFromList
->setWhatsThis(i18nc("@info:whatsthis", "Your email identity, used to identify you as the sender when sending email alarms."));
1096 connect(mEmailFromList
, &EmailIdCombo::identityChanged
, this, &EditEmailAlarmDlg::contentsChanged
);
1097 grid
->addWidget(mEmailFromList
, 0, 1, 1, 2);
1101 QLabel
* label
= new QLabel(i18nc("@label:textbox Email addressee", "To:"), parent
);
1102 label
->setFixedSize(label
->sizeHint());
1103 grid
->addWidget(label
, 1, 0);
1105 mEmailToEdit
= new LineEdit(LineEdit::Emails
, parent
);
1106 mEmailToEdit
->setMinimumSize(mEmailToEdit
->sizeHint());
1107 mEmailToEdit
->setWhatsThis(i18nc("@info:whatsthis", "Enter the addresses of the email recipients. Separate multiple addresses by "
1108 "commas or semicolons."));
1109 connect(mEmailToEdit
, &LineEdit::textChanged
, this, &EditEmailAlarmDlg::contentsChanged
);
1110 grid
->addWidget(mEmailToEdit
, 1, 1);
1112 mEmailAddressButton
= new QPushButton(parent
);
1113 mEmailAddressButton
->setIcon(QIcon::fromTheme(QStringLiteral("help-contents")));
1114 int size
= mEmailAddressButton
->sizeHint().height();
1115 mEmailAddressButton
->setFixedSize(size
, size
);
1116 connect(mEmailAddressButton
, &QPushButton::clicked
, this, &EditEmailAlarmDlg::openAddressBook
);
1117 mEmailAddressButton
->setToolTip(i18nc("@info:tooltip", "Open address book"));
1118 mEmailAddressButton
->setWhatsThis(i18nc("@info:whatsthis", "Select email addresses from your address book."));
1119 grid
->addWidget(mEmailAddressButton
, 1, 2);
1122 label
= new QLabel(i18nc("@label:textbox Email subject", "Subject:"), parent
);
1123 label
->setFixedSize(label
->sizeHint());
1124 grid
->addWidget(label
, 2, 0);
1126 mEmailSubjectEdit
= new LineEdit(parent
);
1127 mEmailSubjectEdit
->setMinimumSize(mEmailSubjectEdit
->sizeHint());
1128 label
->setBuddy(mEmailSubjectEdit
);
1129 mEmailSubjectEdit
->setWhatsThis(i18nc("@info:whatsthis", "Enter the email subject."));
1130 connect(mEmailSubjectEdit
, &LineEdit::textChanged
, this, &EditEmailAlarmDlg::contentsChanged
);
1131 grid
->addWidget(mEmailSubjectEdit
, 2, 1, 1, 2);
1134 mEmailMessageEdit
= new TextEdit(parent
);
1135 mEmailMessageEdit
->setWhatsThis(i18nc("@info:whatsthis", "Enter the email message."));
1136 connect(mEmailMessageEdit
, &TextEdit::textChanged
, this, &EditEmailAlarmDlg::contentsChanged
);
1137 frameLayout
->addWidget(mEmailMessageEdit
);
1139 // Email attachments
1140 grid
= new QGridLayout();
1142 frameLayout
->addLayout(grid
);
1143 label
= new QLabel(i18nc("@label:listbox", "Attachments:"), parent
);
1144 label
->setFixedSize(label
->sizeHint());
1145 grid
->addWidget(label
, 0, 0);
1147 mEmailAttachList
= new QComboBox(parent
);
1148 mEmailAttachList
->setEditable(true);
1149 mEmailAttachList
->setMinimumSize(mEmailAttachList
->sizeHint());
1150 if (mEmailAttachList
->lineEdit())
1151 mEmailAttachList
->lineEdit()->setReadOnly(true);
1152 label
->setBuddy(mEmailAttachList
);
1153 mEmailAttachList
->setWhatsThis(i18nc("@info:whatsthis", "Files to send as attachments to the email."));
1154 grid
->addWidget(mEmailAttachList
, 0, 1);
1155 grid
->setColumnStretch(1, 1);
1157 mEmailAddAttachButton
= new QPushButton(i18nc("@action:button", "Add..."), parent
);
1158 connect(mEmailAddAttachButton
, &QPushButton::clicked
, this, &EditEmailAlarmDlg::slotAddAttachment
);
1159 mEmailAddAttachButton
->setWhatsThis(i18nc("@info:whatsthis", "Add an attachment to the email."));
1160 grid
->addWidget(mEmailAddAttachButton
, 0, 2);
1162 mEmailRemoveButton
= new QPushButton(i18nc("@action:button", "Remove"), parent
);
1163 connect(mEmailRemoveButton
, &QPushButton::clicked
, this, &EditEmailAlarmDlg::slotRemoveAttachment
);
1164 mEmailRemoveButton
->setWhatsThis(i18nc("@info:whatsthis", "Remove the highlighted attachment from the email."));
1165 grid
->addWidget(mEmailRemoveButton
, 1, 2);
1167 // BCC email to sender
1168 mEmailBcc
= new CheckBox(i18n_chk_CopyEmailToSelf(), parent
);
1169 mEmailBcc
->setFixedSize(mEmailBcc
->sizeHint());
1170 mEmailBcc
->setWhatsThis(i18nc("@info:whatsthis", "If checked, the email will be blind copied to you."));
1171 connect(mEmailBcc
, &CheckBox::toggled
, this, &EditEmailAlarmDlg::contentsChanged
);
1172 grid
->addWidget(mEmailBcc
, 1, 0, 1, 2, Qt::AlignLeft
);
1175 /******************************************************************************
1176 * Initialise the dialog controls from the specified event.
1178 void EditEmailAlarmDlg::type_initValues(const KAEvent
* event
)
1182 // Set the values to those for the specified event
1183 mEmailAttachList
->addItems(event
->emailAttachments());
1184 mEmailToEdit
->setText(event
->emailAddresses(QStringLiteral(", ")));
1185 mEmailSubjectEdit
->setText(event
->emailSubject());
1186 mEmailBcc
->setChecked(event
->emailBcc());
1188 mEmailFromList
->setCurrentIdentity(event
->emailFromId());
1192 // Set the values to their defaults
1193 mEmailBcc
->setChecked(Preferences::defaultEmailBcc());
1198 /******************************************************************************
1199 * Enable/disable controls depending on whether any attachments are entered.
1201 void EditEmailAlarmDlg::attachmentEnable()
1203 bool enable
= mEmailAttachList
->count();
1204 mEmailAttachList
->setEnabled(enable
);
1205 if (mEmailRemoveButton
)
1206 mEmailRemoveButton
->setEnabled(enable
);
1209 /******************************************************************************
1210 * Set the dialog's action and the action's text.
1212 void EditEmailAlarmDlg::setAction(KAEvent::SubAction action
, const AlarmText
& alarmText
)
1215 Q_ASSERT(action
== KAEvent::EMAIL
);
1216 if (alarmText
.isEmail())
1218 mEmailToEdit
->setText(alarmText
.to());
1219 mEmailSubjectEdit
->setText(alarmText
.subject());
1220 mEmailMessageEdit
->setPlainText(alarmText
.body());
1223 mEmailMessageEdit
->setPlainText(alarmText
.displayText());
1226 /******************************************************************************
1227 * Initialise various values in the New Alarm dialogue.
1229 void EditEmailAlarmDlg::setEmailFields(uint fromID
, const KCalCore::Person::List
& addresses
,
1230 const QString
& subject
, const QStringList
& attachments
)
1233 mEmailFromList
->setCurrentIdentity(fromID
);
1234 if (!addresses
.isEmpty())
1235 mEmailToEdit
->setText(KAEvent::joinEmailAddresses(addresses
, QStringLiteral(", ")));
1236 if (!subject
.isEmpty())
1237 mEmailSubjectEdit
->setText(subject
);
1238 if (!attachments
.isEmpty())
1240 mEmailAttachList
->addItems(attachments
);
1244 void EditEmailAlarmDlg::setBcc(bool bcc
)
1246 mEmailBcc
->setChecked(bcc
);
1249 /******************************************************************************
1250 * Set the read-only status of all non-template controls.
1252 void EditEmailAlarmDlg::setReadOnly(bool readOnly
)
1254 mEmailToEdit
->setReadOnly(readOnly
);
1255 mEmailSubjectEdit
->setReadOnly(readOnly
);
1256 mEmailMessageEdit
->setReadOnly(readOnly
);
1257 mEmailBcc
->setReadOnly(readOnly
);
1259 mEmailFromList
->setReadOnly(readOnly
);
1262 mEmailAddressButton
->hide();
1263 mEmailAddAttachButton
->hide();
1264 mEmailRemoveButton
->hide();
1268 mEmailAddressButton
->show();
1269 mEmailAddAttachButton
->show();
1270 mEmailRemoveButton
->show();
1272 EditAlarmDlg::setReadOnly(readOnly
);
1275 /******************************************************************************
1276 * Save the state of all controls.
1278 void EditEmailAlarmDlg::saveState(const KAEvent
* event
)
1280 EditAlarmDlg::saveState(event
);
1282 mSavedEmailFrom
= mEmailFromList
->currentIdentityName();
1283 mSavedEmailTo
= mEmailToEdit
->text();
1284 mSavedEmailSubject
= mEmailSubjectEdit
->text();
1285 mSavedEmailAttach
.clear();
1286 for (int i
= 0, end
= mEmailAttachList
->count(); i
< end
; ++i
)
1287 mSavedEmailAttach
+= mEmailAttachList
->itemText(i
);
1288 mSavedEmailBcc
= mEmailBcc
->isChecked();
1291 /******************************************************************************
1292 * Check whether any of the controls has changed state since the dialog was
1294 * Reply = true if any controls have changed, or if it's a new event.
1295 * = false if no controls have changed.
1297 bool EditEmailAlarmDlg::type_stateChanged() const
1299 QStringList emailAttach
;
1300 for (int i
= 0, end
= mEmailAttachList
->count(); i
< end
; ++i
)
1301 emailAttach
+= mEmailAttachList
->itemText(i
);
1302 if ((mEmailFromList
&& mSavedEmailFrom
!= mEmailFromList
->currentIdentityName())
1303 || mSavedEmailTo
!= mEmailToEdit
->text()
1304 || mSavedEmailSubject
!= mEmailSubjectEdit
->text()
1305 || mSavedEmailAttach
!= emailAttach
1306 || mSavedEmailBcc
!= mEmailBcc
->isChecked())
1311 /******************************************************************************
1312 * Extract the data in the dialog specific to the alarm type and set up a
1315 void EditEmailAlarmDlg::type_setEvent(KAEvent
& event
, const KDateTime
& dt
, const QString
& text
, int lateCancel
, bool trial
)
1318 event
.set(dt
, text
, QColor(), QColor(), QFont(), KAEvent::EMAIL
, lateCancel
, getAlarmFlags());
1319 uint from
= mEmailFromList
? mEmailFromList
->currentIdentity() : 0;
1320 event
.setEmail(from
, mEmailAddresses
, mEmailSubjectEdit
->text(), mEmailAttachments
);
1323 /******************************************************************************
1324 * Get the currently specified alarm flag bits.
1326 KAEvent::Flags
EditEmailAlarmDlg::getAlarmFlags() const
1328 KAEvent::Flags flags
= EditAlarmDlg::getAlarmFlags();
1329 if (mEmailBcc
->isChecked()) flags
|= KAEvent::EMAIL_BCC
;
1333 /******************************************************************************
1334 * Convert the email addresses to a list, and validate them. Convert the email
1335 * attachments to a list.
1337 bool EditEmailAlarmDlg::type_validate(bool trial
)
1339 QString addrs
= mEmailToEdit
->text();
1340 if (addrs
.isEmpty())
1341 mEmailAddresses
.clear();
1344 QString bad
= KAMail::convertAddresses(addrs
, mEmailAddresses
);
1347 mEmailToEdit
->setFocus();
1348 KAMessageBox::error(this, xi18nc("@info", "Invalid email address: <email>%1</email>", bad
));
1352 if (mEmailAddresses
.isEmpty())
1354 mEmailToEdit
->setFocus();
1355 KAMessageBox::error(this, i18nc("@info", "No email address specified"));
1359 mEmailAttachments
.clear();
1360 for (int i
= 0, end
= mEmailAttachList
->count(); i
< end
; ++i
)
1362 QString att
= mEmailAttachList
->itemText(i
);
1363 switch (KAMail::checkAttachment(att
))
1366 mEmailAttachments
.append(att
);
1371 mEmailAttachList
->setFocus();
1372 KAMessageBox::error(this, xi18nc("@info", "Invalid email attachment: <filename>%1</filename>", att
));
1376 if (trial
&& KAMessageBox::warningContinueCancel(this, i18nc("@info", "Do you really want to send the email now to the specified recipient(s)?"),
1377 i18nc("@action:button", "Confirm Email"), KGuiItem(i18nc("@action:button", "Send"))) != KMessageBox::Continue
)
1382 /******************************************************************************
1383 * Called when the Try action is about to be executed.
1385 void EditEmailAlarmDlg::type_aboutToTry()
1387 // Disconnect any previous connections, to prevent multiple messages being output
1388 disconnect(theApp(), &KAlarmApp::execAlarmSuccess
, this, &EditEmailAlarmDlg::slotTrySuccess
);
1389 connect(theApp(), &KAlarmApp::execAlarmSuccess
, this, &EditEmailAlarmDlg::slotTrySuccess
);
1392 /******************************************************************************
1393 * Tell the user the result of the Try action.
1395 void EditEmailAlarmDlg::slotTrySuccess()
1397 disconnect(theApp(), &KAlarmApp::execAlarmSuccess
, this, &EditEmailAlarmDlg::slotTrySuccess
);
1399 QString to
= KAEvent::joinEmailAddresses(mEmailAddresses
, QStringLiteral("<nl/>"));
1400 to
.replace(QLatin1Char('<'), QStringLiteral("<"));
1401 to
.replace(QLatin1Char('>'), QStringLiteral(">"));
1402 if (mEmailBcc
->isChecked())
1403 msg
= QLatin1String("<qt>") + xi18nc("@info", "Email sent to:<nl/>%1<nl/>Bcc: <email>%2</email>",
1404 to
, Preferences::emailBccAddress()) + QLatin1String("</qt>");
1406 msg
= QLatin1String("<qt>") + xi18nc("@info", "Email sent to:<nl/>%1", to
) + QLatin1String("</qt>");
1407 KAMessageBox::information(this, msg
);
1410 /******************************************************************************
1411 * Get a selection from the Address Book.
1413 void EditEmailAlarmDlg::openAddressBook()
1415 // Use AutoQPointer to guard against crash on application exit while
1416 // the dialogue is still open. It prevents double deletion (both on
1417 // deletion of MainWindow, and on return from this function).
1418 AutoQPointer
<Akonadi::EmailAddressSelectionDialog
> dlg
= new Akonadi::EmailAddressSelectionDialog(this);
1419 if (dlg
->exec() != QDialog::Accepted
)
1422 Akonadi::EmailAddressSelection::List selections
= dlg
->selectedAddresses();
1423 if (selections
.isEmpty())
1425 Person
person(selections
.first().name(), selections
.first().email());
1426 QString addrs
= mEmailToEdit
->text().trimmed();
1427 if (!addrs
.isEmpty())
1428 addrs
+= QLatin1String(", ");
1429 addrs
+= person
.fullName();
1430 mEmailToEdit
->setText(addrs
);
1433 /******************************************************************************
1434 * Select a file to attach to the email.
1436 void EditEmailAlarmDlg::slotAddAttachment()
1438 QString url
= KAlarm::browseFile(i18nc("@title:window", "Choose File to Attach"), mAttachDefaultDir
, QString(),
1439 QString(), KFile::ExistingOnly
, this);
1442 mEmailAttachList
->addItem(url
);
1443 mEmailAttachList
->setCurrentIndex(mEmailAttachList
->count() - 1); // select the new item
1444 mEmailRemoveButton
->setEnabled(true);
1445 mEmailAttachList
->setEnabled(true);
1450 /******************************************************************************
1451 * Remove the currently selected attachment from the email.
1453 void EditEmailAlarmDlg::slotRemoveAttachment()
1455 int item
= mEmailAttachList
->currentIndex();
1456 mEmailAttachList
->removeItem(item
);
1457 int count
= mEmailAttachList
->count();
1459 mEmailAttachList
->setCurrentIndex(count
- 1);
1462 mEmailRemoveButton
->setEnabled(false);
1463 mEmailAttachList
->setEnabled(false);
1468 /******************************************************************************
1469 * Clean up the alarm text.
1471 bool EditEmailAlarmDlg::checkText(QString
& result
, bool showErrorMessage
) const
1473 Q_UNUSED(showErrorMessage
);
1474 result
= mEmailMessageEdit
->toPlainText();
1479 /*=============================================================================
1480 = Class EditAudioAlarmDlg
1481 = Dialog to edit audio alarms with no display window.
1482 =============================================================================*/
1484 /******************************************************************************
1487 * Template = true to edit/create an alarm template
1488 * = false to edit/create an alarm.
1489 * event != to initialise the dialog to show the specified event's data.
1491 EditAudioAlarmDlg::EditAudioAlarmDlg(bool Template
, QWidget
* parent
, GetResourceType getResource
)
1492 : EditAlarmDlg(Template
, KAEvent::AUDIO
, parent
, getResource
),
1493 mMessageWin(Q_NULLPTR
)
1495 qCDebug(KALARM_LOG
) << "New";
1499 EditAudioAlarmDlg::EditAudioAlarmDlg(bool Template
, const KAEvent
* event
, bool newAlarm
, QWidget
* parent
,
1500 GetResourceType getResource
, bool readOnly
)
1501 : EditAlarmDlg(Template
, event
, newAlarm
, parent
, getResource
, readOnly
),
1502 mMessageWin(Q_NULLPTR
)
1504 qCDebug(KALARM_LOG
) << "Event.id()";
1506 mTryButton
->setEnabled(!MessageWin::isAudioPlaying());
1507 connect(theApp(), &KAlarmApp::audioPlaying
, this, &EditAudioAlarmDlg::slotAudioPlaying
);
1510 /******************************************************************************
1511 * Return the window caption.
1513 QString
EditAudioAlarmDlg::type_caption() const
1515 return isTemplate() ? (isNewAlarm() ? i18nc("@title:window", "New Audio Alarm Template") : i18nc("@title:window", "Edit Audio Alarm Template"))
1516 : (isNewAlarm() ? i18nc("@title:window", "New Audio Alarm") : i18nc("@title:window", "Edit Audio Alarm"));
1519 /******************************************************************************
1520 * Set up the dialog controls common to display alarms.
1522 void EditAudioAlarmDlg::type_init(QWidget
* parent
, QVBoxLayout
* frameLayout
)
1524 // File name edit box
1525 mSoundConfig
= new SoundWidget(false, true, parent
);
1527 mSoundConfig
->setAllowEmptyFile();
1528 connect(mSoundConfig
, &SoundWidget::changed
, this, &EditAudioAlarmDlg::contentsChanged
);
1529 frameLayout
->addWidget(mSoundConfig
);
1531 // Top-adjust the controls
1532 mPadding
= new QWidget(parent
);
1533 QHBoxLayout
* hlayout
= new QHBoxLayout(mPadding
);
1534 hlayout
->setMargin(0);
1535 hlayout
->setSpacing(0);
1536 frameLayout
->addWidget(mPadding
);
1537 frameLayout
->setStretchFactor(mPadding
, 1);
1540 /******************************************************************************
1541 * Initialise the dialog controls from the specified event.
1543 void EditAudioAlarmDlg::type_initValues(const KAEvent
* event
)
1547 mSoundConfig
->set(event
->audioFile(), event
->soundVolume(), event
->fadeVolume(), event
->fadeSeconds(),
1548 (event
->flags() & KAEvent::REPEAT_SOUND
) ? event
->repeatSoundPause() : -1);
1552 // Set the values to their defaults
1553 mSoundConfig
->set(Preferences::defaultSoundFile(), Preferences::defaultSoundVolume(),
1554 -1, 0, (Preferences::defaultSoundRepeat() ? 0 : -1));
1558 /******************************************************************************
1559 * Initialise various values in the New Alarm dialogue.
1561 void EditAudioAlarmDlg::setAudio(const QString
& file
, float volume
)
1563 mSoundConfig
->set(file
, volume
);
1566 /******************************************************************************
1567 * Set the dialog's action and the action's text.
1569 void EditAudioAlarmDlg::setAction(KAEvent::SubAction action
, const AlarmText
& alarmText
)
1572 Q_ASSERT(action
== KAEvent::AUDIO
);
1573 mSoundConfig
->set(alarmText
.displayText(), Preferences::defaultSoundVolume());
1576 /******************************************************************************
1577 * Set the read-only status of all non-template controls.
1579 void EditAudioAlarmDlg::setReadOnly(bool readOnly
)
1581 mSoundConfig
->setReadOnly(readOnly
);
1582 EditAlarmDlg::setReadOnly(readOnly
);
1585 /******************************************************************************
1586 * Save the state of all controls.
1588 void EditAudioAlarmDlg::saveState(const KAEvent
* event
)
1590 EditAlarmDlg::saveState(event
);
1591 mSavedFile
= mSoundConfig
->fileName();
1592 mSoundConfig
->getVolume(mSavedVolume
, mSavedFadeVolume
, mSavedFadeSeconds
);
1593 mSavedRepeatPause
= mSoundConfig
->repeatPause();
1596 /******************************************************************************
1597 * Check whether any of the controls has changed state since the dialog was
1599 * Reply = true if any controls have changed, or if it's a new event.
1600 * = false if no controls have changed.
1602 bool EditAudioAlarmDlg::type_stateChanged() const
1604 if (mSavedFile
!= mSoundConfig
->fileName())
1606 if (!mSavedFile
.isEmpty() || isTemplate())
1608 float volume
, fadeVolume
;
1610 mSoundConfig
->getVolume(volume
, fadeVolume
, fadeSecs
);
1611 if (mSavedRepeatPause
!= mSoundConfig
->repeatPause()
1612 || mSavedVolume
!= volume
1613 || mSavedFadeVolume
!= fadeVolume
1614 || mSavedFadeSeconds
!= fadeSecs
)
1620 /******************************************************************************
1621 * Extract the data in the dialog specific to the alarm type and set up a
1624 void EditAudioAlarmDlg::type_setEvent(KAEvent
& event
, const KDateTime
& dt
, const QString
& text
, int lateCancel
, bool trial
)
1628 event
.set(dt
, QString(), QColor(), QColor(), QFont(), KAEvent::AUDIO
, lateCancel
, getAlarmFlags());
1629 float volume
, fadeVolume
;
1631 mSoundConfig
->getVolume(volume
, fadeVolume
, fadeSecs
);
1632 int repeatPause
= mSoundConfig
->repeatPause();
1634 mSoundConfig
->file(url
, false);
1635 event
.setAudioFile(url
.toString(), volume
, fadeVolume
, fadeSecs
, repeatPause
, isTemplate());
1638 /******************************************************************************
1639 * Get the currently specified alarm flag bits.
1641 KAEvent::Flags
EditAudioAlarmDlg::getAlarmFlags() const
1643 KAEvent::Flags flags
= EditAlarmDlg::getAlarmFlags();
1644 if (mSoundConfig
->repeatPause() >= 0) flags
|= KAEvent::REPEAT_SOUND
;
1648 /******************************************************************************
1649 * Check whether the file name is valid.
1651 bool EditAudioAlarmDlg::checkText(QString
& result
, bool showErrorMessage
) const
1654 if (!mSoundConfig
->file(url
, showErrorMessage
))
1659 result
= url
.isLocalFile() ? url
.toLocalFile() : url
.toString();
1663 /******************************************************************************
1664 * Called when the Try button is clicked.
1665 * If the audio file is currently playing (as a result of previously clicking
1666 * the Try button), cancel playback. Otherwise, play the audio file.
1668 void EditAudioAlarmDlg::slotTry()
1670 if (!MessageWin::isAudioPlaying())
1671 EditAlarmDlg::slotTry(); // play the audio file
1672 else if (mMessageWin
)
1674 mMessageWin
->stopAudio();
1675 mMessageWin
= Q_NULLPTR
;
1679 /******************************************************************************
1680 * Called when the Try action has been executed.
1682 void EditAudioAlarmDlg::type_executedTry(const QString
&, void* result
)
1684 mMessageWin
= (MessageWin
*)result
; // note which MessageWin controls the audio playback
1687 slotAudioPlaying(true);
1688 connect(mMessageWin
, &MessageWin::destroyed
, this, &EditAudioAlarmDlg::audioWinDestroyed
);
1692 /******************************************************************************
1693 * Called when audio playing starts or stops.
1694 * Enable/disable/toggle the Try button.
1696 void EditAudioAlarmDlg::slotAudioPlaying(bool playing
)
1700 // Nothing is playing, so enable the Try button
1701 mTryButton
->setEnabled(true);
1702 mTryButton
->setCheckable(false);
1703 mTryButton
->setChecked(false);
1704 mMessageWin
= Q_NULLPTR
;
1706 else if (mMessageWin
)
1708 // The test sound file is playing, so enable the Try button and depress it
1709 mTryButton
->setEnabled(true);
1710 mTryButton
->setCheckable(true);
1711 mTryButton
->setChecked(true);
1715 // An alarm is playing, so disable the Try button
1716 mTryButton
->setEnabled(false);
1717 mTryButton
->setCheckable(false);
1718 mTryButton
->setChecked(false);
1723 /*=============================================================================
1725 = A widget to allow entry of a command or a command script.
1726 =============================================================================*/
1727 CommandEdit::CommandEdit(QWidget
* parent
)
1730 QVBoxLayout
* vlayout
= new QVBoxLayout(this);
1731 vlayout
->setMargin(0);
1732 vlayout
->setSpacing(style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing
));
1733 mTypeScript
= new CheckBox(EditCommandAlarmDlg::i18n_chk_EnterScript(), this);
1734 mTypeScript
->setFixedSize(mTypeScript
->sizeHint());
1735 mTypeScript
->setWhatsThis(i18nc("@info:whatsthis", "Check to enter the contents of a script instead of a shell command line"));
1736 connect(mTypeScript
, &CheckBox::toggled
, this, &CommandEdit::slotCmdScriptToggled
);
1737 connect(mTypeScript
, &CheckBox::toggled
, this, &CommandEdit::changed
);
1738 vlayout
->addWidget(mTypeScript
, 0, Qt::AlignLeft
);
1740 mCommandEdit
= new LineEdit(LineEdit::Url
, this);
1741 mCommandEdit
->setWhatsThis(i18nc("@info:whatsthis", "Enter a shell command to execute."));
1742 connect(mCommandEdit
, &LineEdit::textChanged
, this, &CommandEdit::changed
);
1743 vlayout
->addWidget(mCommandEdit
);
1745 mScriptEdit
= new TextEdit(this);
1746 mScriptEdit
->setWhatsThis(i18nc("@info:whatsthis", "Enter the contents of a script to execute"));
1747 connect(mScriptEdit
, &TextEdit::textChanged
, this, &CommandEdit::changed
);
1748 vlayout
->addWidget(mScriptEdit
);
1750 slotCmdScriptToggled(mTypeScript
->isChecked());
1753 /******************************************************************************
1754 * Initialise the widget controls from the specified event.
1756 void CommandEdit::setScript(bool script
)
1758 mTypeScript
->setChecked(script
);
1761 bool CommandEdit::isScript() const
1763 return mTypeScript
->isChecked();
1766 /******************************************************************************
1767 * Set the widget's text.
1769 void CommandEdit::setText(const AlarmText
& alarmText
)
1771 QString text
= alarmText
.displayText();
1772 bool script
= alarmText
.isScript();
1773 mTypeScript
->setChecked(script
);
1775 mScriptEdit
->setPlainText(text
);
1777 mCommandEdit
->setText(KAlarm::pathOrUrl(text
));
1780 /******************************************************************************
1781 * Return the widget's text.
1783 QString
CommandEdit::text() const
1786 if (mTypeScript
->isChecked())
1787 result
= mScriptEdit
->toPlainText();
1789 result
= mCommandEdit
->text();
1790 return result
.trimmed();
1793 /******************************************************************************
1794 * Return the alarm text.
1795 * If 'showErrorMessage' is true and the text is empty, an error message is
1798 QString
CommandEdit::text(EditAlarmDlg
* dlg
, bool showErrorMessage
) const
1800 QString result
= text();
1801 if (showErrorMessage
&& result
.isEmpty())
1802 KAMessageBox::sorry(dlg
, i18nc("@info", "Please enter a command or script to execute"));
1806 /******************************************************************************
1807 * Set the read-only status of all controls.
1809 void CommandEdit::setReadOnly(bool readOnly
)
1811 mTypeScript
->setReadOnly(readOnly
);
1812 mCommandEdit
->setReadOnly(readOnly
);
1813 mScriptEdit
->setReadOnly(readOnly
);
1816 /******************************************************************************
1817 * Called when one of the command type radio buttons is clicked,
1818 * to display the appropriate edit field.
1820 void CommandEdit::slotCmdScriptToggled(bool on
)
1824 mCommandEdit
->hide();
1825 mScriptEdit
->show();
1826 mScriptEdit
->setFocus();
1830 mScriptEdit
->hide();
1831 mCommandEdit
->show();
1832 mCommandEdit
->setFocus();
1834 Q_EMIT
scriptToggled(on
);
1837 /******************************************************************************
1838 * Returns the minimum size of the widget.
1840 QSize
CommandEdit::minimumSizeHint() const
1842 QSize
t(mTypeScript
->minimumSizeHint());
1843 QSize
s(mCommandEdit
->minimumSizeHint().expandedTo(mScriptEdit
->minimumSizeHint()));
1844 s
.setHeight(s
.height() + style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing
) + t
.height());
1845 if (s
.width() < t
.width())
1846 s
.setWidth(t
.width());
1852 /*=============================================================================
1854 = A text edit field with a minimum height of 3 text lines.
1855 =============================================================================*/
1856 TextEdit::TextEdit(QWidget
* parent
)
1859 QSize tsize
= sizeHint();
1860 tsize
.setHeight(fontMetrics().lineSpacing()*13/4 + 2*frameWidth());
1861 setMinimumSize(tsize
);
1864 void TextEdit::dragEnterEvent(QDragEnterEvent
* e
)
1866 if (KCalUtils::ICalDrag::canDecode(e
->mimeData()))
1867 e
->ignore(); // don't accept "text/calendar" objects
1868 KTextEdit::dragEnterEvent(e
);