File indexing completed on 2024-04-28 05:11:38
0001 /* 0002 SPDX-FileCopyrightText: 2010 Casey Link <unnamedrambler@gmail.com> 0003 SPDX-FileCopyrightText: 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company <info@kdab.net> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "schedulingdialog.h" 0009 #include "conflictresolver.h" 0010 #include "visualfreebusywidget.h" 0011 #include <CalendarSupport/FreePeriodModel> 0012 #include <KCalUtils/Stringify> 0013 0014 #include <KLocalizedString> 0015 0016 #include <QDialogButtonBox> 0017 #include <QLocale> 0018 #include <QPushButton> 0019 #include <QVBoxLayout> 0020 0021 using namespace IncidenceEditorNG; 0022 0023 SchedulingDialog::SchedulingDialog(QDate startDate, QTime startTime, int duration, ConflictResolver *resolver, QWidget *parent) 0024 : QDialog(parent) 0025 , mResolver(resolver) 0026 , mPeriodModel(new CalendarSupport::FreePeriodModel(this)) 0027 { 0028 setWindowTitle(i18nc("@title:window", "Scheduling")); 0029 auto mainLayout = new QVBoxLayout(this); 0030 auto w = new QWidget(this); 0031 setupUi(w); 0032 auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); 0033 QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok); 0034 okButton->setDefault(true); 0035 okButton->setShortcut(Qt::CTRL | Qt::Key_Return); 0036 connect(buttonBox, &QDialogButtonBox::accepted, this, &SchedulingDialog::accept); 0037 connect(buttonBox, &QDialogButtonBox::rejected, this, &SchedulingDialog::reject); 0038 0039 mainLayout->addWidget(w); 0040 mainLayout->addWidget(buttonBox); 0041 fillCombos(); 0042 0043 Q_ASSERT(duration > 0); 0044 mDuration = duration; 0045 0046 mVisualWidget = new VisualFreeBusyWidget(resolver->model(), 8); 0047 auto ganttlayout = new QVBoxLayout(mGanttTab); 0048 0049 mGanttTab->setLayout(ganttlayout); 0050 ganttlayout->addWidget(mVisualWidget); 0051 0052 connect(mStartDate, &KDateComboBox::dateEdited, mResolver, &ConflictResolver::setEarliestDate); 0053 connect(mStartTime, &KTimeComboBox::timeEdited, mResolver, &ConflictResolver::setEarliestTime); 0054 connect(mEndDate, &KDateComboBox::dateEdited, mResolver, &ConflictResolver::setLatestDate); 0055 connect(mEndTime, &KTimeComboBox::timeEdited, mResolver, &ConflictResolver::setLatestTime); 0056 0057 connect(mStartDate, &KDateComboBox::dateEdited, this, &SchedulingDialog::slotStartDateChanged); 0058 0059 connect(mWeekdayCombo, &IncidenceEditorNG::KWeekdayCheckCombo::checkedItemsChanged, this, &SchedulingDialog::slotWeekdaysChanged); 0060 connect(mWeekdayCombo, &IncidenceEditorNG::KWeekdayCheckCombo::checkedItemsChanged, this, &SchedulingDialog::slotMandatoryRolesChanged); 0061 0062 connect(mResolver, &ConflictResolver::freeSlotsAvailable, mPeriodModel, &CalendarSupport::FreePeriodModel::slotNewFreePeriods); 0063 connect(mMoveBeginTimeEdit, &KTimeComboBox::timeEdited, this, &SchedulingDialog::slotSetEndTimeLabel); 0064 0065 mTableView->setModel(mPeriodModel); 0066 connect(mTableView->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &SchedulingDialog::slotRowSelectionChanged); 0067 0068 mStartDate->setDate(startDate); 0069 mEndDate->setDate(mStartDate->date().addDays(7)); 0070 mStartTime->setTime(startTime); 0071 mEndTime->setTime(startTime); 0072 0073 mResolver->setEarliestDate(mStartDate->date()); 0074 mResolver->setEarliestTime(mStartTime->time()); 0075 mResolver->setLatestDate(mEndDate->date()); 0076 mResolver->setLatestTime(mEndTime->time()); 0077 0078 mMoveApptGroupBox->hide(); 0079 } 0080 0081 SchedulingDialog::~SchedulingDialog() = default; 0082 0083 void SchedulingDialog::slotUpdateIncidenceStartEnd(const QDateTime &startDateTime, const QDateTime &endDateTime) 0084 { 0085 mVisualWidget->slotUpdateIncidenceStartEnd(startDateTime, endDateTime); 0086 } 0087 0088 void SchedulingDialog::fillCombos() 0089 { 0090 // Note: we depend on the following order 0091 mRolesCombo->addItem(QIcon::fromTheme(QStringLiteral("meeting-participant")), KCalUtils::Stringify::attendeeRole(KCalendarCore::Attendee::ReqParticipant)); 0092 mRolesCombo->addItem(QIcon::fromTheme(QStringLiteral("meeting-participant-optional")), 0093 KCalUtils::Stringify::attendeeRole(KCalendarCore::Attendee::OptParticipant)); 0094 mRolesCombo->addItem(QIcon::fromTheme(QStringLiteral("meeting-observer")), KCalUtils::Stringify::attendeeRole(KCalendarCore::Attendee::NonParticipant)); 0095 mRolesCombo->addItem(QIcon::fromTheme(QStringLiteral("meeting-chair")), KCalUtils::Stringify::attendeeRole(KCalendarCore::Attendee::Chair)); 0096 0097 mRolesCombo->setWhatsThis(i18nc("@info:whatsthis", "Edits the role of the attendee.")); 0098 0099 mRolesCombo->setItemCheckState(0, Qt::Checked); 0100 mRolesCombo->setItemCheckState(1, Qt::Checked); 0101 mRolesCombo->setItemCheckState(2, Qt::Checked); 0102 mRolesCombo->setItemCheckState(3, Qt::Checked); 0103 0104 QBitArray days(7); 0105 days.setBit(0); // Monday 0106 days.setBit(1); // Tuesday 0107 days.setBit(2); // Wednesday 0108 days.setBit(3); // Thursday 0109 days.setBit(4); // Friday.. surprise! 0110 0111 mWeekdayCombo->setDays(days); 0112 mResolver->setAllowedWeekdays(days); 0113 } 0114 0115 void SchedulingDialog::slotStartDateChanged(const QDate &newDate) 0116 { 0117 QDate oldDate = mStDate; 0118 mStDate = newDate; 0119 if (newDate.isValid() && oldDate.isValid()) { 0120 updateWeekDays(oldDate); 0121 } 0122 } 0123 0124 void SchedulingDialog::updateWeekDays(const QDate &oldDate) 0125 { 0126 const int oldStartDayIndex = mWeekdayCombo->weekdayIndex(oldDate); 0127 const int newStartDayIndex = mWeekdayCombo->weekdayIndex(mStDate); 0128 0129 mWeekdayCombo->setItemCheckState(oldStartDayIndex, Qt::Unchecked); 0130 mWeekdayCombo->setItemEnabled(oldStartDayIndex, true); 0131 mWeekdayCombo->setItemCheckState(newStartDayIndex, Qt::Checked); 0132 mWeekdayCombo->setItemEnabled(newStartDayIndex, false); 0133 } 0134 0135 void SchedulingDialog::slotWeekdaysChanged() 0136 { 0137 // notify the resolver 0138 mResolver->setAllowedWeekdays(mWeekdayCombo->days()); 0139 } 0140 0141 void SchedulingDialog::slotMandatoryRolesChanged() 0142 { 0143 QSet<KCalendarCore::Attendee::Role> roles; 0144 for (int i = 0; i < mRolesCombo->count(); ++i) { 0145 if (mRolesCombo->itemCheckState(i) == Qt::Checked) { 0146 roles << KCalendarCore::Attendee::Role(i); 0147 } 0148 } 0149 mResolver->setMandatoryRoles(roles); 0150 } 0151 0152 void SchedulingDialog::slotRowSelectionChanged(const QModelIndex ¤t, const QModelIndex &previous) 0153 { 0154 Q_UNUSED(previous) 0155 if (!current.isValid()) { 0156 mMoveApptGroupBox->hide(); 0157 return; 0158 } 0159 auto period = current.data(CalendarSupport::FreePeriodModel::PeriodRole).value<KCalendarCore::Period>(); 0160 const QDate startDate = period.start().date(); 0161 0162 const int dayOfWeek = startDate.dayOfWeek(); 0163 const QString dayLabel = ki18nc( 0164 "@label Day of week followed by day of the month, then the month. " 0165 "Example: Monday, 12 June", 0166 "%1, %2 %3") 0167 .subs(QLocale::system().dayName(dayOfWeek, QLocale::LongFormat)) 0168 .subs(startDate.day()) 0169 .subs(QLocale::system().monthName(startDate.month(), QLocale::LongFormat)) 0170 .toString(); 0171 0172 mMoveDayLabel->setText(dayLabel); 0173 mMoveBeginTimeEdit->setTimeRange(period.start().time(), period.end().addSecs(-mDuration).time()); 0174 mMoveBeginTimeEdit->setTime(period.start().time()); 0175 slotSetEndTimeLabel(period.start().time()); 0176 mMoveApptGroupBox->show(); 0177 0178 mSelectedDate = startDate; 0179 } 0180 0181 void SchedulingDialog::slotSetEndTimeLabel(const QTime &startTime) 0182 { 0183 const QTime endTime = startTime.addSecs(mDuration); 0184 const QString endTimeLabel = ki18nc( 0185 "@label This is a suffix following a time selecting widget. " 0186 "Example: [timeedit] to 10:00am", 0187 "to %1") 0188 .subs(QLocale::system().toString(endTime)) 0189 .toString(); 0190 0191 mMoveEndTimeLabel->setText(endTimeLabel); 0192 mSelectedTime = startTime; 0193 } 0194 0195 QDate SchedulingDialog::selectedStartDate() const 0196 { 0197 return mSelectedDate; 0198 } 0199 0200 QTime SchedulingDialog::selectedStartTime() const 0201 { 0202 return mSelectedTime; 0203 } 0204 0205 #include "moc_schedulingdialog.cpp"