/*
    This file is part of KOrganizer.
    Copyright (c) 1999 Preston Brown
    Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include <qlistview.h>
#include <qlayout.h>
#include <qlabel.h>
#include <qpopupmenu.h>
#include <qprogressbar.h>
#include <qfileinfo.h>
#include <qmessagebox.h>
#include <qdialog.h>
#include <qtextstream.h>
#include <qdir.h>
#include <qregexp.h>

#include <klocale.h>
#include <kdebug.h>
#include <kiconloader.h>
#include <kglobal.h>

#include <libkdepim/kpimglobalprefs.h>
#include <libkcal/calendar.h>
#include <libkcal/calendarlocal.h>
#include <libkcal/icalformat.h>
#include <libkcal/vcalformat.h>
#include <libkcal/recurrence.h>
#include <libkcal/filestorage.h>
#include <libkdepim/categoryselectdialog.h>
#ifndef DESKTOP_VERSION
#include <qpe/qpeapplication.h>
#else
#include <qapplication.h>
#endif

#ifndef KORG_NOPRINTER
#include "calprinter.h"
#endif
#include "koglobals.h"
#include "koprefs.h"
#include "kfiledialog.h"

#include "kolistview.h"

ListItemVisitor::ListItemVisitor(KOListViewItem *item, QDate date )
{
    mItem = item;
    mDate = date;
}

ListItemVisitor::~ListItemVisitor()
{
}

bool ListItemVisitor::visit(Event *e)
{
    
    bool ok = false;
    QString start, end;
    QDate ds, de;
    if ( e->doesRecur() ) {
        ds = e->getNextOccurence( QDateTime( mDate, QTime(0,0,0)), &ok ).date();
        if ( ok ) {
            int days = e->dtStart().date().daysTo(e->dtEnd().date() );
            start = KGlobal::locale()->formatDate(ds,true);
            de = ds.addDays( days);
            end = KGlobal::locale()->formatDate(de,true);
        }

    } 
    if ( ! ok ) {
        start =e->dtStartDateStr();
        end = e->dtEndDateStr();
        ds = e->dtStart().date();
        de = e->dtEnd().date();
    }
    mItem->setText(0,e->summary());
    mItem->setText(1,start);
    mItem->setText(2,e->dtStartTimeStr());
    mItem->setText(3,end);
    mItem->setText(4,e->dtEndTimeStr());
    mItem->setText(5,e->isAlarmEnabled() ? i18n("Yes") : i18n("No"));
    mItem->setText(6, e->recurrence()->recurrenceText());
    mItem->setText(7,"---");
    mItem->setText(8,"---");
    mItem->setText(9, e->cancelled() ? i18n("Yes") : i18n("No"));
    mItem->setText(10,e->categoriesStr());

    QString key;
    QTime t = e->doesFloat() ? QTime(0,0) : e->dtStart().time();
    key.sprintf("%04d%02d%02d%02d%02d",ds.year(),ds.month(),ds.day(),t.hour(),t.minute());
    mItem->setSortKey(1,key);

    t = e->doesFloat() ? QTime(0,0) : e->dtEnd().time();
    key.sprintf("%04d%02d%02d%02d%02d",de.year(),de.month(),de.day(),t.hour(),t.minute());
    mItem->setSortKey(3,key);

    return true;
}

bool ListItemVisitor::visit(Todo *t)
{
    mItem->setText(0,i18n("To-Do: %1").arg(t->summary()));
    if (t->hasStartDate()) {
        mItem->setText(1,t->dtStartDateStr());
        if (t->doesFloat()) {
            mItem->setText(2,"---");
        } else {
            mItem->setText(2,t->dtStartTimeStr());
        }
    } else {
        mItem->setText(1,"---");
        mItem->setText(2,"---");
    }
    mItem->setText(3,"---");
    mItem->setText(4,"---");
    mItem->setText(5,t->isAlarmEnabled() ? i18n("Yes") : i18n("No"));
    mItem->setText(6,"---");
    if (t->hasDueDate()) {
        mItem->setText(7,t->dtDueDateStr());
        if (t->doesFloat()) {
            mItem->setText(8,"---");
        } else {
            mItem->setText(8,t->dtDueTimeStr());
        }
    } else {
        mItem->setText(7,"---");
        mItem->setText(8,"---");
    }
    mItem->setText(9, t->cancelled() ? i18n("Yes") : i18n("No"));
    mItem->setText(10,t->categoriesStr());

    QString key;
    QDate d;
    if (t->hasDueDate()) {
        d = t->dtDue().date();
        QTime tm = t->doesFloat() ? QTime(0,0) : t->dtDue().time();
        key.sprintf("%04d%02d%02d%02d%02d",d.year(),d.month(),d.day(),tm.hour(),tm.minute());
        mItem->setSortKey(7,key);
    }
    if ( t->hasStartDate() ) {
        d = t->dtStart().date();
        QTime tm = t->doesFloat() ? QTime(0,0) : t->dtStart().time();
        key.sprintf("%04d%02d%02d%02d%02d",d.year(),d.month(),d.day(),tm.hour(),tm.minute());
        mItem->setSortKey(1,key);
    }
    return true;
}

bool ListItemVisitor::visit(Journal * j)
{ 
    QString des = j->description().left(50);
    des = des.simplifyWhiteSpace ();
    des.replace (QRegExp ("\\n"),"" );
    des.replace (QRegExp ("\\r"),"" );
    mItem->setText(0,i18n("Journal")+": "+des.left(25));
    mItem->setText(1,j->dtStartDateStr());
    mItem->setText(2,"---");
    mItem->setText(3,"---");
    mItem->setText(4,"---");
    mItem->setText(5,"---");
    mItem->setText(6,"---");
    mItem->setText(7,j->dtStartDateStr());
    mItem->setText(8,"---");
    mItem->setText(9,"---");
    mItem->setText(10,i18n("Last Modified: ")+  KGlobal::locale()->formatDateTime( j->lastModified() , true) );

    QString key;
    QDate d = j->dtStart().date();
    key.sprintf("%04d%02d%02d",d.year(),d.month(),d.day());
    mItem->setSortKey(1,key);
    mItem->setSortKey(7,key);

    return true;
}

KOListView::KOListView(Calendar *calendar, QWidget *parent,
                       const char *name)
    : KOEventView(calendar, parent, name)
{
    mActiveItem = 0;
    mListView = new KOListViewListView(this);
    mListView->addColumn(i18n("Summary"));
    mListView->addColumn(i18n("Start Date"));
    mListView->addColumn(i18n("Start Time"));
    mListView->addColumn(i18n("End Date"));
    mListView->addColumn(i18n("End Time"));
    mListView->addColumn(i18n("Alarm")); // alarm set?
    mListView->addColumn(i18n("Recurs")); // recurs?
    mListView->addColumn(i18n("Due Date"));
    mListView->addColumn(i18n("Due Time"));
    mListView->addColumn(i18n("Cancelled"));
    mListView->addColumn(i18n("Categories"));

    mListView->setColumnAlignment(0,AlignLeft);
    mListView->setColumnAlignment(1,AlignLeft);
    mListView->setColumnAlignment(2,AlignHCenter);
    mListView->setColumnAlignment(3,AlignLeft);
    mListView->setColumnAlignment(4,AlignHCenter);
    mListView->setColumnAlignment(5,AlignLeft);
    mListView->setColumnAlignment(6,AlignLeft);
    mListView->setColumnAlignment(7,AlignLeft);
    mListView->setColumnAlignment(8,AlignLeft);
    mListView->setColumnAlignment(9,AlignLeft);
    mListView->setColumnAlignment(10,AlignLeft);
    mListView->setColumnWidthMode(10, QListView::Manual);

    int iii = 0;
    for ( iii = 0; iii< 10 ; ++iii )
        mListView->setColumnWidthMode( iii, QListView::Manual );

    QBoxLayout *layoutTop = new QVBoxLayout(this);
    layoutTop->addWidget(mListView);
    mListView->setFont ( KOPrefs::instance()->mListViewFont );
    mPopupMenu = eventPopup();
    mPopupMenu->addAdditionalItem(QIconSet(QPixmap()),
                                  i18n("Select all"),this,
                                  SLOT(allSelection()),true);
    mPopupMenu->addAdditionalItem(QIconSet(QPixmap()),
                                  i18n("Deselect All"),this,
                                  SLOT(clearSelection()),true);
    mPopupMenu->addAdditionalItem(QIconSet(QPixmap()),
                                  i18n("Delete all selected"),this,
                                  SLOT(deleteAll()),true);
    mPopupMenu->insertSeparator();
    mPopupMenu->addAdditionalItem(QIconSet(QPixmap()),
                                  i18n("Save selected to file..."),this,
                                  SLOT(saveToFile()),true);
    mPopupMenu->addAdditionalItem(QIconSet(QPixmap()),
                                  i18n("Save Journal/Description..."),this,
                                  SLOT(saveDescriptionToFile()),true);
    mPopupMenu->insertSeparator();
    mPopupMenu->addAdditionalItem(QIconSet(QPixmap()),
                                  i18n("Add Categ. to selected..."),this,
                                  SLOT(addCat()),true);
    mPopupMenu->addAdditionalItem(QIconSet(QPixmap()),
                                  i18n("Set Categ. for selected..."),this,
                                  SLOT(setCat()),true);
    mPopupMenu->insertSeparator();


#ifndef DESKTOP_VERSION
    mPopupMenu->addAdditionalItem(QIconSet(QPixmap()),
                                  i18n("Beam selected via IR"),this,
                                  SLOT(beamSelected()),true);
#endif
    /*
      mPopupMenu = new QPopupMenu;
      mPopupMenu->insertItem(i18n("Edit Event"), this,
      SLOT (editEvent()));
      mPopupMenu->insertItem(SmallIcon("delete"), i18n("Delete Event"), this,
      SLOT (deleteEvent()));
      mPopupMenu->insertSeparator();
      mPopupMenu->insertItem(i18n("Show Dates"), this,
      SLOT(showDates()));
      mPopupMenu->insertItem(i18n("Hide Dates"), this,
      SLOT(hideDates()));
    */
    QObject::connect(mListView,SIGNAL( newEvent()),
                     this,SIGNAL(signalNewEvent()));
    QObject::connect(mListView,SIGNAL(doubleClicked(QListViewItem *)),
                     this,SLOT(defaultItemAction(QListViewItem *)));
    QObject::connect(mListView,SIGNAL(rightButtonClicked ( QListViewItem *,
                                                           const QPoint &, int )),
                     this,SLOT(popupMenu(QListViewItem *,const QPoint &,int)));
    QObject::connect(mListView,SIGNAL(currentChanged(QListViewItem *)),
                     SLOT(processSelectionChange(QListViewItem *)));
    QObject::connect(mListView,SIGNAL(showIncidence(Incidence *)),
                     SIGNAL(showIncidenceSignal(Incidence *)) );

    readSettings(KOGlobals::config(),"KOListView Layout");
}

