You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdepim/korganizer/kolistview.cpp

508 lines
14 KiB

/*
This file is part of KOrganizer.
Copyright (c) 1999 Preston Brown <pbrown@kde.org>
Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org>
Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
As a special exception, permission is given to link this program
with any edition of TQt, and distribute the resulting executable,
without including the source code for TQt in the source distribution.
*/
#include <tqlistview.h>
#include <tqlayout.h>
#include <tqpopupmenu.h>
#include <tqcursor.h>
#include <tqstyle.h>
#include <tdelocale.h>
#include <kdebug.h>
#include <kiconloader.h>
#include <tdeglobal.h>
#include <libkcal/calendar.h>
#include <libkcal/incidenceformatter.h>
#include "koglobals.h"
#include "koprefs.h"
#include "koincidencetooltip.h"
#include "koeventpopupmenu.h"
#include "kolistview.h"
#include "kolistview.moc"
enum {
Summary_Column = 0,
Reminder_Column,
Recurs_Column,
StartDateTime_Column,
EndDateTime_Column,
Categories_Column
};
KOListViewToolTip::KOListViewToolTip( TQWidget* parent,
Calendar *calendar,
TDEListView *lv )
:TQToolTip( parent ), mCalendar( calendar )
{
eventlist = lv;
}
void KOListViewToolTip::maybeTip( const TQPoint &pos )
{
TQRect r;
TQListViewItem *it = eventlist->itemAt( pos );
KOListViewItem *i = static_cast<KOListViewItem*>( it );
if ( i && KOPrefs::instance()->mEnableToolTips ) {
/* Calculate the rectangle. */
r = eventlist->itemRect( it );
/* Show the tip */
TQString tipText( IncidenceFormatter::toolTipStr( mCalendar, i->data() ) );
if ( !tipText.isEmpty() ) {
tip( r, tipText );
}
}
}
/**
This class provides the initialization of a KOListViewItem for calendar
components using the Incidence::Visitor.
*/
class KOListView::ListItemVisitor : public IncidenceBase::Visitor
{
public:
ListItemVisitor( KOListViewItem *item ) : mItem( item ) {}
~ListItemVisitor() {}
bool visit( Event * );
bool visit( Todo * );
bool visit( Journal * );
private:
KOListViewItem *mItem;
};
bool KOListView::ListItemVisitor::visit( Event *e )
{
mItem->setText( Summary_Column, e->summary() );
if ( e->isAlarmEnabled() ) {
static const TQPixmap alarmPxmp = KOGlobals::self()->smallIcon( "bell" );
mItem->setPixmap( Reminder_Column, alarmPxmp );
mItem->setSortKey( Reminder_Column, "1" );
} else {
mItem->setSortKey( Reminder_Column, "0" );
}
if ( e->doesRecur() ) {
static const TQPixmap recurPxmp = KOGlobals::self()->smallIcon( "recur" );
mItem->setPixmap( Recurs_Column, recurPxmp );
mItem->setSortKey( Recurs_Column, "1" );
} else {
mItem->setSortKey( Recurs_Column, "0" );
}
TQPixmap eventPxmp;
if ( e->customProperty( "KABC", "BIRTHDAY" ) == "YES" ) {
if ( e->customProperty( "KABC", "ANNIVERSARY" ) == "YES" ) {
eventPxmp = KOGlobals::self()->smallIcon( "calendaranniversary" );
} else {
eventPxmp = KOGlobals::self()->smallIcon( "calendarbirthday" );
}
} else {
eventPxmp = KOGlobals::self()->smallIcon( "appointment" );
}
mItem->setPixmap( Summary_Column, eventPxmp );
TQString startDateTime;
TQString endDateTime;
mItem->setText( StartDateTime_Column, IncidenceFormatter::dateTimeToString( e->dtStart(), e->doesFloat() ) );
mItem->setSortKey( StartDateTime_Column, e->dtStart().toString( TQt::ISODate ) );
mItem->setText( EndDateTime_Column, IncidenceFormatter::dateTimeToString( e->dtEnd(), e->doesFloat() ) );
mItem->setSortKey( EndDateTime_Column, e->dtEnd().toString( TQt::ISODate ) );
mItem->setText( Categories_Column, e->categoriesStr() );
return true;
}
bool KOListView::ListItemVisitor::visit( Todo *t )
{
static const TQPixmap todoPxmp = KOGlobals::self()->smallIcon( "todo" );
static const TQPixmap todoDonePxmp = KOGlobals::self()->smallIcon( "checkedbox" );
mItem->setPixmap(Summary_Column, t->isCompleted() ? todoDonePxmp : todoPxmp );
mItem->setText(Summary_Column, t->summary());
if ( t->isAlarmEnabled() ) {
static const TQPixmap alarmPxmp = KOGlobals::self()->smallIcon( "bell" );
mItem->setPixmap( Reminder_Column, alarmPxmp );
mItem->setSortKey( Reminder_Column, "1" );
} else {
mItem->setSortKey( Reminder_Column, "0" );
}
if ( t->doesRecur() ) {
static const TQPixmap recurPxmp = KOGlobals::self()->smallIcon( "recur" );
mItem->setPixmap( Recurs_Column, recurPxmp );
mItem->setSortKey( Recurs_Column, "1" );
} else {
mItem->setSortKey( Recurs_Column, "0" );
}
if ( t->hasStartDate() ) {
mItem->setText( StartDateTime_Column, IncidenceFormatter::dateTimeToString( t->dtStart(), t->doesFloat() ) );
mItem->setSortKey( StartDateTime_Column, t->dtStart().toString( TQt::ISODate ) );
} else {
mItem->setText( StartDateTime_Column, "---" );
}
if ( t->hasDueDate() ) {
mItem->setText( EndDateTime_Column, IncidenceFormatter::dateTimeToString( t->dtDue(), t->doesFloat() ) );
mItem->setSortKey( EndDateTime_Column, t->dtDue().toString( TQt::ISODate ) );
} else {
mItem->setText( EndDateTime_Column, "---" );
}
mItem->setText( Categories_Column, t->categoriesStr() );
return true;
}
bool KOListView::ListItemVisitor::visit( Journal *j )
{
static const TQPixmap jornalPxmp = KOGlobals::self()->smallIcon( "journal" );
mItem->setPixmap( Summary_Column, jornalPxmp );
// Just use the first line
mItem->setText( Summary_Column, j->description().section( "\n", 0, 0 ) );
mItem->setText( StartDateTime_Column, IncidenceFormatter::dateTimeToString( j->dtStart(), j->doesFloat() ) );
mItem->setSortKey( StartDateTime_Column, j->dtStart().toString( TQt::ISODate ) );
return true;
}
KOListView::KOListView( Calendar *calendar,
TQWidget *parent,
const char *name,
bool nonInteractive )
: KOEventView( calendar, parent, name )
{
mActiveItem = 0;
mIsNonInteractive = nonInteractive;
mListView = new TDEListView( this );
mListView->addColumn( i18n("Summary") );
mListView->addColumn( i18n("Reminder") ); // alarm set?
mListView->setColumnAlignment( Reminder_Column, AlignHCenter );
mListView->addColumn( i18n("Recurs") ); // recurs?
mListView->setColumnAlignment( Recurs_Column, AlignHCenter );
mListView->addColumn( i18n("Start Date/Time") );
mListView->setColumnAlignment( StartDateTime_Column, AlignHCenter );
mListView->addColumn( i18n("End Date/Time") );
mListView->setColumnAlignment( EndDateTime_Column, AlignHCenter );
mListView->addColumn( i18n("Categories") );
TQBoxLayout *layoutTop = new TQVBoxLayout( this );
layoutTop->addWidget( mListView );
mPopupMenu = eventPopup();
/*
mPopupMenu->insertSeparator();
mPopupMenu->insertItem(i18n("Show Dates"), this,
TQT_SLOT(showDates()));
mPopupMenu->insertItem(i18n("Hide Dates"), this,
TQT_SLOT(hideDates()));
*/
connect( mListView, TQT_SIGNAL( doubleClicked( TQListViewItem * ) ),
TQT_SLOT( defaultItemAction( TQListViewItem * ) ) );
connect( mListView, TQT_SIGNAL( returnPressed( TQListViewItem * ) ),
TQT_SLOT( defaultItemAction( TQListViewItem * ) ) );
connect( mListView, TQT_SIGNAL( rightButtonClicked ( TQListViewItem *,
const TQPoint &,
int ) ),
TQT_SLOT( popupMenu( TQListViewItem *, const TQPoint &, int ) ) );
connect( mListView, TQT_SIGNAL( selectionChanged() ),
TQT_SLOT( processSelectionChange() ) );
// setMinimumSize(100,100);
mListView->restoreLayout( KOGlobals::self()->config(), "KOListView Layout" );
new KOListViewToolTip( mListView->viewport(), calendar, mListView );
mSelectedDates.append( TQDate::currentDate() );
}
KOListView::~KOListView()
{
delete mPopupMenu;
}
int KOListView::maxDatesHint()
{
return 0;
}
int KOListView::currentDateCount()
{
return mSelectedDates.count();
}
Incidence::List KOListView::selectedIncidences()
{
Incidence::List eventList;
TQListViewItem *item = mListView->selectedItem();
if ( item ) {
eventList.append( static_cast<KOListViewItem *>( item )->data() );
}
return eventList;
}
DateList KOListView::selectedIncidenceDates()
{
return mSelectedDates;
}
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::showDates()
{
showDates( true );
}
void KOListView::hideDates()
{
showDates( false );
}
void KOListView::updateView()
{
kdDebug(5850) << "KOListView::updateView() does nothing" << endl;
}
void KOListView::showDates( const TQDate &start, const TQDate &end )
{
clear();
TQDate date = start;
while( date <= end ) {
addIncidences( calendar()->incidences( date ), date );
mSelectedDates.append( date );
date = date.addDays( 1 );
}
emit incidenceSelected( 0, TQDate() );
}
void KOListView::showAll()
{
Incidence::List incidenceList = calendar()->incidences();
Incidence::List::ConstIterator it;
for( it = incidenceList.begin(); it != incidenceList.end(); ++it ) {
// we don't need the date, using showAll in non interactive mode for now
addIncidence( *it, TQDate() );
}
}
void KOListView::addIncidences( const Incidence::List &incidenceList, const TQDate &date )
{
Incidence::List::ConstIterator it;
for( it = incidenceList.begin(); it != incidenceList.end(); ++it ) {
addIncidence( *it, date );
}
}
void KOListView::addIncidence( Incidence *incidence, const TQDate &date )
{
if ( mUidDict.find( incidence->uid() ) ) {
return;
}
mDateList[incidence->uid()] = date;
mUidDict.insert( incidence->uid(), incidence );
KOListViewItem *item = new KOListViewItem( incidence, mListView );
ListItemVisitor v( item );
if (incidence->accept( v ) ) {
return;
} else {
delete item;
}
}
void KOListView::showIncidences( const Incidence::List &incidenceList, const TQDate &date )
{
clear();
addIncidences( incidenceList, date );
// After new creation of list view no events are selected.
emit incidenceSelected( 0, date );
}
void KOListView::changeIncidenceDisplay( Incidence *incidence, int action )
{
KOListViewItem *item;
TQDate f = mSelectedDates.first();
TQDate l = mSelectedDates.last();
TQDate date;
if ( incidence->type() == "Todo" ) {
date = static_cast<Todo *>( incidence )->dtDue().date();
} else {
date = incidence->dtStart().date();
}
switch( action ) {
case KOGlobals::INCIDENCEADDED: {
if ( date >= f && date <= l )
addIncidence( incidence, date );
break;
}
case KOGlobals::INCIDENCEEDITED: {
item = getItemForIncidence( incidence );
if ( item ) {
delete item;
mUidDict.remove( incidence->uid() );
mDateList.remove( incidence->uid() );
}
if ( date >= f && date <= l ) {
addIncidence( incidence, date );
}
}
break;
case KOGlobals::INCIDENCEDELETED: {
item = getItemForIncidence( incidence );
if ( item ) {
delete item;
}
break;
}
default:
kdDebug(5850) << "KOListView::changeIncidenceDisplay(): Illegal action " << action << endl;
}
}
KOListViewItem *KOListView::getItemForIncidence( Incidence *incidence )
{
KOListViewItem *item = static_cast<KOListViewItem *>( mListView->firstChild() );
while ( item ) {
// kdDebug(5850) << "Item " << item->text(0) << " found" << endl;
if ( item->data() == incidence ) {
return item;
}
item = static_cast<KOListViewItem *>( item->nextSibling() );
}
return 0;
}
void KOListView::defaultItemAction( TQListViewItem *i )
{
if ( !mIsNonInteractive ) {
KOListViewItem *item = static_cast<KOListViewItem *>( i );
if ( item ) {
defaultAction( item->data() );
}
}
}
void KOListView::popupMenu( TQListViewItem *item,const TQPoint &, int )
{
if ( !mIsNonInteractive ) {
mActiveItem = static_cast<KOListViewItem *>( item );
if ( mActiveItem ) {
Incidence *incidence = mActiveItem->data();
// FIXME: For recurring incidences we don't know the date of this
// occurrence, there's no reference to it at all!
mPopupMenu->showIncidencePopup( calendar(), incidence, TQDate() );
} else {
showNewEventPopup();
}
}
}
void KOListView::readSettings( TDEConfig *config )
{
mListView->restoreLayout( config,"KOListView Layout" );
}
void KOListView::writeSettings( TDEConfig *config )
{
mListView->saveLayout( config, "KOListView Layout" );
}
void KOListView::processSelectionChange()
{
if ( !mIsNonInteractive ) {
kdDebug(5850) << "KOListView::processSelectionChange()" << endl;
KOListViewItem *item =
static_cast<KOListViewItem *>( mListView->selectedItem() );
if ( !item ) {
emit incidenceSelected( 0, TQDate() );
} else {
Incidence *incidence = static_cast<Incidence *>( item->data() );
emit incidenceSelected( incidence, mDateList[incidence->uid()] );
}
}
}
void KOListView::clearSelection()
{
mListView->selectAll( false );
}
void KOListView::clear()
{
mSelectedDates.clear();
mListView->clear();
mUidDict.clear();
mDateList.clear();
}
TQSize KOListView::sizeHint() const
{
const TQSize s = KOEventView::sizeHint();
return TQSize( s.width() + style().pixelMetric( TQStyle::PM_ScrollBarExtent ) + 1,
s.height() );
}