2 * editdlgtypes.cpp - dialogs to create or edit alarm or alarm template types
4 * Copyright © 2001-2011 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.moc"
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 "identities.h"
33 #include "kalarmapp.h"
35 #include "latecancel.h"
37 #include "mainwindow.h"
38 #include "messagebox.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 <akonadi/contact/emailaddressselectiondialog.h>
52 #include <kcalcore/person.h>
53 #include <kcalutils/icaldrag.h>
54 using namespace KCalCore
;
56 #include <kcal/person.h>
57 #include <kcal/icaldrag.h>
62 #include <kiconloader.h>
63 #include <kio/netaccess.h>
64 #include <kfileitem.h>
72 #include <QGridLayout>
73 #include <QHBoxLayout>
74 #include <QVBoxLayout>
75 #include <QDragEnterEvent>
76 #include <QStandardItemModel>
78 enum { tTEXT
, tFILE
, tCOMMAND
}; // order of mTypeCombo items
81 /*=============================================================================
82 = Class PickLogFileRadio
83 =============================================================================*/
84 class PickLogFileRadio
: public PickFileRadio
87 PickLogFileRadio(QPushButton
* b
, LineEdit
* e
, const QString
& text
, ButtonGroup
* group
, QWidget
* parent
)
88 : PickFileRadio(b
, e
, text
, group
, parent
) { }
89 virtual QString
pickFile() // called when browse button is pressed to select a log file
91 return KAlarm::browseFile(i18nc("@title:window", "Choose Log File"), mDefaultDir
, fileEdit()->text(), QString(),
92 KFile::LocalOnly
, parentWidget());
95 QString mDefaultDir
; // default directory for log file browse button
99 /*=============================================================================
100 = Class EditDisplayAlarmDlg
101 = Dialog to edit display alarms.
102 =============================================================================*/
104 QString
EditDisplayAlarmDlg::i18n_chk_ConfirmAck() { return i18nc("@option:check", "Confirm acknowledgment"); }
107 /******************************************************************************
110 * Template = true to edit/create an alarm template
111 * = false to edit/create an alarm.
112 * event != to initialise the dialog to show the specified event's data.
114 EditDisplayAlarmDlg::EditDisplayAlarmDlg(bool Template
, QWidget
* parent
, GetResourceType getResource
)
115 : EditAlarmDlg(Template
, KAEvent::MESSAGE
, parent
, getResource
),
116 mSpecialActionsButton(0),
117 mReminderDeferral(false),
118 mReminderArchived(false)
124 EditDisplayAlarmDlg::EditDisplayAlarmDlg(bool Template
, const KAEvent
* event
, bool newAlarm
, QWidget
* parent
,
125 GetResourceType getResource
, bool readOnly
)
126 : EditAlarmDlg(Template
, event
, newAlarm
, parent
, getResource
, readOnly
),
127 mSpecialActionsButton(0),
128 mReminderDeferral(false),
129 mReminderArchived(false)
131 kDebug() << "Event.id()";
135 /******************************************************************************
136 * Return the window caption.
138 QString
EditDisplayAlarmDlg::type_caption() const
140 return isTemplate() ? (isNewAlarm() ? i18nc("@title:window", "New Display Alarm Template") : i18nc("@title:window", "Edit Display Alarm Template"))
141 : (isNewAlarm() ? i18nc("@title:window", "New Display Alarm") : i18nc("@title:window", "Edit Display Alarm"));
144 /******************************************************************************
145 * Set up the dialog controls common to display alarms.
147 void EditDisplayAlarmDlg::type_init(QWidget
* parent
, QVBoxLayout
* frameLayout
)
149 // Display type combo box
150 KHBox
* box
= new KHBox(parent
); // to group widgets for QWhatsThis text
152 box
->setSpacing(KDialog::spacingHint());
153 QLabel
* label
= new QLabel(i18nc("@label:listbox", "Display type:"), box
);
154 label
->setFixedSize(label
->sizeHint());
155 mTypeCombo
= new ComboBox(box
);
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
, SIGNAL(currentIndexChanged(int)), SLOT(slotAlarmTypeChanged(int)));
177 connect(mTypeCombo
, SIGNAL(currentIndexChanged(int)), SLOT(contentsChanged()));
178 label
->setBuddy(mTypeCombo
);
179 box
->setWhatsThis(i18nc("@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 box
->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
, SIGNAL(textChanged()), SLOT(contentsChanged()));
192 frameLayout
->addWidget(mTextMessageEdit
);
194 // File name edit box
195 mFileBox
= new KHBox(parent
);
196 mFileBox
->setMargin(0);
197 frameLayout
->addWidget(mFileBox
);
198 mFileMessageEdit
= new LineEdit(LineEdit::Url
, mFileBox
);
199 mFileMessageEdit
->setAcceptDrops(true);
200 mFileMessageEdit
->setWhatsThis(i18nc("@info:whatsthis", "Enter the name or URL of a text or image file to display."));
201 connect(mFileMessageEdit
, SIGNAL(textChanged(QString
)), SLOT(contentsChanged()));
203 // File browse button
204 mFileBrowseButton
= new QPushButton(mFileBox
);
205 mFileBrowseButton
->setIcon(SmallIcon("document-open"));
206 int size
= mFileBrowseButton
->sizeHint().height();
207 mFileBrowseButton
->setFixedSize(size
, size
);
208 mFileBrowseButton
->setToolTip(i18nc("@info:tooltip", "Choose a file"));
209 mFileBrowseButton
->setWhatsThis(i18nc("@info:whatsthis", "Select a text or image file to display."));
210 connect(mFileBrowseButton
, SIGNAL(clicked()), SLOT(slotPickFile()));
212 // Command type checkbox and edit box
213 mCmdEdit
= new CommandEdit(parent
);
214 connect(mCmdEdit
, SIGNAL(scriptToggled(bool)), SLOT(slotCmdScriptToggled(bool)));
215 connect(mCmdEdit
, SIGNAL(changed()), SLOT(contentsChanged()));
216 frameLayout
->addWidget(mCmdEdit
);
218 // Sound checkbox and file selector
219 QHBoxLayout
* hlayout
= new QHBoxLayout();
220 hlayout
->setMargin(0);
221 frameLayout
->addLayout(hlayout
);
222 mSoundPicker
= new SoundPicker(parent
);
223 mSoundPicker
->setFixedSize(mSoundPicker
->sizeHint());
224 connect(mSoundPicker
, SIGNAL(changed()), SLOT(contentsChanged()));
225 hlayout
->addWidget(mSoundPicker
);
226 hlayout
->addSpacing(2*spacingHint());
227 hlayout
->addStretch();
229 // Font and colour choice button and sample text
230 mFontColourButton
= new FontColourButton(parent
);
231 mFontColourButton
->setMaximumHeight(mFontColourButton
->sizeHint().height() * 3/2);
232 hlayout
->addWidget(mFontColourButton
);
233 connect(mFontColourButton
, SIGNAL(selected(QColor
,QColor
)), SLOT(setColours(QColor
,QColor
)));
234 connect(mFontColourButton
, SIGNAL(selected(QColor
,QColor
)), SLOT(contentsChanged()));
236 if (ShellProcess::authorised()) // don't display if shell commands not allowed (e.g. kiosk mode)
238 // Special actions button
239 mSpecialActionsButton
= new SpecialActionsButton(false, parent
);
240 mSpecialActionsButton
->setFixedSize(mSpecialActionsButton
->sizeHint());
241 connect(mSpecialActionsButton
, SIGNAL(selected()), SLOT(contentsChanged()));
242 frameLayout
->addWidget(mSpecialActionsButton
, 0, Qt::AlignRight
);
245 // Top-adjust the controls
246 mFilePadding
= new KHBox(parent
);
247 mFilePadding
->setMargin(0);
248 frameLayout
->addWidget(mFilePadding
);
249 frameLayout
->setStretchFactor(mFilePadding
, 1);
252 /******************************************************************************
253 * Create a reminder control.
255 Reminder
* EditDisplayAlarmDlg::createReminder(QWidget
* parent
)
257 static const QString reminderText
= i18nc("@info:whatsthis", "Enter how long in advance of or after the main alarm to display a reminder alarm.");
258 return new Reminder(i18nc("@info:whatsthis", "Check to additionally display a reminder in advance of or after the main alarm time(s)."),
259 i18nc("@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()),
260 i18nc("@info:whatsthis", "Select whether the reminder should be triggered before or after the main alarm"),
264 /******************************************************************************
265 * Create an "acknowledgement confirmation required" checkbox.
267 CheckBox
* EditDisplayAlarmDlg::createConfirmAckCheckbox(QWidget
* parent
)
269 CheckBox
* confirmAck
= new CheckBox(i18n_chk_ConfirmAck(), parent
);
270 confirmAck
->setWhatsThis(i18nc("@info:whatsthis", "Check to be prompted for confirmation when you acknowledge the alarm."));
274 /******************************************************************************
275 * Initialise the dialog controls from the specified event.
277 void EditDisplayAlarmDlg::type_initValues(const KAEvent
* event
)
279 mKMailSerialNumber
= 0;
280 lateCancel()->showAutoClose(true);
283 if (mAlarmType
== KAEvent::MESSAGE
&& event
->kmailSerialNumber()
284 && AlarmText::checkIfEmail(event
->cleanText()))
285 mKMailSerialNumber
= event
->kmailSerialNumber();
286 lateCancel()->setAutoClose(event
->autoClose());
287 if (event
->useDefaultFont())
288 mFontColourButton
->setDefaultFont();
290 mFontColourButton
->setFont(event
->font());
291 mFontColourButton
->setBgColour(event
->bgColour());
292 mFontColourButton
->setFgColour(event
->fgColour());
293 setColours(event
->fgColour(), event
->bgColour());
294 mConfirmAck
->setChecked(event
->confirmAck());
295 bool recurs
= event
->recurs();
296 int reminderMins
= event
->reminderMinutes();
297 if (reminderMins
> 0 && !event
->reminderActive())
298 reminderMins
= 0; // don't show advance reminder which has already passed
301 if (event
->reminderDeferral() && !recurs
)
303 reminderMins
= event
->deferDateTime().minsTo(event
->mainDateTime());
304 mReminderDeferral
= true;
306 else if (event
->reminderMinutes() && recurs
)
308 reminderMins
= event
->reminderMinutes();
309 mReminderArchived
= true;
312 reminder()->setMinutes(reminderMins
, dateOnly());
313 reminder()->setOnceOnly(event
->reminderOnceOnly());
314 reminder()->enableOnceOnly(recurs
);
315 if (mSpecialActionsButton
)
316 mSpecialActionsButton
->setActions(event
->preAction(), event
->postAction(), event
->cancelOnPreActionError(), event
->dontShowPreActionError());
317 Preferences::SoundType soundType
= event
->speak() ? Preferences::Sound_Speak
318 : event
->beep() ? Preferences::Sound_Beep
319 : !event
->audioFile().isEmpty() ? Preferences::Sound_File
320 : Preferences::Sound_None
;
321 mSoundPicker
->set(soundType
, event
->audioFile(), event
->soundVolume(),
322 event
->fadeVolume(), event
->fadeSeconds(), event
->repeatSound());
326 // Set the values to their defaults
327 if (!ShellProcess::authorised())
329 // Don't allow shell commands in kiosk mode
330 if (mSpecialActionsButton
)
331 mSpecialActionsButton
->setEnabled(false);
333 lateCancel()->setAutoClose(Preferences::defaultAutoClose());
334 mTypeCombo
->setCurrentIndex(0);
335 mFontColourButton
->setDefaultFont();
336 mFontColourButton
->setBgColour(Preferences::defaultBgColour());
337 mFontColourButton
->setFgColour(Preferences::defaultFgColour());
338 setColours(Preferences::defaultFgColour(), Preferences::defaultBgColour());
339 mConfirmAck
->setChecked(Preferences::defaultConfirmAck());
340 reminder()->setMinutes(0, false);
341 reminder()->enableOnceOnly(isTimedRecurrence()); // must be called after mRecurrenceEdit is set up
342 if (mSpecialActionsButton
)
343 mSpecialActionsButton
->setActions(Preferences::defaultPreAction(), Preferences::defaultPostAction(),
344 Preferences::defaultCancelOnPreActionError(), Preferences::defaultDontShowPreActionError());
345 mSoundPicker
->set(Preferences::defaultSoundType(), Preferences::defaultSoundFile(),
346 Preferences::defaultSoundVolume(), -1, 0, Preferences::defaultSoundRepeat());
350 /******************************************************************************
351 * Called when the More/Less Options button is clicked.
352 * Show/hide the optional options.
354 void EditDisplayAlarmDlg::type_showOptions(bool more
)
356 if (mSpecialActionsButton
)
359 mSpecialActionsButton
->show();
361 mSpecialActionsButton
->hide();
365 /******************************************************************************
366 * Called when the font/color button has been clicked.
367 * Set the colors in the message text entry control.
369 void EditDisplayAlarmDlg::setColours(const QColor
& fgColour
, const QColor
& bgColour
)
371 QPalette pal
= mTextMessageEdit
->palette();
372 pal
.setColor(mTextMessageEdit
->backgroundRole(), bgColour
);
373 pal
.setColor(QPalette::Text
, fgColour
);
374 mTextMessageEdit
->setPalette(pal
);
375 pal
= mTextMessageEdit
->viewport()->palette();
376 pal
.setColor(mTextMessageEdit
->viewport()->backgroundRole(), bgColour
);
377 pal
.setColor(QPalette::Text
, fgColour
);
378 mTextMessageEdit
->viewport()->setPalette(pal
);
379 // Change the color of existing text
380 QTextCursor cursor
= mTextMessageEdit
->textCursor();
381 mTextMessageEdit
->selectAll();
382 mTextMessageEdit
->setTextColor(fgColour
);
383 mTextMessageEdit
->setTextCursor(cursor
);
386 /******************************************************************************
387 * Set the dialog's action and the action's text.
389 void EditDisplayAlarmDlg::setAction(KAEvent::SubAction action
, const AlarmText
& alarmText
)
391 QString text
= alarmText
.displayText();
394 case KAEvent::MESSAGE
:
395 mTypeCombo
->setCurrentIndex(tTEXT
);
396 mTextMessageEdit
->setPlainText(text
);
397 mKMailSerialNumber
= alarmText
.isEmail() ? alarmText
.kmailSerialNumber() : 0;
400 mTypeCombo
->setCurrentIndex(tFILE
);
401 mFileMessageEdit
->setText(text
);
403 case KAEvent::COMMAND
:
404 mTypeCombo
->setCurrentIndex(tCOMMAND
);
405 mCmdEdit
->setText(alarmText
);
413 /******************************************************************************
414 * Initialise various values in the New Alarm dialogue.
416 void EditDisplayAlarmDlg::setBgColour(const QColor
& colour
)
418 mFontColourButton
->setBgColour(colour
);
419 setColours(mFontColourButton
->fgColour(), colour
);
421 void EditDisplayAlarmDlg::setFgColour(const QColor
& colour
)
423 mFontColourButton
->setFgColour(colour
);
424 setColours(colour
, mFontColourButton
->bgColour());
426 void EditDisplayAlarmDlg::setConfirmAck(bool confirm
)
428 mConfirmAck
->setChecked(confirm
);
430 void EditDisplayAlarmDlg::setAutoClose(bool close
)
432 lateCancel()->setAutoClose(close
);
434 void EditDisplayAlarmDlg::setAudio(Preferences::SoundType type
, const QString
& file
, float volume
, bool repeat
)
436 mSoundPicker
->set(type
, file
, volume
, -1, 0, repeat
);
438 void EditDisplayAlarmDlg::setReminder(int minutes
, bool onceOnly
)
440 reminder()->setMinutes(minutes
, dateOnly());
441 reminder()->setOnceOnly(onceOnly
);
442 reminder()->enableOnceOnly(isTimedRecurrence());
445 /******************************************************************************
446 * Set the read-only status of all non-template controls.
448 void EditDisplayAlarmDlg::setReadOnly(bool readOnly
)
450 mTypeCombo
->setReadOnly(readOnly
);
451 mTextMessageEdit
->setReadOnly(readOnly
);
452 mFileMessageEdit
->setReadOnly(readOnly
);
453 mCmdEdit
->setReadOnly(readOnly
);
454 mFontColourButton
->setReadOnly(readOnly
);
455 mSoundPicker
->setReadOnly(readOnly
);
456 mConfirmAck
->setReadOnly(readOnly
);
457 reminder()->setReadOnly(readOnly
);
458 if (mSpecialActionsButton
)
459 mSpecialActionsButton
->setReadOnly(readOnly
);
461 mFileBrowseButton
->hide();
463 mFileBrowseButton
->show();
464 EditAlarmDlg::setReadOnly(readOnly
);
467 /******************************************************************************
468 * Save the state of all controls.
470 void EditDisplayAlarmDlg::saveState(const KAEvent
* event
)
472 EditAlarmDlg::saveState(event
);
473 mSavedType
= mTypeCombo
->currentIndex();
474 mSavedCmdScript
= mCmdEdit
->isScript();
475 mSavedSoundType
= mSoundPicker
->sound();
476 mSavedSoundFile
= mSoundPicker
->file();
477 mSavedSoundVolume
= mSoundPicker
->volume(mSavedSoundFadeVolume
, mSavedSoundFadeSeconds
);
478 mSavedRepeatSound
= mSoundPicker
->repeat();
479 mSavedConfirmAck
= mConfirmAck
->isChecked();
480 mSavedFont
= mFontColourButton
->font();
481 mSavedFgColour
= mFontColourButton
->fgColour();
482 mSavedBgColour
= mFontColourButton
->bgColour();
483 mSavedReminder
= reminder()->minutes();
484 mSavedOnceOnly
= reminder()->isOnceOnly();
485 mSavedAutoClose
= lateCancel()->isAutoClose();
486 if (mSpecialActionsButton
)
488 mSavedPreAction
= mSpecialActionsButton
->preAction();
489 mSavedPostAction
= mSpecialActionsButton
->postAction();
490 mSavedPreActionCancel
= mSpecialActionsButton
->cancelOnError();
494 /******************************************************************************
495 * Check whether any of the controls has changed state since the dialog was
497 * Reply = true if any controls have changed, or if it's a new event.
498 * = false if no controls have changed.
500 bool EditDisplayAlarmDlg::type_stateChanged() const
502 if (mSavedType
!= mTypeCombo
->currentIndex()
503 || mSavedCmdScript
!= mCmdEdit
->isScript()
504 || mSavedSoundType
!= mSoundPicker
->sound()
505 || mSavedConfirmAck
!= mConfirmAck
->isChecked()
506 || mSavedFont
!= mFontColourButton
->font()
507 || mSavedFgColour
!= mFontColourButton
->fgColour()
508 || mSavedBgColour
!= mFontColourButton
->bgColour()
509 || mSavedReminder
!= reminder()->minutes()
510 || mSavedOnceOnly
!= reminder()->isOnceOnly()
511 || mSavedAutoClose
!= lateCancel()->isAutoClose())
513 if (mSpecialActionsButton
)
515 if (mSavedPreAction
!= mSpecialActionsButton
->preAction()
516 || mSavedPostAction
!= mSpecialActionsButton
->postAction()
517 || mSavedPreActionCancel
!= mSpecialActionsButton
->cancelOnError())
520 if (mSavedSoundType
== Preferences::Sound_File
)
522 if (mSavedSoundFile
!= mSoundPicker
->file())
524 if (!mSavedSoundFile
.isEmpty())
528 if (mSavedRepeatSound
!= mSoundPicker
->repeat()
529 || mSavedSoundVolume
!= mSoundPicker
->volume(fadeVolume
, fadeSecs
)
530 || mSavedSoundFadeVolume
!= fadeVolume
531 || mSavedSoundFadeSeconds
!= fadeSecs
)
538 /******************************************************************************
539 * Extract the data in the dialog specific to the alarm type and set up a
542 void EditDisplayAlarmDlg::type_setEvent(KAEvent
& event
, const KDateTime
& dt
, const QString
& text
, int lateCancel
, bool trial
)
544 KAEvent::SubAction type
;
545 switch (mTypeCombo
->currentIndex())
547 case tFILE
: type
= KAEvent::FILE; break;
548 case tCOMMAND
: type
= KAEvent::COMMAND
; break;
550 case tTEXT
: type
= KAEvent::MESSAGE
; break;
552 event
.set(dt
, text
, mFontColourButton
->bgColour(), mFontColourButton
->fgColour(), mFontColourButton
->font(),
553 type
, lateCancel
, getAlarmFlags());
554 if (type
== KAEvent::MESSAGE
)
556 if (AlarmText::checkIfEmail(text
))
557 event
.setKMailSerialNumber(mKMailSerialNumber
);
561 float volume
= mSoundPicker
->volume(fadeVolume
, fadeSecs
);
562 event
.setAudioFile(mSoundPicker
->file().prettyUrl(), volume
, fadeVolume
, fadeSecs
);
563 if (!trial
&& reminder()->isEnabled())
564 event
.setReminder(reminder()->minutes(), reminder()->isOnceOnly());
565 if (mSpecialActionsButton
&& mSpecialActionsButton
->isEnabled())
566 event
.setActions(mSpecialActionsButton
->preAction(), mSpecialActionsButton
->postAction(),
567 mSpecialActionsButton
->cancelOnError(), mSpecialActionsButton
->dontShowError());
570 /******************************************************************************
571 * Get the currently specified alarm flag bits.
573 int EditDisplayAlarmDlg::getAlarmFlags() const
575 bool cmd
= (mTypeCombo
->currentIndex() == tCOMMAND
);
576 return EditAlarmDlg::getAlarmFlags()
577 | (mSoundPicker
->sound() == Preferences::Sound_Beep
? KAEvent::BEEP
: 0)
578 | (mSoundPicker
->sound() == Preferences::Sound_Speak
? KAEvent::SPEAK
: 0)
579 | (mSoundPicker
->repeat() ? KAEvent::REPEAT_SOUND
: 0)
580 | (mConfirmAck
->isChecked() ? KAEvent::CONFIRM_ACK
: 0)
581 | (lateCancel()->isAutoClose() ? KAEvent::AUTO_CLOSE
: 0)
582 | (mFontColourButton
->defaultFont() ? KAEvent::DEFAULT_FONT
: 0)
583 | (cmd
? KAEvent::DISPLAY_COMMAND
: 0)
584 | (cmd
&& mCmdEdit
->isScript() ? KAEvent::SCRIPT
: 0);
587 /******************************************************************************
588 * Called when one of the alarm display type combo box is changed, to display
589 * the appropriate set of controls for that action type.
591 void EditDisplayAlarmDlg::slotAlarmTypeChanged(int index
)
596 case tTEXT
: // text message
598 mFilePadding
->hide();
600 mTextMessageEdit
->show();
601 mSoundPicker
->showSpeak(true);
602 setButtonWhatsThis(Try
, i18nc("@info:whatsthis", "Display the alarm message now"));
603 focus
= mTextMessageEdit
;
605 case tFILE
: // file contents
606 mTextMessageEdit
->hide();
608 mFilePadding
->show();
610 mSoundPicker
->showSpeak(false);
611 setButtonWhatsThis(Try
, i18nc("@info:whatsthis", "Display the file now"));
612 mFileMessageEdit
->setNoSelect();
613 focus
= mFileMessageEdit
;
615 case tCOMMAND
: // command output
616 mTextMessageEdit
->hide();
618 slotCmdScriptToggled(mCmdEdit
->isScript()); // show/hide mFilePadding
620 mSoundPicker
->showSpeak(true);
621 setButtonWhatsThis(Try
, i18nc("@info:whatsthis", "Display the command output now"));
629 /******************************************************************************
630 * Called when the file browse button is pressed to select a file to display.
632 void EditDisplayAlarmDlg::slotPickFile()
634 static QString defaultDir
; // default directory for file browse button
635 QString file
= KAlarm::browseFile(i18nc("@title:window", "Choose Text or Image File to Display"),
636 defaultDir
, mFileMessageEdit
->text(), QString(), KFile::ExistingOnly
, this);
639 mFileMessageEdit
->setText(KAlarm::pathOrUrl(file
));
644 /******************************************************************************
645 * Called when one of the command type radio buttons is clicked,
646 * to display the appropriate edit field.
648 void EditDisplayAlarmDlg::slotCmdScriptToggled(bool on
)
651 mFilePadding
->hide();
653 mFilePadding
->show();
656 /******************************************************************************
657 * Clean up the alarm text, and if it's a file, check whether it's valid.
659 bool EditDisplayAlarmDlg::checkText(QString
& result
, bool showErrorMessage
) const
661 switch (mTypeCombo
->currentIndex())
664 result
= mTextMessageEdit
->toPlainText();
669 QString alarmtext
= mFileMessageEdit
->text().trimmed();
671 KAlarm::FileErr err
= KAlarm::checkFileExists(alarmtext
, url
);
672 if (err
== KAlarm::FileErr_None
)
674 switch (KAlarm::fileType(KFileItem(KFileItem::Unknown
, KFileItem::Unknown
, url
).mimeTypePtr()))
676 case KAlarm::TextFormatted
:
677 case KAlarm::TextPlain
:
678 case KAlarm::TextApplication
:
682 err
= KAlarm::FileErr_NotTextImage
;
686 if (err
!= KAlarm::FileErr_None
&& showErrorMessage
)
688 mFileMessageEdit
->setFocus();
689 if (!KAlarm::showFileErrMessage(alarmtext
, err
, KAlarm::FileErr_BlankDisplay
, const_cast<EditDisplayAlarmDlg
*>(this)))
696 result
= mCmdEdit
->text(const_cast<EditDisplayAlarmDlg
*>(this), showErrorMessage
);
697 if (result
.isEmpty())
705 /*=============================================================================
706 = Class EditCommandAlarmDlg
707 = Dialog to edit command alarms.
708 =============================================================================*/
710 QString
EditCommandAlarmDlg::i18n_chk_EnterScript() { return i18nc("@option:check", "Enter a script"); }
711 QString
EditCommandAlarmDlg::i18n_radio_ExecInTermWindow() { return i18nc("@option:radio", "Execute in terminal window"); }
712 QString
EditCommandAlarmDlg::i18n_chk_ExecInTermWindow() { return i18nc("@option:check", "Execute in terminal window"); }
715 /******************************************************************************
718 * Template = true to edit/create an alarm template
719 * = false to edit/create an alarm.
720 * event != to initialise the dialog to show the specified event's data.
722 EditCommandAlarmDlg::EditCommandAlarmDlg(bool Template
, QWidget
* parent
, GetResourceType getResource
)
723 : EditAlarmDlg(Template
, KAEvent::COMMAND
, parent
, getResource
)
729 EditCommandAlarmDlg::EditCommandAlarmDlg(bool Template
, const KAEvent
* event
, bool newAlarm
, QWidget
* parent
,
730 GetResourceType getResource
, bool readOnly
)
731 : EditAlarmDlg(Template
, event
, newAlarm
, parent
, getResource
, readOnly
)
733 kDebug() << "Event.id()";
737 /******************************************************************************
738 * Return the window caption.
740 QString
EditCommandAlarmDlg::type_caption() const
742 return isTemplate() ? (isNewAlarm() ? i18nc("@title:window", "New Command Alarm Template") : i18nc("@title:window", "Edit Command Alarm Template"))
743 : (isNewAlarm() ? i18nc("@title:window", "New Command Alarm") : i18nc("@title:window", "Edit Command Alarm"));
746 /******************************************************************************
747 * Set up the command alarm dialog controls.
749 void EditCommandAlarmDlg::type_init(QWidget
* parent
, QVBoxLayout
* frameLayout
)
751 setButtonWhatsThis(Try
, i18nc("@info:whatsthis", "Execute the specified command now"));
753 mCmdEdit
= new CommandEdit(parent
);
754 connect(mCmdEdit
, SIGNAL(scriptToggled(bool)), SLOT(slotCmdScriptToggled(bool)));
755 connect(mCmdEdit
, SIGNAL(changed()), SLOT(contentsChanged()));
756 frameLayout
->addWidget(mCmdEdit
);
758 // What to do with command output
760 mCmdOutputBox
= new QGroupBox(i18nc("@title:group", "Command Output"), parent
);
761 frameLayout
->addWidget(mCmdOutputBox
);
762 QVBoxLayout
* vlayout
= new QVBoxLayout(mCmdOutputBox
);
763 vlayout
->setMargin(marginHint());
764 vlayout
->setSpacing(spacingHint());
765 mCmdOutputGroup
= new ButtonGroup(mCmdOutputBox
);
766 connect(mCmdOutputGroup
, SIGNAL(buttonSet(QAbstractButton
*)), SLOT(contentsChanged()));
768 // Execute in terminal window
769 mCmdExecInTerm
= new RadioButton(i18n_radio_ExecInTermWindow(), mCmdOutputBox
);
770 mCmdExecInTerm
->setFixedSize(mCmdExecInTerm
->sizeHint());
771 mCmdExecInTerm
->setWhatsThis(i18nc("@info:whatsthis", "Check to execute the command in a terminal window"));
772 mCmdOutputGroup
->addButton(mCmdExecInTerm
, Preferences::Log_Terminal
);
773 vlayout
->addWidget(mCmdExecInTerm
, 0, Qt::AlignLeft
);
775 // Log file name edit box
776 KHBox
* box
= new KHBox(mCmdOutputBox
);
778 (new QWidget(box
))->setFixedWidth(mCmdExecInTerm
->style()->pixelMetric(QStyle::PM_ExclusiveIndicatorWidth
)); // indent the edit box
779 mCmdLogFileEdit
= new LineEdit(LineEdit::Url
, box
);
780 mCmdLogFileEdit
->setAcceptDrops(true);
781 mCmdLogFileEdit
->setWhatsThis(i18nc("@info:whatsthis", "Enter the name or path of the log file."));
782 connect(mCmdLogFileEdit
, SIGNAL(textChanged(QString
)), SLOT(contentsChanged()));
784 // Log file browse button.
785 // The file browser dialog is activated by the PickLogFileRadio class.
786 QPushButton
* browseButton
= new QPushButton(box
);
787 browseButton
->setIcon(SmallIcon("document-open"));
788 int size
= browseButton
->sizeHint().height();
789 browseButton
->setFixedSize(size
, size
);
790 browseButton
->setToolTip(i18nc("@info:tooltip", "Choose a file"));
791 browseButton
->setWhatsThis(i18nc("@info:whatsthis", "Select a log file."));
793 // Log output to file
794 mCmdLogToFile
= new PickLogFileRadio(browseButton
, mCmdLogFileEdit
, i18nc("@option:radio", "Log to file"), mCmdOutputGroup
, mCmdOutputBox
);
795 mCmdLogToFile
->setFixedSize(mCmdLogToFile
->sizeHint());
796 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."));
797 connect(mCmdLogToFile
, SIGNAL(fileChanged()), SLOT(contentsChanged()));
798 mCmdOutputGroup
->addButton(mCmdLogToFile
, Preferences::Log_File
);
799 vlayout
->addWidget(mCmdLogToFile
, 0, Qt::AlignLeft
);
800 vlayout
->addWidget(box
);
803 mCmdDiscardOutput
= new RadioButton(i18nc("@option:radio", "Discard"), mCmdOutputBox
);
804 mCmdDiscardOutput
->setFixedSize(mCmdDiscardOutput
->sizeHint());
805 mCmdDiscardOutput
->setWhatsThis(i18nc("@info:whatsthis", "Check to discard command output."));
806 mCmdOutputGroup
->addButton(mCmdDiscardOutput
, Preferences::Log_Discard
);
807 vlayout
->addWidget(mCmdDiscardOutput
, 0, Qt::AlignLeft
);
809 // Top-adjust the controls
810 mCmdPadding
= new KHBox(parent
);
811 mCmdPadding
->setMargin(0);
812 frameLayout
->addWidget(mCmdPadding
);
813 frameLayout
->setStretchFactor(mCmdPadding
, 1);
816 /******************************************************************************
817 * Initialise the dialog controls from the specified event.
819 void EditCommandAlarmDlg::type_initValues(const KAEvent
* event
)
823 // Set the values to those for the specified event
824 RadioButton
* logType
= event
->commandXterm() ? mCmdExecInTerm
825 : !event
->logFile().isEmpty() ? mCmdLogToFile
827 if (logType
== mCmdLogToFile
)
828 mCmdLogFileEdit
->setText(event
->logFile()); // set file name before setting radio button
829 logType
->setChecked(true);
833 // Set the values to their defaults
834 mCmdEdit
->setScript(Preferences::defaultCmdScript());
835 mCmdLogFileEdit
->setText(Preferences::defaultCmdLogFile()); // set file name before setting radio button
836 mCmdOutputGroup
->setButton(Preferences::defaultCmdLogType());
838 slotCmdScriptToggled(mCmdEdit
->isScript());
841 /******************************************************************************
842 * Called when the More/Less Options button is clicked.
843 * Show/hide the optional options.
845 void EditCommandAlarmDlg::type_showOptions(bool more
)
848 mCmdOutputBox
->show();
850 mCmdOutputBox
->hide();
853 /******************************************************************************
854 * Set the dialog's action and the action's text.
856 void EditCommandAlarmDlg::setAction(KAEvent::SubAction action
, const AlarmText
& alarmText
)
859 Q_ASSERT(action
== KAEvent::COMMAND
);
860 mCmdEdit
->setText(alarmText
);
863 /******************************************************************************
864 * Set the read-only status of all non-template controls.
866 void EditCommandAlarmDlg::setReadOnly(bool readOnly
)
868 if (!isTemplate() && !ShellProcess::authorised())
869 readOnly
= true; // don't allow editing of existing command alarms in kiosk mode
870 mCmdEdit
->setReadOnly(readOnly
);
871 mCmdExecInTerm
->setReadOnly(readOnly
);
872 mCmdLogToFile
->setReadOnly(readOnly
);
873 mCmdDiscardOutput
->setReadOnly(readOnly
);
874 EditAlarmDlg::setReadOnly(readOnly
);
877 /******************************************************************************
878 * Save the state of all controls.
880 void EditCommandAlarmDlg::saveState(const KAEvent
* event
)
882 EditAlarmDlg::saveState(event
);
883 mSavedCmdScript
= mCmdEdit
->isScript();
884 mSavedCmdOutputRadio
= mCmdOutputGroup
->checkedButton();
885 mSavedCmdLogFile
= mCmdLogFileEdit
->text();
888 /******************************************************************************
889 * Check whether any of the controls has changed state since the dialog was
891 * Reply = true if any controls have changed, or if it's a new event.
892 * = false if no controls have changed.
894 bool EditCommandAlarmDlg::type_stateChanged() const
896 if (mSavedCmdScript
!= mCmdEdit
->isScript()
897 || mSavedCmdOutputRadio
!= mCmdOutputGroup
->checkedButton())
899 if (mCmdOutputGroup
->checkedButton() == mCmdLogToFile
)
901 if (mSavedCmdLogFile
!= mCmdLogFileEdit
->text())
907 /******************************************************************************
908 * Extract the data in the dialog specific to the alarm type and set up a
911 void EditCommandAlarmDlg::type_setEvent(KAEvent
& event
, const KDateTime
& dt
, const QString
& text
, int lateCancel
, bool trial
)
914 event
.set(dt
, text
, QColor(), QColor(), QFont(), KAEvent::COMMAND
, lateCancel
, getAlarmFlags());
915 if (mCmdOutputGroup
->checkedButton() == mCmdLogToFile
)
916 event
.setLogFile(mCmdLogFileEdit
->text());
919 /******************************************************************************
920 * Get the currently specified alarm flag bits.
922 int EditCommandAlarmDlg::getAlarmFlags() const
924 return EditAlarmDlg::getAlarmFlags()
925 | (mCmdEdit
->isScript() ? KAEvent::SCRIPT
: 0)
926 | (mCmdOutputGroup
->checkedButton() == mCmdExecInTerm
? KAEvent::EXEC_IN_XTERM
: 0);
929 /******************************************************************************
930 * Validate and convert command alarm data.
932 bool EditCommandAlarmDlg::type_validate(bool trial
)
935 if (mCmdOutputGroup
->checkedButton() == mCmdLogToFile
)
937 // Validate the log file name
938 QString file
= mCmdLogFileEdit
->text();
939 QFileInfo
info(file
);
940 QDir::setCurrent(QDir::homePath());
941 bool err
= file
.isEmpty() || info
.isDir();
946 err
= !info
.isWritable();
950 QFileInfo
dirinfo(info
.absolutePath()); // get absolute directory path
951 err
= (!dirinfo
.isDir() || !dirinfo
.isWritable());
957 mCmdLogFileEdit
->setFocus();
958 KAMessageBox::sorry(this, i18nc("@info", "Log file must be the name or path of a local file, with write permission."));
961 // Convert the log file to an absolute path
962 mCmdLogFileEdit
->setText(info
.absoluteFilePath());
967 /******************************************************************************
968 * Tell the user the result of the Try action.
970 void EditCommandAlarmDlg::type_trySuccessMessage(ShellProcess
* proc
, const QString
& text
)
972 if (mCmdOutputGroup
->checkedButton() != mCmdExecInTerm
)
974 theApp()->commandMessage(proc
, this);
975 KAMessageBox::information(this, i18nc("@info", "Command executed: <icode>%1</icode>", text
));
976 theApp()->commandMessage(proc
, 0);
980 /******************************************************************************
981 * Called when one of the command type radio buttons is clicked,
982 * to display the appropriate edit field.
984 void EditCommandAlarmDlg::slotCmdScriptToggled(bool on
)
992 /******************************************************************************
993 * Clean up the alarm text.
995 bool EditCommandAlarmDlg::checkText(QString
& result
, bool showErrorMessage
) const
997 result
= mCmdEdit
->text(const_cast<EditCommandAlarmDlg
*>(this), showErrorMessage
);
998 if (result
.isEmpty())
1004 /*=============================================================================
1005 = Class EditEmailAlarmDlg
1006 = Dialog to edit email alarms.
1007 =============================================================================*/
1009 QString
EditEmailAlarmDlg::i18n_chk_CopyEmailToSelf() { return i18nc("@option:check", "Copy email to self"); }
1012 /******************************************************************************
1015 * Template = true to edit/create an alarm template
1016 * = false to edit/create an alarm.
1017 * event != to initialise the dialog to show the specified event's data.
1019 EditEmailAlarmDlg::EditEmailAlarmDlg(bool Template
, QWidget
* parent
, GetResourceType getResource
)
1020 : EditAlarmDlg(Template
, KAEvent::EMAIL
, parent
, getResource
),
1021 mEmailRemoveButton(0)
1027 EditEmailAlarmDlg::EditEmailAlarmDlg(bool Template
, const KAEvent
* event
, bool newAlarm
, QWidget
* parent
,
1028 GetResourceType getResource
, bool readOnly
)
1029 : EditAlarmDlg(Template
, event
, newAlarm
, parent
, getResource
, readOnly
),
1030 mEmailRemoveButton(0)
1032 kDebug() << "Event.id()";
1036 /******************************************************************************
1037 * Return the window caption.
1039 QString
EditEmailAlarmDlg::type_caption() const
1041 return isTemplate() ? (isNewAlarm() ? i18nc("@title:window", "New Email Alarm Template") : i18nc("@title:window", "Edit Email Alarm Template"))
1042 : (isNewAlarm() ? i18nc("@title:window", "New Email Alarm") : i18nc("@title:window", "Edit Email Alarm"));
1045 /******************************************************************************
1046 * Set up the email alarm dialog controls.
1048 void EditEmailAlarmDlg::type_init(QWidget
* parent
, QVBoxLayout
* frameLayout
)
1050 setButtonWhatsThis(Try
, i18nc("@info:whatsthis", "Send the email to the specified addressees now"));
1052 QGridLayout
* grid
= new QGridLayout();
1054 grid
->setColumnStretch(1, 1);
1055 frameLayout
->addLayout(grid
);
1058 if (Preferences::emailFrom() == Preferences::MAIL_FROM_KMAIL
)
1060 // Email sender identity
1061 QLabel
* label
= new QLabel(i18nc("@label:listbox 'From' email address", "From:"), parent
);
1062 label
->setFixedSize(label
->sizeHint());
1063 grid
->addWidget(label
, 0, 0);
1065 mEmailFromList
= new EmailIdCombo(Identities::identityManager(), parent
);
1066 mEmailFromList
->setMinimumSize(mEmailFromList
->sizeHint());
1067 label
->setBuddy(mEmailFromList
);
1068 mEmailFromList
->setWhatsThis(i18nc("@info:whatsthis", "Your email identity, used to identify you as the sender when sending email alarms."));
1069 connect(mEmailFromList
, SIGNAL(identityChanged(uint
)), SLOT(contentsChanged()));
1070 grid
->addWidget(mEmailFromList
, 0, 1, 1, 2);
1074 QLabel
* label
= new QLabel(i18nc("@label:textbox Email addressee", "To:"), parent
);
1075 label
->setFixedSize(label
->sizeHint());
1076 grid
->addWidget(label
, 1, 0);
1078 mEmailToEdit
= new LineEdit(LineEdit::Emails
, parent
);
1079 mEmailToEdit
->setMinimumSize(mEmailToEdit
->sizeHint());
1080 mEmailToEdit
->setWhatsThis(i18nc("@info:whatsthis", "Enter the addresses of the email recipients. Separate multiple addresses by "
1081 "commas or semicolons."));
1082 connect(mEmailToEdit
, SIGNAL(textChanged(QString
)), SLOT(contentsChanged()));
1083 grid
->addWidget(mEmailToEdit
, 1, 1);
1085 mEmailAddressButton
= new QPushButton(parent
);
1086 mEmailAddressButton
->setIcon(SmallIcon("help-contents"));
1087 int size
= mEmailAddressButton
->sizeHint().height();
1088 mEmailAddressButton
->setFixedSize(size
, size
);
1089 connect(mEmailAddressButton
, SIGNAL(clicked()), SLOT(openAddressBook()));
1090 mEmailAddressButton
->setToolTip(i18nc("@info:tooltip", "Open address book"));
1091 mEmailAddressButton
->setWhatsThis(i18nc("@info:whatsthis", "Select email addresses from your address book."));
1092 grid
->addWidget(mEmailAddressButton
, 1, 2);
1095 label
= new QLabel(i18nc("@label:textbox Email subject", "Subject:"), parent
);
1096 label
->setFixedSize(label
->sizeHint());
1097 grid
->addWidget(label
, 2, 0);
1099 mEmailSubjectEdit
= new LineEdit(parent
);
1100 mEmailSubjectEdit
->setMinimumSize(mEmailSubjectEdit
->sizeHint());
1101 label
->setBuddy(mEmailSubjectEdit
);
1102 mEmailSubjectEdit
->setWhatsThis(i18nc("@info:whatsthis", "Enter the email subject."));
1103 connect(mEmailSubjectEdit
, SIGNAL(textChanged(QString
)), SLOT(contentsChanged()));
1104 grid
->addWidget(mEmailSubjectEdit
, 2, 1, 1, 2);
1107 mEmailMessageEdit
= new TextEdit(parent
);
1108 mEmailMessageEdit
->setWhatsThis(i18nc("@info:whatsthis", "Enter the email message."));
1109 connect(mEmailMessageEdit
, SIGNAL(textChanged()), SLOT(contentsChanged()));
1110 frameLayout
->addWidget(mEmailMessageEdit
);
1112 // Email attachments
1113 grid
= new QGridLayout();
1115 frameLayout
->addLayout(grid
);
1116 label
= new QLabel(i18nc("@label:listbox", "Attachments:"), parent
);
1117 label
->setFixedSize(label
->sizeHint());
1118 grid
->addWidget(label
, 0, 0);
1120 mEmailAttachList
= new KComboBox(parent
);
1121 mEmailAttachList
->setEditable(true);
1122 mEmailAttachList
->setMinimumSize(mEmailAttachList
->sizeHint());
1123 if (mEmailAttachList
->lineEdit())
1124 mEmailAttachList
->lineEdit()->setReadOnly(true);
1125 //Q3ListBox* list = mEmailAttachList->listBox();
1126 //QRect rect = list->geometry();
1127 //list->setGeometry(rect.left() - 50, rect.top(), rect.width(), rect.height());
1128 label
->setBuddy(mEmailAttachList
);
1129 mEmailAttachList
->setWhatsThis(i18nc("@info:whatsthis", "Files to send as attachments to the email."));
1130 grid
->addWidget(mEmailAttachList
, 0, 1);
1131 grid
->setColumnStretch(1, 1);
1133 mEmailAddAttachButton
= new QPushButton(i18nc("@action:button", "Add..."), parent
);
1134 connect(mEmailAddAttachButton
, SIGNAL(clicked()), SLOT(slotAddAttachment()));
1135 mEmailAddAttachButton
->setWhatsThis(i18nc("@info:whatsthis", "Add an attachment to the email."));
1136 grid
->addWidget(mEmailAddAttachButton
, 0, 2);
1138 mEmailRemoveButton
= new QPushButton(i18nc("@action:button", "Remove"), parent
);
1139 connect(mEmailRemoveButton
, SIGNAL(clicked()), SLOT(slotRemoveAttachment()));
1140 mEmailRemoveButton
->setWhatsThis(i18nc("@info:whatsthis", "Remove the highlighted attachment from the email."));
1141 grid
->addWidget(mEmailRemoveButton
, 1, 2);
1143 // BCC email to sender
1144 mEmailBcc
= new CheckBox(i18n_chk_CopyEmailToSelf(), parent
);
1145 mEmailBcc
->setFixedSize(mEmailBcc
->sizeHint());
1146 mEmailBcc
->setWhatsThis(i18nc("@info:whatsthis", "If checked, the email will be blind copied to you."));
1147 connect(mEmailBcc
, SIGNAL(toggled(bool)), SLOT(contentsChanged()));
1148 grid
->addWidget(mEmailBcc
, 1, 0, 1, 2, Qt::AlignLeft
);
1151 /******************************************************************************
1152 * Initialise the dialog controls from the specified event.
1154 void EditEmailAlarmDlg::type_initValues(const KAEvent
* event
)
1158 // Set the values to those for the specified event
1159 mEmailAttachList
->addItems(event
->emailAttachments());
1160 mEmailToEdit
->setText(event
->emailAddresses(", "));
1161 mEmailSubjectEdit
->setText(event
->emailSubject());
1162 mEmailBcc
->setChecked(event
->emailBcc());
1164 mEmailFromList
->setCurrentIdentity(event
->emailFromId());
1168 // Set the values to their defaults
1169 mEmailBcc
->setChecked(Preferences::defaultEmailBcc());
1174 /******************************************************************************
1175 * Enable/disable controls depending on whether any attachments are entered.
1177 void EditEmailAlarmDlg::attachmentEnable()
1179 bool enable
= mEmailAttachList
->count();
1180 mEmailAttachList
->setEnabled(enable
);
1181 if (mEmailRemoveButton
)
1182 mEmailRemoveButton
->setEnabled(enable
);
1185 /******************************************************************************
1186 * Set the dialog's action and the action's text.
1188 void EditEmailAlarmDlg::setAction(KAEvent::SubAction action
, const AlarmText
& alarmText
)
1191 Q_ASSERT(action
== KAEvent::EMAIL
);
1192 if (alarmText
.isEmail())
1194 mEmailToEdit
->setText(alarmText
.to());
1195 mEmailSubjectEdit
->setText(alarmText
.subject());
1196 mEmailMessageEdit
->setPlainText(alarmText
.body());
1199 mEmailMessageEdit
->setPlainText(alarmText
.displayText());
1202 /******************************************************************************
1203 * Initialise various values in the New Alarm dialogue.
1205 void EditEmailAlarmDlg::setEmailFields(uint fromID
, const EmailAddressList
& addresses
,
1206 const QString
& subject
, const QStringList
& attachments
)
1209 mEmailFromList
->setCurrentIdentity(fromID
);
1210 if (!addresses
.isEmpty())
1211 mEmailToEdit
->setText(addresses
.join(", "));
1212 if (!subject
.isEmpty())
1213 mEmailSubjectEdit
->setText(subject
);
1214 if (!attachments
.isEmpty())
1216 mEmailAttachList
->addItems(attachments
);
1220 void EditEmailAlarmDlg::setBcc(bool bcc
)
1222 mEmailBcc
->setChecked(bcc
);
1225 /******************************************************************************
1226 * Set the read-only status of all non-template controls.
1228 void EditEmailAlarmDlg::setReadOnly(bool readOnly
)
1230 mEmailToEdit
->setReadOnly(readOnly
);
1231 mEmailSubjectEdit
->setReadOnly(readOnly
);
1232 mEmailMessageEdit
->setReadOnly(readOnly
);
1233 mEmailBcc
->setReadOnly(readOnly
);
1235 mEmailFromList
->setReadOnly(readOnly
);
1238 mEmailAddressButton
->hide();
1239 mEmailAddAttachButton
->hide();
1240 mEmailRemoveButton
->hide();
1244 mEmailAddressButton
->show();
1245 mEmailAddAttachButton
->show();
1246 mEmailRemoveButton
->show();
1248 EditAlarmDlg::setReadOnly(readOnly
);
1251 /******************************************************************************
1252 * Save the state of all controls.
1254 void EditEmailAlarmDlg::saveState(const KAEvent
* event
)
1256 EditAlarmDlg::saveState(event
);
1258 mSavedEmailFrom
= mEmailFromList
->currentIdentityName();
1259 mSavedEmailTo
= mEmailToEdit
->text();
1260 mSavedEmailSubject
= mEmailSubjectEdit
->text();
1261 mSavedEmailAttach
.clear();
1262 for (int i
= 0, end
= mEmailAttachList
->count(); i
< end
; ++i
)
1263 mSavedEmailAttach
+= mEmailAttachList
->itemText(i
);
1264 mSavedEmailBcc
= mEmailBcc
->isChecked();
1267 /******************************************************************************
1268 * Check whether any of the controls has changed state since the dialog was
1270 * Reply = true if any controls have changed, or if it's a new event.
1271 * = false if no controls have changed.
1273 bool EditEmailAlarmDlg::type_stateChanged() const
1275 QStringList emailAttach
;
1276 for (int i
= 0, end
= mEmailAttachList
->count(); i
< end
; ++i
)
1277 emailAttach
+= mEmailAttachList
->itemText(i
);
1278 if ((mEmailFromList
&& mSavedEmailFrom
!= mEmailFromList
->currentIdentityName())
1279 || mSavedEmailTo
!= mEmailToEdit
->text()
1280 || mSavedEmailSubject
!= mEmailSubjectEdit
->text()
1281 || mSavedEmailAttach
!= emailAttach
1282 || mSavedEmailBcc
!= mEmailBcc
->isChecked())
1287 /******************************************************************************
1288 * Extract the data in the dialog specific to the alarm type and set up a
1291 void EditEmailAlarmDlg::type_setEvent(KAEvent
& event
, const KDateTime
& dt
, const QString
& text
, int lateCancel
, bool trial
)
1294 event
.set(dt
, text
, QColor(), QColor(), QFont(), KAEvent::EMAIL
, lateCancel
, getAlarmFlags());
1295 uint from
= mEmailFromList
? mEmailFromList
->currentIdentity() : 0;
1296 event
.setEmail(from
, mEmailAddresses
, mEmailSubjectEdit
->text(), mEmailAttachments
);
1299 /******************************************************************************
1300 * Get the currently specified alarm flag bits.
1302 int EditEmailAlarmDlg::getAlarmFlags() const
1304 return EditAlarmDlg::getAlarmFlags()
1305 | (mEmailBcc
->isChecked() ? KAEvent::EMAIL_BCC
: 0);
1308 /******************************************************************************
1309 * Convert the email addresses to a list, and validate them. Convert the email
1310 * attachments to a list.
1312 bool EditEmailAlarmDlg::type_validate(bool trial
)
1314 QString addrs
= mEmailToEdit
->text();
1315 if (addrs
.isEmpty())
1316 mEmailAddresses
.clear();
1319 QString bad
= KAMail::convertAddresses(addrs
, mEmailAddresses
);
1322 mEmailToEdit
->setFocus();
1323 KAMessageBox::error(this, i18nc("@info", "Invalid email address: <email>%1</email>", bad
));
1327 if (mEmailAddresses
.isEmpty())
1329 mEmailToEdit
->setFocus();
1330 KAMessageBox::error(this, i18nc("@info", "No email address specified"));
1334 mEmailAttachments
.clear();
1335 for (int i
= 0, end
= mEmailAttachList
->count(); i
< end
; ++i
)
1337 QString att
= mEmailAttachList
->itemText(i
);
1338 switch (KAMail::checkAttachment(att
))
1341 mEmailAttachments
.append(att
);
1346 mEmailAttachList
->setFocus();
1347 KAMessageBox::error(this, i18nc("@info", "Invalid email attachment: <filename>%1</filename>", att
));
1351 if (trial
&& KAMessageBox::warningContinueCancel(this, i18nc("@info", "Do you really want to send the email now to the specified recipient(s)?"),
1352 i18nc("@action:button", "Confirm Email"), KGuiItem(i18nc("@action:button", "Send"))) != KMessageBox::Continue
)
1357 /******************************************************************************
1358 * Tell the user the result of the Try action.
1360 void EditEmailAlarmDlg::type_trySuccessMessage(ShellProcess
*, const QString
&)
1363 QString to
= mEmailAddresses
.join("<nl/>");
1364 to
.replace('<', "<");
1365 to
.replace('>', ">");
1366 if (mEmailBcc
->isChecked())
1367 msg
= "<qt>" + i18nc("@info", "Email sent to:<nl/>%1<nl/>Bcc: <email>%2</email>",
1368 to
, Preferences::emailBccAddress()) + "</qt>";
1370 msg
= "<qt>" + i18nc("@info", "Email sent to:<nl/>%1", to
) + "</qt>";
1371 KAMessageBox::information(this, msg
);
1374 /******************************************************************************
1375 * Get a selection from the Address Book.
1377 void EditEmailAlarmDlg::openAddressBook()
1379 // Use AutoQPointer to guard against crash on application exit while
1380 // the dialogue is still open. It prevents double deletion (both on
1381 // deletion of MainWindow, and on return from this function).
1382 AutoQPointer
<Akonadi::EmailAddressSelectionDialog
> dlg
= new Akonadi::EmailAddressSelectionDialog(this);
1383 if (dlg
->exec() != QDialog::Accepted
)
1386 Akonadi::EmailAddressSelection::List selections
= dlg
->selectedAddresses();
1387 if (selections
.isEmpty())
1389 Person
person(selections
.first().name(), selections
.first().email());
1390 QString addrs
= mEmailToEdit
->text().trimmed();
1391 if (!addrs
.isEmpty())
1393 addrs
+= person
.fullName();
1394 mEmailToEdit
->setText(addrs
);
1397 /******************************************************************************
1398 * Select a file to attach to the email.
1400 void EditEmailAlarmDlg::slotAddAttachment()
1402 QString url
= KAlarm::browseFile(i18nc("@title:window", "Choose File to Attach"), mAttachDefaultDir
, QString(),
1403 QString(), KFile::ExistingOnly
, this);
1406 mEmailAttachList
->addItem(url
);
1407 mEmailAttachList
->setCurrentIndex(mEmailAttachList
->count() - 1); // select the new item
1408 mEmailRemoveButton
->setEnabled(true);
1409 mEmailAttachList
->setEnabled(true);
1414 /******************************************************************************
1415 * Remove the currently selected attachment from the email.
1417 void EditEmailAlarmDlg::slotRemoveAttachment()
1419 int item
= mEmailAttachList
->currentIndex();
1420 mEmailAttachList
->removeItem(item
);
1421 int count
= mEmailAttachList
->count();
1423 mEmailAttachList
->setCurrentIndex(count
- 1);
1426 mEmailRemoveButton
->setEnabled(false);
1427 mEmailAttachList
->setEnabled(false);
1432 /******************************************************************************
1433 * Clean up the alarm text.
1435 bool EditEmailAlarmDlg::checkText(QString
& result
, bool showErrorMessage
) const
1437 Q_UNUSED(showErrorMessage
);
1438 result
= mEmailMessageEdit
->toPlainText();
1443 /*=============================================================================
1444 = Class EditAudioAlarmDlg
1445 = Dialog to edit audio alarms with no display window.
1446 =============================================================================*/
1448 /******************************************************************************
1451 * Template = true to edit/create an alarm template
1452 * = false to edit/create an alarm.
1453 * event != to initialise the dialog to show the specified event's data.
1455 EditAudioAlarmDlg::EditAudioAlarmDlg(bool Template
, QWidget
* parent
, GetResourceType getResource
)
1456 : EditAlarmDlg(Template
, KAEvent::AUDIO
, parent
, getResource
)
1462 EditAudioAlarmDlg::EditAudioAlarmDlg(bool Template
, const KAEvent
* event
, bool newAlarm
, QWidget
* parent
,
1463 GetResourceType getResource
, bool readOnly
)
1464 : EditAlarmDlg(Template
, event
, newAlarm
, parent
, getResource
, readOnly
)
1466 kDebug() << "Event.id()";
1470 /******************************************************************************
1471 * Return the window caption.
1473 QString
EditAudioAlarmDlg::type_caption() const
1475 return isTemplate() ? (isNewAlarm() ? i18nc("@title:window", "New Audio Alarm Template") : i18nc("@title:window", "Edit Audio Alarm Template"))
1476 : (isNewAlarm() ? i18nc("@title:window", "New Audio Alarm") : i18nc("@title:window", "Edit Audio Alarm"));
1479 /******************************************************************************
1480 * Set up the dialog controls common to display alarms.
1482 void EditAudioAlarmDlg::type_init(QWidget
* parent
, QVBoxLayout
* frameLayout
)
1484 // File name edit box
1485 mSoundConfig
= new SoundWidget(false, true, parent
);
1487 mSoundConfig
->setAllowEmptyFile();
1488 connect(mSoundConfig
, SIGNAL(changed()), SLOT(contentsChanged()));
1489 frameLayout
->addWidget(mSoundConfig
);
1491 // Top-adjust the controls
1492 mPadding
= new KHBox(parent
);
1493 mPadding
->setMargin(0);
1494 frameLayout
->addWidget(mPadding
);
1495 frameLayout
->setStretchFactor(mPadding
, 1);
1498 /******************************************************************************
1499 * Initialise the dialog controls from the specified event.
1501 void EditAudioAlarmDlg::type_initValues(const KAEvent
* event
)
1505 mSoundConfig
->set(event
->audioFile(), event
->soundVolume(), event
->fadeVolume(), event
->fadeSeconds(),
1506 (event
->flags() & KAEvent::REPEAT_SOUND
));
1510 // Set the values to their defaults
1511 mSoundConfig
->set(Preferences::defaultSoundFile(), Preferences::defaultSoundVolume());
1515 /******************************************************************************
1516 * Initialise various values in the New Alarm dialogue.
1518 void EditAudioAlarmDlg::setAudio(const QString
& file
, float volume
)
1520 mSoundConfig
->set(file
, volume
);
1523 /******************************************************************************
1524 * Set the dialog's action and the action's text.
1526 void EditAudioAlarmDlg::setAction(KAEvent::SubAction action
, const AlarmText
& alarmText
)
1529 Q_ASSERT(action
== KAEvent::AUDIO
);
1530 mSoundConfig
->set(alarmText
.displayText(), Preferences::defaultSoundVolume());
1533 /******************************************************************************
1534 * Set the read-only status of all non-template controls.
1536 void EditAudioAlarmDlg::setReadOnly(bool readOnly
)
1538 mSoundConfig
->setReadOnly(readOnly
);
1539 EditAlarmDlg::setReadOnly(readOnly
);
1542 /******************************************************************************
1543 * Save the state of all controls.
1545 void EditAudioAlarmDlg::saveState(const KAEvent
* event
)
1547 EditAlarmDlg::saveState(event
);
1548 mSavedFile
= mSoundConfig
->fileName();
1549 mSavedRepeat
= mSoundConfig
->getVolume(mSavedVolume
, mSavedFadeVolume
, mSavedFadeSeconds
);
1552 /******************************************************************************
1553 * Check whether any of the controls has changed state since the dialog was
1555 * Reply = true if any controls have changed, or if it's a new event.
1556 * = false if no controls have changed.
1558 bool EditAudioAlarmDlg::type_stateChanged() const
1560 if (mSavedFile
!= mSoundConfig
->fileName())
1562 if (!mSavedFile
.isEmpty() || isTemplate())
1564 float volume
, fadeVolume
;
1566 if (mSavedRepeat
!= mSoundConfig
->getVolume(volume
, fadeVolume
, fadeSecs
)
1567 || mSavedVolume
!= volume
1568 || mSavedFadeVolume
!= fadeVolume
1569 || mSavedFadeSeconds
!= fadeSecs
)
1575 /******************************************************************************
1576 * Extract the data in the dialog specific to the alarm type and set up a
1579 void EditAudioAlarmDlg::type_setEvent(KAEvent
& event
, const KDateTime
& dt
, const QString
& text
, int lateCancel
, bool trial
)
1583 event
.set(dt
, QString(), QColor(), QColor(), QFont(), KAEvent::AUDIO
, lateCancel
, getAlarmFlags());
1584 float volume
, fadeVolume
;
1586 mSoundConfig
->getVolume(volume
, fadeVolume
, fadeSecs
);
1588 mSoundConfig
->file(url
, false);
1589 event
.setAudioFile(url
.prettyUrl(), volume
, fadeVolume
, fadeSecs
, isTemplate());
1592 /******************************************************************************
1593 * Get the currently specified alarm flag bits.
1595 int EditAudioAlarmDlg::getAlarmFlags() const
1597 return EditAlarmDlg::getAlarmFlags()
1598 | (mSoundConfig
->getRepeat() ? KAEvent::REPEAT_SOUND
: 0);
1601 /******************************************************************************
1602 * Check whether the file name is valid.
1604 bool EditAudioAlarmDlg::checkText(QString
& result
, bool showErrorMessage
) const
1607 if (!mSoundConfig
->file(url
, showErrorMessage
))
1612 result
= url
.pathOrUrl();
1617 /*=============================================================================
1619 = A widget to allow entry of a command or a command script.
1620 =============================================================================*/
1621 CommandEdit::CommandEdit(QWidget
* parent
)
1624 QVBoxLayout
* vlayout
= new QVBoxLayout(this);
1625 vlayout
->setMargin(0);
1626 vlayout
->setSpacing(KDialog::spacingHint());
1627 mTypeScript
= new CheckBox(EditCommandAlarmDlg::i18n_chk_EnterScript(), this);
1628 mTypeScript
->setFixedSize(mTypeScript
->sizeHint());
1629 mTypeScript
->setWhatsThis(i18nc("@info:whatsthis", "Check to enter the contents of a script instead of a shell command line"));
1630 connect(mTypeScript
, SIGNAL(toggled(bool)), SLOT(slotCmdScriptToggled(bool)));
1631 connect(mTypeScript
, SIGNAL(toggled(bool)), SIGNAL(changed()));
1632 vlayout
->addWidget(mTypeScript
, 0, Qt::AlignLeft
);
1634 mCommandEdit
= new LineEdit(LineEdit::Url
, this);
1635 mCommandEdit
->setWhatsThis(i18nc("@info:whatsthis", "Enter a shell command to execute."));
1636 connect(mCommandEdit
, SIGNAL(textChanged(QString
)), SIGNAL(changed()));
1637 vlayout
->addWidget(mCommandEdit
);
1639 mScriptEdit
= new TextEdit(this);
1640 mScriptEdit
->setWhatsThis(i18nc("@info:whatsthis", "Enter the contents of a script to execute"));
1641 connect(mScriptEdit
, SIGNAL(textChanged()), SIGNAL(changed()));
1642 vlayout
->addWidget(mScriptEdit
);
1644 slotCmdScriptToggled(mTypeScript
->isChecked());
1647 /******************************************************************************
1648 * Initialise the widget controls from the specified event.
1650 void CommandEdit::setScript(bool script
)
1652 mTypeScript
->setChecked(script
);
1655 bool CommandEdit::isScript() const
1657 return mTypeScript
->isChecked();
1660 /******************************************************************************
1661 * Set the widget's text.
1663 void CommandEdit::setText(const AlarmText
& alarmText
)
1665 QString text
= alarmText
.displayText();
1666 bool script
= alarmText
.isScript();
1667 mTypeScript
->setChecked(script
);
1669 mScriptEdit
->setPlainText(text
);
1671 mCommandEdit
->setText(KAlarm::pathOrUrl(text
));
1674 /******************************************************************************
1675 * Return the widget's text.
1677 QString
CommandEdit::text() const
1680 if (mTypeScript
->isChecked())
1681 result
= mScriptEdit
->toPlainText();
1683 result
= mCommandEdit
->text();
1684 return result
.trimmed();
1687 /******************************************************************************
1688 * Return the alarm text.
1689 * If 'showErrorMessage' is true and the text is empty, an error message is
1692 QString
CommandEdit::text(EditAlarmDlg
* dlg
, bool showErrorMessage
) const
1694 QString result
= text();
1695 if (showErrorMessage
&& result
.isEmpty())
1696 KAMessageBox::sorry(dlg
, i18nc("@info", "Please enter a command or script to execute"));
1700 /******************************************************************************
1701 * Set the read-only status of all controls.
1703 void CommandEdit::setReadOnly(bool readOnly
)
1705 mTypeScript
->setReadOnly(readOnly
);
1706 mCommandEdit
->setReadOnly(readOnly
);
1707 mScriptEdit
->setReadOnly(readOnly
);
1710 /******************************************************************************
1711 * Called when one of the command type radio buttons is clicked,
1712 * to display the appropriate edit field.
1714 void CommandEdit::slotCmdScriptToggled(bool on
)
1718 mCommandEdit
->hide();
1719 mScriptEdit
->show();
1720 mScriptEdit
->setFocus();
1724 mScriptEdit
->hide();
1725 mCommandEdit
->show();
1726 mCommandEdit
->setFocus();
1728 emit
scriptToggled(on
);
1731 /******************************************************************************
1732 * Returns the minimum size of the widget.
1734 QSize
CommandEdit::minimumSizeHint() const
1736 QSize
t(mTypeScript
->minimumSizeHint());
1737 QSize
s(mCommandEdit
->minimumSizeHint().expandedTo(mScriptEdit
->minimumSizeHint()));
1738 s
.setHeight(s
.height() + KDialog::spacingHint() + t
.height());
1739 if (s
.width() < t
.width())
1740 s
.setWidth(t
.width());
1746 /*=============================================================================
1748 = A text edit field with a minimum height of 3 text lines.
1749 =============================================================================*/
1750 TextEdit::TextEdit(QWidget
* parent
)
1753 QSize tsize
= sizeHint();
1754 tsize
.setHeight(fontMetrics().lineSpacing()*13/4 + 2*frameWidth());
1755 setMinimumSize(tsize
);
1758 void TextEdit::dragEnterEvent(QDragEnterEvent
* e
)
1761 if (KCalUtils::ICalDrag::canDecode(e
->mimeData()))
1763 if (KCal::ICalDrag::canDecode(e
->mimeData()))
1765 e
->ignore(); // don't accept "text/calendar" objects
1766 KTextEdit::dragEnterEvent(e
);