KOListView::~KOListView()
{
    delete mPopupMenu;
}

void KOListView::updateList()
{
    // qDebug(" KOListView::updateList() ");

}

void KOListView::addCat( )
{
    setCategories( false );
}
void KOListView::setCat()
{
    setCategories( true );
}
void KOListView::setCategories( bool removeOld )
{
   
    KPIM::CategorySelectDialog* csd = new KPIM::CategorySelectDialog( KOPrefs::instance(), 0 );
    if (! csd->exec()) { 
        delete csd;
        return;
    }
    QStringList catList = csd->selectedCategories();
    delete csd;
    // if ( catList.count() == 0 )
    //   return;
    catList.sort();
    QString categoriesStr = catList.join(",");
    int i;
    QStringList itemList;
    QPtrList<KOListViewItem> sel ;
    QListViewItem *qitem  = mListView->firstChild ();
    while ( qitem ) {
        if ( qitem->isSelected() ) {
            sel.append(((KOListViewItem *)qitem));
        }
        qitem = qitem->nextSibling();
    }
    KOListViewItem * item, *temp;
    item = sel.first();
    Incidence* inc;
    while ( item ) {
        inc = item->data();
        if ( removeOld ) {
            inc->setCategories( categoriesStr );
        } else {
            itemList = QStringList::split (",", inc->categoriesStr() );
            for( i = 0; i<   catList.count(); ++i ) {
                if (  !itemList.contains (catList[i]))
                    itemList.append( catList[i] );
            }
            itemList.sort();
            inc->setCategories( itemList.join(",") );
        }
        temp = item;
        item = sel.next();
        mUidDict.remove( inc->uid() ); 
        delete temp;;
        addIncidence( inc );
    }
}

