kplato

kptcalendarlistdialog.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 2004 - 2005 Dag Andersen <danders@get2net.dk>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation;
00007    version 2 of the License.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include "kptcalendarlistdialog.h"
00021 #include "kptproject.h"
00022 #include "kptcalendar.h"
00023 #include "kptcommand.h"
00024 #include "kptpart.h"
00025 
00026 #include <qpushbutton.h>
00027 #include <qcombobox.h>
00028 #include <qheader.h>
00029 #include <qlabel.h>
00030 #include <qtextedit.h>
00031 #include <qlineedit.h>
00032 #include <qdatetimeedit.h>
00033 #include <qdatetime.h>
00034 #include <qtabwidget.h>
00035 #include <qtextbrowser.h>
00036 
00037 #include <klocale.h>
00038 
00039 #include <kabc/addressee.h>
00040 #include <kabc/addresseedialog.h>
00041 
00042 #include <kdebug.h>
00043 
00044 namespace KPlato
00045 {
00046 
00047 class CalendarListViewItem : public KListViewItem
00048 {
00049 public:
00050     CalendarListViewItem(CalendarListDialogImpl &pan, QListView *lv, Calendar *cal,  Calendar *orig=0)
00051         : KListViewItem(lv, cal->name()), panel(pan) {
00052 
00053         calendar = cal;
00054         original = orig;
00055         state = None;
00056         base = 0;
00057         setRenameEnabled(0, false);
00058     }
00059     ~CalendarListViewItem() {
00060         delete calendar;
00061     }
00062 
00063     enum State { None=0, New=1, Modified=2, Deleted=4 };
00064 
00065     void setState(State s) { state |= s; }
00066     
00067     Calendar *baseCalendar() {
00068         if (state & Deleted) return 0;
00069         return original ? original : calendar;
00070     }
00071     bool hasBaseCalendar(CalendarListViewItem *item) {
00072         if (!base) return false;
00073         return base == item || base->hasBaseCalendar(item);
00074     }
00075     KMacroCommand *buildCommand(Part *part, Project &p) {
00076         KMacroCommand *macro=0;
00077         if (state & New) {
00078             if (macro == 0) macro = new KMacroCommand("");
00079             //kdDebug()<<k_funcinfo<<"add: "<<calendar->name()<<" p="<<&p<<endl;
00080             base ? calendar->setParent(base->baseCalendar()) : calendar->setParent(0);
00081             macro->addCommand(new CalendarAddCmd(part, &p, calendar));
00082             calendar = 0;
00083         } else if (state & Modified) {
00084             //kdDebug()<<k_funcinfo<<"modified: "<<calendar->name()<<endl;
00085             if (original->name() != calendar->name()) {
00086                 if (macro == 0) macro = new KMacroCommand("");
00087                 macro->addCommand(new CalendarModifyNameCmd(part, original, calendar->name()));
00088             }
00089             Calendar *c = base ? base->baseCalendar() : 0;
00090             if (c != original->parent()) {
00091                 if (macro == 0) macro = new KMacroCommand("");
00092                 macro->addCommand(new CalendarModifyParentCmd(part, original, c));
00093                 //kdDebug()<<k_funcinfo<<"Base modified: "<<c->name()<<endl;
00094             }
00095             
00096             //kdDebug()<<k_funcinfo<<"Check for days deleted: "<<calendar->name()<<endl;
00097             QPtrListIterator<CalendarDay> oit = original->days();
00098             for (; oit.current(); ++oit) {
00099                 if (calendar->findDay(oit.current()->date()) == 0) {
00100                     if (macro == 0) macro = new KMacroCommand("");
00101                     macro->addCommand(new CalendarRemoveDayCmd(part, original, oit.current()->date()));
00102                     //kdDebug()<<k_funcinfo<<"Removed day"<<endl;
00103                 }
00104             }
00105         
00106             //kdDebug()<<k_funcinfo<<"Check for days added or modified: "<<calendar->name()<<endl;
00107             QPtrListIterator<CalendarDay> cit = calendar->days();
00108             for (; cit.current(); ++cit) {
00109                 CalendarDay *day = original->findDay(cit.current()->date());
00110                 if (day == 0) {
00111                     if (macro == 0) macro = new KMacroCommand("");
00112                     // added
00113                     //kdDebug()<<k_funcinfo<<"Added day"<<endl;
00114                     macro->addCommand(new CalendarAddDayCmd(part, original, new CalendarDay(cit.current())));
00115                 } else if (*day != cit.current()) {
00116                     if (macro == 0) macro = new KMacroCommand("");
00117                     // modified
00118                     //kdDebug()<<k_funcinfo<<"Modified day"<<endl;
00119                     macro->addCommand(new CalendarModifyDayCmd(part, original, new CalendarDay(cit.current())));
00120                 }
00121             }
00122             //kdDebug()<<k_funcinfo<<"Check for weekdays modified: "<<calendar->name()<<endl;
00123             CalendarDay *day = 0, *org = 0;
00124             for (int i=0; i < 7; ++i) {
00125                 day = calendar->weekdays()->weekday(i);
00126                 org = original->weekdays()->weekday(i);
00127                 if (day && org) {
00128                     if (*org != *day) {
00129                         if (macro == 0) macro = new KMacroCommand("");
00130                         //kdDebug()<<k_funcinfo<<"Weekday["<<i<<"] modified"<<endl;
00131                         macro->addCommand(new CalendarModifyWeekdayCmd(part, original, i, new CalendarDay(day)));
00132                     }
00133                 } else if (day) {
00134                     // shouldn't happen: hmmm, add day to original??
00135                     kdError()<<k_funcinfo<<"Should always have 7 weekdays"<<endl;
00136                 } else if (org) {
00137                     // shouldn't happen: set org to default??
00138                     kdError()<<k_funcinfo<<"Should always have 7 weekdays"<<endl;
00139                 }
00140             }
00141         }
00142         return macro;
00143     }
00144 
00145     Calendar *calendar;
00146     Calendar *original;
00147     CalendarListViewItem* base;
00148     CalendarListDialogImpl &panel;
00149     QString oldText;
00150     
00151 protected:
00152     virtual void cancelRename(int col) {
00153         //kdDebug()<<k_funcinfo<<endl;
00154         if (col == 0 && oldText.isEmpty()) {
00155             return;
00156         }
00157         panel.renameStopped(this);
00158         KListViewItem::cancelRename(col);
00159         setRenameEnabled(col, false);
00160     }
00161 private:
00162     int state;
00163 };
00164 
00165 //----------------------------------------------------
00166 CalendarListDialog::CalendarListDialog(Project &p, QWidget *parent, const char *name)
00167     : KDialogBase( Swallow, i18n("Calendar's Settings"), Ok|Cancel, Ok, parent, name, true, true),
00168       project(p)
00169 {
00170     //kdDebug()<<k_funcinfo<<&p<<endl;
00171     dia = new CalendarListDialogImpl(p, this);
00172     QPtrList<Calendar> list = p.calendars();
00173     QPtrListIterator<Calendar> it = list;
00174     for (; it.current(); ++it) {
00175         Calendar *c = new Calendar(it.current());
00176         c->setProject(&p);
00177         new CalendarListViewItem(*dia, dia->calendarList, c, it.current());
00178     }
00179     dia->setBaseCalendars();
00180     
00181     QListViewItem *f = dia->calendarList->firstChild();
00182     if (f) {
00183         dia->calendarList->setSelected(f, true);
00184     }
00185     //kdDebug()<<"size="<<size().width()<<"x"<<size().height()<<" hint="<<sizeHint().width()<<"x"<<sizeHint().height()<<endl;
00186     resize(QSize(725, 388).expandedTo(minimumSizeHint()));
00187 
00188     setMainWidget(dia);
00189     enableButtonOK(false);
00190 
00191     connect(dia, SIGNAL(enableButtonOk(bool)), SLOT(enableButtonOK(bool)));
00192 }
00193 
00194 KCommand *CalendarListDialog::buildCommand(Part *part) {
00195     //kdDebug()<<k_funcinfo<<endl;
00196     KMacroCommand *cmd = 0;
00197     QListViewItemIterator cit(dia->calendarList);
00198     for (;cit.current(); ++cit) {
00199         CalendarListViewItem *item = dynamic_cast<CalendarListViewItem *>(cit.current());
00200         if (item) {
00201             KMacroCommand *c = item->buildCommand(part, project);
00202             if (c != 0) {
00203                 if (cmd == 0) cmd = new KMacroCommand("");
00204                 cmd->addCommand(c);
00205             }
00206         }
00207     }
00208     QPtrListIterator<CalendarListViewItem> it = dia->deletedItems();
00209     for (; it.current(); ++it) {
00210         //kdDebug()<<k_funcinfo<<"deleted: "<<it.current()->calendar->name()<<endl;
00211         if (it.current()->original) {
00212             if (cmd == 0) cmd = new KMacroCommand("");
00213             cmd->addCommand(new CalendarDeleteCmd(part, it.current()->original));
00214         }
00215     }
00216     if (cmd) {
00217         cmd->setName(i18n("Modify Calendars"));
00218     }
00219     return cmd;
00220 }
00221 
00222 void CalendarListDialog::slotOk() {
00223     accept();
00224 }
00225 
00226 //--------------------------------------------------
00227 CalendarListDialogImpl::CalendarListDialogImpl (Project &p, QWidget *parent) 
00228     : CalendarListDialogBase(parent),
00229       project(p),
00230       m_renameItem(0) {
00231 
00232     calendarList->header()->setStretchEnabled(true, 0);
00233     calendarList->setShowSortIndicator(true);
00234     calendarList->setSorting(0);
00235     calendarList->setDefaultRenameAction(QListView::Accept);
00236 
00237     m_deletedItems.setAutoDelete(true);
00238     calendar->setEnabled(false);
00239 
00240     slotSelectionChanged();
00241 
00242     connect(calendar, SIGNAL(obligatedFieldsFilled(bool)), SLOT(slotEnableButtonOk(bool)));
00243     connect(calendar, SIGNAL(applyClicked()), SLOT(slotCalendarModified()));
00244 
00245     connect(bDelete, SIGNAL(clicked()), SLOT(slotDeleteClicked()));
00246     connect(bAdd, SIGNAL(clicked()), SLOT(slotAddClicked()));
00247     //connect(editName, SIGNAL(returnPressed()), SLOT(slotAddClicked()));
00248 
00249     connect(calendarList, SIGNAL(selectionChanged()), SLOT(slotSelectionChanged()));
00250     connect(calendarList, SIGNAL(doubleClicked(QListViewItem*, const QPoint&, int)), SLOT(slotListDoubleClicked(QListViewItem*, const QPoint&, int)));
00251     connect(calendarList, SIGNAL(itemRenamed(QListViewItem*, int)), SLOT(slotItemRenamed(QListViewItem*, int)));
00252     
00253     connect (baseCalendar, SIGNAL(activated(int)), SLOT(slotBaseCalendarActivated(int)));
00254 
00255     // Internal rename stuff
00256     connect(this, SIGNAL(renameStarted(QListViewItem*, int)), SLOT(slotRenameStarted(QListViewItem*, int)));
00257     connect(this, SIGNAL(startRename(QListViewItem*, int)), SLOT(slotStartRename(QListViewItem*, int)));
00258     connect(this, SIGNAL(selectionChanged()), SLOT(slotSelectionChanged()));
00259 }
00260 
00261 void CalendarListDialogImpl::setBaseCalendars() {
00262     QListViewItemIterator it(calendarList);
00263     for (;it.current(); ++it) {
00264         CalendarListViewItem *item = dynamic_cast<CalendarListViewItem *>(it.current());
00265         if (item) {
00266             item->base = findItem(item->calendar->parent());
00267         }
00268     }
00269 }
00270 
00271 void CalendarListDialogImpl::slotEnableButtonOk(bool on) {
00272     emit enableButtonOk(on);
00273 }
00274 
00275 void CalendarListDialogImpl::slotBaseCalendarActivated(int id) {
00276     CalendarListViewItem *item = dynamic_cast<CalendarListViewItem*>(calendarList->selectedItem());
00277     if (item) {
00278         item->base = baseCalendarList.at(id);
00279         item->setState(CalendarListViewItem::Modified);
00280         slotEnableButtonOk(true);
00281     } else {
00282         kdError()<<k_funcinfo<<"No CalendarListViewItem"<<endl;
00283     }
00284 }
00285 
00286 void CalendarListDialogImpl::slotSelectionChanged() {
00287     //kdDebug()<<k_funcinfo<<endl;
00288     QListViewItem *item = calendarList->selectedItem();
00289     bDelete->setEnabled((bool)item);
00290     bAdd->setEnabled(true);
00291     slotSelectionChanged(item);
00292 }
00293 
00294 void CalendarListDialogImpl::slotSelectionChanged(QListViewItem *listItem) {
00295     //kdDebug()<<k_funcinfo<<endl;
00296     baseCalendarList.clear();
00297     baseCalendar->clear();
00298     baseCalendar->setEnabled(false);
00299     CalendarListViewItem *cal = dynamic_cast<CalendarListViewItem *>(listItem);
00300     if (cal) {
00301         setCalendar(cal->calendar);
00302         baseCalendar->insertItem(i18n("None"));
00303         baseCalendarList.append(0);
00304         int me = 0, i = 0;
00305         QListViewItemIterator it(calendarList);
00306         for (; it.current(); ++it) {
00307             CalendarListViewItem *item = dynamic_cast<CalendarListViewItem*>(it.current());
00308             if (item && cal != item && !item->hasBaseCalendar(cal)) {
00309                 baseCalendar->insertItem(item->text(0));
00310                 baseCalendarList.append(item);
00311                 i++;
00312                 if (item == cal->base) {
00313                     me = i;
00314                     //kdDebug()<<k_funcinfo<<"item="<<item<<": cal="<<cal->calendar->name()<<" has parent "<<cal->base->calendar->name()<<endl;
00315                 }
00316             }
00317         }
00318         baseCalendar->setCurrentItem(me);
00319         baseCalendar->setEnabled(true);
00320         return;
00321     }
00322     calendar->clear();
00323 }
00324 void CalendarListDialogImpl::setCalendar(Calendar *cal) {
00325     calendar->setCalendar(cal); 
00326     calendar->setEnabled(true); 
00327 }
00328  
00329 void CalendarListDialogImpl::slotCalendarModified() {
00330     CalendarListViewItem *item = dynamic_cast<CalendarListViewItem*>(calendarList->currentItem());
00331     if (item) {
00332         item->setState(CalendarListViewItem::Modified);
00333         //kdDebug()<<k_funcinfo<<"("<<item->calendar<<")"<<endl;
00334     }
00335     emit calendarModified();
00336 }
00337 
00338 void CalendarListDialogImpl::slotDeleteClicked() {
00339     CalendarListViewItem *item = static_cast<CalendarListViewItem*>(calendarList->selectedItem());
00340     if (item) {
00341         calendarList->takeItem(item);
00342         item->setState(CalendarListViewItem::Deleted);
00343         m_deletedItems.append(item);
00344 
00345         emit enableButtonOk(true);
00346     }
00347 }
00348 
00349 void CalendarListDialogImpl::slotAddClicked() {
00350     Calendar *cal = new Calendar();
00351     cal->setProject(&project);
00352     CalendarListViewItem *item = new CalendarListViewItem(*this, calendarList, cal);
00353     item->setState(CalendarListViewItem::New);
00354     
00355     slotListDoubleClicked(item, QPoint(), 0);
00356     
00357 }
00358 
00359 QPtrList<CalendarListViewItem> &CalendarListDialogImpl::deletedItems() {
00360     return m_deletedItems;
00361 }
00362 
00363 CalendarListViewItem *CalendarListDialogImpl::findItem(Calendar *cal) {
00364     if (!cal)
00365         return 0;
00366     QListViewItemIterator it(calendarList);
00367     for (;it.current(); ++it) {
00368         CalendarListViewItem *item = dynamic_cast<CalendarListViewItem *>(it.current());
00369         if (item && (cal == item->original || cal == item->calendar)) {
00370             //kdDebug()<<k_funcinfo<<"Found: "<<cal->name()<<endl;
00371             return item;
00372         }
00373     }
00374     return 0;
00375 }
00376 
00377 void CalendarListDialogImpl::slotItemRenamed(QListViewItem *itm, int col) {
00378     //kdDebug()<<k_funcinfo<<itm->text(0)<<endl;
00379     itm->setRenameEnabled(col, false);
00380     m_renameItem = 0;
00381     CalendarListViewItem *item = static_cast<CalendarListViewItem*>(itm);
00382     if (item->text(0).isEmpty()) {
00383         item->setText(0, item->oldText); // keep the old name
00384     }
00385     if (item->text(0).isEmpty()) {
00386         // Not allowed
00387         //kdDebug()<<k_funcinfo<<"name empty"<<endl;
00388         emit startRename(item, 0);
00389         return;
00390     }
00391     if (item->text(0) != item->oldText) {
00392         item->setState(CalendarListViewItem::Modified);
00393         item->calendar->setName(item->text(0));
00394     }
00395     renameStopped(item);
00396     slotEnableButtonOk(true);
00397 }
00398 
00399 // We don't get notified when rename is cancelled, this is called from the item
00400 void CalendarListDialogImpl::renameStopped(QListViewItem */*item*/) {
00401     //kdDebug()<<k_funcinfo<<(item?item->text(0):"")<<endl;
00402     m_renameItem = 0;
00403     emit selectionChanged();
00404 }
00405 
00406 void CalendarListDialogImpl::slotListDoubleClicked(QListViewItem *item, const QPoint&, int col) {
00407     //kdDebug()<<k_funcinfo<<(item?item->text(0):"")<<endl;
00408     if (m_renameItem)
00409         return;
00410     slotStartRename(item, col);
00411 }
00412 
00413 void CalendarListDialogImpl::slotRenameStarted(QListViewItem */*item*/, int /*col*/) {
00414     //kdDebug()<<k_funcinfo<<(item?item->text(0):"")<<endl;
00415     if (calendarList->isRenaming()) {
00416         bDelete->setEnabled(false);
00417         bAdd->setEnabled(false);
00418     }
00419 }
00420 
00421 void CalendarListDialogImpl::slotStartRename(QListViewItem *item, int col) {
00422     //kdDebug()<<k_funcinfo<<(item?item->text(0):"")<<endl;
00423     static_cast<CalendarListViewItem*>(item)->oldText = item->text(col);
00424     item->setRenameEnabled(col, true);
00425     item->startRename(col);
00426     m_renameItem = item;
00427     
00428     emit renameStarted(item, col);
00429 }
00430 
00431 }  //KPlato namespace
00432 
00433 #include "kptcalendarlistdialog.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys