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 "pickfileradio.h"
39 #include "preferences.h"
40 #include "radiobutton.h"
42 #include "shellprocess.h"
43 #include "soundpicker.h"
45 #include "specialactions.h"
46 #include "templatepickdlg.h"
47 #include "timespinbox.h"
49 #include <akonadi/contact/emailaddressselectiondialog.h>
51 #include <kcalcore/person.h>
52 #include <kcalutils/icaldrag.h>
53 using namespace KCalCore
;
55 #include <kcal/person.h>
56 #include <kcal/icaldrag.h>
61 #include <kiconloader.h>
62 #include <kio/netaccess.h>
63 #include <kfileitem.h>
64 #include <kmessagebox.h>
72 #include <QGridLayout>
73 #include <QHBoxLayout>
74 #include <QVBoxLayout>
75 #include <QDragEnterEvent>
77 enum { tTEXT
, tFILE
, tCOMMAND
}; // order of mTypeCombo items
80 /*=============================================================================
81 = Class PickLogFileRadio
82 =============================================================================*/
83 class PickLogFileRadio
: public PickFileRadio
86 PickLogFileRadio(QPushButton
* b
, LineEdit
* e
, const QString
& text
, ButtonGroup
* group
, QWidget
* parent
)
87 : PickFileRadio(b
, e
, text
, group
, parent
) { }
88 virtual QString
pickFile() // called when browse button is pressed to select a log file
90 return KAlarm::browseFile(i18nc("@title:window", "Choose Log File"), mDefaultDir
, fileEdit()->text(), QString(),
91 KFile::LocalOnly
, parentWidget());
94 QString mDefaultDir
; // default directory for log file browse button
98 /*=============================================================================
99 = Class EditDisplayAlarmDlg
100 = Dialog to edit display alarms.
101 =============================================================================*/
103 QString
EditDisplayAlarmDlg::i18n_chk_ConfirmAck() { return i18nc("@option:check", "Confirm acknowledgment"); }
106 /******************************************************************************
109 * Template = true to edit/create an alarm template
110 * = false to edit/create an alarm.
111 * event != to initialise the dialog to show the specified event's data.
113 EditDisplayAlarmDlg::EditDisplayAlarmDlg(bool Template
, QWidget
* parent
, GetResourceType getResource
)
114 : EditAlarmDlg(Template
, KAEvent::MESSAGE
, parent
, getResource
),
115 mSpecialActionsButton(0),
116 mReminderDeferral(false),
117 mReminderArchived(false)
123 EditDisplayAlarmDlg::EditDisplayAlarmDlg(bool Template
, const KAEvent
* event
, bool newAlarm
, QWidget
* parent
,
124 GetResourceType getResource
, bool readOnly
)
125 : EditAlarmDlg(Template
, event
, newAlarm
, parent
, getResource
, readOnly
),
126 mSpecialActionsButton(0),
127 mReminderDeferral(false),
128 mReminderArchived(false)
130 kDebug() << "Event.id()";
134 /******************************************************************************
135 * Return the window caption.
137 QString
EditDisplayAlarmDlg::type_caption() const
139 return isTemplate() ? (isNewAlarm() ? i18nc("@title:window", "New Display Alarm Template") : i18nc("@title:window", "Edit Display Alarm Template"))
140 : (isNewAlarm() ? i18nc("@title:window", "New Display Alarm") : i18nc("@title:window", "Edit Display Alarm"));
143 /******************************************************************************
144 * Set up the dialog controls common to display alarms.
146 void EditDisplayAlarmDlg::type_init(QWidget
* parent
, QVBoxLayout
* frameLayout
)
148 // Display type combo box
149 KHBox
* box
= new KHBox(parent
); // to group widgets for QWhatsThis text
151 box
->setSpacing(KDialog::spacingHint());
152 QLabel
* label
= new QLabel(i18nc("@label:listbox", "Display type:"), box
);
153 label
->setFixedSize(label
->sizeHint());
154 mTypeCombo
= new ComboBox(box
);
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 connect(mTypeCombo
, SIGNAL(currentIndexChanged(int)), SLOT(slotAlarmTypeChanged(int)));
164 connect(mTypeCombo
, SIGNAL(currentIndexChanged(int)), SLOT(contentsChanged()));
165 label
->setBuddy(mTypeCombo
);
166 box
->setWhatsThis(i18nc("@info:whatsthis", "<para>Select what the alarm should display:"
167 "<list><item><interface>%1</interface>: the alarm will display the text message you type in.</item>"
168 "<item><interface>%2</interface>: the alarm will display the contents of a text or image file.</item>"
169 "<item><interface>%3</interface>: the alarm will display the output from a command.</item></list></para>",
170 textItem
, fileItem
, commandItem
));
171 box
->setStretchFactor(new QWidget(box
), 1); // left adjust the control
172 frameLayout
->addWidget(box
);
174 // Text message edit box
175 mTextMessageEdit
= new TextEdit(parent
);
176 mTextMessageEdit
->setLineWrapMode(KTextEdit::NoWrap
);
177 mTextMessageEdit
->setWhatsThis(i18nc("@info:whatsthis", "Enter the text of the alarm message. It may be multi-line."));
178 connect(mTextMessageEdit
, SIGNAL(textChanged()), SLOT(contentsChanged()));
179 frameLayout
->addWidget(mTextMessageEdit
);
181 // File name edit box
182 mFileBox
= new KHBox(parent
);
183 mFileBox
->setMargin(0);
184 frameLayout
->addWidget(mFileBox
);
185 mFileMessageEdit
= new LineEdit(LineEdit::Url
, mFileBox
);
186 mFileMessageEdit
->setAcceptDrops(true);
187 mFileMessageEdit
->setWhatsThis(i18nc("@info:whatsthis", "Enter the name or URL of a text or image file to display."));
188 connect(mFileMessageEdit
, SIGNAL(textChanged(const QString
&)), SLOT(contentsChanged()));
190 // File browse button
191 mFileBrowseButton
= new QPushButton(mFileBox
);
192 mFileBrowseButton
->setIcon(SmallIcon("document-open"));
193 int size
= mFileBrowseButton
->sizeHint().height();
194 mFileBrowseButton
->setFixedSize(size
, size
);
195 mFileBrowseButton
->setToolTip(i18nc("@info:tooltip", "Choose a file"));
196 mFileBrowseButton
->setWhatsThis(i18nc("@info:whatsthis", "Select a text or image file to display."));
197 connect(mFileBrowseButton
, SIGNAL(clicked()), SLOT(slotPickFile()));
199 // Command type checkbox and edit box
200 mCmdEdit
= new CommandEdit(parent
);
201 connect(mCmdEdit
, SIGNAL(scriptToggled(bool)), SLOT(slotCmdScriptToggled(bool)));
202 connect(mCmdEdit
, SIGNAL(changed()), SLOT(contentsChanged()));
203 frameLayout
->addWidget(mCmdEdit
);
205 // Sound checkbox and file selector
206 QHBoxLayout
* hlayout
= new QHBoxLayout();
207 hlayout
->setMargin(0);
208 frameLayout
->addLayout(hlayout
);
209 mSoundPicker
= new SoundPicker(parent
);
210 mSoundPicker
->setFixedSize(mSoundPicker
->sizeHint());
211 connect(mSoundPicker
, SIGNAL(changed()), SLOT(contentsChanged()));
212 hlayout
->addWidget(mSoundPicker
);
213 hlayout
->addSpacing(2*spacingHint());
214 hlayout
->addStretch();
216 // Font and colour choice button and sample text
217 mFontColourButton
= new FontColourButton(parent
);
218 mFontColourButton
->setMaximumHeight(mFontColourButton
->sizeHint().height() * 3/2);
219 hlayout
->addWidget(mFontColourButton
);
220 connect(mFontColourButton
, SIGNAL(selected(const QColor
&, const QColor
&)), SLOT(setColours(const QColor
&, const QColor
&)));
221 connect(mFontColourButton
, SIGNAL(selected(const QColor
&, const QColor
&)), SLOT(contentsChanged()));
223 if (ShellProcess::authorised()) // don't display if shell commands not allowed (e.g. kiosk mode)
225 // Special actions button
226 mSpecialActionsButton
= new SpecialActionsButton(false, parent
);
227 mSpecialActionsButton
->setFixedSize(mSpecialActionsButton
->sizeHint());
228 connect(mSpecialActionsButton
, SIGNAL(selected()), SLOT(contentsChanged()));
229 frameLayout
->addWidget(mSpecialActionsButton
, 0, Qt::AlignRight
);
232 // Top-adjust the controls
233 mFilePadding
= new KHBox(parent
);
234 mFilePadding
->setMargin(0);
235 frameLayout
->addWidget(mFilePadding
);
236 frameLayout
->setStretchFactor(mFilePadding
, 1);
239 /******************************************************************************
240 * Create a reminder control.
242 Reminder
* EditDisplayAlarmDlg::createReminder(QWidget
* parent
)
244 static const QString reminderText
= i18nc("@info:whatsthis", "Enter how long in advance of or after the main alarm to display a reminder alarm.");
245 return new Reminder(i18nc("@info:whatsthis", "Check to additionally display a reminder in advance of or after the main alarm time(s)."),
246 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()),
247 i18nc("@info:whatsthis", "Select whether the reminder should be triggered before or after the main alarm"),
251 /******************************************************************************
252 * Create an "acknowledgement confirmation required" checkbox.
254 CheckBox
* EditDisplayAlarmDlg::createConfirmAckCheckbox(QWidget
* parent
)
256 CheckBox
* confirmAck
= new CheckBox(i18n_chk_ConfirmAck(), parent
);
257 confirmAck
->setWhatsThis(i18nc("@info:whatsthis", "Check to be prompted for confirmation when you acknowledge the alarm."));
261 /******************************************************************************
262 * Initialise the dialog controls from the specified event.
264 void EditDisplayAlarmDlg::type_initValues(const KAEvent
* event
)
266 mKMailSerialNumber
= 0;
267 lateCancel()->showAutoClose(true);
270 if (mAlarmType
== KAEvent::MESSAGE
&& event
->kmailSerialNumber()
271 && AlarmText::checkIfEmail(event
->cleanText()))
272 mKMailSerialNumber
= event
->kmailSerialNumber();
273 lateCancel()->setAutoClose(event
->autoClose());
274 if (event
->useDefaultFont())
275 mFontColourButton
->setDefaultFont();
277 mFontColourButton
->setFont(event
->font());
278 mFontColourButton
->setBgColour(event
->bgColour());
279 mFontColourButton
->setFgColour(event
->fgColour());
280 setColours(event
->fgColour(), event
->bgColour());
281 mConfirmAck
->setChecked(event
->confirmAck());
282 bool recurs
= event
->recurs();
283 int reminderMins
= event
->reminderMinutes();
284 if (reminderMins
> 0 && !event
->reminderActive())
285 reminderMins
= 0; // don't show advance reminder which has already passed
288 if (event
->reminderDeferral() && !recurs
)
290 reminderMins
= event
->deferDateTime().minsTo(event
->mainDateTime());
291 mReminderDeferral
= true;
293 else if (event
->reminderMinutes() && recurs
)
295 reminderMins
= event
->reminderMinutes();
296 mReminderArchived
= true;
299 reminder()->setMinutes(reminderMins
, dateOnly());
300 reminder()->setOnceOnly(event
->reminderOnceOnly());
301 reminder()->enableOnceOnly(recurs
);
302 if (mSpecialActionsButton
)
303 mSpecialActionsButton
->setActions(event
->preAction(), event
->postAction(), event
->cancelOnPreActionError(), event
->dontShowPreActionError());
304 Preferences::SoundType soundType
= event
->speak() ? Preferences::Sound_Speak
305 : event
->beep() ? Preferences::Sound_Beep
306 : !event
->audioFile().isEmpty() ? Preferences::Sound_File
307 : Preferences::Sound_None
;
308 mSoundPicker
->set(soundType
, event
->audioFile(), event
->soundVolume(),
309 event
->fadeVolume(), event
->fadeSeconds(), event
->repeatSound());
313 // Set the values to their defaults
314 if (!ShellProcess::authorised())
316 // Don't allow shell commands in kiosk mode
317 if (mSpecialActionsButton
)
318 mSpecialActionsButton
->setEnabled(false);
320 lateCancel()->setAutoClose(Preferences::defaultAutoClose());
321 mTypeCombo
->setCurrentIndex(0);
322 mFontColourButton
->setDefaultFont();
323 mFontColourButton
->setBgColour(Preferences::defaultBgColour());
324 mFontColourButton
->setFgColour(Preferences::defaultFgColour());
325 setColours(Preferences::defaultFgColour(), Preferences::defaultBgColour());
326 mConfirmAck
->setChecked(Preferences::defaultConfirmAck());
327 reminder()->setMinutes(0, false);
328 reminder()->enableOnceOnly(isTimedRecurrence()); // must be called after mRecurrenceEdit is set up
329 if (mSpecialActionsButton
)
330 mSpecialActionsButton
->setActions(Preferences::defaultPreAction(), Preferences::defaultPostAction(),
331 Preferences::defaultCancelOnPreActionError(), Preferences::defaultDontShowPreActionError());
332 mSoundPicker
->set(Preferences::defaultSoundType(), Preferences::defaultSoundFile(),
333 Preferences::defaultSoundVolume(), -1, 0, Preferences::defaultSoundRepeat());
337 /******************************************************************************
338 * Called when the More/Less Options button is clicked.
339 * Show/hide the optional options.
341 void EditDisplayAlarmDlg::type_showOptions(bool more
)
343 if (mSpecialActionsButton
)
346 mSpecialActionsButton
->show();
348 mSpecialActionsButton
->hide();
352 /******************************************************************************
353 * Called when the font/color button has been clicked.
354 * Set the colors in the message text entry control.
356 void EditDisplayAlarmDlg::setColours(const QColor
& fgColour
, const QColor
& bgColour
)
358 QPalette pal
= mTextMessageEdit
->palette();
359 pal
.setColor(mTextMessageEdit
->backgroundRole(), bgColour
);
360 pal
.setColor(QPalette::Text
, fgColour
);
361 mTextMessageEdit
->setPalette(pal
);
362 pal
= mTextMessageEdit
->viewport()->palette();
363 pal
.setColor(mTextMessageEdit
->viewport()->backgroundRole(), bgColour
);
364 pal
.setColor(QPalette::Text
, fgColour
);
365 mTextMessageEdit
->viewport()->setPalette(pal
);
366 // Change the color of existing text
367 QTextCursor cursor
= mTextMessageEdit
->textCursor();
368 mTextMessageEdit
->selectAll();
369 mTextMessageEdit
->setTextColor(fgColour
);
370 mTextMessageEdit
->setTextCursor(cursor
);
373 /******************************************************************************
374 * Set the dialog's action and the action's text.
376 void EditDisplayAlarmDlg::setAction(KAEvent::Action action
, const AlarmText
& alarmText
)
378 QString text
= alarmText
.displayText();
381 case KAEvent::MESSAGE
:
382 mTypeCombo
->setCurrentIndex(tTEXT
);
383 mTextMessageEdit
->setPlainText(text
);
384 mKMailSerialNumber
= alarmText
.isEmail() ? alarmText
.kmailSerialNumber() : 0;
387 mTypeCombo
->setCurrentIndex(tFILE
);
388 mFileMessageEdit
->setText(text
);
390 case KAEvent::COMMAND
:
391 mTypeCombo
->setCurrentIndex(tCOMMAND
);
392 mCmdEdit
->setText(alarmText
);
400 /******************************************************************************
401 * Initialise various values in the New Alarm dialogue.
403 void EditDisplayAlarmDlg::setBgColour(const QColor
& colour
)
405 mFontColourButton
->setBgColour(colour
);
406 setColours(mFontColourButton
->fgColour(), colour
);
408 void EditDisplayAlarmDlg::setFgColour(const QColor
& colour
)
410 mFontColourButton
->setFgColour(colour
);
411 setColours(colour
, mFontColourButton
->bgColour());
413 void EditDisplayAlarmDlg::setConfirmAck(bool confirm
)
415 mConfirmAck
->setChecked(confirm
);
417 void EditDisplayAlarmDlg::setAutoClose(bool close
)
419 lateCancel()->setAutoClose(close
);
421 void EditDisplayAlarmDlg::setAudio(Preferences::SoundType type
, const QString
& file
, float volume
, bool repeat
)
423 mSoundPicker
->set(type
, file
, volume
, -1, 0, repeat
);
425 void EditDisplayAlarmDlg::setReminder(int minutes
, bool onceOnly
)
427 reminder()->setMinutes(minutes
, dateOnly());
428 reminder()->setOnceOnly(onceOnly
);
429 reminder()->enableOnceOnly(isTimedRecurrence());
432 /******************************************************************************
433 * Set the read-only status of all non-template controls.
435 void EditDisplayAlarmDlg::setReadOnly(bool readOnly
)
437 mTypeCombo
->setReadOnly(readOnly
);
438 mTextMessageEdit
->setReadOnly(readOnly
);
439 mFileMessageEdit
->setReadOnly(readOnly
);
440 mCmdEdit
->setReadOnly(readOnly
);
441 mFontColourButton
->setReadOnly(readOnly
);
442 mSoundPicker
->setReadOnly(readOnly
);
443 mConfirmAck
->setReadOnly(readOnly
);
444 reminder()->setReadOnly(readOnly
);
445 if (mSpecialActionsButton
)
446 mSpecialActionsButton
->setReadOnly(readOnly
);
448 mFileBrowseButton
->hide();
450 mFileBrowseButton
->show();
451 EditAlarmDlg::setReadOnly(readOnly
);
454 /******************************************************************************
455 * Save the state of all controls.
457 void EditDisplayAlarmDlg::saveState(const KAEvent
* event
)
459 EditAlarmDlg::saveState(event
);
460 mSavedType
= mTypeCombo
->currentIndex();
461 mSavedCmdScript
= mCmdEdit
->isScript();
462 mSavedSoundType
= mSoundPicker
->sound();
463 mSavedSoundFile
= mSoundPicker
->file();
464 mSavedSoundVolume
= mSoundPicker
->volume(mSavedSoundFadeVolume
, mSavedSoundFadeSeconds
);
465 mSavedRepeatSound
= mSoundPicker
->repeat();
466 mSavedConfirmAck
= mConfirmAck
->isChecked();
467 mSavedFont
= mFontColourButton
->font();
468 mSavedFgColour
= mFontColourButton
->fgColour();
469 mSavedBgColour
= mFontColourButton
->bgColour();
470 mSavedReminder
= reminder()->minutes();
471 mSavedOnceOnly
= reminder()->isOnceOnly();
472 mSavedAutoClose
= lateCancel()->isAutoClose();
473 if (mSpecialActionsButton
)
475 mSavedPreAction
= mSpecialActionsButton
->preAction();
476 mSavedPostAction
= mSpecialActionsButton
->postAction();
477 mSavedPreActionCancel
= mSpecialActionsButton
->cancelOnError();
481 /******************************************************************************
482 * Check whether any of the controls has changed state since the dialog was
484 * Reply = true if any controls have changed, or if it's a new event.
485 * = false if no controls have changed.
487 bool EditDisplayAlarmDlg::type_stateChanged() const
489 if (mSavedType
!= mTypeCombo
->currentIndex()
490 || mSavedCmdScript
!= mCmdEdit
->isScript()
491 || mSavedSoundType
!= mSoundPicker
->sound()
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())
500 if (mSpecialActionsButton
)
502 if (mSavedPreAction
!= mSpecialActionsButton
->preAction()
503 || mSavedPostAction
!= mSpecialActionsButton
->postAction()
504 || mSavedPreActionCancel
!= mSpecialActionsButton
->cancelOnError())
507 if (mSavedSoundType
== Preferences::Sound_File
)
509 if (mSavedSoundFile
!= mSoundPicker
->file())
511 if (!mSavedSoundFile
.isEmpty())
515 if (mSavedRepeatSound
!= mSoundPicker
->repeat()
516 || mSavedSoundVolume
!= mSoundPicker
->volume(fadeVolume
, fadeSecs
)
517 || mSavedSoundFadeVolume
!= fadeVolume
518 || mSavedSoundFadeSeconds
!= fadeSecs
)
525 /******************************************************************************
526 * Extract the data in the dialog specific to the alarm type and set up a
529 void EditDisplayAlarmDlg::type_setEvent(KAEvent
& event
, const KDateTime
& dt
, const QString
& text
, int lateCancel
, bool trial
)
531 KAEvent::Action type
;
532 switch (mTypeCombo
->currentIndex())
534 case tFILE
: type
= KAEvent::FILE; break;
535 case tCOMMAND
: type
= KAEvent::COMMAND
; break;
537 case tTEXT
: type
= KAEvent::MESSAGE
; break;
539 event
.set(dt
, text
, mFontColourButton
->bgColour(), mFontColourButton
->fgColour(), mFontColourButton
->font(),
540 type
, lateCancel
, getAlarmFlags());
541 if (type
== KAEvent::MESSAGE
)
543 if (AlarmText::checkIfEmail(text
))
544 event
.setKMailSerialNumber(mKMailSerialNumber
);
548 float volume
= mSoundPicker
->volume(fadeVolume
, fadeSecs
);
549 event
.setAudioFile(mSoundPicker
->file().prettyUrl(), volume
, fadeVolume
, fadeSecs
);
550 if (!trial
&& reminder()->isEnabled())
551 event
.setReminder(reminder()->minutes(), reminder()->isOnceOnly());
552 if (mSpecialActionsButton
&& mSpecialActionsButton
->isEnabled())
553 event
.setActions(mSpecialActionsButton
->preAction(), mSpecialActionsButton
->postAction(),
554 mSpecialActionsButton
->cancelOnError(), mSpecialActionsButton
->dontShowError());
557 /******************************************************************************
558 * Get the currently specified alarm flag bits.
560 int EditDisplayAlarmDlg::getAlarmFlags() const
562 bool cmd
= (mTypeCombo
->currentIndex() == tCOMMAND
);
563 return EditAlarmDlg::getAlarmFlags()
564 | (mSoundPicker
->sound() == Preferences::Sound_Beep
? KAEvent::BEEP
: 0)
565 | (mSoundPicker
->sound() == Preferences::Sound_Speak
? KAEvent::SPEAK
: 0)
566 | (mSoundPicker
->repeat() ? KAEvent::REPEAT_SOUND
: 0)
567 | (mConfirmAck
->isChecked() ? KAEvent::CONFIRM_ACK
: 0)
568 | (lateCancel()->isAutoClose() ? KAEvent::AUTO_CLOSE
: 0)
569 | (mFontColourButton
->defaultFont() ? KAEvent::DEFAULT_FONT
: 0)
570 | (cmd
? KAEvent::DISPLAY_COMMAND
: 0)
571 | (cmd
&& mCmdEdit
->isScript() ? KAEvent::SCRIPT
: 0);
574 /******************************************************************************
575 * Called when one of the alarm display type combo box is changed, to display
576 * the appropriate set of controls for that action type.
578 void EditDisplayAlarmDlg::slotAlarmTypeChanged(int index
)
583 case tTEXT
: // text message
585 mFilePadding
->hide();
587 mTextMessageEdit
->show();
588 mSoundPicker
->showSpeak(true);
589 setButtonWhatsThis(Try
, i18nc("@info:whatsthis", "Display the alarm message now"));
590 focus
= mTextMessageEdit
;
592 case tFILE
: // file contents
593 mTextMessageEdit
->hide();
595 mFilePadding
->show();
597 mSoundPicker
->showSpeak(false);
598 setButtonWhatsThis(Try
, i18nc("@info:whatsthis", "Display the file now"));
599 mFileMessageEdit
->setNoSelect();
600 focus
= mFileMessageEdit
;
602 case tCOMMAND
: // command output
603 mTextMessageEdit
->hide();
605 slotCmdScriptToggled(mCmdEdit
->isScript()); // show/hide mFilePadding
607 mSoundPicker
->showSpeak(true);
608 setButtonWhatsThis(Try
, i18nc("@info:whatsthis", "Display the command output now"));
616 /******************************************************************************
617 * Called when the file browse button is pressed to select a file to display.
619 void EditDisplayAlarmDlg::slotPickFile()
621 static QString defaultDir
; // default directory for file browse button
622 QString file
= KAlarm::browseFile(i18nc("@title:window", "Choose Text or Image File to Display"),
623 defaultDir
, mFileMessageEdit
->text(), QString(), KFile::ExistingOnly
, this);
626 mFileMessageEdit
->setText(KAlarm::pathOrUrl(file
));
631 /******************************************************************************
632 * Called when one of the command type radio buttons is clicked,
633 * to display the appropriate edit field.
635 void EditDisplayAlarmDlg::slotCmdScriptToggled(bool on
)
638 mFilePadding
->hide();
640 mFilePadding
->show();
643 /******************************************************************************
644 * Clean up the alarm text, and if it's a file, check whether it's valid.
646 bool EditDisplayAlarmDlg::checkText(QString
& result
, bool showErrorMessage
) const
648 switch (mTypeCombo
->currentIndex())
651 result
= mTextMessageEdit
->toPlainText();
656 QString alarmtext
= mFileMessageEdit
->text().trimmed();
658 KAlarm::FileErr err
= KAlarm::checkFileExists(alarmtext
, url
);
659 if (err
== KAlarm::FileErr_None
)
661 switch (KAlarm::fileType(KFileItem(KFileItem::Unknown
, KFileItem::Unknown
, url
).mimeTypePtr()))
663 case KAlarm::TextFormatted
:
664 case KAlarm::TextPlain
:
665 case KAlarm::TextApplication
:
669 err
= KAlarm::FileErr_NotTextImage
;
673 if (err
!= KAlarm::FileErr_None
&& showErrorMessage
)
675 mFileMessageEdit
->setFocus();
676 if (!KAlarm::showFileErrMessage(alarmtext
, err
, KAlarm::FileErr_BlankDisplay
, const_cast<EditDisplayAlarmDlg
*>(this)))
683 result
= mCmdEdit
->text(const_cast<EditDisplayAlarmDlg
*>(this), showErrorMessage
);
684 if (result
.isEmpty())
692 /*=============================================================================
693 = Class EditCommandAlarmDlg
694 = Dialog to edit command alarms.
695 =============================================================================*/
697 QString
EditCommandAlarmDlg::i18n_chk_EnterScript() { return i18nc("@option:check", "Enter a script"); }
698 QString
EditCommandAlarmDlg::i18n_radio_ExecInTermWindow() { return i18nc("@option:radio", "Execute in terminal window"); }
699 QString
EditCommandAlarmDlg::i18n_chk_ExecInTermWindow() { return i18nc("@option:check", "Execute in terminal window"); }
702 /******************************************************************************
705 * Template = true to edit/create an alarm template
706 * = false to edit/create an alarm.
707 * event != to initialise the dialog to show the specified event's data.
709 EditCommandAlarmDlg::EditCommandAlarmDlg(bool Template
, QWidget
* parent
, GetResourceType getResource
)
710 : EditAlarmDlg(Template
, KAEvent::COMMAND
, parent
, getResource
)
716 EditCommandAlarmDlg::EditCommandAlarmDlg(bool Template
, const KAEvent
* event
, bool newAlarm
, QWidget
* parent
,
717 GetResourceType getResource
, bool readOnly
)
718 : EditAlarmDlg(Template
, event
, newAlarm
, parent
, getResource
, readOnly
)
720 kDebug() << "Event.id()";
724 /******************************************************************************
725 * Return the window caption.
727 QString
EditCommandAlarmDlg::type_caption() const
729 return isTemplate() ? (isNewAlarm() ? i18nc("@title:window", "New Command Alarm Template") : i18nc("@title:window", "Edit Command Alarm Template"))
730 : (isNewAlarm() ? i18nc("@title:window", "New Command Alarm") : i18nc("@title:window", "Edit Command Alarm"));
733 /******************************************************************************
734 * Set up the command alarm dialog controls.
736 void EditCommandAlarmDlg::type_init(QWidget
* parent
, QVBoxLayout
* frameLayout
)
738 setButtonWhatsThis(Try
, i18nc("@info:whatsthis", "Execute the specified command now"));
740 mCmdEdit
= new CommandEdit(parent
);
741 connect(mCmdEdit
, SIGNAL(scriptToggled(bool)), SLOT(slotCmdScriptToggled(bool)));
742 connect(mCmdEdit
, SIGNAL(changed()), SLOT(contentsChanged()));
743 frameLayout
->addWidget(mCmdEdit
);
745 // What to do with command output
747 mCmdOutputBox
= new QGroupBox(i18nc("@title:group", "Command Output"), parent
);
748 frameLayout
->addWidget(mCmdOutputBox
);
749 QVBoxLayout
* vlayout
= new QVBoxLayout(mCmdOutputBox
);
750 vlayout
->setMargin(marginHint());
751 vlayout
->setSpacing(spacingHint());
752 mCmdOutputGroup
= new ButtonGroup(mCmdOutputBox
);
753 connect(mCmdOutputGroup
, SIGNAL(buttonSet(QAbstractButton
*)), SLOT(contentsChanged()));
755 // Execute in terminal window
756 mCmdExecInTerm
= new RadioButton(i18n_radio_ExecInTermWindow(), mCmdOutputBox
);
757 mCmdExecInTerm
->setFixedSize(mCmdExecInTerm
->sizeHint());
758 mCmdExecInTerm
->setWhatsThis(i18nc("@info:whatsthis", "Check to execute the command in a terminal window"));
759 mCmdOutputGroup
->addButton(mCmdExecInTerm
, Preferences::Log_Terminal
);
760 vlayout
->addWidget(mCmdExecInTerm
, 0, Qt::AlignLeft
);
762 // Log file name edit box
763 KHBox
* box
= new KHBox(mCmdOutputBox
);
765 (new QWidget(box
))->setFixedWidth(mCmdExecInTerm
->style()->pixelMetric(QStyle::PM_ExclusiveIndicatorWidth
)); // indent the edit box
766 mCmdLogFileEdit
= new LineEdit(LineEdit::Url
, box
);
767 mCmdLogFileEdit
->setAcceptDrops(true);
768 mCmdLogFileEdit
->setWhatsThis(i18nc("@info:whatsthis", "Enter the name or path of the log file."));
769 connect(mCmdLogFileEdit
, SIGNAL(textChanged(const QString
&)), SLOT(contentsChanged()));
771 // Log file browse button.
772 // The file browser dialog is activated by the PickLogFileRadio class.
773 QPushButton
* browseButton
= new QPushButton(box
);
774 browseButton
->setIcon(SmallIcon("document-open"));
775 int size
= browseButton
->sizeHint().height();
776 browseButton
->setFixedSize(size
, size
);
777 browseButton
->setToolTip(i18nc("@info:tooltip", "Choose a file"));
778 browseButton
->setWhatsThis(i18nc("@info:whatsthis", "Select a log file."));
780 // Log output to file
781 mCmdLogToFile
= new PickLogFileRadio(browseButton
, mCmdLogFileEdit
, i18nc("@option:radio", "Log to file"), mCmdOutputGroup
, mCmdOutputBox
);
782 mCmdLogToFile
->setFixedSize(mCmdLogToFile
->sizeHint());
783 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."));
784 connect(mCmdLogToFile
, SIGNAL(fileChanged()), SLOT(contentsChanged()));
785 mCmdOutputGroup
->addButton(mCmdLogToFile
, Preferences::Log_File
);
786 vlayout
->addWidget(mCmdLogToFile
, 0, Qt::AlignLeft
);
787 vlayout
->addWidget(box
);
790 mCmdDiscardOutput
= new RadioButton(i18nc("@option:radio", "Discard"), mCmdOutputBox
);
791 mCmdDiscardOutput
->setFixedSize(mCmdDiscardOutput
->sizeHint());
792 mCmdDiscardOutput
->setWhatsThis(i18nc("@info:whatsthis", "Check to discard command output."));
793 mCmdOutputGroup
->addButton(mCmdDiscardOutput
, Preferences::Log_Discard
);
794 vlayout
->addWidget(mCmdDiscardOutput
, 0, Qt::AlignLeft
);
796 // Top-adjust the controls
797 mCmdPadding
= new KHBox(parent
);
798 mCmdPadding
->setMargin(0);
799 frameLayout
->addWidget(mCmdPadding
);
800 frameLayout
->setStretchFactor(mCmdPadding
, 1);
803 /******************************************************************************
804 * Initialise the dialog controls from the specified event.
806 void EditCommandAlarmDlg::type_initValues(const KAEvent
* event
)
810 // Set the values to those for the specified event
811 RadioButton
* logType
= event
->commandXterm() ? mCmdExecInTerm
812 : !event
->logFile().isEmpty() ? mCmdLogToFile
814 if (logType
== mCmdLogToFile
)
815 mCmdLogFileEdit
->setText(event
->logFile()); // set file name before setting radio button
816 logType
->setChecked(true);
820 // Set the values to their defaults
821 mCmdEdit
->setScript(Preferences::defaultCmdScript());
822 mCmdLogFileEdit
->setText(Preferences::defaultCmdLogFile()); // set file name before setting radio button
823 mCmdOutputGroup
->setButton(Preferences::defaultCmdLogType());
825 slotCmdScriptToggled(mCmdEdit
->isScript());
828 /******************************************************************************
829 * Called when the More/Less Options button is clicked.
830 * Show/hide the optional options.
832 void EditCommandAlarmDlg::type_showOptions(bool more
)
835 mCmdOutputBox
->show();
837 mCmdOutputBox
->hide();
840 /******************************************************************************
841 * Set the dialog's action and the action's text.
843 void EditCommandAlarmDlg::setAction(KAEvent::Action action
, const AlarmText
& alarmText
)
846 Q_ASSERT(action
== KAEvent::COMMAND
);
847 mCmdEdit
->setText(alarmText
);
850 /******************************************************************************
851 * Set the read-only status of all non-template controls.
853 void EditCommandAlarmDlg::setReadOnly(bool readOnly
)
855 if (!isTemplate() && !ShellProcess::authorised())
856 readOnly
= true; // don't allow editing of existing command alarms in kiosk mode
857 mCmdEdit
->setReadOnly(readOnly
);
858 mCmdExecInTerm
->setReadOnly(readOnly
);
859 mCmdLogToFile
->setReadOnly(readOnly
);
860 mCmdDiscardOutput
->setReadOnly(readOnly
);
861 EditAlarmDlg::setReadOnly(readOnly
);
864 /******************************************************************************
865 * Save the state of all controls.
867 void EditCommandAlarmDlg::saveState(const KAEvent
* event
)
869 EditAlarmDlg::saveState(event
);
870 mSavedCmdScript
= mCmdEdit
->isScript();
871 mSavedCmdOutputRadio
= mCmdOutputGroup
->checkedButton();
872 mSavedCmdLogFile
= mCmdLogFileEdit
->text();
875 /******************************************************************************
876 * Check whether any of the controls has changed state since the dialog was
878 * Reply = true if any controls have changed, or if it's a new event.
879 * = false if no controls have changed.
881 bool EditCommandAlarmDlg::type_stateChanged() const
883 if (mSavedCmdScript
!= mCmdEdit
->isScript()
884 || mSavedCmdOutputRadio
!= mCmdOutputGroup
->checkedButton())
886 if (mCmdOutputGroup
->checkedButton() == mCmdLogToFile
)
888 if (mSavedCmdLogFile
!= mCmdLogFileEdit
->text())
894 /******************************************************************************
895 * Extract the data in the dialog specific to the alarm type and set up a
898 void EditCommandAlarmDlg::type_setEvent(KAEvent
& event
, const KDateTime
& dt
, const QString
& text
, int lateCancel
, bool trial
)
901 event
.set(dt
, text
, QColor(), QColor(), QFont(), KAEvent::COMMAND
, lateCancel
, getAlarmFlags());
902 if (mCmdOutputGroup
->checkedButton() == mCmdLogToFile
)
903 event
.setLogFile(mCmdLogFileEdit
->text());
906 /******************************************************************************
907 * Get the currently specified alarm flag bits.
909 int EditCommandAlarmDlg::getAlarmFlags() const
911 return EditAlarmDlg::getAlarmFlags()
912 | (mCmdEdit
->isScript() ? KAEvent::SCRIPT
: 0)
913 | (mCmdOutputGroup
->checkedButton() == mCmdExecInTerm
? KAEvent::EXEC_IN_XTERM
: 0);
916 /******************************************************************************
917 * Validate and convert command alarm data.
919 bool EditCommandAlarmDlg::type_validate(bool trial
)
922 if (mCmdOutputGroup
->checkedButton() == mCmdLogToFile
)
924 // Validate the log file name
925 QString file
= mCmdLogFileEdit
->text();
926 QFileInfo
info(file
);
927 QDir::setCurrent(QDir::homePath());
928 bool err
= file
.isEmpty() || info
.isDir();
933 err
= !info
.isWritable();
937 QFileInfo
dirinfo(info
.absolutePath()); // get absolute directory path
938 err
= (!dirinfo
.isDir() || !dirinfo
.isWritable());
944 mCmdLogFileEdit
->setFocus();
945 KMessageBox::sorry(this, i18nc("@info", "Log file must be the name or path of a local file, with write permission."));
948 // Convert the log file to an absolute path
949 mCmdLogFileEdit
->setText(info
.absoluteFilePath());
954 /******************************************************************************
955 * Tell the user the result of the Try action.
957 void EditCommandAlarmDlg::type_trySuccessMessage(ShellProcess
* proc
, const QString
& text
)
959 if (mCmdOutputGroup
->checkedButton() != mCmdExecInTerm
)
961 theApp()->commandMessage(proc
, this);
962 KMessageBox::information(this, i18nc("@info", "Command executed: <icode>%1</icode>", text
));
963 theApp()->commandMessage(proc
, 0);
967 /******************************************************************************
968 * Called when one of the command type radio buttons is clicked,
969 * to display the appropriate edit field.
971 void EditCommandAlarmDlg::slotCmdScriptToggled(bool on
)
979 /******************************************************************************
980 * Clean up the alarm text.
982 bool EditCommandAlarmDlg::checkText(QString
& result
, bool showErrorMessage
) const
984 result
= mCmdEdit
->text(const_cast<EditCommandAlarmDlg
*>(this), showErrorMessage
);
985 if (result
.isEmpty())
991 /*=============================================================================
992 = Class EditEmailAlarmDlg
993 = Dialog to edit email alarms.
994 =============================================================================*/
996 QString
EditEmailAlarmDlg::i18n_chk_CopyEmailToSelf() { return i18nc("@option:check", "Copy email to self"); }
999 /******************************************************************************
1002 * Template = true to edit/create an alarm template
1003 * = false to edit/create an alarm.
1004 * event != to initialise the dialog to show the specified event's data.
1006 EditEmailAlarmDlg::EditEmailAlarmDlg(bool Template
, QWidget
* parent
, GetResourceType getResource
)
1007 : EditAlarmDlg(Template
, KAEvent::EMAIL
, parent
, getResource
),
1008 mEmailRemoveButton(0)
1014 EditEmailAlarmDlg::EditEmailAlarmDlg(bool Template
, const KAEvent
* event
, bool newAlarm
, QWidget
* parent
,
1015 GetResourceType getResource
, bool readOnly
)
1016 : EditAlarmDlg(Template
, event
, newAlarm
, parent
, getResource
, readOnly
),
1017 mEmailRemoveButton(0)
1019 kDebug() << "Event.id()";
1023 /******************************************************************************
1024 * Return the window caption.
1026 QString
EditEmailAlarmDlg::type_caption() const
1028 return isTemplate() ? (isNewAlarm() ? i18nc("@title:window", "New Email Alarm Template") : i18nc("@title:window", "Edit Email Alarm Template"))
1029 : (isNewAlarm() ? i18nc("@title:window", "New Email Alarm") : i18nc("@title:window", "Edit Email Alarm"));
1032 /******************************************************************************
1033 * Set up the email alarm dialog controls.
1035 void EditEmailAlarmDlg::type_init(QWidget
* parent
, QVBoxLayout
* frameLayout
)
1037 setButtonWhatsThis(Try
, i18nc("@info:whatsthis", "Send the email to the specified addressees now"));
1039 QGridLayout
* grid
= new QGridLayout();
1041 grid
->setColumnStretch(1, 1);
1042 frameLayout
->addLayout(grid
);
1045 if (Preferences::emailFrom() == Preferences::MAIL_FROM_KMAIL
)
1047 // Email sender identity
1048 QLabel
* label
= new QLabel(i18nc("@label:listbox 'From' email address", "From:"), parent
);
1049 label
->setFixedSize(label
->sizeHint());
1050 grid
->addWidget(label
, 0, 0);
1052 mEmailFromList
= new EmailIdCombo(Identities::identityManager(), parent
);
1053 mEmailFromList
->setMinimumSize(mEmailFromList
->sizeHint());
1054 label
->setBuddy(mEmailFromList
);
1055 mEmailFromList
->setWhatsThis(i18nc("@info:whatsthis", "Your email identity, used to identify you as the sender when sending email alarms."));
1056 connect(mEmailFromList
, SIGNAL(identityChanged(uint
)), SLOT(contentsChanged()));
1057 grid
->addWidget(mEmailFromList
, 0, 1, 1, 2);
1061 QLabel
* label
= new QLabel(i18nc("@label:textbox Email addressee", "To:"), parent
);
1062 label
->setFixedSize(label
->sizeHint());
1063 grid
->addWidget(label
, 1, 0);
1065 mEmailToEdit
= new LineEdit(LineEdit::Emails
, parent
);
1066 mEmailToEdit
->setMinimumSize(mEmailToEdit
->sizeHint());
1067 mEmailToEdit
->setWhatsThis(i18nc("@info:whatsthis", "Enter the addresses of the email recipients. Separate multiple addresses by "
1068 "commas or semicolons."));
1069 connect(mEmailToEdit
, SIGNAL(textChanged(const QString
&)), SLOT(contentsChanged()));
1070 grid
->addWidget(mEmailToEdit
, 1, 1);
1072 mEmailAddressButton
= new QPushButton(parent
);
1073 mEmailAddressButton
->setIcon(SmallIcon("help-contents"));
1074 int size
= mEmailAddressButton
->sizeHint().height();
1075 mEmailAddressButton
->setFixedSize(size
, size
);
1076 connect(mEmailAddressButton
, SIGNAL(clicked()), SLOT(openAddressBook()));
1077 mEmailAddressButton
->setToolTip(i18nc("@info:tooltip", "Open address book"));
1078 mEmailAddressButton
->setWhatsThis(i18nc("@info:whatsthis", "Select email addresses from your address book."));
1079 grid
->addWidget(mEmailAddressButton
, 1, 2);
1082 label
= new QLabel(i18nc("@label:textbox Email subject", "Subject:"), parent
);
1083 label
->setFixedSize(label
->sizeHint());
1084 grid
->addWidget(label
, 2, 0);
1086 mEmailSubjectEdit
= new LineEdit(parent
);
1087 mEmailSubjectEdit
->setMinimumSize(mEmailSubjectEdit
->sizeHint());
1088 label
->setBuddy(mEmailSubjectEdit
);
1089 mEmailSubjectEdit
->setWhatsThis(i18nc("@info:whatsthis", "Enter the email subject."));
1090 connect(mEmailSubjectEdit
, SIGNAL(textChanged(const QString
&)), SLOT(contentsChanged()));
1091 grid
->addWidget(mEmailSubjectEdit
, 2, 1, 1, 2);
1094 mEmailMessageEdit
= new TextEdit(parent
);
1095 mEmailMessageEdit
->setWhatsThis(i18nc("@info:whatsthis", "Enter the email message."));
1096 connect(mEmailMessageEdit
, SIGNAL(textChanged()), SLOT(contentsChanged()));
1097 frameLayout
->addWidget(mEmailMessageEdit
);
1099 // Email attachments
1100 grid
= new QGridLayout();
1102 frameLayout
->addLayout(grid
);
1103 label
= new QLabel(i18nc("@label:listbox", "Attachments:"), parent
);
1104 label
->setFixedSize(label
->sizeHint());
1105 grid
->addWidget(label
, 0, 0);
1107 mEmailAttachList
= new KComboBox(parent
);
1108 mEmailAttachList
->setEditable(true);
1109 mEmailAttachList
->setMinimumSize(mEmailAttachList
->sizeHint());
1110 if (mEmailAttachList
->lineEdit())
1111 mEmailAttachList
->lineEdit()->setReadOnly(true);
1112 //Q3ListBox* list = mEmailAttachList->listBox();
1113 //QRect rect = list->geometry();
1114 //list->setGeometry(rect.left() - 50, rect.top(), rect.width(), rect.height());
1115 label
->setBuddy(mEmailAttachList
);
1116 mEmailAttachList
->setWhatsThis(i18nc("@info:whatsthis", "Files to send as attachments to the email."));
1117 grid
->addWidget(mEmailAttachList
, 0, 1);
1118 grid
->setColumnStretch(1, 1);
1120 mEmailAddAttachButton
= new QPushButton(i18nc("@action:button", "Add..."), parent
);
1121 connect(mEmailAddAttachButton
, SIGNAL(clicked()), SLOT(slotAddAttachment()));
1122 mEmailAddAttachButton
->setWhatsThis(i18nc("@info:whatsthis", "Add an attachment to the email."));
1123 grid
->addWidget(mEmailAddAttachButton
, 0, 2);
1125 mEmailRemoveButton
= new QPushButton(i18nc("@action:button", "Remove"), parent
);
1126 connect(mEmailRemoveButton
, SIGNAL(clicked()), SLOT(slotRemoveAttachment()));
1127 mEmailRemoveButton
->setWhatsThis(i18nc("@info:whatsthis", "Remove the highlighted attachment from the email."));
1128 grid
->addWidget(mEmailRemoveButton
, 1, 2);
1130 // BCC email to sender
1131 mEmailBcc
= new CheckBox(i18n_chk_CopyEmailToSelf(), parent
);
1132 mEmailBcc
->setFixedSize(mEmailBcc
->sizeHint());
1133 mEmailBcc
->setWhatsThis(i18nc("@info:whatsthis", "If checked, the email will be blind copied to you."));
1134 connect(mEmailBcc
, SIGNAL(toggled(bool)), SLOT(contentsChanged()));
1135 grid
->addWidget(mEmailBcc
, 1, 0, 1, 2, Qt::AlignLeft
);
1138 /******************************************************************************
1139 * Initialise the dialog controls from the specified event.
1141 void EditEmailAlarmDlg::type_initValues(const KAEvent
* event
)
1145 // Set the values to those for the specified event
1146 mEmailAttachList
->addItems(event
->emailAttachments());
1147 mEmailToEdit
->setText(event
->emailAddresses(", "));
1148 mEmailSubjectEdit
->setText(event
->emailSubject());
1149 mEmailBcc
->setChecked(event
->emailBcc());
1151 mEmailFromList
->setCurrentIdentity(event
->emailFromId());
1155 // Set the values to their defaults
1156 mEmailBcc
->setChecked(Preferences::defaultEmailBcc());
1161 /******************************************************************************
1162 * Enable/disable controls depending on whether any attachments are entered.
1164 void EditEmailAlarmDlg::attachmentEnable()
1166 bool enable
= mEmailAttachList
->count();
1167 mEmailAttachList
->setEnabled(enable
);
1168 if (mEmailRemoveButton
)
1169 mEmailRemoveButton
->setEnabled(enable
);
1172 /******************************************************************************
1173 * Set the dialog's action and the action's text.
1175 void EditEmailAlarmDlg::setAction(KAEvent::Action action
, const AlarmText
& alarmText
)
1178 Q_ASSERT(action
== KAEvent::EMAIL
);
1179 if (alarmText
.isEmail())
1181 mEmailToEdit
->setText(alarmText
.to());
1182 mEmailSubjectEdit
->setText(alarmText
.subject());
1183 mEmailMessageEdit
->setPlainText(alarmText
.body());
1186 mEmailMessageEdit
->setPlainText(alarmText
.displayText());
1189 /******************************************************************************
1190 * Initialise various values in the New Alarm dialogue.
1192 void EditEmailAlarmDlg::setEmailFields(uint fromID
, const EmailAddressList
& addresses
,
1193 const QString
& subject
, const QStringList
& attachments
)
1196 mEmailFromList
->setCurrentIdentity(fromID
);
1197 if (!addresses
.isEmpty())
1198 mEmailToEdit
->setText(addresses
.join(", "));
1199 if (!subject
.isEmpty())
1200 mEmailSubjectEdit
->setText(subject
);
1201 if (!attachments
.isEmpty())
1203 mEmailAttachList
->addItems(attachments
);
1207 void EditEmailAlarmDlg::setBcc(bool bcc
)
1209 mEmailBcc
->setChecked(bcc
);
1212 /******************************************************************************
1213 * Set the read-only status of all non-template controls.
1215 void EditEmailAlarmDlg::setReadOnly(bool readOnly
)
1217 mEmailToEdit
->setReadOnly(readOnly
);
1218 mEmailSubjectEdit
->setReadOnly(readOnly
);
1219 mEmailMessageEdit
->setReadOnly(readOnly
);
1220 mEmailBcc
->setReadOnly(readOnly
);
1222 mEmailFromList
->setReadOnly(readOnly
);
1225 mEmailAddressButton
->hide();
1226 mEmailAddAttachButton
->hide();
1227 mEmailRemoveButton
->hide();
1231 mEmailAddressButton
->show();
1232 mEmailAddAttachButton
->show();
1233 mEmailRemoveButton
->show();
1235 EditAlarmDlg::setReadOnly(readOnly
);
1238 /******************************************************************************
1239 * Save the state of all controls.
1241 void EditEmailAlarmDlg::saveState(const KAEvent
* event
)
1243 EditAlarmDlg::saveState(event
);
1245 mSavedEmailFrom
= mEmailFromList
->currentIdentityName();
1246 mSavedEmailTo
= mEmailToEdit
->text();
1247 mSavedEmailSubject
= mEmailSubjectEdit
->text();
1248 mSavedEmailAttach
.clear();
1249 for (int i
= 0, end
= mEmailAttachList
->count(); i
< end
; ++i
)
1250 mSavedEmailAttach
+= mEmailAttachList
->itemText(i
);
1251 mSavedEmailBcc
= mEmailBcc
->isChecked();
1254 /******************************************************************************
1255 * Check whether any of the controls has changed state since the dialog was
1257 * Reply = true if any controls have changed, or if it's a new event.
1258 * = false if no controls have changed.
1260 bool EditEmailAlarmDlg::type_stateChanged() const
1262 QStringList emailAttach
;
1263 for (int i
= 0, end
= mEmailAttachList
->count(); i
< end
; ++i
)
1264 emailAttach
+= mEmailAttachList
->itemText(i
);
1265 if ((mEmailFromList
&& mSavedEmailFrom
!= mEmailFromList
->currentIdentityName())
1266 || mSavedEmailTo
!= mEmailToEdit
->text()
1267 || mSavedEmailSubject
!= mEmailSubjectEdit
->text()
1268 || mSavedEmailAttach
!= emailAttach
1269 || mSavedEmailBcc
!= mEmailBcc
->isChecked())
1274 /******************************************************************************
1275 * Extract the data in the dialog specific to the alarm type and set up a
1278 void EditEmailAlarmDlg::type_setEvent(KAEvent
& event
, const KDateTime
& dt
, const QString
& text
, int lateCancel
, bool trial
)
1281 event
.set(dt
, text
, QColor(), QColor(), QFont(), KAEvent::EMAIL
, lateCancel
, getAlarmFlags());
1282 uint from
= mEmailFromList
? mEmailFromList
->currentIdentity() : 0;
1283 event
.setEmail(from
, mEmailAddresses
, mEmailSubjectEdit
->text(), mEmailAttachments
);
1286 /******************************************************************************
1287 * Get the currently specified alarm flag bits.
1289 int EditEmailAlarmDlg::getAlarmFlags() const
1291 return EditAlarmDlg::getAlarmFlags()
1292 | (mEmailBcc
->isChecked() ? KAEvent::EMAIL_BCC
: 0);
1295 /******************************************************************************
1296 * Convert the email addresses to a list, and validate them. Convert the email
1297 * attachments to a list.
1299 bool EditEmailAlarmDlg::type_validate(bool trial
)
1301 QString addrs
= mEmailToEdit
->text();
1302 if (addrs
.isEmpty())
1303 mEmailAddresses
.clear();
1306 QString bad
= KAMail::convertAddresses(addrs
, mEmailAddresses
);
1309 mEmailToEdit
->setFocus();
1310 KMessageBox::error(this, i18nc("@info", "Invalid email address: <email>%1</email>", bad
));
1314 if (mEmailAddresses
.isEmpty())
1316 mEmailToEdit
->setFocus();
1317 KMessageBox::error(this, i18nc("@info", "No email address specified"));
1321 mEmailAttachments
.clear();
1322 for (int i
= 0, end
= mEmailAttachList
->count(); i
< end
; ++i
)
1324 QString att
= mEmailAttachList
->itemText(i
);
1325 switch (KAMail::checkAttachment(att
))
1328 mEmailAttachments
.append(att
);
1333 mEmailAttachList
->setFocus();
1334 KMessageBox::error(this, i18nc("@info", "Invalid email attachment: <filename>%1</filename>", att
));
1338 if (trial
&& KMessageBox::warningContinueCancel(this, i18nc("@info", "Do you really want to send the email now to the specified recipient(s)?"),
1339 i18nc("@action:button", "Confirm Email"), KGuiItem(i18nc("@action:button", "Send"))) != KMessageBox::Continue
)
1344 /******************************************************************************
1345 * Tell the user the result of the Try action.
1347 void EditEmailAlarmDlg::type_trySuccessMessage(ShellProcess
*, const QString
&)
1350 QString to
= mEmailAddresses
.join("<nl/>");
1351 to
.replace('<', "<");
1352 to
.replace('>', ">");
1353 if (mEmailBcc
->isChecked())
1354 msg
= "<qt>" + i18nc("@info", "Email sent to:<nl/>%1<nl/>Bcc: <email>%2</email>",
1355 to
, Preferences::emailBccAddress()) + "</qt>";
1357 msg
= "<qt>" + i18nc("@info", "Email sent to:<nl/>%1", to
) + "</qt>";
1358 KMessageBox::information(this, msg
);
1361 /******************************************************************************
1362 * Get a selection from the Address Book.
1364 void EditEmailAlarmDlg::openAddressBook()
1366 // Use AutoQPointer to guard against crash on application exit while
1367 // the dialogue is still open. It prevents double deletion (both on
1368 // deletion of MainWindow, and on return from this function).
1369 AutoQPointer
<Akonadi::EmailAddressSelectionDialog
> dlg
= new Akonadi::EmailAddressSelectionDialog(this);
1370 if (dlg
->exec() != QDialog::Accepted
)
1373 Akonadi::EmailAddressSelection::List selections
= dlg
->selectedAddresses();
1374 if (selections
.isEmpty())
1376 Person
person(selections
.first().name(), selections
.first().email());
1377 QString addrs
= mEmailToEdit
->text().trimmed();
1378 if (!addrs
.isEmpty())
1380 addrs
+= person
.fullName();
1381 mEmailToEdit
->setText(addrs
);
1384 /******************************************************************************
1385 * Select a file to attach to the email.
1387 void EditEmailAlarmDlg::slotAddAttachment()
1389 QString url
= KAlarm::browseFile(i18nc("@title:window", "Choose File to Attach"), mAttachDefaultDir
, QString(),
1390 QString(), KFile::ExistingOnly
, this);
1393 mEmailAttachList
->addItem(url
);
1394 mEmailAttachList
->setCurrentIndex(mEmailAttachList
->count() - 1); // select the new item
1395 mEmailRemoveButton
->setEnabled(true);
1396 mEmailAttachList
->setEnabled(true);
1401 /******************************************************************************
1402 * Remove the currently selected attachment from the email.
1404 void EditEmailAlarmDlg::slotRemoveAttachment()
1406 int item
= mEmailAttachList
->currentIndex();
1407 mEmailAttachList
->removeItem(item
);
1408 int count
= mEmailAttachList
->count();
1410 mEmailAttachList
->setCurrentIndex(count
- 1);
1413 mEmailRemoveButton
->setEnabled(false);
1414 mEmailAttachList
->setEnabled(false);
1419 /******************************************************************************
1420 * Clean up the alarm text.
1422 bool EditEmailAlarmDlg::checkText(QString
& result
, bool showErrorMessage
) const
1424 Q_UNUSED(showErrorMessage
);
1425 result
= mEmailMessageEdit
->toPlainText();
1430 /*=============================================================================
1431 = Class EditAudioAlarmDlg
1432 = Dialog to edit audio alarms with no display window.
1433 =============================================================================*/
1435 /******************************************************************************
1438 * Template = true to edit/create an alarm template
1439 * = false to edit/create an alarm.
1440 * event != to initialise the dialog to show the specified event's data.
1442 EditAudioAlarmDlg::EditAudioAlarmDlg(bool Template
, QWidget
* parent
, GetResourceType getResource
)
1443 : EditAlarmDlg(Template
, KAEvent::AUDIO
, parent
, getResource
)
1449 EditAudioAlarmDlg::EditAudioAlarmDlg(bool Template
, const KAEvent
* event
, bool newAlarm
, QWidget
* parent
,
1450 GetResourceType getResource
, bool readOnly
)
1451 : EditAlarmDlg(Template
, event
, newAlarm
, parent
, getResource
, readOnly
)
1453 kDebug() << "Event.id()";
1457 /******************************************************************************
1458 * Return the window caption.
1460 QString
EditAudioAlarmDlg::type_caption() const
1462 return isTemplate() ? (isNewAlarm() ? i18nc("@title:window", "New Audio Alarm Template") : i18nc("@title:window", "Edit Audio Alarm Template"))
1463 : (isNewAlarm() ? i18nc("@title:window", "New Audio Alarm") : i18nc("@title:window", "Edit Audio Alarm"));
1466 /******************************************************************************
1467 * Set up the dialog controls common to display alarms.
1469 void EditAudioAlarmDlg::type_init(QWidget
* parent
, QVBoxLayout
* frameLayout
)
1471 // File name edit box
1472 mSoundConfig
= new SoundWidget(false, true, parent
);
1474 mSoundConfig
->setAllowEmptyFile();
1475 connect(mSoundConfig
, SIGNAL(changed()), SLOT(contentsChanged()));
1476 frameLayout
->addWidget(mSoundConfig
);
1478 // Top-adjust the controls
1479 mPadding
= new KHBox(parent
);
1480 mPadding
->setMargin(0);
1481 frameLayout
->addWidget(mPadding
);
1482 frameLayout
->setStretchFactor(mPadding
, 1);
1485 /******************************************************************************
1486 * Initialise the dialog controls from the specified event.
1488 void EditAudioAlarmDlg::type_initValues(const KAEvent
* event
)
1492 mSoundConfig
->set(event
->audioFile(), event
->soundVolume(), event
->fadeVolume(), event
->fadeSeconds(),
1493 (event
->flags() & KAEvent::REPEAT_SOUND
));
1497 // Set the values to their defaults
1498 mSoundConfig
->set(Preferences::defaultSoundFile(), Preferences::defaultSoundVolume());
1502 /******************************************************************************
1503 * Initialise various values in the New Alarm dialogue.
1505 void EditAudioAlarmDlg::setAudio(const QString
& file
, float volume
)
1507 mSoundConfig
->set(file
, volume
);
1510 /******************************************************************************
1511 * Set the dialog's action and the action's text.
1513 void EditAudioAlarmDlg::setAction(KAEvent::Action action
, const AlarmText
& alarmText
)
1516 Q_ASSERT(action
== KAEvent::AUDIO
);
1517 mSoundConfig
->set(alarmText
.displayText(), Preferences::defaultSoundVolume());
1520 /******************************************************************************
1521 * Set the read-only status of all non-template controls.
1523 void EditAudioAlarmDlg::setReadOnly(bool readOnly
)
1525 mSoundConfig
->setReadOnly(readOnly
);
1526 EditAlarmDlg::setReadOnly(readOnly
);
1529 /******************************************************************************
1530 * Save the state of all controls.
1532 void EditAudioAlarmDlg::saveState(const KAEvent
* event
)
1534 EditAlarmDlg::saveState(event
);
1535 mSavedFile
= mSoundConfig
->fileName();
1536 mSavedRepeat
= mSoundConfig
->getVolume(mSavedVolume
, mSavedFadeVolume
, mSavedFadeSeconds
);
1539 /******************************************************************************
1540 * Check whether any of the controls has changed state since the dialog was
1542 * Reply = true if any controls have changed, or if it's a new event.
1543 * = false if no controls have changed.
1545 bool EditAudioAlarmDlg::type_stateChanged() const
1547 if (mSavedFile
!= mSoundConfig
->fileName())
1549 if (!mSavedFile
.isEmpty() || isTemplate())
1551 float volume
, fadeVolume
;
1553 if (mSavedRepeat
!= mSoundConfig
->getVolume(volume
, fadeVolume
, fadeSecs
)
1554 || mSavedVolume
!= volume
1555 || mSavedFadeVolume
!= fadeVolume
1556 || mSavedFadeSeconds
!= fadeSecs
)
1562 /******************************************************************************
1563 * Extract the data in the dialog specific to the alarm type and set up a
1566 void EditAudioAlarmDlg::type_setEvent(KAEvent
& event
, const KDateTime
& dt
, const QString
& text
, int lateCancel
, bool trial
)
1570 event
.set(dt
, QString(), QColor(), QColor(), QFont(), KAEvent::AUDIO
, lateCancel
, getAlarmFlags());
1571 float volume
, fadeVolume
;
1573 mSoundConfig
->getVolume(volume
, fadeVolume
, fadeSecs
);
1575 mSoundConfig
->file(url
, false);
1576 event
.setAudioFile(url
.prettyUrl(), volume
, fadeVolume
, fadeSecs
, isTemplate());
1579 /******************************************************************************
1580 * Get the currently specified alarm flag bits.
1582 int EditAudioAlarmDlg::getAlarmFlags() const
1584 return EditAlarmDlg::getAlarmFlags()
1585 | (mSoundConfig
->getRepeat() ? KAEvent::REPEAT_SOUND
: 0);
1588 /******************************************************************************
1589 * Check whether the file name is valid.
1591 bool EditAudioAlarmDlg::checkText(QString
& result
, bool showErrorMessage
) const
1594 if (!mSoundConfig
->file(url
, showErrorMessage
))
1599 result
= url
.pathOrUrl();
1604 /*=============================================================================
1606 = A widget to allow entry of a command or a command script.
1607 =============================================================================*/
1608 CommandEdit::CommandEdit(QWidget
* parent
)
1611 QVBoxLayout
* vlayout
= new QVBoxLayout(this);
1612 vlayout
->setMargin(0);
1613 vlayout
->setSpacing(KDialog::spacingHint());
1614 mTypeScript
= new CheckBox(EditCommandAlarmDlg::i18n_chk_EnterScript(), this);
1615 mTypeScript
->setFixedSize(mTypeScript
->sizeHint());
1616 mTypeScript
->setWhatsThis(i18nc("@info:whatsthis", "Check to enter the contents of a script instead of a shell command line"));
1617 connect(mTypeScript
, SIGNAL(toggled(bool)), SLOT(slotCmdScriptToggled(bool)));
1618 connect(mTypeScript
, SIGNAL(toggled(bool)), SIGNAL(changed()));
1619 vlayout
->addWidget(mTypeScript
, 0, Qt::AlignLeft
);
1621 mCommandEdit
= new LineEdit(LineEdit::Url
, this);
1622 mCommandEdit
->setWhatsThis(i18nc("@info:whatsthis", "Enter a shell command to execute."));
1623 connect(mCommandEdit
, SIGNAL(textChanged(const QString
&)), SIGNAL(changed()));
1624 vlayout
->addWidget(mCommandEdit
);
1626 mScriptEdit
= new TextEdit(this);
1627 mScriptEdit
->setWhatsThis(i18nc("@info:whatsthis", "Enter the contents of a script to execute"));
1628 connect(mScriptEdit
, SIGNAL(textChanged()), SIGNAL(changed()));
1629 vlayout
->addWidget(mScriptEdit
);
1631 slotCmdScriptToggled(mTypeScript
->isChecked());
1634 /******************************************************************************
1635 * Initialise the widget controls from the specified event.
1637 void CommandEdit::setScript(bool script
)
1639 mTypeScript
->setChecked(script
);
1642 bool CommandEdit::isScript() const
1644 return mTypeScript
->isChecked();
1647 /******************************************************************************
1648 * Set the widget's text.
1650 void CommandEdit::setText(const AlarmText
& alarmText
)
1652 QString text
= alarmText
.displayText();
1653 bool script
= alarmText
.isScript();
1654 mTypeScript
->setChecked(script
);
1656 mScriptEdit
->setPlainText(text
);
1658 mCommandEdit
->setText(KAlarm::pathOrUrl(text
));
1661 /******************************************************************************
1662 * Return the widget's text.
1664 QString
CommandEdit::text() const
1667 if (mTypeScript
->isChecked())
1668 result
= mScriptEdit
->toPlainText();
1670 result
= mCommandEdit
->text();
1671 return result
.trimmed();
1674 /******************************************************************************
1675 * Return the alarm text.
1676 * If 'showErrorMessage' is true and the text is empty, an error message is
1679 QString
CommandEdit::text(EditAlarmDlg
* dlg
, bool showErrorMessage
) const
1681 QString result
= text();
1682 if (showErrorMessage
&& result
.isEmpty())
1683 KMessageBox::sorry(dlg
, i18nc("@info", "Please enter a command or script to execute"));
1687 /******************************************************************************
1688 * Set the read-only status of all controls.
1690 void CommandEdit::setReadOnly(bool readOnly
)
1692 mTypeScript
->setReadOnly(readOnly
);
1693 mCommandEdit
->setReadOnly(readOnly
);
1694 mScriptEdit
->setReadOnly(readOnly
);
1697 /******************************************************************************
1698 * Called when one of the command type radio buttons is clicked,
1699 * to display the appropriate edit field.
1701 void CommandEdit::slotCmdScriptToggled(bool on
)
1705 mCommandEdit
->hide();
1706 mScriptEdit
->show();
1707 mScriptEdit
->setFocus();
1711 mScriptEdit
->hide();
1712 mCommandEdit
->show();
1713 mCommandEdit
->setFocus();
1715 emit
scriptToggled(on
);
1718 /******************************************************************************
1719 * Returns the minimum size of the widget.
1721 QSize
CommandEdit::minimumSizeHint() const
1723 QSize
t(mTypeScript
->minimumSizeHint());
1724 QSize
s(mCommandEdit
->minimumSizeHint().expandedTo(mScriptEdit
->minimumSizeHint()));
1725 s
.setHeight(s
.height() + KDialog::spacingHint() + t
.height());
1726 if (s
.width() < t
.width())
1727 s
.setWidth(t
.width());
1733 /*=============================================================================
1735 = A text edit field with a minimum height of 3 text lines.
1736 =============================================================================*/
1737 TextEdit::TextEdit(QWidget
* parent
)
1740 QSize tsize
= sizeHint();
1741 tsize
.setHeight(fontMetrics().lineSpacing()*13/4 + 2*frameWidth());
1742 setMinimumSize(tsize
);
1745 void TextEdit::dragEnterEvent(QDragEnterEvent
* e
)
1748 if (KCalUtils::ICalDrag::canDecode(e
->mimeData()))
1750 if (KCal::ICalDrag::canDecode(e
->mimeData()))
1752 e
->ignore(); // don't accept "text/calendar" objects
1753 KTextEdit::dragEnterEvent(e
);