void KOListView::beamSelected()
{
    int icount = 0;
    QPtrList<Incidence> delSel ;
    QListViewItem *item  = mListView->firstChild ();
    while ( item ) {
        if ( item->isSelected() ) {
            delSel.append(((KOListViewItem *)item)->data());
            ++icount;
        }
        
        item = item->nextSibling();
    }
    if ( icount ) {
        emit beamIncidenceList( delSel );
        return;
        QString fn ;
        fn = QDir::homeDirPath()+"/kopitempbeamfile.vcs";
        QString mes;
        bool createbup = true;
        if ( createbup ) {
            QString description = "\n";
            CalendarLocal* cal = new CalendarLocal();
            cal->setTimeZoneId(KPimGlobalPrefs::instance()->mTimeZoneId);
            Incidence *incidence = delSel.first();
            while ( incidence ) {
                Incidence *in = incidence->clone();
                description += in->summary() + "\n";
                cal->addIncidence( in );
                incidence = delSel.next();
            }
            FileStorage storage( cal, fn, new VCalFormat );
            storage.save();
            delete cal;
            mes = i18n("KO/Pi: Ready for beaming");
            topLevelWidget()->setCaption(mes); 

#ifndef DESKTOP_VERSION
            Ir *ir = new Ir( this ); 
            connect( ir, SIGNAL( done( Ir * ) ), this, SLOT( beamDone( Ir * ) ) );
            ir->send( fn, description, "text/x-vCalendar" );
#endif
        }
    }
}
void KOListView::beamDone( Ir *ir )
{
#ifndef DESKTOP_VERSION
    delete ir;
#endif
    topLevelWidget()->setCaption(i18n("KO/Pi:Beaming done")); 
}

