kplato

kptcalendarlistdialog.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2004 - 2005 Dag Andersen <danders@get2net.dk>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation;
7 version 2 of the License.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18*/
19
20#include "kptcalendarlistdialog.h"
21#include "kptproject.h"
22#include "kptcalendar.h"
23#include "kptcommand.h"
24#include "kptpart.h"
25
26#include <tqpushbutton.h>
27#include <tqcombobox.h>
28#include <tqheader.h>
29#include <tqlabel.h>
30#include <tqtextedit.h>
31#include <tqlineedit.h>
32#include <tqdatetimeedit.h>
33#include <tqdatetime.h>
34#include <tqtabwidget.h>
35#include <tqtextbrowser.h>
36
37#include <tdelocale.h>
38
39#include <tdeabc/addressee.h>
40#include <tdeabc/addresseedialog.h>
41
42#include <kdebug.h>
43
44namespace KPlato
45{
46
47class CalendarListViewItem : public TDEListViewItem
48{
49public:
50 CalendarListViewItem(CalendarListDialogImpl &pan, TQListView *lv, Calendar *cal, Calendar *orig=0)
51 : TDEListViewItem(lv, cal->name()), panel(pan) {
52
53 calendar = cal;
54 original = orig;
55 state = None;
56 base = 0;
57 setRenameEnabled(0, false);
58 }
59 ~CalendarListViewItem() {
60 delete calendar;
61 }
62
63 enum State { None=0, New=1, Modified=2, Deleted=4 };
64
65 void setState(State s) { state |= s; }
66
67 Calendar *baseCalendar() {
68 if (state & Deleted) return 0;
69 return original ? original : calendar;
70 }
71 bool hasBaseCalendar(CalendarListViewItem *item) {
72 if (!base) return false;
73 return base == item || base->hasBaseCalendar(item);
74 }
75 KMacroCommand *buildCommand(Part *part, Project &p) {
76 KMacroCommand *macro=0;
77 if (state & New) {
78 if (macro == 0) macro = new KMacroCommand("");
79 //kdDebug()<<k_funcinfo<<"add: "<<calendar->name()<<" p="<<&p<<endl;
80 base ? calendar->setParent(base->baseCalendar()) : calendar->setParent(0);
81 macro->addCommand(new CalendarAddCmd(part, &p, calendar));
82 calendar = 0;
83 } else if (state & Modified) {
84 //kdDebug()<<k_funcinfo<<"modified: "<<calendar->name()<<endl;
85 if (original->name() != calendar->name()) {
86 if (macro == 0) macro = new KMacroCommand("");
87 macro->addCommand(new CalendarModifyNameCmd(part, original, calendar->name()));
88 }
89 Calendar *c = base ? base->baseCalendar() : 0;
90 if (c != original->parent()) {
91 if (macro == 0) macro = new KMacroCommand("");
92 macro->addCommand(new CalendarModifyParentCmd(part, original, c));
93 //kdDebug()<<k_funcinfo<<"Base modified: "<<c->name()<<endl;
94 }
95
96 //kdDebug()<<k_funcinfo<<"Check for days deleted: "<<calendar->name()<<endl;
97 TQPtrListIterator<CalendarDay> oit = original->days();
98 for (; oit.current(); ++oit) {
99 if (calendar->findDay(oit.current()->date()) == 0) {
100 if (macro == 0) macro = new KMacroCommand("");
101 macro->addCommand(new CalendarRemoveDayCmd(part, original, oit.current()->date()));
102 //kdDebug()<<k_funcinfo<<"Removed day"<<endl;
103 }
104 }
105
106 //kdDebug()<<k_funcinfo<<"Check for days added or modified: "<<calendar->name()<<endl;
107 TQPtrListIterator<CalendarDay> cit = calendar->days();
108 for (; cit.current(); ++cit) {
109 CalendarDay *day = original->findDay(cit.current()->date());
110 if (day == 0) {
111 if (macro == 0) macro = new KMacroCommand("");
112 // added
113 //kdDebug()<<k_funcinfo<<"Added day"<<endl;
114 macro->addCommand(new CalendarAddDayCmd(part, original, new CalendarDay(cit.current())));
115 } else if (*day != cit.current()) {
116 if (macro == 0) macro = new KMacroCommand("");
117 // modified
118 //kdDebug()<<k_funcinfo<<"Modified day"<<endl;
119 macro->addCommand(new CalendarModifyDayCmd(part, original, new CalendarDay(cit.current())));
120 }
121 }
122 //kdDebug()<<k_funcinfo<<"Check for weekdays modified: "<<calendar->name()<<endl;
123 CalendarDay *day = 0, *org = 0;
124 for (int i=0; i < 7; ++i) {
125 day = calendar->weekdays()->weekday(i);
126 org = original->weekdays()->weekday(i);
127 if (day && org) {
128 if (*org != *day) {
129 if (macro == 0) macro = new KMacroCommand("");
130 //kdDebug()<<k_funcinfo<<"Weekday["<<i<<"] modified"<<endl;
131 macro->addCommand(new CalendarModifyWeekdayCmd(part, original, i, new CalendarDay(day)));
132 }
133 } else if (day) {
134 // shouldn't happen: hmmm, add day to original??
135 kdError()<<k_funcinfo<<"Should always have 7 weekdays"<<endl;
136 } else if (org) {
137 // shouldn't happen: set org to default??
138 kdError()<<k_funcinfo<<"Should always have 7 weekdays"<<endl;
139 }
140 }
141 }
142 return macro;
143 }
144
145 Calendar *calendar;
146 Calendar *original;
147 CalendarListViewItem* base;
148 CalendarListDialogImpl &panel;
149 TQString oldText;
150
151protected:
152 virtual void cancelRename(int col) {
153 //kdDebug()<<k_funcinfo<<endl;
154 if (col == 0 && oldText.isEmpty()) {
155 return;
156 }
157 panel.renameStopped(this);
158 TDEListViewItem::cancelRename(col);
159 setRenameEnabled(col, false);
160 }
161private:
162 int state;
163};
164
165//----------------------------------------------------
166CalendarListDialog::CalendarListDialog(Project &p, TQWidget *parent, const char *name)
167 : KDialogBase( Swallow, i18n("Calendar's Settings"), Ok|Cancel, Ok, parent, name, true, true),
168 project(p)
169{
170 //kdDebug()<<k_funcinfo<<&p<<endl;
171 dia = new CalendarListDialogImpl(p, this);
172 TQPtrList<Calendar> list = p.calendars();
173 TQPtrListIterator<Calendar> it = list;
174 for (; it.current(); ++it) {
175 Calendar *c = new Calendar(it.current());
176 //c->setProject(&p);
177 new CalendarListViewItem(*dia, dia->calendarList, c, it.current());
178 }
179 dia->setBaseCalendars();
180
181 TQListViewItem *f = dia->calendarList->firstChild();
182 if (f) {
183 dia->calendarList->setSelected(f, true);
184 }
185 //kdDebug()<<"size="<<size().width()<<"x"<<size().height()<<" hint="<<sizeHint().width()<<"x"<<sizeHint().height()<<endl;
186 resize(TQSize(725, 388).expandedTo(minimumSizeHint()));
187
188 setMainWidget(dia);
189 enableButtonOK(false);
190
191 connect(dia, TQ_SIGNAL(enableButtonOk(bool)), TQ_SLOT(enableButtonOK(bool)));
192}
193
194KCommand *CalendarListDialog::buildCommand(Part *part) {
195 //kdDebug()<<k_funcinfo<<endl;
196 KMacroCommand *cmd = 0;
197 TQListViewItemIterator cit(dia->calendarList);
198 for (;cit.current(); ++cit) {
199 CalendarListViewItem *item = dynamic_cast<CalendarListViewItem *>(cit.current());
200 if (item) {
201 KMacroCommand *c = item->buildCommand(part, project);
202 if (c != 0) {
203 if (cmd == 0) cmd = new KMacroCommand("");
204 cmd->addCommand(c);
205 }
206 }
207 }
208 TQPtrListIterator<CalendarListViewItem> it = dia->deletedItems();
209 for (; it.current(); ++it) {
210 //kdDebug()<<k_funcinfo<<"deleted: "<<it.current()->calendar->name()<<endl;
211 if (it.current()->original) {
212 if (cmd == 0) cmd = new KMacroCommand("");
213 cmd->addCommand(new CalendarDeleteCmd(part, it.current()->original));
214 }
215 }
216 if (cmd) {
217 cmd->setName(i18n("Modify Calendars"));
218 }
219 return cmd;
220}
221
222void CalendarListDialog::slotOk() {
223 accept();
224}
225
226//--------------------------------------------------
227CalendarListDialogImpl::CalendarListDialogImpl (Project &p, TQWidget *parent)
228 : CalendarListDialogBase(parent),
229 project(p),
230 m_renameItem(0) {
231
232 calendarList->header()->setStretchEnabled(true, 0);
233 calendarList->setShowSortIndicator(true);
234 calendarList->setSorting(0);
235 calendarList->setDefaultRenameAction(TQListView::Accept);
236
237 m_deletedItems.setAutoDelete(true);
238 calendar->setEnabled(false);
239
240 slotSelectionChanged();
241
242 connect(calendar, TQ_SIGNAL(obligatedFieldsFilled(bool)), TQ_SLOT(slotEnableButtonOk(bool)));
243 connect(calendar, TQ_SIGNAL(applyClicked()), TQ_SLOT(slotCalendarModified()));
244
245 connect(bDelete, TQ_SIGNAL(clicked()), TQ_SLOT(slotDeleteClicked()));
246 connect(bAdd, TQ_SIGNAL(clicked()), TQ_SLOT(slotAddClicked()));
247 //connect(editName, TQ_SIGNAL(returnPressed()), TQ_SLOT(slotAddClicked()));
248
249 connect(calendarList, TQ_SIGNAL(selectionChanged()), TQ_SLOT(slotSelectionChanged()));
250 connect(calendarList, TQ_SIGNAL(doubleClicked(TQListViewItem*, const TQPoint&, int)), TQ_SLOT(slotListDoubleClicked(TQListViewItem*, const TQPoint&, int)));
251 connect(calendarList, TQ_SIGNAL(itemRenamed(TQListViewItem*, int)), TQ_SLOT(slotItemRenamed(TQListViewItem*, int)));
252
253 connect (baseCalendar, TQ_SIGNAL(activated(int)), TQ_SLOT(slotBaseCalendarActivated(int)));
254
255 // Internal rename stuff
256 connect(this, TQ_SIGNAL(renameStarted(TQListViewItem*, int)), TQ_SLOT(slotRenameStarted(TQListViewItem*, int)));
257 connect(this, TQ_SIGNAL(startRename(TQListViewItem*, int)), TQ_SLOT(slotStartRename(TQListViewItem*, int)));
258 connect(this, TQ_SIGNAL(selectionChanged()), TQ_SLOT(slotSelectionChanged()));
259}
260
261void CalendarListDialogImpl::setBaseCalendars() {
262 TQListViewItemIterator it(calendarList);
263 for (;it.current(); ++it) {
264 CalendarListViewItem *item = dynamic_cast<CalendarListViewItem *>(it.current());
265 if (item) {
266 item->base = findItem(item->calendar->parent());
267 }
268 }
269}
270
271void CalendarListDialogImpl::slotEnableButtonOk(bool on) {
272 emit enableButtonOk(on);
273}
274
275void CalendarListDialogImpl::slotBaseCalendarActivated(int id) {
276 CalendarListViewItem *item = dynamic_cast<CalendarListViewItem*>(calendarList->selectedItem());
277 if (item) {
278 item->base = baseCalendarList.at(id);
279 item->setState(CalendarListViewItem::Modified);
280 slotEnableButtonOk(true);
281 } else {
282 kdError()<<k_funcinfo<<"No CalendarListViewItem"<<endl;
283 }
284}
285
286void CalendarListDialogImpl::slotSelectionChanged() {
287 //kdDebug()<<k_funcinfo<<endl;
288 TQListViewItem *item = calendarList->selectedItem();
289 bDelete->setEnabled((bool)item);
290 bAdd->setEnabled(true);
291 slotSelectionChanged(item);
292}
293
294void CalendarListDialogImpl::slotSelectionChanged(TQListViewItem *listItem) {
295 //kdDebug()<<k_funcinfo<<endl;
296 baseCalendarList.clear();
297 baseCalendar->clear();
298 baseCalendar->setEnabled(false);
299 CalendarListViewItem *cal = dynamic_cast<CalendarListViewItem *>(listItem);
300 if (cal) {
301 setCalendar(cal->calendar);
302 baseCalendar->insertItem(i18n("None"));
303 baseCalendarList.append(0);
304 int me = 0, i = 0;
305 TQListViewItemIterator it(calendarList);
306 for (; it.current(); ++it) {
307 CalendarListViewItem *item = dynamic_cast<CalendarListViewItem*>(it.current());
308 if (item && cal != item && !item->hasBaseCalendar(cal)) {
309 baseCalendar->insertItem(item->text(0));
310 baseCalendarList.append(item);
311 i++;
312 if (item == cal->base) {
313 me = i;
314 //kdDebug()<<k_funcinfo<<"item="<<item<<": cal="<<cal->calendar->name()<<" has parent "<<cal->base->calendar->name()<<endl;
315 }
316 }
317 }
318 baseCalendar->setCurrentItem(me);
319 baseCalendar->setEnabled(true);
320 return;
321 }
322 calendar->clear();
323}
324void CalendarListDialogImpl::setCalendar(Calendar *cal) {
325 calendar->setCalendar(cal);
326 calendar->setEnabled(true);
327}
328
329void CalendarListDialogImpl::slotCalendarModified() {
330 CalendarListViewItem *item = dynamic_cast<CalendarListViewItem*>(calendarList->currentItem());
331 if (item) {
332 item->setState(CalendarListViewItem::Modified);
333 //kdDebug()<<k_funcinfo<<"("<<item->calendar<<")"<<endl;
334 }
335 emit calendarModified();
336}
337
338void CalendarListDialogImpl::slotDeleteClicked() {
339 CalendarListViewItem *item = static_cast<CalendarListViewItem*>(calendarList->selectedItem());
340 if (item) {
341 calendarList->takeItem(item);
342 item->setState(CalendarListViewItem::Deleted);
343 m_deletedItems.append(item);
344
345 emit enableButtonOk(true);
346 }
347}
348
349void CalendarListDialogImpl::slotAddClicked() {
350 Calendar *cal = new Calendar();
351 cal->setProject(&project);
352 CalendarListViewItem *item = new CalendarListViewItem(*this, calendarList, cal);
353 item->setState(CalendarListViewItem::New);
354
355 slotListDoubleClicked(item, TQPoint(), 0);
356
357}
358
359TQPtrList<CalendarListViewItem> &CalendarListDialogImpl::deletedItems() {
360 return m_deletedItems;
361}
362
363CalendarListViewItem *CalendarListDialogImpl::findItem(Calendar *cal) {
364 if (!cal)
365 return 0;
366 TQListViewItemIterator it(calendarList);
367 for (;it.current(); ++it) {
368 CalendarListViewItem *item = dynamic_cast<CalendarListViewItem *>(it.current());
369 if (item && (cal == item->original || cal == item->calendar)) {
370 //kdDebug()<<k_funcinfo<<"Found: "<<cal->name()<<endl;
371 return item;
372 }
373 }
374 return 0;
375}
376
377void CalendarListDialogImpl::slotItemRenamed(TQListViewItem *itm, int col) {
378 //kdDebug()<<k_funcinfo<<itm->text(0)<<endl;
379 itm->setRenameEnabled(col, false);
380 m_renameItem = 0;
381 CalendarListViewItem *item = static_cast<CalendarListViewItem*>(itm);
382 if (item->text(0).isEmpty()) {
383 item->setText(0, item->oldText); // keep the old name
384 }
385 if (item->text(0).isEmpty()) {
386 // Not allowed
387 //kdDebug()<<k_funcinfo<<"name empty"<<endl;
388 emit startRename(item, 0);
389 return;
390 }
391 if (item->text(0) != item->oldText) {
392 item->setState(CalendarListViewItem::Modified);
393 item->calendar->setName(item->text(0));
394 }
395 renameStopped(item);
396 slotEnableButtonOk(true);
397}
398
399// We don't get notified when rename is cancelled, this is called from the item
400void CalendarListDialogImpl::renameStopped(TQListViewItem */*item*/) {
401 //kdDebug()<<k_funcinfo<<(item?item->text(0):"")<<endl;
402 m_renameItem = 0;
403 emit selectionChanged();
404}
405
406void CalendarListDialogImpl::slotListDoubleClicked(TQListViewItem *item, const TQPoint&, int col) {
407 //kdDebug()<<k_funcinfo<<(item?item->text(0):"")<<endl;
408 if (m_renameItem)
409 return;
410 slotStartRename(item, col);
411}
412
413void CalendarListDialogImpl::slotRenameStarted(TQListViewItem */*item*/, int /*col*/) {
414 //kdDebug()<<k_funcinfo<<(item?item->text(0):"")<<endl;
415 if (calendarList->isRenaming()) {
416 bDelete->setEnabled(false);
417 bAdd->setEnabled(false);
418 }
419}
420
421void CalendarListDialogImpl::slotStartRename(TQListViewItem *item, int col) {
422 //kdDebug()<<k_funcinfo<<(item?item->text(0):"")<<endl;
423 static_cast<CalendarListViewItem*>(item)->oldText = item->text(col);
424 item->setRenameEnabled(col, true);
425 item->startRename(col);
426 m_renameItem = item;
427
428 emit renameStarted(item, col);
429}
430
431} //KPlato namespace
432
433#include "kptcalendarlistdialog.moc"