28 #include "korganizer/korganizerinterface.h"
30 #include <calendarsupport/utils.h>
31 #include <calendarsupport/calendarsingleton.h>
33 #include <Akonadi/Collection>
34 #include <Akonadi/ItemFetchScope>
35 #include <Akonadi/Calendar/IncidenceChanger>
37 #include <KCalUtils/IncidenceFormatter>
39 #include <KontactInterface/Core>
42 #include <KConfigGroup>
43 #include <KIconLoader>
44 #include <KLocalizedString>
46 #include <KSystemTimeZones>
49 #include <QGridLayout>
51 #include <QTextDocument>
52 #include <QVBoxLayout>
54 using namespace KCalUtils;
57 : KontactInterface::Summary( parent ), mPlugin( plugin )
70 mCalendar = CalendarSupport::calendarSingleton();
72 mChanger =
new Akonadi::IncidenceChanger( parent );
74 connect( mCalendar.data(), SIGNAL(calendarChanged()), SLOT(updateView()) );
75 connect( mPlugin->core(), SIGNAL(dayChanged(
QDate)), SLOT(updateView()) );
84 void TodoSummaryWidget::updateView()
86 qDeleteAll( mLabels );
90 KConfigGroup group = config.group(
"Days" );
91 int mDaysToGo = group.readEntry(
"DaysToShow", 7 );
93 group = config.group(
"Hide" );
94 mHideInProgress = group.readEntry(
"InProgress",
false );
95 mHideOverdue = group.readEntry(
"Overdue",
false );
96 mHideCompleted = group.readEntry(
"Completed",
true );
97 mHideOpenEnded = group.readEntry(
"OpenEnded",
true );
98 mHideNotStarted = group.readEntry(
"NotStarted",
false );
100 group = config.group(
"Groupware" );
101 mShowMineOnly = group.readEntry(
"ShowMineOnly",
false );
115 KCalCore::Todo::List prList;
118 KCalCore::Todo::List todos = mCalendar->todos();
119 Q_FOREACH (
const KCalCore::Todo::Ptr &todo, todos ) {
120 if ( todo->hasDueDate() ) {
121 const int daysTo = currDate.
daysTo( todo->dtDue().date() );
122 if ( daysTo >= mDaysToGo ) {
127 if ( mHideOverdue && todo->isOverdue() ) {
130 if ( mHideInProgress && todo->isInProgress(
false ) ) {
133 if ( mHideCompleted && todo->isCompleted() ) {
136 if ( mHideOpenEnded && todo->isOpenEnded() ) {
139 if ( mHideNotStarted && todo->isNotStarted(
false ) ) {
143 prList.append( todo );
145 if ( !prList.isEmpty() ) {
146 prList = Akonadi::ETMCalendar::sortTodos( prList,
147 KCalCore::TodoSortSummary,
148 KCalCore::SortDirectionAscending );
149 prList = Akonadi::ETMCalendar::sortTodos( prList,
150 KCalCore::TodoSortPriority,
151 KCalCore::SortDirectionAscending );
152 prList = Akonadi::ETMCalendar::sortTodos( prList,
153 KCalCore::TodoSortDueDate,
154 KCalCore::SortDirectionAscending );
176 if ( !prList.isEmpty() ) {
183 Q_FOREACH (
const KCalCore::Todo::Ptr &todo, prList ) {
184 bool makeBold =
false;
196 label =
new QLabel(
this );
204 if ( todo->hasDueDate() && todo->dtDue().date().isValid() ) {
205 daysTo = currDate.
daysTo( todo->dtDue().date() );
209 str = i18nc(
"the to-do is due today",
"Today" );
210 }
else if ( daysTo == 1 ) {
211 str = i18nc(
"the to-do is due tomorrow",
"Tomorrow" );
213 str = KGlobal::locale()->formatDate( todo->dtDue().date(), KLocale::FancyLongDate );
217 label =
new QLabel( str,
this );
218 label->
setAlignment( Qt::AlignLeft | Qt::AlignVCenter );
229 if ( todo->hasDueDate() && todo->dtDue().date().isValid() ) {
231 str = i18np(
"in 1 day",
"in %1 days", daysTo );
232 }
else if ( daysTo < 0 ) {
233 str = i18np(
"1 day ago",
"%1 days ago", -daysTo );
235 str = i18nc(
"the to-do is due",
"due" );
238 label =
new QLabel( str,
this );
239 label->
setAlignment( Qt::AlignLeft | Qt::AlignVCenter );
245 label =
new QLabel( str,
this );
246 label->
setAlignment( Qt::AlignRight | Qt::AlignVCenter );
251 str = todo->summary();
252 if ( !todo->relatedTo().isEmpty() ) {
253 KCalCore::Incidence::Ptr inc = mCalendar->incidence( todo->relatedTo() );
262 KUrlLabel *urlLabel =
new KUrlLabel(
this );
263 urlLabel->setText( str );
264 urlLabel->setUrl( todo->uid() );
265 urlLabel->installEventFilter(
this );
266 urlLabel->setTextFormat( Qt::RichText );
267 urlLabel->setWordWrap(
true );
268 mLayout->
addWidget( urlLabel, counter, 4 );
269 mLabels.
append( urlLabel );
271 connect( urlLabel, SIGNAL(leftClickedUrl(
QString)),
272 this, SLOT(viewTodo(
QString)) );
273 connect( urlLabel, SIGNAL(rightClickedUrl(
QString)),
274 this, SLOT(popupMenu(
QString)) );
289 str = stateStr( todo );
290 label =
new QLabel( str,
this );
291 label->
setAlignment( Qt::AlignLeft | Qt::AlignVCenter );
299 if ( counter == 0 ) {
301 i18np(
"No pending to-dos due within the next day",
302 "No pending to-dos due within the next %1 days",
304 noTodos->
setAlignment( Qt::AlignHCenter | Qt::AlignVCenter );
306 mLabels.
append( noTodos );
309 Q_FOREACH ( label, mLabels ) {
314 void TodoSummaryWidget::viewTodo(
const QString &uid )
316 Akonadi::Item::Id
id = mCalendar->item( uid ).id();
319 mPlugin->core()->selectPlugin(
QLatin1String(
"kontact_todoplugin") );
320 OrgKdeKorganizerKorganizerInterface korganizer(
327 void TodoSummaryWidget::removeTodo(
const Akonadi::Item &item )
329 mChanger->deleteIncidence( item );
332 void TodoSummaryWidget::completeTodo( Akonadi::Item::Id
id )
334 Akonadi::Item todoItem = mCalendar->item(
id );
336 if ( todoItem.isValid() ) {
337 KCalCore::Todo::Ptr todo = CalendarSupport::todo( todoItem );
338 if ( !todo->isReadOnly() ) {
339 KCalCore::Todo::Ptr oldTodo( todo->clone() );
340 todo->setCompleted( KDateTime::currentLocalDateTime() );
341 mChanger->modifyIncidence( todoItem, oldTodo );
347 void TodoSummaryWidget::popupMenu(
const QString &uid )
349 KCalCore::Todo::Ptr todo = mCalendar->todo( uid );
352 Akonadi::Item item = mCalendar->item( uid );
354 QAction *editIt = popup.addAction( i18n(
"&Edit To-do..." ) );
355 QAction *delIt = popup.addAction( i18n(
"&Delete To-do" ) );
356 delIt->
setIcon( KIconLoader::global()->loadIcon(
QLatin1String(
"edit-delete"), KIconLoader::Small ) );
359 delIt->
setEnabled( mCalendar->hasRight( item, Akonadi::Collection::CanDeleteItem ) );
361 if ( !todo->isCompleted() ) {
362 doneIt = popup.addAction( i18n(
"&Mark To-do Completed" ) );
363 doneIt->
setIcon( KIconLoader::global()->loadIcon(
QLatin1String(
"task-complete"), KIconLoader::Small ) );
364 doneIt->
setEnabled( mCalendar->hasRight( item, Akonadi::Collection::CanChangeItem ) );
369 if ( selectedAction == editIt ) {
371 }
else if ( selectedAction == delIt ) {
373 }
else if ( doneIt && selectedAction == doneIt ) {
374 completeTodo( item.id() );
380 if ( obj->
inherits(
"KUrlLabel" ) ) {
381 KUrlLabel* label =
static_cast<KUrlLabel*
>( obj );
382 if ( e->
type() == QEvent::Enter ) {
383 emit message( i18n(
"Edit To-do: \"%1\"", label->text() ) );
385 if ( e->
type() == QEvent::Leave ) {
386 emit message( QString::null );
389 return KontactInterface::Summary::eventFilter( obj, e );
397 bool TodoSummaryWidget::startsToday(
const KCalCore::Todo::Ptr &todo )
399 return todo->hasStartDate() &&
403 const QString TodoSummaryWidget::stateStr(
const KCalCore::Todo::Ptr &todo )
407 if ( todo->isOpenEnded() ) {
408 str1 = i18n(
"open-ended" );
409 }
else if ( todo->isOverdue() ) {
411 i18nc(
"the to-do is overdue",
"overdue" ) +
413 }
else if ( startsToday( todo ) ) {
414 str1 = i18nc(
"the to-do starts today",
"starts today" );
417 if ( todo->isNotStarted(
false ) ) {
418 str2 += i18nc(
"the to-do has not been started yet",
"not-started" );
419 }
else if ( todo->isCompleted() ) {
420 str2 += i18nc(
"the to-do is completed",
"completed" );
421 }
else if ( todo->isInProgress(
false ) ) {
422 str2 += i18nc(
"the to-do is in-progress",
"in-progress " );
427 str1 += i18nc(
"Separator for status like this: overdue, completed",
"," );
int daysTo(const QDate &d) const
void setPixmap(const QPixmap &)
void setIcon(const QIcon &icon)
void setAlignment(QFlags< Qt::AlignmentFlag >)
QDBusConnection sessionBus()
void setSpacing(int spacing)
void setBold(bool enable)
QString number(int n, int base)
void append(const T &value)
void setRowStretch(int row, int stretch)
bool inherits(const char *className) const
virtual void addItem(QLayoutItem *item)
void setMargin(int margin)
QString escape(const QString &plain)
bool mightBeRichText(const QString &text)
virtual QSize minimumSizeHint() const
void setSpacing(int spacing)