void KOListView::saveDescriptionToFile()
{

    int result = QMessageBox::warning( this, i18n("KO/Pi: Warning!"),
                                       i18n("This saves the text/details of selected\nJournals and Events/Todos\nto a text file."),
                                       i18n("Continue"), i18n("Cancel"), 0,
                                       0, 1 );
    if ( result != 0 ) {
        return;
    }
  int icount = 0;
    QPtrList<Incidence> delSel ;
    QListViewItem *item  = mListView->firstChild ();
    while ( item ) {
        if ( item->isSelected() ) {
            delSel.append(((KOListViewItem *)item)->data());
            ++icount;
        }
        
        item = item->nextSibling();
    }
    if ( icount ) {
        QString fn =  KOPrefs::instance()->mLastSaveFile;
        fn =  KFileDialog::getSaveFileName( fn, i18n("Save filename"), this );
    
        if ( fn == "" )
            return;
        QFileInfo info;
        info.setFile( fn );
        QString mes;
        bool createbup = true;
        if ( info. exists() ) { 
            mes =  i18n("File already exists!\nOld file from:\n%1\nOverwrite?\n").arg (KGlobal::locale()->formatDateTime(info.lastModified (), true, false )  );
            int result = QMessageBox::warning( this, i18n("KO/Pi: Warning!"),mes,
                                               i18n("Overwrite!"), i18n("Cancel"), 0,
                                               0, 1 );
            if ( result != 0 ) {
                createbup = false;
            }
        }
        if ( createbup ) {
            QString text = i18n("KO/Pi Description/Journal save file.\nSave date: ") + 
                KGlobal::locale()->formatDateTime(QDateTime::currentDateTime(), false);
            Incidence *incidence = delSel.first();
            icount = 0;
            while ( incidence ) {
                if ( incidence->type()  == "Journal" ) {
                    text += "\n************************************\n";
                    text += i18n("Journal from: ") +incidence->dtStartDateStr( false );
                    text +="\n" +  i18n("Last modified: ") +KGlobal::locale()->formatDateTime(incidence->lastModified(), false);
                    text +="\n" +  i18n("Description: ") + "\n"+ incidence->description();
                    ++icount;

                } else {
                    if ( !incidence->description().isEmpty() ) {
                        text += "\n************************************\n";
                        if ( incidence->type()  == "Todo" )
                            text += i18n("To-Do: ");
                        text += incidence->summary();
                        if ( incidence->hasStartDate() )
                            text +="\n"+ i18n("Start Date: ") + incidence->dtStartStr( false );
                        text +="\n"+ i18n("Last modified: ") +KGlobal::locale()->formatDateTime(incidence->lastModified(), false);
                        if ( !incidence->location().isEmpty() )
                            text += "\n" +i18n("Location: ") + incidence->location();
                        text += "\n" + i18n("Description: ") + "\n" + incidence->description();
                        ++icount;

                    }
                }
                incidence = delSel.next();
            }
            QFile file( fn );
            if (!file.open( IO_WriteOnly ) ) {
                topLevelWidget()->setCaption(i18n("File open error - nothing saved!") ); 
                return;
            }  
            QTextStream ts( &file );
            ts << text;
            file.close();
            //qDebug("%s ", text.latin1());
            mes = i18n("KO/Pi:Saved %1 descriptions/journals").arg(icount );
            KOPrefs::instance()->mLastSaveFile = fn;
            topLevelWidget()->setCaption(mes); 
        }
    }
}
void KOListView::saveToFile()
{

    int icount = 0;
    QPtrList<Incidence> delSel ;
    QListViewItem *item  = mListView->firstChild ();
    while ( item ) {
        if ( item->isSelected() ) {
            delSel.append(((KOListViewItem *)item)->data());
            ++icount;
        }
        
        item = item->nextSibling();
    }
    if ( icount ) {
        QString fn =  KOPrefs::instance()->mLastSaveFile;
        fn =  KFileDialog::getSaveFileName( fn, i18n("Save filename"), this );
    
        if ( fn == "" )
            return;
        QFileInfo info;
        info.setFile( fn );
        QString mes;
        bool createbup = true;
        if ( info. exists() ) { 
            mes =  i18n("File already exists!\nOld file from:\n%1\nOverwrite?\n").arg (KGlobal::locale()->formatDateTime(info.lastModified (), true, false )  );
            int result = QMessageBox::warning( this, i18n("KO/Pi: Warning!"),mes,
                                               i18n("Overwrite!"), i18n("Cancel"), 0,
                                               0, 1 );
            if ( result != 0 ) {
                createbup = false;
            }
        }
        if ( createbup ) {
            CalendarLocal cal;
            cal.setTimeZoneId(KPimGlobalPrefs::instance()->mTimeZoneId);
            Incidence *incidence = delSel.first();
            while ( incidence ) {
                cal.addIncidence( incidence->clone() );
                incidence = delSel.next();
            }
            ICalFormat format;
            format.save( &cal, fn );
            mes = i18n("KO/Pi:Saved %1").arg(fn );
            KOPrefs::instance()->mLastSaveFile = fn;
            topLevelWidget()->setCaption(mes); 
        }
    }
}
void KOListView::deleteAll()
{
    int icount = 0;
    QPtrList<Incidence> delSel ;
    QListViewItem *item  = mListView->firstChild ();
    while ( item ) {
        if ( item->isSelected() ) {
            delSel.append(((KOListViewItem *)item)->data());
            ++icount;
        }
        
        item = item->nextSibling();
    }
    if ( icount ) {
        Incidence *incidence = delSel.first();
        Incidence *toDelete;   
        KOPrefs *p = KOPrefs::instance();
        bool confirm = p->mConfirm;
        QString mess;
        mess = mess.sprintf( i18n("You have %d item(s) selected.\n"), icount );
        if ( KMessageBox::Continue == KMessageBox::warningContinueCancel(this, mess + i18n("All selected items will be\npermanently deleted.\n(Deleting items will take\nsome time on a PDA)\n"), i18n("KO/Pi Confirmation"),i18n("Delete")) ) {
            p->mConfirm = false;
            int delCounter = 0;
            QDialog dia ( this, "p-dialog", true ); 
            QLabel lab (i18n("Close dialog to abort deletion!"), &dia ); 
            QVBoxLayout lay( &dia );
            lay.setMargin(7); 
            lay.setSpacing(7); 
            lay.addWidget( &lab);
            QProgressBar bar( icount, &dia );
            lay.addWidget( &bar);
            int w = 220;
            int h = 50;
            int dw = QApplication::desktop()->width();
            int dh = QApplication::desktop()->height();
            dia.setGeometry( (dw-w)/2, (dh - h )/2 ,w,h );
            //dia.resize( 240,50 );
            dia.show();
            
            while ( incidence ) {
                bar.setProgress( delCounter );
                mess = mess.sprintf( i18n("Deleting item %d ..."), ++delCounter );
                dia.setCaption( mess );
                qApp->processEvents();
                toDelete =  (incidence);
                incidence = delSel.next();
                emit deleteIncidenceSignal(toDelete ); 
                if (  dia.result() != 0 )
                    break;
               
            }
            mess = mess.sprintf( i18n("%d items remaining in list."), count() );
            topLevelWidget ()->setCaption( mess );
            p->mConfirm = confirm;
        }    
    }  
        

}
int KOListView::maxDatesHint()
{
    return 0;
}

