mirror of
https://bitbucket.org/smil3y/kde-playground.git
synced 2025-02-24 10:52:52 +00:00
638 lines
19 KiB
C++
638 lines
19 KiB
C++
/*
|
|
Copyright (c) 2008 Bruno Virlet <bruno.virlet@gmail.com>
|
|
Copyright (C) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net
|
|
Author: Bertjan Broeksema, broeksema@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.,
|
|
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 Qt, and distribute the resulting executable,
|
|
without including the source code for Qt in the source distribution.
|
|
*/
|
|
|
|
#include "monthview.h"
|
|
#include "monthgraphicsitems.h"
|
|
#include "monthitem.h"
|
|
#include "monthscene.h"
|
|
#include "prefs.h"
|
|
|
|
#include <calendarsupport/collectionselection.h>
|
|
#include <Akonadi/Calendar/ETMCalendar>
|
|
#include <calendarsupport/kcalprefs.h>
|
|
#include <calendarsupport/utils.h>
|
|
|
|
#include <KCalCore/OccurrenceIterator>
|
|
#include <KCheckableProxyModel>
|
|
#include <KIcon>
|
|
|
|
#include <QHBoxLayout>
|
|
#include <QTimer>
|
|
#include <QToolButton>
|
|
#include <QWheelEvent>
|
|
|
|
using namespace EventViews;
|
|
|
|
namespace EventViews {
|
|
|
|
class MonthViewPrivate : public Akonadi::ETMCalendar::CalendarObserver
|
|
{
|
|
MonthView *q;
|
|
|
|
public: /// Methods
|
|
explicit MonthViewPrivate( MonthView *qq );
|
|
|
|
void addIncidence( const Akonadi::Item &incidence );
|
|
void moveStartDate( int weeks, int months );
|
|
// void setUpModels();
|
|
void triggerDelayedReload( EventView::Change reason );
|
|
|
|
public: /// Members
|
|
QTimer reloadTimer;
|
|
MonthScene *scene;
|
|
QDate selectedItemDate;
|
|
Akonadi::Item::Id selectedItemId;
|
|
MonthGraphicsView *view;
|
|
QToolButton *fullView;
|
|
|
|
// List of uids for QDate
|
|
QMap<QDate, QStringList > mBusyDays;
|
|
|
|
protected:
|
|
/* reimplemented from KCalCore::Calendar::CalendarObserver */
|
|
void calendarIncidenceAdded( const KCalCore::Incidence::Ptr &incidence );
|
|
void calendarIncidenceChanged( const KCalCore::Incidence::Ptr &incidence );
|
|
void calendarIncidenceDeleted( const KCalCore::Incidence::Ptr &incidence );
|
|
};
|
|
|
|
}
|
|
|
|
MonthViewPrivate::MonthViewPrivate( MonthView *qq )
|
|
: q( qq ),
|
|
scene( new MonthScene( qq ) ),
|
|
selectedItemId( -1 ),
|
|
view( new MonthGraphicsView( qq ) ),
|
|
fullView( 0 )
|
|
{
|
|
reloadTimer.setSingleShot( true );
|
|
view->setScene( scene );
|
|
}
|
|
|
|
void MonthViewPrivate::addIncidence( const Akonadi::Item &incidence )
|
|
{
|
|
Q_UNUSED( incidence );
|
|
//TODO: add some more intelligence here...
|
|
q->setChanges( q->changes() | EventView::IncidencesAdded );
|
|
reloadTimer.start( 50 );
|
|
}
|
|
|
|
void MonthViewPrivate::moveStartDate( int weeks, int months )
|
|
{
|
|
KDateTime start = q->startDateTime();
|
|
KDateTime end = q->endDateTime();
|
|
start = start.addDays( weeks * 7 );
|
|
end = end.addDays( weeks * 7 );
|
|
start = start.addMonths( months );
|
|
end = end.addMonths( months );
|
|
|
|
#ifndef KDEPIM_MOBILE_UI
|
|
KCalCore::DateList dateList;
|
|
QDate d = start.date();
|
|
while ( d <= end.date() ) {
|
|
dateList.append( d );
|
|
d = d.addDays( 1 );
|
|
}
|
|
|
|
/**
|
|
* If we call q->setDateRange( start, end ); directly,
|
|
* it will change the selected dates in month view,
|
|
* but the application won't know about it.
|
|
* The correct way is to emit datesSelected()
|
|
* #250256
|
|
* */
|
|
emit q->datesSelected( dateList );
|
|
#else
|
|
// korg-mobile doesn't use korg's date navigator.
|
|
// Before creating a solution with no #ifndef, we must first extract the remaining views from
|
|
// korg, and review the API.
|
|
q->setDateRange( start, end );
|
|
#endif
|
|
}
|
|
|
|
void MonthViewPrivate::triggerDelayedReload( EventView::Change reason )
|
|
{
|
|
q->setChanges( q->changes() | reason );
|
|
if ( !reloadTimer.isActive() ) {
|
|
reloadTimer.start( 50 );
|
|
}
|
|
}
|
|
|
|
void MonthViewPrivate::calendarIncidenceAdded( const KCalCore::Incidence::Ptr & )
|
|
{
|
|
triggerDelayedReload( MonthView::IncidencesAdded );
|
|
}
|
|
|
|
void MonthViewPrivate::calendarIncidenceChanged( const KCalCore::Incidence::Ptr & )
|
|
{
|
|
triggerDelayedReload( MonthView::IncidencesEdited );
|
|
}
|
|
|
|
void MonthViewPrivate::calendarIncidenceDeleted( const KCalCore::Incidence::Ptr &incidence )
|
|
{
|
|
Q_ASSERT( !incidence->uid().isEmpty() );
|
|
scene->removeIncidence( incidence->uid() );
|
|
}
|
|
|
|
/// MonthView
|
|
|
|
MonthView::MonthView( NavButtonsVisibility visibility, QWidget *parent )
|
|
: EventView( parent ), d( new MonthViewPrivate( this ) )
|
|
{
|
|
QHBoxLayout *topLayout = new QHBoxLayout( this );
|
|
topLayout->addWidget( d->view );
|
|
topLayout->setMargin( 0 );
|
|
|
|
if ( visibility == Visible ) {
|
|
QVBoxLayout *rightLayout = new QVBoxLayout( );
|
|
rightLayout->setSpacing( 0 );
|
|
rightLayout->setMargin( 0 );
|
|
|
|
// push buttons to the bottom
|
|
rightLayout->addStretch( 1 );
|
|
|
|
d->fullView = new QToolButton( this );
|
|
d->fullView->setIcon( KIcon( QLatin1String("view-fullscreen") ) );
|
|
d->fullView->setAutoRaise( true );
|
|
d->fullView->setCheckable( true );
|
|
d->fullView->setChecked( preferences()->fullViewMonth() );
|
|
d->fullView->isChecked() ?
|
|
d->fullView->setToolTip( i18nc( "@info:tooltip",
|
|
"Display calendar in a normal size" ) ) :
|
|
d->fullView->setToolTip( i18nc( "@info:tooltip",
|
|
"Display calendar in a full window" ) );
|
|
d->fullView->setWhatsThis(
|
|
i18nc( "@info:whatsthis",
|
|
"Click this button and the month view will be enlarged to fill the "
|
|
"maximum available window space / or shrunk back to its normal size." ) );
|
|
connect( d->fullView, SIGNAL(clicked()),
|
|
this, SLOT(changeFullView()) );
|
|
|
|
QToolButton *minusMonth = new QToolButton( this );
|
|
minusMonth->setIcon( KIcon( QLatin1String("arrow-up-double") ) );
|
|
minusMonth->setAutoRaise( true );
|
|
minusMonth->setToolTip( i18nc( "@info:tooltip", "Go back one month" ) );
|
|
minusMonth->setWhatsThis(
|
|
i18nc( "@info:whatsthis",
|
|
"Click this button and the view will be scrolled back in time by 1 month." ) );
|
|
connect( minusMonth, SIGNAL(clicked()),
|
|
this, SLOT(moveBackMonth()) );
|
|
|
|
QToolButton *minusWeek = new QToolButton( this );
|
|
minusWeek->setIcon( KIcon( QLatin1String("arrow-up") ) );
|
|
minusWeek->setAutoRaise( true );
|
|
minusWeek->setToolTip( i18nc( "@info:tooltip", "Go back one week" ) );
|
|
minusWeek->setWhatsThis(
|
|
i18nc( "@info:whatsthis",
|
|
"Click this button and the view will be scrolled back in time by 1 week." ) );
|
|
connect( minusWeek, SIGNAL(clicked()),
|
|
this, SLOT(moveBackWeek()) );
|
|
|
|
QToolButton *plusWeek = new QToolButton( this );
|
|
plusWeek->setIcon( KIcon( QLatin1String("arrow-down") ) );
|
|
plusWeek->setAutoRaise( true );
|
|
plusWeek->setToolTip( i18nc( "@info:tooltip", "Go forward one week" ) );
|
|
plusWeek->setWhatsThis(
|
|
i18nc( "@info:whatsthis",
|
|
"Click this button and the view will be scrolled forward in time by 1 week." ) );
|
|
connect( plusWeek, SIGNAL(clicked()),
|
|
this, SLOT(moveFwdWeek()) );
|
|
|
|
QToolButton *plusMonth = new QToolButton( this );
|
|
plusMonth->setIcon( KIcon( QLatin1String("arrow-down-double") ) );
|
|
plusMonth->setAutoRaise( true );
|
|
plusMonth->setToolTip( i18nc( "@info:tooltip", "Go forward one month" ) );
|
|
plusMonth->setWhatsThis(
|
|
i18nc( "@info:whatsthis",
|
|
"Click this button and the view will be scrolled forward in time by 1 month." ) );
|
|
connect( plusMonth, SIGNAL(clicked()),
|
|
this, SLOT(moveFwdMonth()) );
|
|
|
|
rightLayout->addWidget( d->fullView );
|
|
rightLayout->addWidget( minusMonth );
|
|
rightLayout->addWidget( minusWeek );
|
|
rightLayout->addWidget( plusWeek );
|
|
rightLayout->addWidget( plusMonth );
|
|
|
|
topLayout->addLayout( rightLayout );
|
|
} else {
|
|
d->view->setFrameStyle( QFrame::NoFrame );
|
|
}
|
|
|
|
connect( d->scene, SIGNAL(showIncidencePopupSignal(Akonadi::Item,QDate)),
|
|
SIGNAL(showIncidencePopupSignal(Akonadi::Item,QDate)) );
|
|
|
|
connect( d->scene, SIGNAL(incidenceSelected(Akonadi::Item,QDate)),
|
|
SIGNAL(incidenceSelected(Akonadi::Item,QDate)) );
|
|
|
|
connect( d->scene, SIGNAL(newEventSignal()),
|
|
SIGNAL(newEventSignal()) );
|
|
|
|
connect( d->scene, SIGNAL(showNewEventPopupSignal()),
|
|
SIGNAL(showNewEventPopupSignal()) );
|
|
|
|
connect( &d->reloadTimer, SIGNAL(timeout()), this, SLOT(reloadIncidences()) );
|
|
updateConfig();
|
|
|
|
// d->setUpModels();
|
|
d->reloadTimer.start( 50 );
|
|
}
|
|
|
|
MonthView::~MonthView()
|
|
{
|
|
if ( calendar() ) {
|
|
calendar()->unregisterObserver( d );
|
|
}
|
|
|
|
delete d;
|
|
}
|
|
|
|
void MonthView::updateConfig()
|
|
{
|
|
d->scene->update();
|
|
setChanges( changes() | ConfigChanged );
|
|
d->reloadTimer.start( 50 );
|
|
}
|
|
|
|
int MonthView::currentDateCount() const
|
|
{
|
|
return actualStartDateTime().date().daysTo( actualEndDateTime().date() );
|
|
}
|
|
|
|
KCalCore::DateList MonthView::selectedIncidenceDates() const
|
|
{
|
|
KCalCore::DateList list;
|
|
if ( d->scene->selectedItem() ) {
|
|
IncidenceMonthItem *tmp = qobject_cast<IncidenceMonthItem *>( d->scene->selectedItem() );
|
|
if ( tmp ) {
|
|
QDate selectedItemDate = tmp->realStartDate();
|
|
if ( selectedItemDate.isValid() ) {
|
|
list << selectedItemDate;
|
|
}
|
|
}
|
|
} else if ( d->scene->selectedCell() ) {
|
|
list << d->scene->selectedCell()->date();
|
|
}
|
|
|
|
return list;
|
|
}
|
|
|
|
QDateTime MonthView::selectionStart() const
|
|
{
|
|
if ( d->scene->selectedCell() ) {
|
|
return QDateTime( d->scene->selectedCell()->date() );
|
|
} else {
|
|
return QDateTime();
|
|
}
|
|
}
|
|
|
|
QDateTime MonthView::selectionEnd() const
|
|
{
|
|
// Only one cell can be selected (for now)
|
|
return selectionStart();
|
|
}
|
|
|
|
void MonthView::setDateRange( const KDateTime &start, const KDateTime &end,
|
|
const QDate &preferredMonth )
|
|
{
|
|
EventView::setDateRange( start, end, preferredMonth );
|
|
setChanges( changes() | DatesChanged );
|
|
d->reloadTimer.start( 50 );
|
|
}
|
|
|
|
bool MonthView::eventDurationHint( QDateTime &startDt, QDateTime &endDt, bool &allDay ) const
|
|
{
|
|
if ( d->scene->selectedCell() ) {
|
|
startDt.setDate( d->scene->selectedCell()->date() );
|
|
endDt.setDate( d->scene->selectedCell()->date() );
|
|
allDay = true;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void MonthView::showIncidences( const Akonadi::Item::List &incidenceList, const QDate &date )
|
|
{
|
|
Q_UNUSED( incidenceList );
|
|
Q_UNUSED( date );
|
|
}
|
|
|
|
void MonthView::changeIncidenceDisplay( const Akonadi::Item &incidence, int action )
|
|
{
|
|
Q_UNUSED( incidence );
|
|
Q_UNUSED( action );
|
|
|
|
//TODO: add some more intelligence here...
|
|
|
|
// don't call reloadIncidences() directly. It would delete all
|
|
// MonthItems, but this changeIncidenceDisplay()-method was probably
|
|
// called by one of the MonthItem objects. So only schedule a reload
|
|
// as event
|
|
setChanges( changes() | IncidencesEdited );
|
|
d->reloadTimer.start( 50 );
|
|
}
|
|
|
|
void MonthView::updateView()
|
|
{
|
|
d->view->update();
|
|
}
|
|
|
|
#ifndef QT_NO_WHEELEVENT
|
|
void MonthView::wheelEvent( QWheelEvent *event )
|
|
{
|
|
// invert direction to get scroll-like behaviour
|
|
if ( event->delta() > 0 ) {
|
|
d->moveStartDate( -1, 0 );
|
|
} else if ( event->delta() < 0 ) {
|
|
d->moveStartDate( 1, 0 );
|
|
}
|
|
|
|
// call accept in every case, we do not want anybody else to react
|
|
event->accept();
|
|
}
|
|
#endif
|
|
|
|
void MonthView::keyPressEvent( QKeyEvent *event )
|
|
{
|
|
if ( event->key() == Qt::Key_PageUp ) {
|
|
d->moveStartDate( 0, -1 );
|
|
event->accept();
|
|
} else if ( event->key() == Qt::Key_PageDown ) {
|
|
d->moveStartDate( 0, 1 );
|
|
event->accept();
|
|
} else if ( processKeyEvent( event ) ) {
|
|
event->accept();
|
|
} else {
|
|
event->ignore();
|
|
}
|
|
}
|
|
|
|
void MonthView::keyReleaseEvent( QKeyEvent *event )
|
|
{
|
|
if ( processKeyEvent( event ) ) {
|
|
event->accept();
|
|
} else {
|
|
event->ignore();
|
|
}
|
|
}
|
|
|
|
void MonthView::changeFullView()
|
|
{
|
|
bool fullView = d->fullView->isChecked();
|
|
|
|
if( fullView ) {
|
|
d->fullView->setIcon( KIcon( QLatin1String("view-restore") ) );
|
|
d->fullView->setToolTip( i18nc( "@info:tooltip",
|
|
"Display calendar in a normal size" ) );
|
|
} else {
|
|
d->fullView->setIcon( KIcon( QLatin1String("view-fullscreen") ) );
|
|
d->fullView->setToolTip( i18nc( "@info:tooltip",
|
|
"Display calendar in a full window" ) );
|
|
}
|
|
preferences()->setFullViewMonth( fullView );
|
|
preferences()->writeConfig();
|
|
|
|
emit fullViewChanged( fullView );
|
|
}
|
|
|
|
void MonthView::moveBackMonth()
|
|
{
|
|
d->moveStartDate( 0, -1 );
|
|
}
|
|
|
|
void MonthView::moveBackWeek()
|
|
{
|
|
d->moveStartDate( -1, 0 );
|
|
}
|
|
|
|
void MonthView::moveFwdWeek()
|
|
{
|
|
d->moveStartDate( 1, 0 );
|
|
}
|
|
|
|
void MonthView::moveFwdMonth()
|
|
{
|
|
d->moveStartDate( 0, 1 );
|
|
}
|
|
|
|
void MonthView::showDates( const QDate &start, const QDate &end, const QDate &preferedMonth )
|
|
{
|
|
Q_UNUSED( start );
|
|
Q_UNUSED( end );
|
|
Q_UNUSED( preferedMonth );
|
|
d->triggerDelayedReload( DatesChanged );
|
|
}
|
|
|
|
QPair<KDateTime,KDateTime> MonthView::actualDateRange( const KDateTime &start,
|
|
const KDateTime &,
|
|
const QDate &preferredMonth ) const
|
|
{
|
|
KDateTime dayOne = preferredMonth.isValid() ? KDateTime( preferredMonth ) : start;
|
|
dayOne.setDate( QDate( dayOne.date().year(), dayOne.date().month(), 1 ) );
|
|
const int weekdayCol = ( dayOne.date().dayOfWeek() + 7 - KGlobal::locale()->weekStartDay() ) % 7;
|
|
KDateTime actualStart = dayOne.addDays( -weekdayCol );
|
|
actualStart.setTime( QTime( 0, 0, 0, 0 ) );
|
|
KDateTime actualEnd = actualStart.addDays( 6 * 7 - 1 );
|
|
actualEnd.setTime( QTime( 23, 59, 59, 99 ) );
|
|
return qMakePair( actualStart, actualEnd );
|
|
}
|
|
|
|
Akonadi::Item::List MonthView::selectedIncidences() const
|
|
{
|
|
Akonadi::Item::List selected;
|
|
if ( d->scene->selectedItem() ) {
|
|
IncidenceMonthItem *tmp = qobject_cast<IncidenceMonthItem *>( d->scene->selectedItem() );
|
|
if ( tmp ) {
|
|
Akonadi::Item incidenceSelected = tmp->akonadiItem();
|
|
if ( incidenceSelected.isValid() ) {
|
|
selected.append( incidenceSelected );
|
|
}
|
|
}
|
|
}
|
|
return selected;
|
|
}
|
|
|
|
void MonthView::reloadIncidences()
|
|
{
|
|
if ( changes() == NothingChanged ) {
|
|
return;
|
|
}
|
|
// keep selection if it exists
|
|
Akonadi::Item incidenceSelected;
|
|
|
|
MonthItem *itemToReselect = 0;
|
|
|
|
if ( IncidenceMonthItem *tmp = qobject_cast<IncidenceMonthItem *>( d->scene->selectedItem() ) ) {
|
|
d->selectedItemId = tmp->akonadiItem().id();
|
|
d->selectedItemDate = tmp->realStartDate();
|
|
if ( !d->selectedItemDate.isValid() ) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
d->scene->resetAll();
|
|
d->mBusyDays.clear();
|
|
// build monthcells hash
|
|
int i = 0;
|
|
for ( QDate date = actualStartDateTime().date();
|
|
date <= actualEndDateTime().date(); date = date.addDays( 1 ) ) {
|
|
d->scene->mMonthCellMap[ date ] = new MonthCell( i, date, d->scene );
|
|
i ++;
|
|
}
|
|
|
|
// build global event list
|
|
KDateTime::Spec timeSpec = CalendarSupport::KCalPrefs::instance()->timeSpec();
|
|
const bool colorMonthBusyDays = preferences()->colorMonthBusyDays();
|
|
|
|
KCalCore::OccurrenceIterator occurIter( *calendar(), actualStartDateTime(), actualEndDateTime() );
|
|
while ( occurIter.hasNext() ) {
|
|
occurIter.next();
|
|
|
|
// Remove the two checks when filtering is done through a proxyModel, when using calendar search
|
|
if ( !preferences()->showTodosMonthView() &&
|
|
occurIter.incidence()->type() == KCalCore::Incidence::TypeTodo ) {
|
|
continue;
|
|
}
|
|
if ( !preferences()->showJournalsMonthView() &&
|
|
occurIter.incidence()->type() == KCalCore::Incidence::TypeJournal ) {
|
|
continue;
|
|
}
|
|
|
|
const bool busyDay = colorMonthBusyDays && makesWholeDayBusy( occurIter.incidence() );
|
|
if ( busyDay ) {
|
|
QStringList &list = d->mBusyDays[occurIter.occurrenceStartDate().date()];
|
|
list.append( occurIter.incidence()->uid() );
|
|
}
|
|
|
|
const Akonadi::Item item = calendar()->item( occurIter.incidence() );
|
|
if ( !item.isValid() ) {
|
|
continue;
|
|
}
|
|
Q_ASSERT(item.isValid());
|
|
Q_ASSERT(item.hasPayload());
|
|
MonthItem *manager = new IncidenceMonthItem( d->scene,
|
|
calendar(),
|
|
item,
|
|
occurIter.incidence(),
|
|
occurIter.occurrenceStartDate().toTimeSpec( timeSpec ).date() );
|
|
d->scene->mManagerList << manager;
|
|
if ( d->selectedItemId == item.id() &&
|
|
manager->realStartDate() == d->selectedItemDate ) {
|
|
// only select it outside the loop because we are still creating items
|
|
itemToReselect = manager;
|
|
}
|
|
}
|
|
|
|
if ( itemToReselect ) {
|
|
d->scene->selectItem( itemToReselect );
|
|
}
|
|
|
|
// add holidays
|
|
const QList<QDate> workDays = CalendarSupport::workDays( actualStartDateTime().date(),
|
|
actualEndDateTime().date() );
|
|
|
|
for ( QDate date = actualStartDateTime().date();
|
|
date <= actualEndDateTime().date(); date = date.addDays( 1 ) ) {
|
|
// Only call CalendarSupport::holiday() if it's not a workDay, saves come cpu cicles.
|
|
if ( !workDays.contains( date ) ) {
|
|
QStringList holidays( CalendarSupport::holiday( date ) );
|
|
if ( !holidays.isEmpty() ) {
|
|
MonthItem *holidayItem =
|
|
new HolidayMonthItem(
|
|
d->scene, date,
|
|
holidays.join( i18nc( "@item:intext delimiter for joining holiday names", "," ) ) );
|
|
d->scene->mManagerList << holidayItem;
|
|
}
|
|
}
|
|
}
|
|
|
|
// sort it
|
|
qSort( d->scene->mManagerList.begin(),
|
|
d->scene->mManagerList.end(),
|
|
MonthItem::greaterThan );
|
|
|
|
// build each month's cell event list
|
|
foreach ( MonthItem *manager, d->scene->mManagerList ) {
|
|
for ( QDate date = manager->startDate();
|
|
date <= manager->endDate(); date = date.addDays( 1 ) ) {
|
|
MonthCell *cell = d->scene->mMonthCellMap.value( date );
|
|
if ( cell ) {
|
|
cell->mMonthItemList << manager;
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach ( MonthItem *manager, d->scene->mManagerList ) {
|
|
manager->updateMonthGraphicsItems();
|
|
manager->updatePosition();
|
|
}
|
|
|
|
foreach ( MonthItem *manager, d->scene->mManagerList ) {
|
|
manager->updateGeometry();
|
|
}
|
|
|
|
d->scene->setInitialized( true );
|
|
d->view->update();
|
|
d->scene->update();
|
|
}
|
|
|
|
void MonthView::calendarReset()
|
|
{
|
|
kDebug();
|
|
d->triggerDelayedReload( ResourcesChanged );
|
|
}
|
|
|
|
QDate MonthView::averageDate() const
|
|
{
|
|
return actualStartDateTime().date().addDays(
|
|
actualStartDateTime().date().daysTo( actualEndDateTime().date() ) / 2 );
|
|
}
|
|
|
|
int MonthView::currentMonth() const
|
|
{
|
|
return averageDate().month();
|
|
}
|
|
|
|
bool MonthView::usesFullWindow()
|
|
{
|
|
return preferences()->fullViewMonth();
|
|
}
|
|
|
|
bool MonthView::isBusyDay( const QDate &day ) const
|
|
{
|
|
return !d->mBusyDays[day].isEmpty();
|
|
}
|
|
|
|
void MonthView::setCalendar( const Akonadi::ETMCalendar::Ptr &cal )
|
|
{
|
|
Q_ASSERT( cal );
|
|
|
|
if ( calendar() ) {
|
|
calendar()->unregisterObserver( d );
|
|
}
|
|
|
|
EventView::setCalendar( cal );
|
|
calendar()->registerObserver( d );
|
|
}
|
|
|