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 QBoxLayout* layout = new QHBoxLayout(groupLayout, 2*spacingHint());
00133 QHBox* box;
00134 mBgColourChoose = EditAlarmDlg::createBgColourChooser(&box, group);
00135 connect(mBgColourChoose, SIGNAL(highlighted(const QColor&)), SLOT(slotBgColourSelected(const QColor&)));
00136 layout->addWidget(box);
00137 layout->addStretch();
00138
00139
00140 mFontColourButton = new FontColourButton(group);
00141 mFontColourButton->setFixedSize(mFontColourButton->sizeHint());
00142 connect(mFontColourButton, SIGNAL(selected()), SLOT(slotFontColourSelected()));
00143 layout->addWidget(mFontColourButton);
00144
00145
00146 mSoundPicker = new SoundPicker(group);
00147 mSoundPicker->setFixedSize(mSoundPicker->sizeHint());
00148 groupLayout->addWidget(mSoundPicker, 0, Qt::AlignAuto);
00149
00150
00151 mReminder = new Reminder(i18n("&Reminder"),
00152 i18n("Check to display a reminder in advance of the birthday."),
00153 i18n("Enter the number of days before each birthday to display a reminder. "
00154 "This is in addition to the alarm which is displayed on the birthday."),
00155 false, false, group);
00156 mReminder->setFixedSize(mReminder->sizeHint());
00157 mReminder->setMaximum(0, 364);
00158 mReminder->setMinutes(0, true);
00159 groupLayout->addWidget(mReminder, 0, Qt::AlignAuto);
00160
00161
00162 layout = new QHBoxLayout(groupLayout, 2*spacingHint());
00163 mConfirmAck = EditAlarmDlg::createConfirmAckCheckbox(group);
00164 mConfirmAck->setFixedSize(mConfirmAck->sizeHint());
00165 layout->addWidget(mConfirmAck);
00166 layout->addSpacing(2*spacingHint());
00167 layout->addStretch();
00168
00169 if (ShellProcess::authorised())
00170 {
00171
00172 mSpecialActionsButton = new SpecialActionsButton(i18n("Special Actions..."), group);
00173 mSpecialActionsButton->setFixedSize(mSpecialActionsButton->sizeHint());
00174 layout->addWidget(mSpecialActionsButton);
00175 }
00176
00177
00178 layout = new QHBoxLayout(groupLayout, 2*spacingHint());
00179 mLateCancel = new LateCancelSelector(false, group);
00180 mLateCancel->setFixedSize(mLateCancel->sizeHint());
00181 layout->addWidget(mLateCancel);
00182 layout->addStretch();
00183
00184
00185 mSimpleRepetition = new RepetitionButton(i18n("Simple Repetition"), false, group);
00186 mSimpleRepetition->setFixedSize(mSimpleRepetition->sizeHint());
00187 mSimpleRepetition->set(0, 0, true, 364*24*60);
00188 QWhatsThis::add(mSimpleRepetition, i18n("Set up an additional alarm repetition"));
00189 layout->addWidget(mSimpleRepetition);
00190
00191
00192 mFontColourButton->setDefaultFont();
00193 mFontColourButton->setBgColour(Preferences::defaultBgColour());
00194 mBgColourChoose->setColour(Preferences::defaultBgColour());
00195 mLateCancel->setMinutes(Preferences::defaultLateCancel(), true, TimePeriod::DAYS);
00196 mConfirmAck->setChecked(Preferences::defaultConfirmAck());
00197 mSoundPicker->set(Preferences::defaultSoundType(), Preferences::defaultSoundFile(),
00198 Preferences::defaultSoundVolume(), -1, 0, Preferences::defaultSoundRepeat());
00199 if (mSpecialActionsButton)
00200 mSpecialActionsButton->setActions(Preferences::defaultPreAction(), Preferences::defaultPostAction());
00201
00202
00203 loadAddressBook();
00204 }
00205
00206
00207
00208
00209 void BirthdayDlg::loadAddressBook()
00210 {
00211 if (!mAddressBook)
00212 {
00213 #if KDE_IS_VERSION(3,1,90)
00214 mAddressBook = KABC::StdAddressBook::self(true);
00215 if (mAddressBook)
00216 connect(mAddressBook, SIGNAL(addressBookChanged(AddressBook*)), SLOT(updateSelectionList()));
00217 #else
00218 mAddressBook = KABC::StdAddressBook::self();
00219 if (mAddressBook)
00220 updateSelectionList();
00221 #endif
00222 }
00223 else
00224 updateSelectionList();
00225 if (!mAddressBook)
00226 KMessageBox::error(this, i18n("Error reading address book"));
00227 }
00228
00229
00230
00231
00232
00233 void BirthdayDlg::updateSelectionList()
00234 {
00235
00236 QStringList messageList;
00237 KAEvent event;
00238 Event::List events = AlarmCalendar::activeCalendar()->events();
00239 for (Event::List::ConstIterator it = events.begin(); it != events.end(); ++it)
00240 {
00241 Event* kcalEvent = *it;
00242 event.set(*kcalEvent);
00243 if (event.action() == KAEvent::MESSAGE
00244 && event.recurType() == KARecurrence::ANNUAL_DATE
00245 && (mPrefixText.isEmpty() || event.message().startsWith(mPrefixText)))
00246 messageList.append(event.message());
00247 }
00248
00249
00250 for (KABC::AddressBook::ConstIterator abit = mAddressBook->begin(); abit != mAddressBook->end(); ++abit)
00251 {
00252 const KABC::Addressee& addressee = *abit;
00253 if (addressee.birthday().isValid())
00254 {
00255
00256 QDate birthday = addressee.birthday().date();
00257 QString name = addressee.nickName();
00258 if (name.isEmpty())
00259 name = addressee.realName();
00260
00261 QString text = mPrefixText + name + mSuffixText;
00262 bool alarmExists = (messageList.find(text) != messageList.end());
00263
00264 bool inSelectionList = false;
00265 AddresseeItem* item = 0;
00266 for (QListViewItem* qitem = mAddresseeList->firstChild(); qitem; qitem = qitem->nextSibling())
00267 {
00268 item = dynamic_cast<AddresseeItem*>(qitem);
00269 if (item && item->text(AddresseeItem::NAME) == name && item->birthday() == birthday)
00270 {
00271 inSelectionList = true;
00272 break;
00273 }
00274 }
00275
00276 if (alarmExists && inSelectionList)
00277 delete item;
00278 else if (!alarmExists && !inSelectionList)
00279 new AddresseeItem(mAddresseeList, name, birthday);
00280 }
00281 }
00282
00283
00284
00285 bool selection = false;
00286 for (QListViewItem* item = mAddresseeList->firstChild(); item; item = item->nextSibling())
00287 if (mAddresseeList->isSelected(item))
00288 {
00289 selection = true;
00290 break;
00291 }
00292 enableButtonOK(selection);
00293 }
00294
00295
00296
00297
00298 QValueList<KAEvent> BirthdayDlg::events() const
00299 {
00300 QValueList<KAEvent> list;
00301 QDate today = QDate::currentDate();
00302 QDateTime todayNoon(today, QTime(12, 0, 0));
00303 int thisYear = today.year();
00304 int reminder = mReminder->minutes();
00305
00306 for (QListViewItem* item = mAddresseeList->firstChild(); item; item = item->nextSibling())
00307 {
00308 if (mAddresseeList->isSelected(item))
00309 {
00310 AddresseeItem* aItem = dynamic_cast<AddresseeItem*>(item);
00311 if (aItem)
00312 {
00313 QDate date = aItem->birthday();
00314 date.setYMD(thisYear, date.month(), date.day());
00315 if (date <= today)
00316 date.setYMD(thisYear + 1, date.month(), date.day());
00317 KAEvent event(date,
00318 mPrefix->text() + aItem->text(AddresseeItem::NAME) + mSuffix->text(),
00319 mBgColourChoose->color(), mFontColourButton->fgColour(),
00320 mFontColourButton->font(), KAEvent::MESSAGE, mLateCancel->minutes(),
00321 mFlags);
00322 float fadeVolume;
00323 int fadeSecs;
00324 float volume = mSoundPicker->volume(fadeVolume, fadeSecs);
00325 event.setAudioFile(mSoundPicker->file(), volume, fadeVolume, fadeSecs);
00326 QValueList<int> months;
00327 months.append(date.month());
00328 event.setRecurAnnualByDate(1, months, 0, Preferences::defaultFeb29Type(), -1, QDate());
00329 event.setNextOccurrence(todayNoon, true);
00330 event.setRepetition(mSimpleRepetition->interval(), mSimpleRepetition->count());
00331 if (reminder)
00332 event.setReminder(reminder, false);
00333 if (mSpecialActionsButton)
00334 event.setActions(mSpecialActionsButton->preAction(),
00335 mSpecialActionsButton->postAction());
00336 list.append(event);
00337 }
00338 }
00339 }
00340 return list;
00341 }
00342
00343
00344
00345
00346 void BirthdayDlg::slotOk()
00347 {
00348
00349 KConfig* config = kapp->config();
00350 config->setGroup(QString::fromLatin1("General"));
00351 config->writeEntry(QString::fromLatin1("BirthdayPrefix"), mPrefix->text());
00352 config->writeEntry(QString::fromLatin1("BirthdaySuffix"), mSuffix->text());
00353 config->sync();
00354
00355 mFlags = (mSoundPicker->sound() == SoundPicker::BEEP ? KAEvent::BEEP : 0)
00356 | (mSoundPicker->repeat() ? KAEvent::REPEAT_SOUND : 0)
00357 | (mConfirmAck->isChecked() ? KAEvent::CONFIRM_ACK : 0)
00358 | (mFontColourButton->defaultFont() ? KAEvent::DEFAULT_FONT : 0)
00359 | KAEvent::ANY_TIME;
00360 KDialogBase::slotOk();
00361 }
00362
00363
00364
00365
00366
00367 void BirthdayDlg::slotSelectionChanged()
00368 {
00369 for (QListViewItem* item = mAddresseeList->firstChild(); item; item = item->nextSibling())
00370 if (mAddresseeList->isSelected(item))
00371 {
00372 enableButtonOK(true);
00373 return;
00374 }
00375 enableButtonOK(false);
00376
00377 }
00378
00379
00380
00381
00382
00383
00384 void BirthdayDlg::slotTextLostFocus()
00385 {
00386 QString prefix = mPrefix->text();
00387 QString suffix = mSuffix->text();
00388 if (prefix != mPrefixText || suffix != mSuffixText)
00389 {
00390
00391 mPrefixText = prefix;
00392 mSuffixText = suffix;
00393 loadAddressBook();
00394 }
00395 }
00396
00397
00398
00399
00400
00401 void BirthdayDlg::slotBgColourSelected(const QColor& colour)
00402 {
00403 mFontColourButton->setBgColour(colour);
00404 }
00405
00406
00407
00408
00409
00410 void BirthdayDlg::slotFontColourSelected()
00411 {
00412 mBgColourChoose->setColour(mFontColourButton->bgColour());
00413 }
00414
00415
00416
00417
00418
00419
00420 AddresseeItem::AddresseeItem(QListView* parent, const QString& name, const QDate& birthday)
00421 : QListViewItem(parent),
00422 mBirthday(birthday)
00423 {
00424 setText(NAME, name);
00425 setText(BIRTHDAY, KGlobal::locale()->formatDate(mBirthday, true));
00426 mBirthdayOrder.sprintf("%04d%03d", mBirthday.year(), mBirthday.dayOfYear());
00427 }
00428
00429 QString AddresseeItem::key(int column, bool) const
00430 {
00431 if (column == BIRTHDAY)
00432 return mBirthdayOrder;
00433 return text(column).lower();
00434 }
00435
00436
00437
00438
00439
00440
00441 BListView::BListView(QWidget* parent, const char* name)
00442 : KListView(parent, name)
00443 {
00444 KAccel* accel = new KAccel(this);
00445 accel->insert(KStdAccel::SelectAll, this, SLOT(slotSelectAll()));
00446 accel->insert(KStdAccel::Deselect, this, SLOT(slotDeselect()));
00447 accel->readSettings();
00448 }