int KOListView::currentDateCount()
{
    return 0;
}

QPtrList<Incidence> KOListView::selectedIncidences()
{
    QPtrList<Incidence> eventList;
    QListViewItem *item  = mListView->firstChild ();
    while ( item ) {
        if ( item->isSelected() ) {
            eventList.append(((KOListViewItem *)item)->data());
        }

        item = item->nextSibling();
    }

    //  // QListViewItem *item = mListView->selectedItem();
    //if (item) eventList.append(((KOListViewItem *)item)->data());

    return eventList;
}

DateList KOListView::selectedDates()
{
    DateList eventList;
    return eventList;
}

void KOListView::showDates(bool show)
{
    // Shouldn't we set it to a value greater 0? When showDates is called with
    // show == true at first, then the columnwidths are set to zero.
    static int oldColWidth1 = 0;
    static int oldColWidth3 = 0;

    if (!show) {
        oldColWidth1 = mListView->columnWidth(1);
        oldColWidth3 = mListView->columnWidth(3);
        mListView->setColumnWidth(1, 0);
        mListView->setColumnWidth(3, 0);
    } else {
        mListView->setColumnWidth(1, oldColWidth1);
        mListView->setColumnWidth(3, oldColWidth3);
    }
    mListView->repaint();
}

void KOListView::printPreview(CalPrinter *calPrinter, const QDate &fd,
                              const QDate &td)
{
#ifndef KORG_NOPRINTER
    calPrinter->preview(CalPrinter::Day, fd, td);
#endif
}

