diff --git a/incidenceeditor-ng/conflictresolver.cpp b/incidenceeditor-ng/conflictresolver.cpp --- a/incidenceeditor-ng/conflictresolver.cpp +++ b/incidenceeditor-ng/conflictresolver.cpp @@ -319,71 +319,74 @@ // now we know the number of attendees we are calculating for const int number_attendees = filteredFBItems.size(); - if ( number_attendees <= 0 ) { - kDebug() << "no attendees match search criteria"; - return; - } kDebug() << "num attendees: " << number_attendees; // this is a 2 dimensional array where the rows are attendees // and the columns are 0 or 1 denoting freee or busy respectively. QVector< QVector > fbTable; - // Explanation of the following loop: - // iterate: through each attendee - // allocate: an array of length and fill it with 0s - // iterate: through each attendee's busy period - // if: the period lies inside our timeframe - // then: - // calculate the array index within the timeframe range of the beginning of the busy period - // fill from that index until the period ends with a 1, representing busy - // fi - // etareti - // append the allocated array to - // etareti - foreach ( KCalCore::FreeBusy::Ptr currentFB, filteredFBItems ) { - Q_ASSERT( currentFB ); // sanity check - KCalCore::Period::List busyPeriods = currentFB->busyPeriods(); - QVector fbArray( range ); - fbArray.fill( 0 ); // initialize to zero - for ( KCalCore::Period::List::Iterator it = busyPeriods.begin(); - it != busyPeriods.end(); ++it ) { - if ( it->end() >= begin && it->start() <= end ) { - int start_index = -1; // Initialize it to an invalid value. - int duration = -1; // Initialize it to an invalid value. - // case1: the period is completely in our timeframe - if( it->end() <= end && it->start() >= begin ) { - start_index = begin.secsTo( it->start() ) / mSlotResolutionSeconds; - duration = it->start().secsTo( it->end() ) / mSlotResolutionSeconds; - duration -= 1; // vector starts at 0 - // case2: the period begins before our timeframe begins - } else if( it->start() <= begin && it->end() <= end ) { - start_index = 0; - duration = ( begin.secsTo( it->end() ) / mSlotResolutionSeconds ) - 1; - // case3: the period ends after our timeframe ends - } else if( it->end() >= end && it->start() >= begin ) { - start_index = begin.secsTo( it->start() ) / mSlotResolutionSeconds; - duration = range - start_index - 1; - // case4: case2+case3: our timeframe is inside the period - } else if( it->start() <= begin && it->end() >= end ) { - start_index = 0; - duration = range - 1; - } else { - kFatal() << "impossible condition reached" << it->start() << it->end(); - } - // kDebug() << start_index << "+" << duration << "=" - // << start_index + duration << "<=" << range; - Q_ASSERT( ( start_index + duration ) < range ); // sanity check - for ( int i = start_index; i <= start_index + duration; ++i ) { - fbArray[i] = 1; + if ( number_attendees > 0 ) { + // Explanation of the following loop: + // iterate: through each attendee + // allocate: an array of length and fill it with 0s + // iterate: through each attendee's busy period + // if: the period lies inside our timeframe + // then: + // calculate the array index within the timeframe range of the beginning of the busy period + // fill from that index until the period ends with a 1, representing busy + // fi + // etareti + // append the allocated array to + // etareti + foreach ( KCalCore::FreeBusy::Ptr currentFB, filteredFBItems ) { + Q_ASSERT( currentFB ); // sanity check + KCalCore::Period::List busyPeriods = currentFB->busyPeriods(); + QVector fbArray( range ); + fbArray.fill( 0 ); // initialize to zero + for ( KCalCore::Period::List::Iterator it = busyPeriods.begin(); + it != busyPeriods.end(); ++it ) { + if ( it->end() >= begin && it->start() <= end ) { + int start_index = -1; // Initialize it to an invalid value. + int duration = -1; // Initialize it to an invalid value. + // case1: the period is completely in our timeframe + if( it->end() <= end && it->start() >= begin ) { + start_index = begin.secsTo( it->start() ) / mSlotResolutionSeconds; + duration = it->start().secsTo( it->end() ) / mSlotResolutionSeconds; + duration -= 1; // vector starts at 0 + // case2: the period begins before our timeframe begins + } else if( it->start() <= begin && it->end() <= end ) { + start_index = 0; + duration = ( begin.secsTo( it->end() ) / mSlotResolutionSeconds ) - 1; + // case3: the period ends after our timeframe ends + } else if( it->end() >= end && it->start() >= begin ) { + start_index = begin.secsTo( it->start() ) / mSlotResolutionSeconds; + duration = range - start_index - 1; + // case4: case2+case3: our timeframe is inside the period + } else if( it->start() <= begin && it->end() >= end ) { + start_index = 0; + duration = range - 1; + } else { + kFatal() << "impossible condition reached" << it->start() << it->end(); + } + // kDebug() << start_index << "+" << duration << "=" + // << start_index + duration << "<=" << range; + Q_ASSERT( ( start_index + duration ) < range ); // sanity check + for ( int i = start_index; i <= start_index + duration; ++i ) { + fbArray[i] = 1; + } + } } - } + Q_ASSERT( fbArray.size() == range ); // sanity check + fbTable.append( fbArray ); } - Q_ASSERT( fbArray.size() == range ); // sanity check + + Q_ASSERT( fbTable.size() == number_attendees ); + } else { + //If we have no information about freebusytime of participants, everything is free + QVector fbArray( range ); + fbArray.fill( 0 ); fbTable.append( fbArray ); } - Q_ASSERT( fbTable.size() == number_attendees ); - // Now, create another array to represent the allowed weekdays constraints // All days which are not allowed, will be marked as busy const KCalendarSystem *calSys = KGlobal::locale()->calendar(); diff --git a/incidenceeditor-ng/incidenceattendee.cpp b/incidenceeditor-ng/incidenceattendee.cpp --- a/incidenceeditor-ng/incidenceattendee.cpp +++ b/incidenceeditor-ng/incidenceattendee.cpp @@ -526,8 +526,6 @@ mDateTime->startTime(), duration, mConflictResolver, mParentWidget ) ); - dialog->slotUpdateIncidenceStartEnd( mDateTime->currentStartDateTime(), - mDateTime->currentEndDateTime() ); if ( dialog->exec() == KDialog::Accepted ) { kDebug () << dialog->selectedStartDate() << dialog->selectedStartTime(); mDateTime->setStartDate( dialog->selectedStartDate() ); @@ -556,6 +554,7 @@ void IncidenceAttendee::slotConflictResolverAttendeeAdded(const QModelIndex &index, int first, int last) { + mUi->mSolveButton->setEnabled( true ); for (int i = first; i <= last; i++) { QModelIndex email = dataModel()->index(i, AttendeeTableModel::Email, index); if (!dataModel()->data(email).toString().isEmpty()) { diff --git a/incidenceeditor-ng/resourcemanagement.cpp b/incidenceeditor-ng/resourcemanagement.cpp --- a/incidenceeditor-ng/resourcemanagement.cpp +++ b/incidenceeditor-ng/resourcemanagement.cpp @@ -28,19 +28,12 @@ #include "freebusymodel/freebusycalendar.h" #include "ldaputils.h" -#include "freebusyganttproxymodel.h" - #include #include #include #include -#include -#include -#include -#include - #include #include diff --git a/incidenceeditor-ng/schedulingdialog.h b/incidenceeditor-ng/schedulingdialog.h --- a/incidenceeditor-ng/schedulingdialog.h +++ b/incidenceeditor-ng/schedulingdialog.h @@ -48,9 +48,6 @@ QDate selectedStartDate() const; QTime selectedStartTime() const; - public slots: - void slotUpdateIncidenceStartEnd( const KDateTime &startDateTime, - const KDateTime &endDateTime ); signals: void startDateChanged( const QDate &newDate ); @@ -62,11 +59,14 @@ void slotWeekdaysChanged(); void slotMandatoryRolesChanged(); void slotStartDateChanged( const QDate &newDate ); + void updateDateRange(); void slotRowSelectionChanged( const QModelIndex ¤t, const QModelIndex &previous ); void slotSetEndTimeLabel( const QTime &startTime ); + void slotVisualDateSelection( const KDateTime &startTime, const KDateTime &endTime ); private: + void setSelectedTimeRange(const QDateTime &startDt, const QDateTime &endDt, const QDateTime &endOfPeriod); void updateWeekDays( const QDate &oldDate ); void fillCombos(); diff --git a/incidenceeditor-ng/schedulingdialog.cpp b/incidenceeditor-ng/schedulingdialog.cpp --- a/incidenceeditor-ng/schedulingdialog.cpp +++ b/incidenceeditor-ng/schedulingdialog.cpp @@ -48,6 +48,8 @@ mGanttTab->setLayout( ganttlayout ); ganttlayout->addWidget( mVisualWidget ); + connect( mVisualWidget, SIGNAL(dateTimesChanged(KDateTime, KDateTime)), + this, SLOT(slotVisualDateSelection(KDateTime, KDateTime)) ); #endif connect( mStartDate, SIGNAL(dateEdited(QDate)), @@ -64,6 +66,11 @@ connect( mStartDate, SIGNAL(dateEdited(QDate)), this, SLOT(slotStartDateChanged(QDate)) ); + connect( mStartDate, SIGNAL(dateEdited(QDate)), + this, SLOT(updateDateRange()) ); + connect( mEndDate, SIGNAL(dateEdited(QDate)), + this, SLOT(updateDateRange()) ); + connect( mWeekdayCombo, SIGNAL(checkedItemsChanged(QStringList)), SLOT(slotWeekdaysChanged()) ); connect( mWeekdayCombo, SIGNAL(checkedItemsChanged(QStringList)), @@ -91,22 +98,16 @@ mResolver->setLatestTime( mEndTime->time() ); mSearchOnlyWorkingTime->setChecked(mResolver->workingHoursOnly()); - mMoveApptGroupBox->hide(); + updateDateRange(); } SchedulingDialog::~SchedulingDialog() { } -void SchedulingDialog::slotUpdateIncidenceStartEnd( const KDateTime &startDateTime, - const KDateTime &endDateTime ) +void SchedulingDialog::updateDateRange() { -#ifdef KDEPIM_MOBILE_UI - Q_UNUSED( startDateTime ); - Q_UNUSED( endDateTime ); -#else - mVisualWidget->slotUpdateIncidenceStartEnd( startDateTime, endDateTime ); -#endif + mVisualWidget->setTimeRange(KDateTime(mStartDate->date()), KDateTime(mEndDate->date())); } void SchedulingDialog::fillCombos() @@ -189,35 +190,42 @@ mResolver->setMandatoryRoles( roles ); } +void SchedulingDialog::slotVisualDateSelection( const KDateTime &startTime, const KDateTime &endTime ) +{ + setSelectedTimeRange(startTime.dateTime(), startTime.dateTime().addSecs(mDuration), QDateTime()); +} + void SchedulingDialog::slotRowSelectionChanged( const QModelIndex ¤t, const QModelIndex &previous ) { Q_UNUSED( previous ); if ( !current.isValid() ) { - mMoveApptGroupBox->hide(); return; } KCalCore::Period period = current.data( FreePeriodModel::PeriodRole ).value(); const QDate startDate = period.start().date(); + setSelectedTimeRange(period.start().dateTime(), period.start().dateTime().addSecs(mDuration), period.end().dateTime()); +} +void SchedulingDialog::setSelectedTimeRange(const QDateTime &startDt, const QDateTime &endDt, const QDateTime &endOfPeriod) +{ const KCalendarSystem *calSys = KGlobal::locale()->calendar(); - const int dayOfWeek = calSys->dayOfWeek( startDate ); + const int dayOfWeek = calSys->dayOfWeek( startDt.date() ); const QString dayLabel = ki18nc( "@label Day of week followed by day of the month, then the month. " "Example: Monday, 12 June", "%1, %2 %3" ). subs( calSys->weekDayName( dayOfWeek, KCalendarSystem::LongDayName ) ). - subs( startDate.day() ). - subs( calSys->monthName( startDate ) ).toString(); + subs( startDt.date().day() ). + subs( calSys->monthName( startDt.date() ) ).toString(); mMoveDayLabel->setText( dayLabel ); - mMoveBeginTimeEdit->setTimeRange( period.start().time(), - period.end().addSecs( -mDuration ).time() ); - mMoveBeginTimeEdit->setTime( period.start().time() ); - slotSetEndTimeLabel( period.start().time() ); - mMoveApptGroupBox->show(); + mMoveBeginTimeEdit->setTimeRange( startDt.time(), + endOfPeriod.addSecs( -mDuration ).time() ); + mMoveBeginTimeEdit->setTime( startDt.time() ); + slotSetEndTimeLabel( endDt.time() ); - mSelectedDate = startDate; + mSelectedDate = startDt.date(); } void SchedulingDialog::slotSetEndTimeLabel( const QTime &startTime ) diff --git a/incidenceeditor-ng/visualfreebusywidget.h b/incidenceeditor-ng/visualfreebusywidget.h --- a/incidenceeditor-ng/visualfreebusywidget.h +++ b/incidenceeditor-ng/visualfreebusywidget.h @@ -24,14 +24,11 @@ #include "incidenceeditors-ng_export.h" #include +#include +#include #include -namespace KDGantt { - class DateTimeGrid; - class GraphicsView; -} - class KComboBox; class QTreeView; @@ -40,8 +37,6 @@ namespace IncidenceEditorNG { -class FreeBusyGanttProxyModel; -class RowController; class INCIDENCEEDITORS_NG_EXPORT VisualFreeBusyWidget : public QWidget { @@ -51,30 +46,18 @@ ~VisualFreeBusyWidget(); public slots: - void slotUpdateIncidenceStartEnd( const KDateTime &, const KDateTime & ); + void setTimeRange( const KDateTime &, const KDateTime & ); signals: void dateTimesChanged( const KDateTime &, const KDateTime & ); void manualReload(); - protected slots: - void slotScaleChanged( int ); - void slotCenterOnStart() ; - void slotZoomToTime(); - void slotPickDate(); - void showAttendeeStatusMenu(); - void slotIntervalColorRectangleMoved( const KDateTime &start, const KDateTime &end ); - private slots: - void splitterMoved(); + void onTimeSpanSelectionChanged(); private: - KDGantt::GraphicsView *mGanttGraphicsView; + EventViews::AgendaView *mAgendaView; QTreeView *mLeftView; - RowController *mRowController; - KDGantt::DateTimeGrid *mGanttGrid; - KComboBox *mScaleCombo; - FreeBusyGanttProxyModel *mModel; KDateTime mDtStart, mDtEnd; }; diff --git a/incidenceeditor-ng/visualfreebusywidget.cpp b/incidenceeditor-ng/visualfreebusywidget.cpp --- a/incidenceeditor-ng/visualfreebusywidget.cpp +++ b/incidenceeditor-ng/visualfreebusywidget.cpp @@ -19,417 +19,126 @@ */ #include "visualfreebusywidget.h" -#include "freebusyganttproxymodel.h" -#include "freebusymodel/freebusyitemmodel.h" +#include +#include +#include -#include -#include -#include -#include +#include +#include -#include #include #include -#include -#include -#include -#include -#include -#include -#include #include using namespace IncidenceEditorNG; -namespace IncidenceEditorNG { - -class RowController : public KDGantt::AbstractRowController +class FreebusyViewCalendar : public EventViews::ViewCalendar { - private: - static const int ROW_HEIGHT ; - QPointer m_model; - - public: - RowController() - { - mRowHeight = 20; - } - - void setModel( QAbstractItemModel *model ) - { - m_model = model; - } - - /*reimp*/ - int headerHeight() const - { - return 2 * mRowHeight + 10; - } - - /*reimp*/ - bool isRowVisible( const QModelIndex & ) const - { - return true; - } - - /*reimp*/ - bool isRowExpanded( const QModelIndex & ) const - { - return false; - } - - /*reimp*/ - KDGantt::Span rowGeometry( const QModelIndex &idx ) const - { - return KDGantt::Span( idx.row() * mRowHeight, mRowHeight ); - } - - /*reimp*/ - int maximumItemHeight() const +public: + virtual ~FreebusyViewCalendar() {}; + virtual bool isValid(const KCalCore::Incidence::Ptr &incidence) const { - return mRowHeight / 2; + return isValid(incidence->uid()); } - /*reimp*/ - int totalHeight() const + virtual bool isValid(const QString &incidenceIdentifier) const { - return m_model->rowCount() * mRowHeight; + kDebug() << incidenceIdentifier; + return incidenceIdentifier.startsWith("fb-"); } - /*reimp*/ - QModelIndex indexAt( int height ) const + virtual QString displayName(const KCalCore::Incidence::Ptr &incidence) const { - return m_model->index( height / mRowHeight, 0 ); + Q_UNUSED(incidence); + return QLatin1String("Freebusy"); } - /*reimp*/ - QModelIndex indexBelow( const QModelIndex &idx ) const + virtual QColor resourceColor(const KCalCore::Incidence::Ptr &incidence) const { - if ( !idx.isValid() ) { - return QModelIndex(); - } - return idx.model()->index( idx.row() + 1, idx.column(), idx.parent() ); + bool ok = false; + int status = incidence->customProperty("FREEBUSY", "STATUS").toInt(&ok); + + if (!ok) { + return QColor("#555"); + } + + switch (status) { + case KCalCore::FreeBusyPeriod::Busy: + return QColor("#f00"); + case KCalCore::FreeBusyPeriod::BusyTentative: + case KCalCore::FreeBusyPeriod::BusyUnavailable: + return QColor("#f70"); + case KCalCore::FreeBusyPeriod::Free: + return QColor("#0f0"); + default: + return QColor("#555"); + } } - /*reimp*/ - QModelIndex indexAbove( const QModelIndex &idx ) const + virtual QString uid(const KCalCore::Incidence::Ptr &incidence) const { - if ( !idx.isValid() ) { - return QModelIndex(); - } - return idx.model()->index( idx.row() - 1, idx.column(), idx.parent() ); + return incidence->uid(); } - void setRowHeight( int height ) + virtual QString iconForIncidence(const KCalCore::Incidence::Ptr &incidence) const { - mRowHeight = height; + return QString(); } - private: - int mRowHeight; - -}; - -class GanttHeaderView : public QHeaderView -{ - public: - explicit GanttHeaderView( QWidget *parent = 0 ) : QHeaderView( Qt::Horizontal, parent ) + virtual KCalCore::Calendar::Ptr getCalendar() const { + return mCalendar; } - QSize sizeHint() const - { - QSize s = QHeaderView::sizeHint(); - s.rheight() *= 2; - return s; - } + KCalCore::Calendar::Ptr mCalendar; }; -} - VisualFreeBusyWidget::VisualFreeBusyWidget( FreeBusyItemModel *model, int spacing, QWidget *parent ) - : QWidget( parent ), mGanttGrid( 0 ), mScaleCombo( 0 ) + : QWidget( parent ), + mAgendaView(0) { QVBoxLayout *topLayout = new QVBoxLayout( this ); topLayout->setSpacing( spacing ); - // The control panel for the gantt widget - QBoxLayout *controlLayout = new QHBoxLayout(); - controlLayout->setSpacing( topLayout->spacing() ); - topLayout->addItem( controlLayout ); - - QLabel *label = new QLabel( i18nc( "@label", "Scale: " ), this ); - controlLayout->addWidget( label ); - - mScaleCombo = new KComboBox( this ); - mScaleCombo->setToolTip( - i18nc( "@info:tooltip", "Set the Gantt chart zoom level" ) ); - mScaleCombo->setWhatsThis( - i18nc( "@info:whatsthis", - "Select the Gantt chart zoom level from one of the following:" - "'Hour' shows a range of several hours," - "'Day' shows a range of a few days," - "'Week' shows a range of a few months," - "and 'Month' shows a range of a few years," - "while 'Automatic' selects the range most " - "appropriate for the current event or to-do." ) ); - mScaleCombo->addItem( i18nc( "@item:inlistbox range in hours", "Hour" ), - QVariant::fromValue( KDGantt::DateTimeGrid::ScaleHour ) ); - mScaleCombo->addItem( i18nc( "@item:inlistbox range in days", "Day" ), - QVariant::fromValue( KDGantt::DateTimeGrid::ScaleDay ) ); - mScaleCombo->addItem( i18nc( "@item:inlistbox range in weeks", "Week" ), - QVariant::fromValue( KDGantt::DateTimeGrid::ScaleWeek ) ); - mScaleCombo->addItem( i18nc( "@item:inlistbox range in months", "Month" ), - QVariant::fromValue( KDGantt::DateTimeGrid::ScaleMonth ) ); - mScaleCombo->addItem( i18nc( "@item:inlistbox range is computed automatically", "Automatic" ), - QVariant::fromValue( KDGantt::DateTimeGrid::ScaleAuto ) ); - mScaleCombo->setCurrentIndex( 0 ); // start with "hour" - connect( mScaleCombo, SIGNAL(activated(int)), SLOT(slotScaleChanged(int)) ); - controlLayout->addWidget( mScaleCombo ); - - QPushButton *button = new QPushButton( i18nc( "@action:button", "Center on Start" ), this ); - button->setToolTip( - i18nc( "@info:tooltip", - "Center the Gantt chart on the event start date and time" ) ); - button->setWhatsThis( - i18nc( "@info:whatsthis", - "Click this button to center the Gantt chart on the start " - "time and day of this event." ) ); - connect( button, SIGNAL(clicked()), SLOT(slotCenterOnStart()) ); - controlLayout->addWidget( button ); - - controlLayout->addStretch( 1 ); + FreeBusyCalendar *freebusyCalendar = new FreeBusyCalendar; + freebusyCalendar->setModel(model); - button = new QPushButton( i18nc( "@action:button", "Pick Date" ), this ); - button->setToolTip( - i18nc( "@info:tooltip", - "Move the event to a date and time when all " - "attendees are available" ) ); - button->setWhatsThis( - i18nc( "@info:whatsthis", - "Click this button to move the event to a date " - "and time when all the attendees have time " - "available in their Free/Busy lists." ) ); - connect( button, SIGNAL(clicked()), SLOT(slotPickDate()) ); - controlLayout->addWidget( button ); + mAgendaView = new EventViews::AgendaView(QDate(), QDate(), false, false); - controlLayout->addStretch( 1 ); + FreebusyViewCalendar *fbCalendar = new FreebusyViewCalendar(); + fbCalendar->mCalendar = freebusyCalendar->calendar(); - button = new QPushButton( i18nc( "@action:button reload freebusy data", "Reload" ), this ); - button->setToolTip( - i18nc( "@info:tooltip", - "Reload Free/Busy data for all attendees" ) ); - button->setWhatsThis( - i18nc( "@info:whatsthis", - "Pressing this button will cause the Free/Busy data for all " - "attendees to be reloaded from their corresponding servers." ) ); - controlLayout->addWidget( button ); - connect( button, SIGNAL(clicked()), SIGNAL(manualReload()) ); + mAgendaView->addCalendar(EventViews::ViewCalendar::Ptr(fbCalendar)); + //We have to call this and not pass in dates in the constructor, because otherwise everything starts to crash. + mAgendaView->showDates(mDtStart.date(), mDtEnd.date(), mDtStart.date()); - QSplitter *splitter = new QSplitter( Qt::Horizontal, this ); - connect( splitter, SIGNAL(splitterMoved(int,int)), SLOT(splitterMoved()) ); - mLeftView = new QTreeView( this ); - mLeftView->setModel( model ); - mLeftView->setHeader( new GanttHeaderView ); - mLeftView->header()->setStretchLastSection( true ); - mLeftView->setRootIsDecorated( false ); - mLeftView->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff ); - mLeftView->setContextMenuPolicy( Qt::CustomContextMenu ); + connect(mAgendaView, SIGNAL(timeSpanSelectionChanged()), this, SLOT(onTimeSpanSelectionChanged())); - mGanttGraphicsView = new KDGantt::GraphicsView( this ); - mGanttGraphicsView->setObjectName( "mGanttGraphicsView" ); - mGanttGraphicsView->setToolTip( - i18nc( "@info:tooltip", - "Shows the Free/Busy status of all attendees" ) ); - mGanttGraphicsView->setWhatsThis( - i18nc( "@info:whatsthis", - "Shows the Free/Busy status of all attendees. " - "Double-clicking on an attendee's entry in the " - "list will allow you to enter the location of " - "their Free/Busy Information." ) ); - mModel = new FreeBusyGanttProxyModel( this ); - mModel->setSourceModel( model ); - - mRowController = new RowController; - mRowController->setRowHeight( fontMetrics().height() ); //TODO: detect - - mRowController->setModel( mModel ); - mGanttGraphicsView->setRowController( mRowController ); - - mGanttGrid = new KDGantt::DateTimeGrid; - mGanttGrid->setScale( KDGantt::DateTimeGrid::ScaleHour ); - mGanttGrid->setDayWidth( 800 ); - mGanttGrid->setRowSeparators( true ); - mGanttGraphicsView->setGrid( mGanttGrid ); - mGanttGraphicsView->setModel( mModel ); - mGanttGraphicsView->viewport()->setFixedWidth( 800 * 30 ); - - splitter->addWidget( mLeftView ); - splitter->addWidget( mGanttGraphicsView ); - - topLayout->addWidget( splitter ); - topLayout->setStretchFactor( splitter, 100 ); - - // Initially, show 15 days back and forth - // set start to even hours, i.e. to 12:AM 0 Min 0 Sec - QDateTime horizonStart = - QDateTime( QDateTime::currentDateTime().addDays( -15 ).date() ); - QDateTime horizonEnd = QDateTime::currentDateTime().addDays( 15 ); - mGanttGrid->setStartDateTime( horizonStart ); - -//connect( mGanttGraphicsView, SIGNAL(timeIntervalSelected(KDateTime,KDateTime)), -// mGanttGraphicsView, SLOT(zoomToSelection(KDateTime,KDateTime)) ); -//connect( mGanttGraphicsView, SIGNAL(doubleClicked(QModelIndex)), -// SLOT(editFreeBusyUrl(QModelIndex)) ); -//connect(mGanttGraphicsView,SIGNAL(intervalColorRectangleMoved(KDateTime,KDateTime)), -// this, SLOT(slotIntervalColorRectangleMoved(KDateTime,KDateTime)) ); - - connect( mLeftView, SIGNAL(customContextMenuRequested(QPoint)), - this, SLOT(showAttendeeStatusMenu()) ); - -// foreach ( FreeBusyItem::Ptr item, mResolver->freeBusyItems() ) { -// newFreeBusy( item ); -// } + topLayout->addWidget( mAgendaView ); + topLayout->setStretchFactor( mAgendaView, 100 ); } VisualFreeBusyWidget::~VisualFreeBusyWidget() { } -void VisualFreeBusyWidget::showAttendeeStatusMenu() -{ -// KMenu *menu = new KMenu( 0 ); -// -// QAction *needsaction = -// menu->addAction( SmallIcon( "help-about" ), -// KCalUtils::Stringify::attendeeStatus( KCalCore::Attendee::NeedsAction ) ); -// QAction *accepted = -// menu->addAction( SmallIcon( "dialog-ok-apply" ), -// KCalUtils::Stringify::attendeeStatus( KCalCore::Attendee::Accepted ) ); -// QAction *declined = -// menu->addAction( SmallIcon( "dialog-cancel" ), -// KCalUtils::Stringify::attendeeStatus( KCalCore::Attendee::Declined ) ); -// QAction *tentative = -// menu->addAction( SmallIcon( "dialog-ok" ), -// KCalUtils::Stringify::attendeeStatus( KCalCore::Attendee::Tentative ) ); -// QAction *delegated = -// menu->addAction( SmallIcon( "mail-forward" ), -// KCalUtils::Stringify::attendeeStatus( KCalCore::Attendee::Delegated ) ); -// QAction *completed = -// menu->addAction( SmallIcon( "mail-mark-read" ), -// KCalUtils::Stringify::attendeeStatus( KCalCore::Attendee::Completed ) ); -// QAction *inprocess = -// menu->addAction( SmallIcon( "help-about" ), -// KCalUtils::Stringify::attendeeStatus( KCalCore::Attendee::InProcess ) ); -// QAction *ret = menu->exec( QCursor::pos() ); -// delete menu; -// if ( ret == needsaction ) { -// currentAttendee()->setStatus( KCalCore::Attendee::NeedsAction ); -// } else if ( ret == accepted ) { -// currentAttendee()->setStatus( KCalCore::Attendee::Accepted ); -// } else if ( ret == declined ) { -// currentAttendee()->setStatus( KCalCore::Attendee::Declined ); -// } else if ( ret == tentative ) { -// currentAttendee()->setStatus( KCalCore::Attendee::Tentative ); -// } else if ( ret == delegated ) { -// currentAttendee()->setStatus( KCalCore::Attendee::Delegated ); -// } else if ( ret == completed ) { -// currentAttendee()->setStatus( KCalCore::Attendee::Completed ); -// } else if ( ret == inprocess ) { -// currentAttendee()->setStatus( KCalCore::Attendee::InProcess ); -// } else { -// return; -// } - -// updateCurrentItem(); -} - -void VisualFreeBusyWidget::slotCenterOnStart() -{ - KDGantt::DateTimeGrid *grid = static_cast( mGanttGraphicsView->grid() ); - int daysTo = grid->startDateTime().daysTo( mDtStart.dateTime() ); - mGanttGraphicsView->horizontalScrollBar()->setValue( daysTo * 800 ); -} - -void VisualFreeBusyWidget::slotIntervalColorRectangleMoved( const KDateTime &start, - const KDateTime &end ) -{ - mDtStart = start; - mDtEnd = end; - emit dateTimesChanged( start, end ); -} - -/*! - This slot is called when the user clicks the "Pick a date" button. -*/ -void VisualFreeBusyWidget::slotPickDate() -{ - //TODO implement or discard -// KDateTime::Spec timeSpec = KSystemTimeZones::local(); -// KDateTime start = mDtStart; -// KDateTime end = mDtEnd; -// bool success = mResolver->findFreeSlot( KCalCore::Period( start, end ) ); -// -// if ( success ) { -// if ( start == mDtStart && end == mDtEnd ) { -// KMessageBox::information( -// this, -// i18nc( "@info", "The meeting already has suitable start/end times." ), -// QString(), -// "MeetingTimeOKFreeBusy" ); -// } else { -// if ( KMessageBox::questionYesNo( -// this, -// i18nc( "@info", -// "The next available time slot for the meeting is:" -// "Start: %1End: %2" -// "Would you like to move the meeting to this time slot?", -// start.dateTime().toString(), end.dateTime().toString() ), QString(), -// KStandardGuiItem::yes(), KStandardGuiItem::no(), -// "MeetingMovedFreeBusy" ) == KMessageBox::Yes ) { -// emit dateTimesChanged( start, end ); -// slotUpdateGanttView( start, end ); -// } -// } -// } else { -// KMessageBox::sorry( this, i18nc( "@info", "No suitable date found." ) ); -// } -} - -void VisualFreeBusyWidget::slotScaleChanged( int newScale ) -{ - const QVariant var = mScaleCombo->itemData( newScale ); - Q_ASSERT( var.isValid() ); - - int value = var.value(); - - mGanttGrid->setScale( ( KDGantt::DateTimeGrid::Scale )value ); -} - -void VisualFreeBusyWidget::slotUpdateIncidenceStartEnd( const KDateTime &dtFrom, - const KDateTime &dtTo ) +void VisualFreeBusyWidget::setTimeRange( const KDateTime &dtFrom, const KDateTime &dtTo ) { + kDebug() << "Changing date range" << dtFrom << dtTo; mDtStart = dtFrom; mDtEnd = dtTo; - QDateTime horizonStart = QDateTime( dtFrom.addDays( -15 ).date() ); - KDGantt::DateTimeGrid *grid = static_cast( mGanttGraphicsView->grid() ); - grid->setStartDateTime( horizonStart ); - slotCenterOnStart(); - mGanttGrid->setStartDateTime( horizonStart ); -} - -void VisualFreeBusyWidget::slotZoomToTime() -{ -#if 0 - mGanttGraphicsView->zoomToFit(); -#else - kDebug() << "Disabled code, port to KDGantt2"; -#endif + mAgendaView->showDates(mDtStart.date(), mDtEnd.date(), mDtStart.date()); } -void VisualFreeBusyWidget::splitterMoved() +void VisualFreeBusyWidget::onTimeSpanSelectionChanged() { -// mLeftView->setColumnWidth( 0, mLeftView->width() ); + if (!mAgendaView) { + return; + } + mDtStart = KDateTime(mAgendaView->selectionStart()); + mDtEnd = KDateTime(mAgendaView->selectionEnd()); + kDebug() << "TimeSpan selection chagned " << mDtStart << mDtEnd; + emit dateTimesChanged( mDtStart, mDtEnd ); } diff --git a/libkdepim/freebusymodel/freebusycalendar.cpp b/libkdepim/freebusymodel/freebusycalendar.cpp --- a/libkdepim/freebusymodel/freebusycalendar.cpp +++ b/libkdepim/freebusymodel/freebusycalendar.cpp @@ -71,6 +71,7 @@ SLOT(onRowsInserted(QModelIndex,int,int))); connect(mModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), SLOT(onRowsChanged(QModelIndex,QModelIndex))); + onLayoutChanged(); } }