00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "kalarm.h"
00022
00023 #include <qlayout.h>
00024 #include <qgroupbox.h>
00025 #include <qhbox.h>
00026 #include <qlabel.h>
00027 #include <qlineedit.h>
00028 #include <qwhatsthis.h>
00029
00030 #include <klocale.h>
00031 #include <kglobal.h>
00032 #include <kconfig.h>
00033 #include <kmessagebox.h>
00034 #include <kaccel.h>
00035 #include <kabc/addressbook.h>
00036 #include <kabc/stdaddressbook.h>
00037 #include <kdebug.h>
00038
00039 #include "alarmcalendar.h"
00040 #include "checkbox.h"
00041 #include "colourcombo.h"
00042 #include "editdlg.h"
00043 #include "fontcolourbutton.h"
00044 #include "kalarmapp.h"
00045 #include "latecancel.h"
00046 #include "preferences.h"
00047 #include "reminder.h"
00048 #include "repetition.h"
00049 #include "shellprocess.h"
00050 #include "soundpicker.h"
00051 #include "specialactions.h"
00052 #include "birthdaydlg.moc"
00053
00054 using namespace KCal;
00055
00056
00057 class AddresseeItem : public QListViewItem
00058 {
00059 public:
00060 enum columns { NAME = 0, BIRTHDAY = 1 };
00061 AddresseeItem(QListView* parent, const QString& name, const QDate& birthday);
00062 QDate birthday() const { return mBirthday; }
00063 virtual QString key(int column, bool ascending) const;
00064 private:
00065 QDate mBirthday;
00066 QString mBirthdayOrder;
00067 };
00068
00069
00070 const KABC::AddressBook* BirthdayDlg::mAddressBook = 0;
00071
00072
00073 BirthdayDlg::BirthdayDlg(QWidget* parent)
00074 : KDialogBase(KDialogBase::Plain, i18n("Import Birthdays From KAddressBook"), Ok|Cancel, Ok, parent, "BirthdayDlg"),
00075 mSpecialActionsButton(0)
00076 {
00077 QWidget* topWidget = plainPage();
00078 QBoxLayout* topLayout = new QVBoxLayout(topWidget);
00079 topLayout->setSpacing(spacingHint());
00080
00081
00082
00083 KConfig* config = kapp->config();
00084 config->setGroup(QString::fromLatin1("General"));
00085 mPrefixText = config->readEntry(QString::fromLatin1("BirthdayPrefix"), i18n("Birthday: "));
00086 mSuffixText = config->readEntry(QString::fromLatin1("BirthdaySuffix"));
00087
00088 QGroupBox* textGroup = new QGroupBox(2, Qt::Horizontal, i18n("Alarm Text"), topWidget);
00089 topLayout->addWidget(textGroup);
00090 QLabel* label = new QLabel(i18n("Pre&fix:"), textGroup);
00091 mPrefix = new BLineEdit(mPrefixText, textGroup);
00092 mPrefix->setMinimumSize(mPrefix->sizeHint());
00093 label->setBuddy(mPrefix);
00094 connect(mPrefix, SIGNAL(focusLost()), SLOT(slotTextLostFocus()));
00095 QWhatsThis::add(mPrefix,
00096 i18n("Enter text to appear before the person's name in the alarm message, "
00097 "including any necessary trailing spaces."));
00098
00099 label = new QLabel(i18n("S&uffix:"), textGroup);
00100 mSuffix = new BLineEdit(mSuffixText, textGroup);
00101 mSuffix->setMinimumSize(mSuffix->sizeHint());
00102 label->setBuddy(mSuffix);
00103 connect(mSuffix, SIGNAL(focusLost()), SLOT(slotTextLostFocus()));
00104 QWhatsThis::add(mSuffix,
00105 i18n("Enter text to appear after the person's name in the alarm message, "
00106 "including any necessary leading spaces."));
00107
00108 QGroupBox* group = new QGroupBox(1, Qt::Horizontal, i18n("Select Birthdays"), topWidget);
00109 topLayout->addWidget(group);
00110 mAddresseeList = new BListView(group);
00111 mAddresseeList->setMultiSelection(true);
00112 mAddresseeList->setSelectionMode(QListView::Extended);
00113 mAddresseeList->setAllColumnsShowFocus(true);
00114 mAddresseeList->setFullWidth(true);
00115 mAddresseeList->addColumn(i18n("Name"));
00116 mAddresseeList->addColumn(i18n("Birthday"));
00117 connect(mAddresseeList, SIGNAL(selectionChanged()), SLOT(slotSelectionChanged()));
00118 QWhatsThis::add(mAddresseeList,
00119 i18n("Select birthdays to set alarms for.\n"
00120 "This list shows all birthdays in KAddressBook except those for which alarms already exist.\n\n"
00121 "You can select multiple birthdays at one time by dragging the mouse over the list, "
00122 "or by clicking the mouse while pressing Ctrl or Shift."));
00123
00124 group = new QGroupBox(i18n("Alarm Configuration"), topWidget);
00125 topLayout->addWidget(group);
00126 QBoxLayout* groupLayout = new QVBoxLayout(group, marginHint(), spacingHint());
00127 groupLayout->addSpacing(fontMetrics().lineSpacing()/2);
00128
00129
00130 mFontColourButton = new FontColourButton(group);
00131 mFontColourButton->setMaximumHeight(mFontColourButton->sizeHint().height() * 3/2);
00132 groupLayout->addWidget(mFontColourButton);
00133
00134
00135 mSoundPicker = new SoundPicker(group);
00136 mSoundPicker->setFixedSize(mSoundPicker->sizeHint());
00137 groupLayout->addWidget(mSoundPicker, 0, Qt::AlignAuto);
00138
00139
00140 mReminder = new Reminder(i18n("&Reminder"),
00141 i18n("Check to display a reminder in advance of the birthday."),
00142 i18n("Enter the number of days before each birthday to display a reminder. "
00143 "This is in addition to the alarm which is displayed on the birthday."),
00144 false, false, group);
00145 mReminder->setFixedSize(mReminder->sizeHint());
00146 mReminder->setMaximum(0, 364);
00147 mReminder->setMinutes(0, true);
00148 groupLayout->addWidget(mReminder, 0, Qt::AlignAuto);
00149
00150
00151 QHBoxLayout* layout = new QHBoxLayout(groupLayout, 2*spacingHint());
00152 mConfirmAck = EditAlarmDlg::createConfirmAckCheckbox(group);
00153 layout->addWidget(mConfirmAck);
00154 layout->addSpacing(2*spacingHint());
00155 layout->addStretch();
00156
00157 if (ShellProcess::authorised())
00158 {
00159
00160 mSpecialActionsButton = new SpecialActionsButton(i18n("Special Actions..."), group);
00161 layout->addWidget(mSpecialActionsButton);
00162 }
00163
00164
00165 layout = new QHBoxLayout(groupLayout, 2*spacingHint());
00166 mLateCancel = new LateCancelSelector(false, group);
00167 layout->addWidget(mLateCancel);
00168 layout->addStretch();
00169
00170
00171 mSubRepetition = new RepetitionButton(i18n("Sub-Repetition"), false, group);
00172 mSubRepetition->set(0, 0, true, 364*24*60);
00173 QWhatsThis::add(mSubRepetition, i18n("Set up an additional alarm repetition"));
00174 layout->addWidget(mSubRepetition);
00175
00176
00177 mFontColourButton->setDefaultFont();
00178 mFontColourButton->setBgColour(Preferences::defaultBgColour());
00179 mFontColourButton->setFgColour(Preferences::defaultFgColour());
00180 mLateCancel->setMinutes(Preferences::defaultLateCancel(), true, TimePeriod::DAYS);
00181 mConfirmAck->setChecked(Preferences::defaultConfirmAck());
00182 mSoundPicker->set(Preferences::defaultSoundType(), Preferences::defaultSoundFile(),
00183 Preferences::defaultSoundVolume(), -1, 0, Preferences::defaultSoundRepeat());
00184 if (mSpecialActionsButton)
00185 mSpecialActionsButton->setActions(Preferences::defaultPreAction(), Preferences::defaultPostAction());
00186
00187
00188 loadAddressBook();
00189 }
00190
00191
00192
00193
00194 void BirthdayDlg::loadAddressBook()
00195 {
00196 if (!mAddressBook)
00197 {
00198 #if KDE_IS_VERSION(3,1,90)
00199 mAddressBook = KABC::StdAddressBook::self(true);
00200 if (mAddressBook)
00201 connect(mAddressBook, SIGNAL(addressBookChanged(AddressBook*)), SLOT(updateSelectionList()));
00202 #else
00203 mAddressBook = KABC::StdAddressBook::self();
00204 if (mAddressBook)
00205 updateSelectionList();
00206 #endif
00207 }
00208 else
00209 updateSelectionList();
00210 if (!mAddressBook)
00211 KMessageBox::error(this, i18n("Error reading address book"));
00212 }
00213
00214
00215
00216
00217
00218 void BirthdayDlg::updateSelectionList()
00219 {
00220
00221 QStringList messageList;
00222 KAEvent event;
00223 Event::List events = AlarmCalendar::activeCalendar()->events();
00224 for (Event::List::ConstIterator it = events.begin(); it != events.end(); ++it)
00225 {
00226 Event* kcalEvent = *it;
00227 event.set(*kcalEvent);
00228 if (event.action() == KAEvent::MESSAGE
00229 && event.recurType() == KARecurrence::ANNUAL_DATE
00230 && (mPrefixText.isEmpty() || event.message().startsWith(mPrefixText)))
00231 messageList.append(event.message());
00232 }
00233
00234
00235 for (KABC::AddressBook::ConstIterator abit = mAddressBook->begin(); abit != mAddressBook->end(); ++abit)
00236 {
00237 const KABC::Addressee& addressee = *abit;
00238 if (addressee.birthday().isValid())
00239 {
00240
00241 QDate birthday = addressee.birthday().date();
00242 QString name = addressee.nickName();
00243 if (name.isEmpty())
00244 name = addressee.realName();
00245
00246 QString text = mPrefixText + name + mSuffixText;
00247 bool alarmExists = (messageList.find(text) != messageList.end());
00248
00249 bool inSelectionList = false;
00250 AddresseeItem* item = 0;
00251 for (QListViewItem* qitem = mAddresseeList->firstChild(); qitem; qitem = qitem->nextSibling())
00252 {
00253 item = dynamic_cast<AddresseeItem*>(qitem);
00254 if (item && item->text(AddresseeItem::NAME) == name && item->birthday() == birthday)
00255 {
00256 inSelectionList = true;
00257 break;
00258 }
00259 }
00260
00261 if (alarmExists && inSelectionList)
00262 delete item;
00263 else if (!alarmExists && !inSelectionList)
00264 new AddresseeItem(mAddresseeList, name, birthday);
00265 }
00266 }
00267
00268
00269
00270 bool selection = false;
00271 for (QListViewItem* item = mAddresseeList->firstChild(); item; item = item->nextSibling())
00272 if (mAddresseeList->isSelected(item))
00273 {
00274 selection = true;
00275 break;
00276 }
00277 enableButtonOK(selection);
00278 }
00279
00280
00281
00282
00283 QValueList<KAEvent> BirthdayDlg::events() const
00284 {
00285 QValueList<KAEvent> list;
00286 QDate today = QDate::currentDate();
00287 QDateTime todayNoon(today, QTime(12, 0, 0));
00288 int thisYear = today.year();
00289 int reminder = mReminder->minutes();
00290
00291 for (QListViewItem* item = mAddresseeList->firstChild(); item; item = item->nextSibling())
00292 {
00293 if (mAddresseeList->isSelected(item))
00294 {
00295 AddresseeItem* aItem = dynamic_cast<AddresseeItem*>(item);
00296 if (aItem)
00297 {
00298 QDate date = aItem->birthday();
00299 date.setYMD(thisYear, date.month(), date.day());
00300 if (date <= today)
00301 date.setYMD(thisYear + 1, date.month(), date.day());
00302 KAEvent event(date,
00303 mPrefix->text() + aItem->text(AddresseeItem::NAME) + mSuffix->text(),
00304 mFontColourButton->bgColour(), mFontColourButton->fgColour(),
00305 mFontColourButton->font(), KAEvent::MESSAGE, mLateCancel->minutes(),
00306 mFlags);
00307 float fadeVolume;
00308 int fadeSecs;
00309 float volume = mSoundPicker->volume(fadeVolume, fadeSecs);
00310 event.setAudioFile(mSoundPicker->file(), volume, fadeVolume, fadeSecs);
00311 QValueList<int> months;
00312 months.append(date.month());
00313 event.setRecurAnnualByDate(1, months, 0, Preferences::defaultFeb29Type(), -1, QDate());
00314 event.setRepetition(mSubRepetition->interval(), mSubRepetition->count());
00315 event.setNextOccurrence(todayNoon);
00316 if (reminder)
00317 event.setReminder(reminder, false);
00318 if (mSpecialActionsButton)
00319 event.setActions(mSpecialActionsButton->preAction(),
00320 mSpecialActionsButton->postAction());
00321 list.append(event);
00322 }
00323 }
00324 }
00325 return list;
00326 }
00327
00328
00329
00330
00331 void BirthdayDlg::slotOk()
00332 {
00333
00334 KConfig* config = kapp->config();
00335 config->setGroup(QString::fromLatin1("General"));
00336 config->writeEntry(QString::fromLatin1("BirthdayPrefix"), mPrefix->text());
00337 config->writeEntry(QString::fromLatin1("BirthdaySuffix"), mSuffix->text());
00338 config->sync();
00339
00340 mFlags = (mSoundPicker->sound() == SoundPicker::BEEP ? KAEvent::BEEP : 0)
00341 | (mSoundPicker->repeat() ? KAEvent::REPEAT_SOUND : 0)
00342 | (mConfirmAck->isChecked() ? KAEvent::CONFIRM_ACK : 0)
00343 | (mFontColourButton->defaultFont() ? KAEvent::DEFAULT_FONT : 0)
00344 | KAEvent::ANY_TIME;
00345 KDialogBase::slotOk();
00346 }
00347
00348
00349
00350
00351
00352 void BirthdayDlg::slotSelectionChanged()
00353 {
00354 for (QListViewItem* item = mAddresseeList->firstChild(); item; item = item->nextSibling())
00355 if (mAddresseeList->isSelected(item))
00356 {
00357 enableButtonOK(true);
00358 return;
00359 }
00360 enableButtonOK(false);
00361
00362 }
00363
00364
00365
00366
00367
00368
00369 void BirthdayDlg::slotTextLostFocus()
00370 {
00371 QString prefix = mPrefix->text();
00372 QString suffix = mSuffix->text();
00373 if (prefix != mPrefixText || suffix != mSuffixText)
00374 {
00375
00376 mPrefixText = prefix;
00377 mSuffixText = suffix;
00378 loadAddressBook();
00379 }
00380 }
00381
00382
00383
00384
00385
00386
00387 AddresseeItem::AddresseeItem(QListView* parent, const QString& name, const QDate& birthday)
00388 : QListViewItem(parent),
00389 mBirthday(birthday)
00390 {
00391 setText(NAME, name);
00392 setText(BIRTHDAY, KGlobal::locale()->formatDate(mBirthday, true));
00393 mBirthdayOrder.sprintf("%04d%03d", mBirthday.year(), mBirthday.dayOfYear());
00394 }
00395
00396 QString AddresseeItem::key(int column, bool) const
00397 {
00398 if (column == BIRTHDAY)
00399 return mBirthdayOrder;
00400 return text(column).lower();
00401 }
00402
00403
00404
00405
00406
00407
00408 BListView::BListView(QWidget* parent, const char* name)
00409 : KListView(parent, name)
00410 {
00411 KAccel* accel = new KAccel(this);
00412 accel->insert(KStdAccel::SelectAll, this, SLOT(slotSelectAll()));
00413 accel->insert(KStdAccel::Deselect, this, SLOT(slotDeselect()));
00414 accel->readSettings();
00415 }