void KOListView::showDates()
{
    showDates(true);
}

void KOListView::hideDates()
{
    showDates(false);
}

void KOListView::updateView()
{
    mListView->setFocus();
    if ( mListView->firstChild () )
        mListView->setCurrentItem( mListView->firstChild () );
}
void KOListView::updateConfig()
{

    mListView->setFont ( KOPrefs::instance()->mListViewFont );
    updateView();

}
void KOListView::setStartDate(const QDate &start)
{
    mStartDate = start;
}

void KOListView::showDates(const QDate &start, const QDate &end)
{
    clear();
    mStartDate = start;
    QDate date = start;
    QPtrList<Journal> j_list;
    while( date <= end ) {
        addEvents(calendar()->events(date));
        addTodos(calendar()->todos(date));
        Journal* jo = calendar()->journal(date);
        if ( jo )
            j_list.append( jo );
        date = date.addDays( 1 );
    }
    addJournals(j_list);
    emit incidenceSelected( 0 );
    updateView();
  
}

void KOListView::addEvents(QPtrList<Event> eventList)
{
    Event *ev;
    for(ev = eventList.first(); ev; ev = eventList.next()) {
        addIncidence(ev);
    }
    if ( !mListView->currentItem() ){
        updateView();
    }
}

void KOListView::addTodos(QPtrList<Todo> eventList)
{
    Todo *ev;
    for(ev = eventList.first(); ev; ev = eventList.next()) {
        addIncidence(ev);
    }
    if ( !mListView->currentItem() ){
        updateView();
    }
}
void KOListView::addJournals(QPtrList<Journal> eventList)
{
    Journal *ev;
    for(ev = eventList.first(); ev; ev = eventList.next()) {
        addIncidence(ev);
    }  
    if ( !mListView->currentItem() ){
        updateView();
    }
}

void KOListView::addIncidence(Incidence *incidence)
{
    if ( mUidDict.find( incidence->uid() ) ) return;
  
    // mListView->setFont ( KOPrefs::instance()->mListViewFont );
    mUidDict.insert( incidence->uid(), incidence );

    KOListViewItem *item = new KOListViewItem( incidence, mListView ); 
    ListItemVisitor v(item, mStartDate );
    if (incidence->accept(v)) return;
    else delete item;
    //qDebug("delete item ");
}

