• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • kdepim
  • Sitemap
  • Contact Us
 

kontact

todosummarywidget.cpp

Go to the documentation of this file.
00001 /*
00002   This file is part of Kontact.
00003 
00004   Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>
00005   Copyright (c) 2005-2006,2008 Allen Winter <winter@kde.org>
00006 
00007   This program is free software; you can redistribute it and/or modify
00008   it under the terms of the GNU General Public License as published by
00009   the Free Software Foundation; either version 2 of the License, or
00010   (at your option) any later version.
00011 
00012   This program is distributed in the hope that it will be useful,
00013   but WITHOUT ANY WARRANTY; without even the implied warranty of
00014   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00015   GNU General Public License for more details.
00016 
00017   You should have received a copy of the GNU General Public License along
00018   with this program; if not, write to the Free Software Foundation, Inc.,
00019   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020 
00021   As a special exception, permission is given to link this program
00022   with any edition of Qt, and distribute the resulting executable,
00023   without including the source code for Qt in the source distribution.
00024 */
00025 
00026 #include "todosummarywidget.h"
00027 #include "todoplugin.h"
00028 #include "korganizerinterface.h"
00029 
00030 #include <korganizer/stdcalendar.h>
00031 #include <korganizer/koglobals.h>
00032 #include <kontactinterfaces/core.h>
00033 
00034 #include <libkdepim/kpimprefs.h>
00035 
00036 #include <kcal/calendar.h>
00037 #include <kcal/resourcecalendar.h>
00038 #include <kcal/resourcelocal.h>
00039 #include <kcal/todo.h>
00040 #include <kcal/incidenceformatter.h>
00041 
00042 #include <kdialog.h>
00043 #include <kglobal.h>
00044 #include <kicon.h>
00045 #include <kiconloader.h>
00046 #include <klocale.h>
00047 #include <kmenu.h>
00048 #include <kstandarddirs.h>
00049 #include <kurllabel.h>
00050 #include <kparts/part.h>
00051 
00052 #include <QCursor>
00053 #include <QEvent>
00054 #include <QGridLayout>
00055 #include <QLabel>
00056 #include <QLayout>
00057 #include <QPixmap>
00058 #include <QVBoxLayout>
00059 #include <QTextDocument>
00060 
00061 TodoSummaryWidget::TodoSummaryWidget( TodoPlugin *plugin, QWidget *parent )
00062   : Kontact::Summary( parent ), mPlugin( plugin )
00063 {
00064   QVBoxLayout *mainLayout = new QVBoxLayout( this );
00065   mainLayout->setSpacing( 3 );
00066   mainLayout->setMargin( 3 );
00067 
00068   QWidget *header = createHeader( this, "view-pim-tasks", i18n( "Pending To-dos" ) );
00069   mainLayout->addWidget( header );
00070 
00071   mLayout = new QGridLayout();
00072   mainLayout->addItem( mLayout );
00073   mLayout->setSpacing( 3 );
00074   mLayout->setRowStretch( 6, 1 );
00075 
00076   mCalendar = KOrg::StdCalendar::self();
00077   mCalendar->load();
00078 
00079   connect( mCalendar, SIGNAL(calendarChanged()), SLOT(updateView()) );
00080   connect( mPlugin->core(), SIGNAL(dayChanged(const QDate&)), SLOT(updateView()) );
00081 
00082   updateView();
00083 }
00084 
00085 TodoSummaryWidget::~TodoSummaryWidget()
00086 {
00087 }
00088 
00089 void TodoSummaryWidget::updateView()
00090 {
00091   qDeleteAll( mLabels );
00092   mLabels.clear();
00093 
00094   KConfig config( "kcmtodosummaryrc" );
00095   KConfigGroup daysGroup( &config, "Days" );
00096   int mDaysToGo = daysGroup.readEntry( "DaysToShow", 7 );
00097 
00098   KConfigGroup hideGroup( &config, "Hide" );
00099   mHideInProgress = hideGroup.readEntry( "InProgress", false );
00100   mHideOverdue = hideGroup.readEntry( "Overdue", false );
00101   mHideCompleted = hideGroup.readEntry( "Completed", true );
00102   mHideOpenEnded = hideGroup.readEntry( "OpenEnded", true );
00103   mHideNotStarted = hideGroup.readEntry( "NotStarted", false );
00104 
00105   // for each todo,
00106   //   if it passes the filter, append to a list
00107   //   else continue
00108   // sort todolist by summary
00109   // sort todolist by priority
00110   // sort todolist by due-date
00111   // print todolist
00112 
00113   // the filter is created by the configuration summary options, but includes
00114   //    days to go before to-do is due
00115   //    which types of to-dos to hide
00116 
00117   KCal::Todo::List prList;
00118 
00119   QDate currDate = QDate::currentDate();
00120   Q_FOREACH ( KCal::Todo *todo, mCalendar->todos() ) {
00121     if ( todo->hasDueDate() ) {
00122       int daysTo = currDate.daysTo( todo->dtDue().date() );
00123       if ( daysTo >= mDaysToGo ) {
00124         continue;
00125       }
00126     }
00127 
00128     if ( mHideOverdue && overdue( todo ) ) {
00129       continue;
00130     }
00131     if ( mHideInProgress && inProgress( todo ) ) {
00132       continue;
00133     }
00134     if ( mHideCompleted && completed( todo ) ) {
00135       continue;
00136     }
00137     if ( mHideOpenEnded && openEnded( todo ) ) {
00138       continue;
00139     }
00140     if ( mHideNotStarted && notStarted( todo ) ) {
00141       continue;
00142     }
00143 
00144     prList.append( todo );
00145   }
00146   if ( !prList.isEmpty() ) {
00147     prList = KCal::Calendar::sortTodos( &prList,
00148                                         KCal::TodoSortSummary,
00149                                         KCal::SortDirectionAscending );
00150     prList = KCal::Calendar::sortTodos( &prList,
00151                                         KCal::TodoSortPriority,
00152                                         KCal::SortDirectionAscending );
00153     prList = KCal::Calendar::sortTodos( &prList,
00154                                         KCal::TodoSortDueDate,
00155                                         KCal::SortDirectionAscending );
00156   }
00157 
00158   // The to-do print consists of the following fields:
00159   //  icon:due date:days-to-go:priority:summary:status
00160   // where,
00161   //   the icon is the typical to-do icon
00162   //   the due date it the to-do due date
00163   //   the days-to-go/past is the #days until/since the to-do is due
00164   //     this field is left blank if the to-do is open-ended
00165   //   the priority is the to-do priority
00166   //   the summary is the to-do summary
00167   //   the status is comma-separated list of:
00168   //     overdue
00169   //     in-progress (started, or >0% completed)
00170   //     complete (100% completed)
00171   //     open-ended
00172   //     not-started (no start date and 0% completed)
00173 
00174   int counter = 0;
00175   QLabel *label = 0;
00176 
00177   if ( !prList.isEmpty() ) {
00178 
00179     KIconLoader loader( "korganizer" );
00180     QPixmap pm = loader.loadIcon( "view-calendar-tasks", KIconLoader::Small );
00181 
00182     QString str;
00183 
00184     Q_FOREACH ( KCal::Todo *todo, prList ) {
00185       bool makeBold = false;
00186       int daysTo = -1;
00187 
00188       // Icon label
00189       label = new QLabel( this );
00190       label->setPixmap( pm );
00191       label->setMaximumWidth( label->minimumSizeHint().width() );
00192       mLayout->addWidget( label, counter, 0 );
00193       mLabels.append( label );
00194 
00195       // Due date label
00196       str = "";
00197       if ( todo->hasDueDate() && todo->dtDue().date().isValid() ) {
00198         daysTo = currDate.daysTo( todo->dtDue().date() );
00199 
00200         if ( daysTo == 0 ) {
00201           makeBold = true;
00202           str = i18n( "Today" );
00203         } else if ( daysTo == 1 ) {
00204           str = i18n( "Tomorrow" );
00205         } else {
00206           str = KGlobal::locale()->formatDate( todo->dtDue().date(), KLocale::FancyLongDate );
00207         }
00208       }
00209 
00210       label = new QLabel( str, this );
00211       label->setAlignment( Qt::AlignLeft | Qt::AlignVCenter );
00212       mLayout->addWidget( label, counter, 1 );
00213       mLabels.append( label );
00214       if ( makeBold ) {
00215         QFont font = label->font();
00216         font.setBold( true );
00217         label->setFont( font );
00218       }
00219 
00220       // Days togo/ago label
00221       str = "";
00222       if ( todo->hasDueDate() && todo->dtDue().date().isValid() ) {
00223         if ( daysTo > 0 ) {
00224           str = i18np( "in 1 day", "in %1 days", daysTo );
00225         } else if ( daysTo < 0 ) {
00226           str = i18np( "1 day ago", "%1 days ago", -daysTo );
00227         } else {
00228           str = i18n( "due" );
00229         }
00230       }
00231       label = new QLabel( str, this );
00232       label->setAlignment( Qt::AlignLeft | Qt::AlignVCenter );
00233       mLayout->addWidget( label, counter, 2 );
00234       mLabels.append( label );
00235 
00236       // Priority label
00237       str = '[' + QString::number( todo->priority() ) + ']';
00238       label = new QLabel( str, this );
00239       label->setAlignment( Qt::AlignRight | Qt::AlignVCenter );
00240       mLayout->addWidget( label, counter, 3 );
00241       mLabels.append( label );
00242 
00243       // Summary label
00244       str = todo->summary();
00245       if ( todo->relatedTo() ) { // show parent only, not entire ancestry
00246         str = todo->relatedTo()->summary() + ':' + str;
00247       }
00248       if ( !Qt::mightBeRichText( str ) ) {
00249         str = Qt::escape( str );
00250       }
00251 
00252       KUrlLabel *urlLabel = new KUrlLabel( this );
00253       urlLabel->setText( str );
00254       urlLabel->setUrl( todo->uid() );
00255       urlLabel->installEventFilter( this );
00256       urlLabel->setTextFormat( Qt::RichText );
00257       mLayout->addWidget( urlLabel, counter, 4 );
00258       mLabels.append( urlLabel );
00259 
00260       connect( urlLabel, SIGNAL(leftClickedUrl(const QString&)),
00261                this, SLOT(viewTodo(const QString&)) );
00262       connect( urlLabel, SIGNAL(rightClickedUrl(const QString&)),
00263                this, SLOT(popupMenu(const QString&)) );
00264 
00265       QString tipText( KCal::IncidenceFormatter::toolTipString( todo, true ) );
00266       if ( !tipText.isEmpty() ) {
00267         urlLabel->setToolTip( tipText );
00268       }
00269 
00270       // State text label
00271       str = stateStr( todo );
00272       label = new QLabel( str, this );
00273       label->setAlignment( Qt::AlignLeft | Qt::AlignVCenter );
00274       mLayout->addWidget( label, counter, 5 );
00275       mLabels.append( label );
00276 
00277       counter++;
00278     }
00279   } //foreach
00280 
00281   if ( counter == 0 ) {
00282     QLabel *noTodos = new QLabel(
00283       i18np( "No pending to-dos due within the next day",
00284              "No pending to-dos due within the next %1 days",
00285              mDaysToGo ), this );
00286     noTodos->setAlignment( Qt::AlignHCenter | Qt::AlignVCenter );
00287     mLayout->addWidget( noTodos, 0, 2 );
00288     mLabels.append( noTodos );
00289   }
00290 
00291   Q_FOREACH( label, mLabels ) {
00292     label->show();
00293   }
00294 }
00295 
00296 void TodoSummaryWidget::viewTodo( const QString &uid )
00297 {
00298   mPlugin->core()->selectPlugin( "kontact_todoplugin" );//ensure loaded
00299   OrgKdeKorganizerKorganizerInterface korganizer(
00300     "org.kde.korganizer", "/Korganizer", QDBusConnection::sessionBus() );
00301   korganizer.editIncidence( uid );
00302 }
00303 
00304 void TodoSummaryWidget::removeTodo( const QString &uid )
00305 {
00306   mPlugin->core()->selectPlugin( "kontact_todoplugin" );//ensure loaded
00307   OrgKdeKorganizerKorganizerInterface korganizer(
00308     "org.kde.korganizer", "/Korganizer", QDBusConnection::sessionBus() );
00309   korganizer.deleteIncidence( uid, false );
00310 }
00311 
00312 void TodoSummaryWidget::completeTodo( const QString &uid )
00313 {
00314   KCal::Todo *todo = mCalendar->todo( uid );
00315   if ( !todo->isReadOnly() ) {
00316     todo->setCompleted( KDateTime::currentLocalDateTime() );
00317     mCalendar->save();
00318     updateView();
00319   }
00320 }
00321 
00322 void TodoSummaryWidget::popupMenu( const QString &uid )
00323 {
00324   KMenu popup( this );
00325   QAction *editIt = popup.addAction( i18n( "&Edit To-do..." ) );
00326   QAction *delIt = popup.addAction( i18n( "&Delete To-do" ) );
00327   delIt->setIcon( KIconLoader::global()->loadIcon( "edit-delete", KIconLoader::Small ) );
00328   QAction *doneIt = 0;
00329   KCal::Todo *todo = mCalendar->todo( uid );
00330   if ( !todo->isCompleted() ) {
00331     doneIt = popup.addAction( i18n( "&Mark To-do Completed" ) );
00332     doneIt->setIcon( KIconLoader::global()->loadIcon( "task-complete", KIconLoader::Small ) );
00333   }
00334   // TODO: add icons to the menu actions
00335 
00336   const QAction *selectedAction = popup.exec( QCursor::pos() );
00337   if ( selectedAction == editIt ) {
00338     viewTodo( uid );
00339   } else if ( selectedAction == delIt ) {
00340     removeTodo( uid );
00341   } else if ( doneIt && selectedAction == doneIt ) {
00342     completeTodo( uid );
00343   }
00344 }
00345 
00346 bool TodoSummaryWidget::eventFilter( QObject *obj, QEvent *e )
00347 {
00348   if ( obj->inherits( "KUrlLabel" ) ) {
00349     KUrlLabel* label = static_cast<KUrlLabel*>( obj );
00350     if ( e->type() == QEvent::Enter ) {
00351       emit message( i18n( "Edit To-do: \"%1\"", label->text() ) );
00352     }
00353     if ( e->type() == QEvent::Leave ) {
00354       emit message( QString::null );    //krazy:exclude=nullstrassign for old broken gcc
00355     }
00356   }
00357   return Kontact::Summary::eventFilter( obj, e );
00358 }
00359 
00360 QStringList TodoSummaryWidget::configModules() const
00361 {
00362   return QStringList( "kcmtodosummary.desktop" );
00363 }
00364 
00365 bool TodoSummaryWidget::overdue( KCal::Todo *todo )
00366 {
00367   if ( todo->hasDueDate() && !todo->isCompleted() &&
00368        todo->dtDue().date() < QDate::currentDate() ) {
00369     return true;
00370   }
00371   return false;
00372 }
00373 
00374 bool TodoSummaryWidget::starts( KCal::Todo *todo )
00375 {
00376   if ( todo->hasStartDate() &&
00377        todo->dtStart().date() == QDate::currentDate() ) {
00378     return true;
00379   }
00380   return false;
00381 }
00382 
00383 bool TodoSummaryWidget::completed( KCal::Todo *todo )
00384 {
00385   return todo->isCompleted();
00386 }
00387 
00388 bool TodoSummaryWidget::openEnded( KCal::Todo *todo )
00389 {
00390   if ( !todo->hasDueDate() && !todo->isCompleted() ) {
00391     return true;
00392   }
00393   return false;
00394 }
00395 
00396 bool TodoSummaryWidget::inProgress( KCal::Todo *todo )
00397 {
00398   if ( todo->percentComplete() > 0 ) {
00399     return true;
00400   }
00401 
00402   QDate currDate = QDate::currentDate();
00403   if ( todo->hasStartDate() && todo->hasDueDate() &&
00404        todo->dtStart().date() < currDate &&
00405        currDate < todo->dtDue().date() ) {
00406     return true;
00407   }
00408 
00409   return false;
00410 }
00411 
00412 bool TodoSummaryWidget::notStarted( KCal::Todo *todo )
00413 {
00414   if ( todo->percentComplete() > 0 ) {
00415     return false;
00416   }
00417 
00418   if ( !todo->hasStartDate() ) {
00419     return false;
00420   }
00421 
00422   if ( todo->dtStart().date() >= QDate::currentDate() ) {
00423     return false;
00424   }
00425 
00426   return true;
00427 }
00428 
00429 const QString TodoSummaryWidget::stateStr( KCal::Todo *todo )
00430 {
00431   QString str1, str2;
00432 
00433   if ( openEnded( todo ) ) {
00434     str1 = i18n( "open-ended" );
00435   } else if ( overdue( todo ) ) {
00436     str1 = "<font color=\"red\">" + i18n( "overdue" ) + "</font>";
00437   } else if ( starts( todo ) ) {
00438     str1 = i18n( "starts today" );
00439   }
00440 
00441   if ( notStarted( todo ) ) {
00442     str2 += i18n( "not-started" );
00443   } else if ( completed( todo ) ) {
00444     str2 += i18n( "completed" );
00445   } else if ( inProgress( todo ) ) {
00446     str2 += i18n( "in-progress " );
00447     str2 += " (" + QString::number( todo->percentComplete() ) + "%)";
00448   }
00449 
00450   if ( !str1.isEmpty() && !str2.isEmpty() ) {
00451     str1 += i18nc( "Separator for status like this: overdue, completed", "," );
00452   }
00453 
00454   return str1 + str2;
00455 }
00456 
00457 #include "todosummarywidget.moc"

kontact

Skip menu "kontact"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members

kdepim

Skip menu "kdepim"
  • akonadi
  •   clients
  •   kabc
  •   kcal
  •   kcm
  • akregator
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt
  • kdgantt1
  • kjots
  • kleopatra
  • kmail
  • kmobiletools
  • knode
  • knotes
  • kontact
  • kontactinterfaces
  • korganizer
  •   korgac
  • kpilot
  • ktimetracker
  •   doc
  • libkdepim
  • libkholidays
  • libkleo
  • libkpgp
  • maildir
Generated for kdepim by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal