libkcal

alarm.cpp
1 /*
2  This file is part of libkcal.
3 
4  Copyright (c) 1998 Preston Brown <pbrown@kde.org>
5  Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
6 
7  This library is free software; you can redistribute it and/or
8  modify it under the terms of the GNU Library General Public
9  License as published by the Free Software Foundation; either
10  version 2 of the License, or (at your option) any later version.
11 
12  This library is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  Library General Public License for more details.
16 
17  You should have received a copy of the GNU Library General Public License
18  along with this library; see the file COPYING.LIB. If not, write to
19  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  Boston, MA 02110-1301, USA.
21 */
22 
23 #include <kdebug.h>
24 
25 #include "incidence.h"
26 #include "todo.h"
27 
28 #include "alarm.h"
29 
30 using namespace KCal;
31 
33  : mParent(parent),
34  mType(Invalid),
35  mDescription(""), // to make operator==() not fail
36  mFile(""), // to make operator==() not fail
37  mMailSubject(""), // to make operator==() not fail
38  mAlarmSnoozeTime(5),
39  mAlarmRepeatCount(0),
40  mEndOffset(false),
41  mHasTime(false),
42  mAlarmEnabled(false)
43 {
44 }
45 
47 {
48 }
49 
51 {
52  return new Alarm( *this );
53 }
54 
56 {
57  mParent = a.mParent;
58  mType = a.mType;
59  mDescription = a.mDescription;
60  mFile = a.mFile;
61  mMailAttachFiles = a.mMailAttachFiles;
62  mMailAddresses = a.mMailAddresses;
63  mMailSubject = a.mMailSubject;
64  mAlarmSnoozeTime = a.mAlarmSnoozeTime;
65  mAlarmRepeatCount = a.mAlarmRepeatCount;
66  mAlarmTime = a.mAlarmTime;
67  mOffset = a.mOffset;
68  mEndOffset = a.mEndOffset;
69  mHasTime = a.mHasTime;
70  mAlarmEnabled = a.mAlarmEnabled;
71  return *this;
72 }
73 
74 bool Alarm::operator==( const Alarm& rhs ) const
75 {
76  if ( mType != rhs.mType ||
77  mAlarmSnoozeTime != rhs.mAlarmSnoozeTime ||
78  mAlarmRepeatCount != rhs.mAlarmRepeatCount ||
79  mAlarmEnabled != rhs.mAlarmEnabled ||
80  mHasTime != rhs.mHasTime)
81  return false;
82 
83  if (mHasTime) {
84  if (mAlarmTime != rhs.mAlarmTime)
85  return false;
86  } else {
87  if (mOffset != rhs.mOffset ||
88  mEndOffset != rhs.mEndOffset)
89  return false;
90  }
91 
92  switch (mType) {
93  case Display:
94  return mDescription == rhs.mDescription;
95 
96  case Email:
97  return mDescription == rhs.mDescription &&
98  mMailAttachFiles == rhs.mMailAttachFiles &&
99  mMailAddresses == rhs.mMailAddresses &&
100  mMailSubject == rhs.mMailSubject;
101 
102  case Procedure:
103  return mFile == rhs.mFile &&
104  mDescription == rhs.mDescription;
105 
106  case Audio:
107  return mFile == rhs.mFile;
108 
109  case Invalid:
110  break;
111  }
112  return false;
113 }
114 
115 void Alarm::setType(Alarm::Type type)
116 {
117  if (type == mType)
118  return;
119 
120  switch (type) {
121  case Display:
122  mDescription = "";
123  break;
124  case Procedure:
125  mFile = mDescription = "";
126  break;
127  case Audio:
128  mFile = "";
129  break;
130  case Email:
131  mMailSubject = mDescription = "";
132  mMailAddresses.clear();
133  mMailAttachFiles.clear();
134  break;
135  case Invalid:
136  break;
137  default:
138  return;
139  }
140  mType = type;
141  if ( mParent ) mParent->updated();
142 }
143 
144 Alarm::Type Alarm::type() const
145 {
146  return mType;
147 }
148 
149 void Alarm::setAudioAlarm(const TQString &audioFile)
150 {
151  mType = Audio;
152  mFile = audioFile;
153  if ( mParent ) mParent->updated();
154 }
155 
156 void Alarm::setAudioFile(const TQString &audioFile)
157 {
158  if (mType == Audio) {
159  mFile = audioFile;
160  if ( mParent ) mParent->updated();
161  }
162 }
163 
164 TQString Alarm::audioFile() const
165 {
166  return (mType == Audio) ? mFile : TQString();
167 }
168 
169 void Alarm::setProcedureAlarm(const TQString &programFile, const TQString &arguments)
170 {
171  mType = Procedure;
172  mFile = programFile;
173  mDescription = arguments;
174  if ( mParent ) mParent->updated();
175 }
176 
177 void Alarm::setProgramFile(const TQString &programFile)
178 {
179  if (mType == Procedure) {
180  mFile = programFile;
181  if ( mParent ) mParent->updated();
182  }
183 }
184 
185 TQString Alarm::programFile() const
186 {
187  return (mType == Procedure) ? mFile : TQString();
188 }
189 
190 void Alarm::setProgramArguments(const TQString &arguments)
191 {
192  if (mType == Procedure) {
193  mDescription = arguments;
194  if ( mParent ) mParent->updated();
195  }
196 }
197 
198 TQString Alarm::programArguments() const
199 {
200  return (mType == Procedure) ? mDescription : TQString();
201 }
202 
203 void Alarm::setEmailAlarm(const TQString &subject, const TQString &text,
204  const TQValueList<Person> &addressees, const TQStringList &attachments)
205 {
206  mType = Email;
207  mMailSubject = subject;
208  mDescription = text;
209  mMailAddresses = addressees;
210  mMailAttachFiles = attachments;
211  if ( mParent ) mParent->updated();
212 }
213 
214 void Alarm::setMailAddress(const Person &mailAddress)
215 {
216  if (mType == Email) {
217  mMailAddresses.clear();
218  mMailAddresses += mailAddress;
219  if ( mParent ) mParent->updated();
220  }
221 }
222 
223 void Alarm::setMailAddresses(const TQValueList<Person> &mailAddresses)
224 {
225  if (mType == Email) {
226  mMailAddresses = mailAddresses;
227  if ( mParent ) mParent->updated();
228  }
229 }
230 
231 void Alarm::addMailAddress(const Person &mailAddress)
232 {
233  if (mType == Email) {
234  mMailAddresses += mailAddress;
235  if ( mParent ) mParent->updated();
236  }
237 }
238 
239 TQValueList<Person> Alarm::mailAddresses() const
240 {
241  return (mType == Email) ? mMailAddresses : TQValueList<Person>();
242 }
243 
244 void Alarm::setMailSubject(const TQString &mailAlarmSubject)
245 {
246  if (mType == Email) {
247  mMailSubject = mailAlarmSubject;
248  if ( mParent ) mParent->updated();
249  }
250 }
251 
252 TQString Alarm::mailSubject() const
253 {
254  return (mType == Email) ? mMailSubject : TQString();
255 }
256 
257 void Alarm::setMailAttachment(const TQString &mailAttachFile)
258 {
259  if (mType == Email) {
260  mMailAttachFiles.clear();
261  mMailAttachFiles += mailAttachFile;
262  if ( mParent ) mParent->updated();
263  }
264 }
265 
266 void Alarm::setMailAttachments(const TQStringList &mailAttachFiles)
267 {
268  if (mType == Email) {
269  mMailAttachFiles = mailAttachFiles;
270  if ( mParent ) mParent->updated();
271  }
272 }
273 
274 void Alarm::addMailAttachment(const TQString &mailAttachFile)
275 {
276  if (mType == Email) {
277  mMailAttachFiles += mailAttachFile;
278  if ( mParent ) mParent->updated();
279  }
280 }
281 
282 TQStringList Alarm::mailAttachments() const
283 {
284  return (mType == Email) ? mMailAttachFiles : TQStringList();
285 }
286 
287 void Alarm::setMailText(const TQString &text)
288 {
289  if (mType == Email) {
290  mDescription = text;
291  if ( mParent ) mParent->updated();
292  }
293 }
294 
295 TQString Alarm::mailText() const
296 {
297  return (mType == Email) ? mDescription : TQString();
298 }
299 
300 void Alarm::setDisplayAlarm(const TQString &text)
301 {
302  mType = Display;
303  if ( !text.isNull() )
304  mDescription = text;
305  if ( mParent ) mParent->updated();
306 }
307 
308 void Alarm::setText(const TQString &text)
309 {
310  if (mType == Display) {
311  mDescription = text;
312  if ( mParent ) mParent->updated();
313  }
314 }
315 
316 TQString Alarm::text() const
317 {
318  return (mType == Display) ? mDescription : TQString();
319 }
320 
321 void Alarm::setTime(const TQDateTime &alarmTime)
322 {
323  mAlarmTime = alarmTime;
324  mHasTime = true;
325 
326  if ( mParent ) mParent->updated();
327 }
328 
329 TQDateTime Alarm::time() const
330 {
331  if ( hasTime() ) {
332  return mAlarmTime;
333  } else if ( mParent ) {
334  if ( mEndOffset ) {
335  if ( mParent->type() == "Todo" ) {
336  Todo *t = static_cast<Todo*>( mParent );
337  return mOffset.end( t->dtDue() );
338  } else {
339  return mOffset.end( mParent->dtEnd() );
340  }
341  } else {
342  return mOffset.end( mParent->dtStart() );
343  }
344  } else {
345  return TQDateTime();
346  }
347 }
348 
349 bool Alarm::hasTime() const
350 {
351  return mHasTime;
352 }
353 
354 void Alarm::setSnoozeTime(const Duration &alarmSnoozeTime)
355 {
356  if (alarmSnoozeTime.value() > 0) {
357  mAlarmSnoozeTime = alarmSnoozeTime;
358  if ( mParent ) mParent->updated();
359  }
360 }
361 
363 {
364  return mAlarmSnoozeTime;
365 }
366 
367 void Alarm::setRepeatCount(int alarmRepeatCount)
368 {
369  mAlarmRepeatCount = alarmRepeatCount;
370  if ( mParent ) mParent->updated();
371 }
372 
374 {
375  return mAlarmRepeatCount;
376 }
377 
379 {
380  return Duration( mAlarmSnoozeTime.value() * mAlarmRepeatCount,
381  mAlarmSnoozeTime.type() );
382 }
383 
384 TQDateTime Alarm::nextRepetition(const TQDateTime& preTime) const
385 {
386  // This method is coded to avoid 32-bit integer overflow using
387  // TQDateTime::secsTo(), which occurs with time spans > 68 years.
388  TQDateTime at = time();
389  if (at > preTime)
390  return at;
391  if (!mAlarmRepeatCount)
392  return TQDateTime(); // there isn't an occurrence after the specified time
393  int snoozeSecs = mAlarmSnoozeTime * 60;
394  TQDateTime lastRepetition = at.addSecs(mAlarmRepeatCount * snoozeSecs);
395  if (lastRepetition <= preTime)
396  return TQDateTime(); // all repetitions have finished before the specified time
397  int repetition = (at.secsTo(preTime) + snoozeSecs) / snoozeSecs;
398  return at.addSecs(repetition * snoozeSecs);
399 }
400 
401 TQDateTime Alarm::previousRepetition(const TQDateTime& afterTime) const
402 {
403  // This method is coded to avoid 32-bit integer overflow using
404  // TQDateTime::secsTo(), which occurs with time spans > 68 years.
405  TQDateTime at = time();
406  if (at >= afterTime)
407  return TQDateTime(); // alarm's first/only time is at/after the specified time
408  if (!mAlarmRepeatCount)
409  return at;
410  int snoozeSecs = mAlarmSnoozeTime * 60;
411  TQDateTime lastRepetition = at.addSecs(mAlarmRepeatCount * snoozeSecs);
412  if (lastRepetition < afterTime)
413  return lastRepetition; // all repetitions have finished before the specified time
414  int repetition = (at.secsTo(afterTime) - 1) / snoozeSecs;
415  return at.addSecs(repetition * snoozeSecs);
416 }
417 
418 TQDateTime Alarm::endTime() const
419 {
420  if (mAlarmRepeatCount)
421  return time().addSecs(mAlarmRepeatCount * mAlarmSnoozeTime * 60);
422  else
423  return time();
424 }
425 
427 {
428  mAlarmEnabled = !mAlarmEnabled;
429  if ( mParent ) mParent->updated();
430 }
431 
432 void Alarm::setEnabled(bool enable)
433 {
434  mAlarmEnabled = enable;
435  if ( mParent ) mParent->updated();
436 }
437 
438 bool Alarm::enabled() const
439 {
440  return mAlarmEnabled;
441 }
442 
443 void Alarm::setStartOffset( const Duration &offset )
444 {
445  mOffset = offset;
446  mEndOffset = false;
447  mHasTime = false;
448  if ( mParent ) mParent->updated();
449 }
450 
452 {
453  return (mHasTime || mEndOffset) ? Duration( 0 ) : mOffset;
454 }
455 
457 {
458  return !mHasTime && !mEndOffset;
459 }
460 
462 {
463  return !mHasTime && mEndOffset;
464 }
465 
466 void Alarm::setEndOffset( const Duration &offset )
467 {
468  mOffset = offset;
469  mEndOffset = true;
470  mHasTime = false;
471  if ( mParent ) mParent->updated();
472 }
473 
475 {
476  return (mHasTime || !mEndOffset) ? Duration( 0 ) : mOffset;
477 }
478 
480 {
481  mParent = parent;
482 }
483 
485 {
486  if ( mParent ) mParent->updated();
487 }