void KOListView::showEvents(QPtrList<Event> eventList)
{
    clear();

    addEvents(eventList);

    // After new creation of list view no events are selected.
    emit incidenceSelected( 0 );
}
int KOListView::count()
{
    return mListView->childCount();
}

void KOListView::changeEventDisplay(Event *event, int action)
{
    KOListViewItem *item;

    switch(action) {
    case KOGlobals::EVENTADDED:
        addIncidence( event );
        break;
    case KOGlobals::EVENTEDITED:
        item = getItemForEvent(event);
        if (item) { 
            mUidDict.remove( event->uid() ); 
            delete item;
            addIncidence( event );
        }
        break;
    case KOGlobals::EVENTDELETED:
        item = getItemForEvent(event);
        if (item) {
            mUidDict.remove( event->uid() ); 
            delete item;
        }
        break;
    default:
        ;
    }
}

KOListViewItem *KOListView::getItemForEvent(Event *event)
{
    KOListViewItem *item = (KOListViewItem *)mListView->firstChild();
    while (item) {
        if (item->data() == event) return item;
        item = (KOListViewItem *)item->nextSibling();
    }
    return 0;
}

void KOListView::defaultItemAction(QListViewItem *i)
{
    KOListViewItem *item = static_cast<KOListViewItem *>( i );
    if ( item ) defaultAction( item->data() );
      
}

void KOListView::popupMenu(QListViewItem *item,const QPoint &,int)
{
    mActiveItem = (KOListViewItem *)item;
    if (mActiveItem) {
        Incidence *incidence = mActiveItem->data();
        mPopupMenu->showIncidencePopup(incidence);

        /*
          if ( incidence && incidence->type() == "Event" ) {
          Event *event = static_cast<Event *>( incidence );
          mPopupMenu->showEventPopup(event);
          }
        */
    }
}

void KOListView::readSettings(KConfig *config, QString setting)
{
    //  qDebug("KOListView::readSettings ");
    mListView->restoreLayout(config,setting);
}

void KOListView::writeSettings(KConfig *config, QString setting)
{
    // qDebug("KOListView::writeSettings ");
    mListView->saveLayout(config, setting);
}

void KOListView::processSelectionChange(QListViewItem *)
{
  
    KOListViewItem *item =
        static_cast<KOListViewItem *>( mListView->currentItem() );

    if ( !item ) {
        emit incidenceSelected( 0 );
    } else {
        emit incidenceSelected( item->data() );
    }
}

void KOListView::clearSelection()
{
    mListView->selectAll( false );
}
void KOListView::allSelection()
{
    mListView->selectAll( true );
}

void KOListView::clear()
{
    mListView->clear();
    mUidDict.clear();
}

