libkcal

dndfactory.cpp
1 /*
2  This file is part of libkcal.
3 
4  Copyright (c) 1998 Preston Brown <pbrown@kde.org>
5  Copyright (c) 2001,2002 Cornelius Schumacher <schumacher@kde.org>
6  Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
7 
8  This library is free software; you can redistribute it and/or
9  modify it under the terms of the GNU Library General Public
10  License as published by the Free Software Foundation; either
11  version 2 of the License, or (at your option) any later version.
12 
13  This library is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  Library General Public License for more details.
17 
18  You should have received a copy of the GNU Library General Public License
19  along with this library; see the file COPYING.LIB. If not, write to
20  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  Boston, MA 02110-1301, USA.
22 */
23 
24 #include <tqapplication.h>
25 #include <tqclipboard.h>
26 #include <tqmap.h>
27 
28 #include <kiconloader.h>
29 #include <kdebug.h>
30 #include <tdemessagebox.h>
31 #include <tdelocale.h>
32 
33 #include "vcaldrag.h"
34 #include "icaldrag.h"
35 #include "calendar.h"
36 #include "vcalformat.h"
37 #include "icalformat.h"
38 #include "calendarlocal.h"
39 
40 #include "dndfactory.h"
41 
42 using namespace KCal;
43 
44 class DndFactory::Private
45 {
46  public:
48  const TQDate &newDate,
49  const TQTime *newTime = 0 )
50  {
51  if ( inc ) {
52  inc = inc->clone();
53  inc->recreate();
54  }
55 
56  if ( inc && newDate.isValid() ) {
57  if ( inc->type() == "Event" ) {
58  Event *anEvent = static_cast<Event*>( inc );
59  // Calculate length of event
60  int daysOffset = anEvent->dtStart().date().daysTo(
61  anEvent->dtEnd().date() );
62  // new end date if event starts at the same time on the new day
63  TQDateTime endDate( newDate.addDays(daysOffset), anEvent->dtEnd().time() );
64 
65  if ( newTime ) {
66  // additional offset for new time of day
67  int addSecsOffset( anEvent->dtStart().time().secsTo( *newTime ));
68  endDate=endDate.addSecs( addSecsOffset );
69  anEvent->setDtStart( TQDateTime( newDate, *newTime ) );
70  } else {
71  anEvent->setDtStart( TQDateTime( newDate, anEvent->dtStart().time() ) );
72  }
73  anEvent->setDtEnd( endDate );
74  } else if ( inc->type() == "Todo" ) {
75  Todo *anTodo = static_cast<Todo*>( inc );
76  if ( newTime ) {
77  anTodo->setDtDue( TQDateTime( newDate, *newTime ) );
78  } else {
79  anTodo->setDtDue( TQDateTime( newDate, anTodo->dtDue().time() ) );
80  }
81  } else if ( inc->type() == "Journal" ) {
82  Journal *anJournal = static_cast<Journal*>( inc );
83  if ( newTime ) {
84  anJournal->setDtStart( TQDateTime( newDate, *newTime ) );
85  } else {
86  anJournal->setDtStart( TQDateTime( newDate ) );
87  }
88  } else {
89  kdDebug(5850) << "Trying to paste unknown incidence of type " << inc->type() << endl;
90  }
91  }
92  return inc;
93  }
94 };
95 
96 DndFactory::DndFactory( Calendar *cal ) :
97  mCalendar( cal ), d( new Private )
98 {
99 }
100 
101 DndFactory::~DndFactory()
102 {
103  delete d;
104 }
105 
106 ICalDrag *DndFactory::createDrag( Incidence *incidence, TQWidget *owner )
107 {
108  CalendarLocal cal( mCalendar->timeZoneId() );
109  Incidence *i = incidence->clone();
110  cal.addIncidence( i );
111 
112  ICalDrag *icd = new ICalDrag( &cal, owner );
113  if ( i->type() == "Event" )
114  icd->setPixmap( BarIcon( "appointment" ) );
115  else if ( i->type() == "Todo" )
116  icd->setPixmap( BarIcon( "todo" ) );
117 
118  return icd;
119 }
120 
121 Event *DndFactory::createDrop(TQDropEvent *de)
122 {
123  kdDebug(5800) << "DndFactory::createDrop()" << endl;
124 
125  CalendarLocal cal( mCalendar->timeZoneId() );
126 
127  if ( ICalDrag::decode( de, &cal ) || VCalDrag::decode( de, &cal ) ) {
128  de->accept();
129 
130  Event::List events = cal.events();
131  if ( !events.isEmpty() ) {
132  Event *event = new Event( *events.first() );
133  return event;
134  }
135  }
136 
137  return 0;
138 }
139 
141 {
142  kdDebug(5800) << "VCalFormat::createDropTodo()" << endl;
143 
144  CalendarLocal cal( mCalendar->timeZoneId() );
145 
146  if ( ICalDrag::decode( de, &cal ) || VCalDrag::decode( de, &cal ) ) {
147  de->accept();
148 
149  Todo::List todos = cal.todos();
150  if ( !todos.isEmpty() ) {
151  Todo *todo = new Todo( *todos.first() );
152  return todo;
153  }
154  }
155 
156  return 0;
157 }
158 
160 {
161  Incidence::List list;
162  list.append( selectedInc );
163  cutIncidences( list );
164 }
165 
167 {
168  if ( copyIncidences( incidences ) ) {
169  Incidence::List::ConstIterator it;
170  for ( it = incidences.constBegin(); it != incidences.constEnd(); ++it ) {
171  mCalendar->deleteIncidence( *it );
172  }
173  return true;
174  } else {
175  return false;
176  }
177 }
178 
180 {
181  TQClipboard *cb = TQApplication::clipboard();
182  CalendarLocal cal( mCalendar->timeZoneId() );
183  Incidence::List::ConstIterator it;
184 
185  for ( it = incidences.constBegin(); it != incidences.constEnd(); ++it ) {
186  if ( *it ) {
187  cal.addIncidence( ( *it )->clone() );
188  }
189  }
190 
191  if ( cal.incidences().isEmpty() ) {
192  return false;
193  } else {
194  cb->setData( new ICalDrag( &cal ) );
195  return true;
196  }
197 }
198 
200 {
201  Incidence::List list;
202  list.append( selectedInc );
203  return copyIncidences( list );
204 }
205 
206 Incidence::List DndFactory::pasteIncidences( const TQDate &newDate, const TQTime *newTime )
207 {
208  CalendarLocal cal( mCalendar->timeZoneId() );
209  TQClipboard *cb = TQApplication::clipboard();
210  Incidence::List list;
211 
212  if ( !ICalDrag::decode( cb->data(), &cal ) &&
213  !VCalDrag::decode( cb->data(), &cal ) ) {
214  kdDebug(5800) << "Can't parse clipboard" << endl;
215  return list;
216  }
217 
218  // All pasted incidences get new uids, must keep track of old uids,
219  // so we can update child's parents
220  TQMap<TQString,Incidence*> oldUidToNewInc;
221 
222  Incidence::List::ConstIterator it;
223  const Incidence::List incs = cal.incidences();
224  for ( it = incs.constBegin(); it != incs.constEnd(); ++it ) {
225  Incidence *inc = d->pasteIncidence( *it, newDate, newTime );
226  if ( inc ) {
227  list.append( inc );
228  oldUidToNewInc[( *it )->uid()] = inc;
229  }
230  }
231 
232  // update relations
233  for ( it = list.constBegin(); it != list.constEnd(); ++it ) {
234  Incidence *inc = *it;
235  if ( oldUidToNewInc.contains( inc->relatedToUid() ) ) {
236  Incidence *parentInc = oldUidToNewInc[inc->relatedToUid()];
237  inc->setRelatedToUid( parentInc->uid() );
238  inc->setRelatedTo( parentInc );
239  } else {
240  // not related to anything in the clipboard
241  inc->setRelatedToUid( TQString() );
242  inc->setRelatedTo( 0 );
243  }
244  }
245 
246  return list;
247 }
248 
249 Incidence *DndFactory::pasteIncidence( const TQDate &newDate, const TQTime *newTime )
250 {
251  CalendarLocal cal( mCalendar->timeZoneId() );
252  TQClipboard *cb = TQApplication::clipboard();
253 
254  if ( !ICalDrag::decode( cb->data(), &cal ) &&
255  !VCalDrag::decode( cb->data(), &cal ) ) {
256  kdDebug(5800) << "Can't parse clipboard" << endl;
257  return 0;
258  }
259 
260  Incidence::List incList = cal.incidences();
261  Incidence *inc = incList.isEmpty() ? 0 : incList.first();
262 
263  Incidence *newInc = d->pasteIncidence( inc, newDate, newTime );
264  newInc->setRelatedTo( 0 );
265  return newInc;
266 }
Provides the main "calendar" object class.
This class provides a calendar stored as a local file.
Definition: calendarlocal.h:37
This is the main "calendar" object class.
Definition: calendar.h:171
virtual bool addIncidence(Incidence *incidence)
Insert an Incidence into the Calendar.
Definition: calendar.cpp:466
virtual Incidence::List incidences()
Return a filtered list of all Incidences for this Calendar.
Definition: calendar.cpp:178
virtual bool deleteIncidence(Incidence *incidence)
Remove an Incidence from the Calendar.
Definition: calendar.cpp:473
TQString timeZoneId() const
Get the Time Zone ID for the Calendar.
Definition: calendar.cpp:112
virtual Event::List events(EventSortField sortField=EventSortUnsorted, SortDirection sortDirection=SortDirectionAscending)
Return a sorted, filtered list of all Events for this Calendar.
Definition: calendar.cpp:458
virtual Todo::List todos(TodoSortField sortField=TodoSortUnsorted, SortDirection sortDirection=SortDirectionAscending)
Return a sorted, filtered list of all Todos for this Calendar.
Definition: calendar.cpp:755
bool cutIncidences(const Incidence::List &incidences)
cuts a list of incidences to the clipboard
Definition: dndfactory.cpp:166
Incidence * pasteIncidence(const TQDate &, const TQTime *newTime=0)
pastes the event or todo and returns a pointer to the new incidence pasted.
Definition: dndfactory.cpp:249
bool copyIncidences(const Incidence::List &incidences)
copies a list of incidences to the clipboard
Definition: dndfactory.cpp:179
Incidence::List pasteIncidences(const TQDate &newDate=TQDate(), const TQTime *newTime=0)
pastes and returns the incidences from the clipboard If no date and time are given,...
Definition: dndfactory.cpp:206
void cutIncidence(Incidence *)
cut incidence to clipboard
Definition: dndfactory.cpp:159
bool copyIncidence(Incidence *)
copy the incidence to clipboard
Definition: dndfactory.cpp:199
ICalDrag * createDrag(Incidence *incidence, TQWidget *owner)
Create a drag object.
Definition: dndfactory.cpp:106
Todo * createDropTodo(TQDropEvent *de)
Create Todo object from drop event.
Definition: dndfactory.cpp:140
Event * createDrop(TQDropEvent *de)
Create Event object from drop event.
Definition: dndfactory.cpp:121
This class provides an Event in the sense of RFC2445.
Definition: event.h:33
virtual TQDateTime dtEnd() const
Return end date and time.
Definition: event.cpp:85
void setDtEnd(const TQDateTime &dtEnd)
Set end date and time.
Definition: event.cpp:73
iCalendar drag&drop class.
Definition: icaldrag.h:36
static bool decode(TQMimeSource *e, Calendar *cal)
Decode drag&drop object to iCalendar component cal.
Definition: icaldrag.cpp:45
TQString uid() const
Return the unique id for the event.
virtual TQDateTime dtStart() const
returns an event's starting date/time as a TQDateTime.
This class provides the base class common to all calendar components.
Definition: incidence.h:48
virtual Incidence * clone()=0
Return copy of this object.
TQString relatedToUid() const
What event does this one relate to? This function should only be used when constructing a calendar be...
Definition: incidence.cpp:340
void recreate()
Recreate event.
Definition: incidence.cpp:208
void setRelatedTo(Incidence *relatedTo)
Point at some other event to which the event relates.
Definition: incidence.cpp:345
void setRelatedToUid(const TQString &)
Point at some other event to which the event relates.
Definition: incidence.cpp:333
virtual void setDtStart(const TQDateTime &dtStart)
Set starting date/time.
Definition: incidence.cpp:264
This class provides a Journal in the sense of RFC2445.
Definition: journal.h:34
This class provides a Todo in the sense of RFC2445.
Definition: todo.h:32
void setDtDue(const TQDateTime &dtDue, bool first=false)
Sets due date and time.
Definition: todo.cpp:85
TQDateTime dtDue(bool first=false) const
Returns due date and time.
Definition: todo.cpp:117
static bool decode(TQMimeSource *e, Calendar *cal)
Decode drag&drop object to vCalendar component vcal.
Definition: vcaldrag.cpp:41
Namespace KCal is for global classes, objects and/or functions in libkcal.
Definition: alarm.h:38