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