Incidence* KOListView::currentItem()
{
    if ( mListView->currentItem()  )
        return ((KOListViewItem*) mListView->currentItem())->data();
    return 0;
}
void KOListView::keyPressEvent ( QKeyEvent *e) 
{
   
    if (  e->key() == Qt::Key_Delete || e->key() == Qt::Key_Backspace ) {
        deleteAll();
        return;
    }
   
    e->ignore();
}
void KOListViewListView::keyPressEvent ( QKeyEvent *e) 
{
  
    switch ( e->key() ) {
    case Qt::Key_Down:
        if ( e->state() == ShiftButton ) {
            QListViewItem* cn = currentItem();
            if ( !cn ) 
                cn = firstChild();
            if ( !cn ) 
                return;
            while (  cn->nextSibling() )
                cn = cn->nextSibling();
            setCurrentItem ( cn );
            ensureItemVisible ( cn );
        
            e->accept();
            return;
        }
        if ( e->state() == ControlButton ) {
            int count = childCount ();
            int jump = count / 5;
            QListViewItem* cn;
            cn = currentItem();
            if ( ! cn )
                return;
            if ( jump  == 0 )
                jump = 1;
            while ( jump && cn->nextSibling() ) {
                cn = cn->nextSibling();
                --jump;
            }
            setCurrentItem ( cn );
            ensureItemVisible ( cn );
            
        } else
            QListView::keyPressEvent ( e ) ;
        e->accept();
        break;
              
    case Qt::Key_Up:
        if ( e->state() == ShiftButton ) {
            QListViewItem* cn = firstChild();
            if ( cn ) {
                setCurrentItem ( cn );
                ensureItemVisible ( cn );
            }
            e->accept();
            return;
        }
        if ( e->state() == ControlButton ) {
            int count = childCount ();
            int jump = count / 5;
            QListViewItem* cn;
            cn = currentItem();
            if ( ! cn )
                return;
            if ( jump  == 0 )
                jump = 1;
            while ( jump && cn->itemAbove ()) {
                cn = cn->itemAbove ();
                --jump;
            }
            setCurrentItem ( cn );
            ensureItemVisible ( cn );
        } else
            QListView::keyPressEvent ( e ) ;
        e->accept();
        break;   
    case Qt::Key_I: {
        QListViewItem* cn;
        cn = currentItem();
        if ( cn ) {
            KOListViewItem* ci = (KOListViewItem*)( cn ); 
            if ( ci ){
                emit showIncidence( ci->data());
                cn = cn->nextSibling();
                if ( cn ) {
                    setCurrentItem ( cn );
                    ensureItemVisible ( cn );
                }
            }
        }
        e->accept();
    }
        break;          
    case Qt::Key_Return:
    case Qt::Key_Enter:
        {
            QListViewItem* cn;
            cn = currentItem();
            if ( cn ) {
                KOListViewItem* ci = (KOListViewItem*)( cn ); 
                if ( ci ){ 
                    if ( e->state() == ShiftButton )
                        ci->setSelected( false );
                    else
                        ci->setSelected( true );
                    cn = cn->nextSibling();
                    if ( cn ) {
                        setCurrentItem ( cn );
                        ensureItemVisible ( cn );
                    }
                }
            }
            e->accept();
        }
    break;             
    default:
        e->ignore();
    }
}
KOListViewListView::KOListViewListView(KOListView * lv ) 
    : KListView( lv )
{
#ifndef DESKTOP_VERSION
    QPEApplication::setStylusOperation(viewport(), QPEApplication::RightOnHold );
#endif
    mYMousePos = -1000;
    setSelectionMode( QListView::Multi );   
    setMultiSelection( true);
    mAllowPopupMenu = true;
    mMouseDown = false;
    
}
void KOListViewListView::contentsMouseDoubleClickEvent(QMouseEvent *e)
{
    if (!e) return;
    QPoint vp = contentsToViewport(e->pos());
    QListViewItem *item = itemAt(vp);
    if (!item) {
        emit newEvent();
        return;
    }
    KListView::contentsMouseDoubleClickEvent(e);
}


void KOListViewListView::contentsMousePressEvent(QMouseEvent *e)
{
    //qDebug("contentsMousePressEvent++++ ");
    if (! mMouseDown ) {
        mAllowPopupMenu = true;
        mYMousePos = mapToGlobal( (e->pos())).y();
    }
    if (  e->button() == RightButton &&  mMouseDown   )
        return;
    if (  e->button() == LeftButton )
        mMouseDown = true;
    KListView::contentsMousePressEvent( e );
}
void KOListViewListView::contentsMouseReleaseEvent(QMouseEvent *e)
{
    //qDebug("contentsMouseReleaseEv---- ");
    if ( ! mMouseDown  ) {
        if (  e->button() == RightButton && ! mAllowPopupMenu   )
            return;
        QListViewItem* ci = currentItem(); 
        if ( ci ) 
            ci->setSelected( true );
        KListView::contentsMouseReleaseEvent(e);
        return;
    }
    if (  e->button() == LeftButton )
        mMouseDown = false;   
    if (  e->button() == RightButton && ! mAllowPopupMenu   )
        return;
    if (  e->button() == RightButton ) {
        QListViewItem* ci = currentItem(); 
        if ( ci ) 
            ci->setSelected( true );
    }
    KListView::contentsMouseReleaseEvent(e);
}
void KOListViewListView::contentsMouseMoveEvent(QMouseEvent *e)
{
    // qDebug("contentsMouseMoveEv....... ");
    //  qDebug("start: %d  current %d ",mYMousePos , mapToGlobal( (e->pos())).y()   );
    int diff = mYMousePos - mapToGlobal( (e->pos())).y();
    if ( diff < 0 ) diff = -diff;
    if ( diff > 20 )
        mAllowPopupMenu = false;
    KListView::contentsMouseMoveEvent(e);
}