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 <kio/netaccess.h>
60 #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 virtual QString
pickFile() // 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(0),
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(0),
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
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(SmallIcon(QLatin1String("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*spacingHint());
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(0);
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().prettyUrl(), 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
)
611 case tTEXT
: // text message
613 mFilePadding
->hide();
615 mTextMessageEdit
->show();
616 mSoundPicker
->showSpeak(true);
617 setButtonWhatsThis(Try
, 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 setButtonWhatsThis(Try
, 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 setButtonWhatsThis(Try
, 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(KFileItem(KFileItem::Unknown
, KFileItem::Unknown
, url
).currentMimeType()))
692 case KAlarm::TextFormatted
:
693 case KAlarm::TextPlain
:
694 case KAlarm::TextApplication
:
698 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 setButtonWhatsThis(Try
, 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(marginHint());
781 vlayout
->setSpacing(spacingHint());
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(SmallIcon(QLatin1String("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
, 0);
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(0)
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(0)
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 setButtonWhatsThis(Try
, 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
);
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(SmallIcon(QLatin1String("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 KComboBox(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(QLatin1String(", ")));
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
, QLatin1String(", ")));
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(), SIGNAL(execAlarmSuccess()), this, SLOT(slotTrySuccess()));
1389 connect(theApp(), SIGNAL(execAlarmSuccess()), SLOT(slotTrySuccess()));
1392 /******************************************************************************
1393 * Tell the user the result of the Try action.
1395 void EditEmailAlarmDlg::slotTrySuccess()
1397 disconnect(theApp(), SIGNAL(execAlarmSuccess()), this, SLOT(slotTrySuccess()));
1399 QString to
= KAEvent::joinEmailAddresses(mEmailAddresses
, QLatin1String("<nl/>"));
1400 to
.replace(QLatin1Char('<'), QLatin1String("<"));
1401 to
.replace(QLatin1Char('>'), QLatin1String(">"));
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
),
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
),
1504 qCDebug(KALARM_LOG
) << "Event.id()";
1506 QPushButton
* tryButton
= button(Try
);
1507 tryButton
->setEnabled(!MessageWin::isAudioPlaying());
1508 connect(theApp(), SIGNAL(audioPlaying(bool)), SLOT(slotAudioPlaying(bool)));
1511 /******************************************************************************
1512 * Return the window caption.
1514 QString
EditAudioAlarmDlg::type_caption() const
1516 return isTemplate() ? (isNewAlarm() ? i18nc("@title:window", "New Audio Alarm Template") : i18nc("@title:window", "Edit Audio Alarm Template"))
1517 : (isNewAlarm() ? i18nc("@title:window", "New Audio Alarm") : i18nc("@title:window", "Edit Audio Alarm"));
1520 /******************************************************************************
1521 * Set up the dialog controls common to display alarms.
1523 void EditAudioAlarmDlg::type_init(QWidget
* parent
, QVBoxLayout
* frameLayout
)
1525 // File name edit box
1526 mSoundConfig
= new SoundWidget(false, true, parent
);
1528 mSoundConfig
->setAllowEmptyFile();
1529 connect(mSoundConfig
, &SoundWidget::changed
, this, &EditAudioAlarmDlg::contentsChanged
);
1530 frameLayout
->addWidget(mSoundConfig
);
1532 // Top-adjust the controls
1533 mPadding
= new QWidget(parent
);
1534 QHBoxLayout
* hlayout
= new QHBoxLayout(mPadding
);
1535 hlayout
->setMargin(0);
1536 hlayout
->setSpacing(0);
1537 frameLayout
->addWidget(mPadding
);
1538 frameLayout
->setStretchFactor(mPadding
, 1);
1541 /******************************************************************************
1542 * Initialise the dialog controls from the specified event.
1544 void EditAudioAlarmDlg::type_initValues(const KAEvent
* event
)
1548 mSoundConfig
->set(event
->audioFile(), event
->soundVolume(), event
->fadeVolume(), event
->fadeSeconds(),
1549 (event
->flags() & KAEvent::REPEAT_SOUND
) ? event
->repeatSoundPause() : -1);
1553 // Set the values to their defaults
1554 mSoundConfig
->set(Preferences::defaultSoundFile(), Preferences::defaultSoundVolume(),
1555 -1, 0, (Preferences::defaultSoundRepeat() ? 0 : -1));
1559 /******************************************************************************
1560 * Initialise various values in the New Alarm dialogue.
1562 void EditAudioAlarmDlg::setAudio(const QString
& file
, float volume
)
1564 mSoundConfig
->set(file
, volume
);
1567 /******************************************************************************
1568 * Set the dialog's action and the action's text.
1570 void EditAudioAlarmDlg::setAction(KAEvent::SubAction action
, const AlarmText
& alarmText
)
1573 Q_ASSERT(action
== KAEvent::AUDIO
);
1574 mSoundConfig
->set(alarmText
.displayText(), Preferences::defaultSoundVolume());
1577 /******************************************************************************
1578 * Set the read-only status of all non-template controls.
1580 void EditAudioAlarmDlg::setReadOnly(bool readOnly
)
1582 mSoundConfig
->setReadOnly(readOnly
);
1583 EditAlarmDlg::setReadOnly(readOnly
);
1586 /******************************************************************************
1587 * Save the state of all controls.
1589 void EditAudioAlarmDlg::saveState(const KAEvent
* event
)
1591 EditAlarmDlg::saveState(event
);
1592 mSavedFile
= mSoundConfig
->fileName();
1593 mSoundConfig
->getVolume(mSavedVolume
, mSavedFadeVolume
, mSavedFadeSeconds
);
1594 mSavedRepeatPause
= mSoundConfig
->repeatPause();
1597 /******************************************************************************
1598 * Check whether any of the controls has changed state since the dialog was
1600 * Reply = true if any controls have changed, or if it's a new event.
1601 * = false if no controls have changed.
1603 bool EditAudioAlarmDlg::type_stateChanged() const
1605 if (mSavedFile
!= mSoundConfig
->fileName())
1607 if (!mSavedFile
.isEmpty() || isTemplate())
1609 float volume
, fadeVolume
;
1611 mSoundConfig
->getVolume(volume
, fadeVolume
, fadeSecs
);
1612 if (mSavedRepeatPause
!= mSoundConfig
->repeatPause()
1613 || mSavedVolume
!= volume
1614 || mSavedFadeVolume
!= fadeVolume
1615 || mSavedFadeSeconds
!= fadeSecs
)
1621 /******************************************************************************
1622 * Extract the data in the dialog specific to the alarm type and set up a
1625 void EditAudioAlarmDlg::type_setEvent(KAEvent
& event
, const KDateTime
& dt
, const QString
& text
, int lateCancel
, bool trial
)
1629 event
.set(dt
, QString(), QColor(), QColor(), QFont(), KAEvent::AUDIO
, lateCancel
, getAlarmFlags());
1630 float volume
, fadeVolume
;
1632 mSoundConfig
->getVolume(volume
, fadeVolume
, fadeSecs
);
1633 int repeatPause
= mSoundConfig
->repeatPause();
1635 mSoundConfig
->file(url
, false);
1636 event
.setAudioFile(url
.prettyUrl(), volume
, fadeVolume
, fadeSecs
, repeatPause
, isTemplate());
1639 /******************************************************************************
1640 * Get the currently specified alarm flag bits.
1642 KAEvent::Flags
EditAudioAlarmDlg::getAlarmFlags() const
1644 KAEvent::Flags flags
= EditAlarmDlg::getAlarmFlags();
1645 if (mSoundConfig
->repeatPause() >= 0) flags
|= KAEvent::REPEAT_SOUND
;
1649 /******************************************************************************
1650 * Check whether the file name is valid.
1652 bool EditAudioAlarmDlg::checkText(QString
& result
, bool showErrorMessage
) const
1655 if (!mSoundConfig
->file(url
, showErrorMessage
))
1660 result
= url
.pathOrUrl();
1664 /******************************************************************************
1665 * Called when the Try button is clicked.
1666 * If the audio file is currently playing (as a result of previously clicking
1667 * the Try button), cancel playback. Otherwise, play the audio file.
1669 void EditAudioAlarmDlg::slotTry()
1671 if (!MessageWin::isAudioPlaying())
1672 EditAlarmDlg::slotTry(); // play the audio file
1673 else if (mMessageWin
)
1675 mMessageWin
->stopAudio();
1680 /******************************************************************************
1681 * Called when the Try action has been executed.
1683 void EditAudioAlarmDlg::type_executedTry(const QString
&, void* result
)
1685 mMessageWin
= (MessageWin
*)result
; // note which MessageWin controls the audio playback
1688 slotAudioPlaying(true);
1689 connect(mMessageWin
, &MessageWin::destroyed
, this, &EditAudioAlarmDlg::audioWinDestroyed
);
1693 /******************************************************************************
1694 * Called when audio playing starts or stops.
1695 * Enable/disable/toggle the Try button.
1697 void EditAudioAlarmDlg::slotAudioPlaying(bool playing
)
1699 QPushButton
* tryButton
= button(Try
);
1702 // Nothing is playing, so enable the Try button
1703 tryButton
->setEnabled(true);
1704 tryButton
->setCheckable(false);
1705 tryButton
->setChecked(false);
1708 else if (mMessageWin
)
1710 // The test sound file is playing, so enable the Try button and depress it
1711 tryButton
->setEnabled(true);
1712 tryButton
->setCheckable(true);
1713 tryButton
->setChecked(true);
1717 // An alarm is playing, so disable the Try button
1718 tryButton
->setEnabled(false);
1719 tryButton
->setCheckable(false);
1720 tryButton
->setChecked(false);
1725 /*=============================================================================
1727 = A widget to allow entry of a command or a command script.
1728 =============================================================================*/
1729 CommandEdit::CommandEdit(QWidget
* parent
)
1732 QVBoxLayout
* vlayout
= new QVBoxLayout(this);
1733 vlayout
->setMargin(0);
1734 vlayout
->setSpacing(KDialog::spacingHint());
1735 mTypeScript
= new CheckBox(EditCommandAlarmDlg::i18n_chk_EnterScript(), this);
1736 mTypeScript
->setFixedSize(mTypeScript
->sizeHint());
1737 mTypeScript
->setWhatsThis(i18nc("@info:whatsthis", "Check to enter the contents of a script instead of a shell command line"));
1738 connect(mTypeScript
, &CheckBox::toggled
, this, &CommandEdit::slotCmdScriptToggled
);
1739 connect(mTypeScript
, &CheckBox::toggled
, this, &CommandEdit::changed
);
1740 vlayout
->addWidget(mTypeScript
, 0, Qt::AlignLeft
);
1742 mCommandEdit
= new LineEdit(LineEdit::Url
, this);
1743 mCommandEdit
->setWhatsThis(i18nc("@info:whatsthis", "Enter a shell command to execute."));
1744 connect(mCommandEdit
, &LineEdit::textChanged
, this, &CommandEdit::changed
);
1745 vlayout
->addWidget(mCommandEdit
);
1747 mScriptEdit
= new TextEdit(this);
1748 mScriptEdit
->setWhatsThis(i18nc("@info:whatsthis", "Enter the contents of a script to execute"));
1749 connect(mScriptEdit
, &TextEdit::textChanged
, this, &CommandEdit::changed
);
1750 vlayout
->addWidget(mScriptEdit
);
1752 slotCmdScriptToggled(mTypeScript
->isChecked());
1755 /******************************************************************************
1756 * Initialise the widget controls from the specified event.
1758 void CommandEdit::setScript(bool script
)
1760 mTypeScript
->setChecked(script
);
1763 bool CommandEdit::isScript() const
1765 return mTypeScript
->isChecked();
1768 /******************************************************************************
1769 * Set the widget's text.
1771 void CommandEdit::setText(const AlarmText
& alarmText
)
1773 QString text
= alarmText
.displayText();
1774 bool script
= alarmText
.isScript();
1775 mTypeScript
->setChecked(script
);
1777 mScriptEdit
->setPlainText(text
);
1779 mCommandEdit
->setText(KAlarm::pathOrUrl(text
));
1782 /******************************************************************************
1783 * Return the widget's text.
1785 QString
CommandEdit::text() const
1788 if (mTypeScript
->isChecked())
1789 result
= mScriptEdit
->toPlainText();
1791 result
= mCommandEdit
->text();
1792 return result
.trimmed();
1795 /******************************************************************************
1796 * Return the alarm text.
1797 * If 'showErrorMessage' is true and the text is empty, an error message is
1800 QString
CommandEdit::text(EditAlarmDlg
* dlg
, bool showErrorMessage
) const
1802 QString result
= text();
1803 if (showErrorMessage
&& result
.isEmpty())
1804 KAMessageBox::sorry(dlg
, i18nc("@info", "Please enter a command or script to execute"));
1808 /******************************************************************************
1809 * Set the read-only status of all controls.
1811 void CommandEdit::setReadOnly(bool readOnly
)
1813 mTypeScript
->setReadOnly(readOnly
);
1814 mCommandEdit
->setReadOnly(readOnly
);
1815 mScriptEdit
->setReadOnly(readOnly
);
1818 /******************************************************************************
1819 * Called when one of the command type radio buttons is clicked,
1820 * to display the appropriate edit field.
1822 void CommandEdit::slotCmdScriptToggled(bool on
)
1826 mCommandEdit
->hide();
1827 mScriptEdit
->show();
1828 mScriptEdit
->setFocus();
1832 mScriptEdit
->hide();
1833 mCommandEdit
->show();
1834 mCommandEdit
->setFocus();
1836 emit
scriptToggled(on
);
1839 /******************************************************************************
1840 * Returns the minimum size of the widget.
1842 QSize
CommandEdit::minimumSizeHint() const
1844 QSize
t(mTypeScript
->minimumSizeHint());
1845 QSize
s(mCommandEdit
->minimumSizeHint().expandedTo(mScriptEdit
->minimumSizeHint()));
1846 s
.setHeight(s
.height() + KDialog::spacingHint() + t
.height());
1847 if (s
.width() < t
.width())
1848 s
.setWidth(t
.width());
1854 /*=============================================================================
1856 = A text edit field with a minimum height of 3 text lines.
1857 =============================================================================*/
1858 TextEdit::TextEdit(QWidget
* parent
)
1861 QSize tsize
= sizeHint();
1862 tsize
.setHeight(fontMetrics().lineSpacing()*13/4 + 2*frameWidth());
1863 setMinimumSize(tsize
);
1866 void TextEdit::dragEnterEvent(QDragEnterEvent
* e
)
1868 if (KCalUtils::ICalDrag::canDecode(e
->mimeData()))
1869 e
->ignore(); // don't accept "text/calendar" objects
1870 KTextEdit::dragEnterEvent(e
);