File indexing completed on 2024-04-28 05:11:36
0001 /* 0002 * SPDX-FileCopyrightText: 2014 Sandro Knauß <knauss@kolabsys.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later WITH Qt-Commercial-exception-1.0 0005 */ 0006 0007 #include "incidenceresource.h" 0008 #include "attendeecomboboxdelegate.h" 0009 #include "attendeelineeditdelegate.h" 0010 #include "incidencedatetime.h" 0011 #include "resourcemanagement.h" 0012 #include "resourcemodel.h" 0013 0014 #include "ui_dialogdesktop.h" 0015 0016 #include <KDescendantsProxyModel> 0017 #include <KEmailAddress> 0018 #include <QCompleter> 0019 0020 using namespace IncidenceEditorNG; 0021 0022 class SwitchRoleProxy : public QSortFilterProxyModel 0023 { 0024 public: 0025 explicit SwitchRoleProxy(QObject *parent = nullptr) 0026 : QSortFilterProxyModel(parent) 0027 { 0028 } 0029 0030 [[nodiscard]] QVariant data(const QModelIndex &index, int role) const override 0031 { 0032 QVariant d; 0033 if (role == Qt::DisplayRole || role == Qt::EditRole) { 0034 d = QSortFilterProxyModel::data(index, ResourceModel::FullName); 0035 return d; 0036 } 0037 d = QSortFilterProxyModel::data(index, role); 0038 return d; 0039 } 0040 }; 0041 0042 IncidenceResource::IncidenceResource(IncidenceAttendee *ieAttendee, IncidenceDateTime *dateTime, Ui::EventOrTodoDesktop *ui) 0043 : IncidenceEditor(nullptr) 0044 , mUi(ui) 0045 , dataModel(ieAttendee->dataModel()) 0046 , mDateTime(dateTime) 0047 , resourceDialog(new ResourceManagement()) 0048 { 0049 setObjectName(QLatin1StringView("IncidenceResource")); 0050 connect(resourceDialog, &ResourceManagement::accepted, this, &IncidenceResource::dialogOkPressed); 0051 0052 connect(mDateTime, &IncidenceDateTime::startDateChanged, this, &IncidenceResource::slotDateChanged); 0053 connect(mDateTime, &IncidenceDateTime::endDateChanged, this, &IncidenceResource::slotDateChanged); 0054 0055 QStringList attrs; 0056 attrs << QStringLiteral("cn") << QStringLiteral("mail"); 0057 0058 completer = new QCompleter(this); 0059 auto model = new ResourceModel(attrs, this); 0060 0061 auto proxyModel = new KDescendantsProxyModel(this); 0062 proxyModel->setSourceModel(model); 0063 auto proxyModel2 = new SwitchRoleProxy(this); 0064 proxyModel2->setSourceModel(proxyModel); 0065 0066 completer->setModel(proxyModel2); 0067 completer->setCompletionRole(ResourceModel::FullName); 0068 completer->setWrapAround(false); 0069 mUi->mNewResource->setCompleter(completer); 0070 0071 auto attendeeDelegate = new AttendeeLineEditDelegate(this); 0072 0073 auto filterProxyModel = new ResourceFilterProxyModel(this); 0074 filterProxyModel->setDynamicSortFilter(true); 0075 filterProxyModel->setSourceModel(dataModel); 0076 0077 mUi->mResourcesTable->setModel(filterProxyModel); 0078 mUi->mResourcesTable->setItemDelegateForColumn(AttendeeTableModel::Role, ieAttendee->roleDelegate()); 0079 mUi->mResourcesTable->setItemDelegateForColumn(AttendeeTableModel::FullName, attendeeDelegate); 0080 mUi->mResourcesTable->setItemDelegateForColumn(AttendeeTableModel::Status, ieAttendee->stateDelegate()); 0081 mUi->mResourcesTable->setItemDelegateForColumn(AttendeeTableModel::Response, ieAttendee->responseDelegate()); 0082 0083 connect(mUi->mFindResourcesButton, &QPushButton::clicked, this, &IncidenceResource::findResources); 0084 connect(mUi->mBookResourceButton, &QPushButton::clicked, this, &IncidenceResource::bookResource); 0085 connect(filterProxyModel, &ResourceFilterProxyModel::layoutChanged, this, &IncidenceResource::layoutChanged); 0086 connect(filterProxyModel, &ResourceFilterProxyModel::modelReset, this, &IncidenceResource::layoutChanged); 0087 connect(filterProxyModel, &ResourceFilterProxyModel::layoutChanged, this, &IncidenceResource::updateCount); 0088 connect(filterProxyModel, &ResourceFilterProxyModel::rowsInserted, this, &IncidenceResource::updateCount); 0089 connect(filterProxyModel, &ResourceFilterProxyModel::rowsRemoved, this, &IncidenceResource::updateCount); 0090 connect(filterProxyModel, &ResourceFilterProxyModel::modelReset, this, &IncidenceResource::updateCount); 0091 // only update when FullName is changed 0092 connect(filterProxyModel, &ResourceFilterProxyModel::dataChanged, this, &IncidenceResource::updateCount); 0093 } 0094 0095 IncidenceResource::~IncidenceResource() 0096 { 0097 delete resourceDialog; 0098 } 0099 0100 void IncidenceResource::load(const KCalendarCore::Incidence::Ptr &incidence) 0101 { 0102 Q_UNUSED(incidence) 0103 slotDateChanged(); 0104 } 0105 0106 void IncidenceResource::slotDateChanged() 0107 { 0108 resourceDialog->slotDateChanged(mDateTime->startDate(), mDateTime->endDate()); 0109 } 0110 0111 void IncidenceResource::save(const KCalendarCore::Incidence::Ptr &incidence) 0112 { 0113 Q_UNUSED(incidence) 0114 // all logic inside IncidenceAtendee (using same model) 0115 } 0116 0117 bool IncidenceResource::isDirty() const 0118 { 0119 // all logic inside IncidenceAtendee (using same model) 0120 return false; 0121 } 0122 0123 void IncidenceResource::bookResource() 0124 { 0125 if (mUi->mNewResource->text().trimmed().isEmpty()) { 0126 return; 0127 } 0128 QString name; 0129 QString email; 0130 KEmailAddress::extractEmailAddressAndName(mUi->mNewResource->text(), email, name); 0131 KCalendarCore::Attendee attendee(name, email); 0132 attendee.setCuType(KCalendarCore::Attendee::Resource); 0133 dataModel->insertAttendee(dataModel->rowCount(), attendee); 0134 } 0135 0136 void IncidenceResource::findResources() 0137 { 0138 resourceDialog->show(); 0139 } 0140 0141 void IncidenceResource::dialogOkPressed() 0142 { 0143 ResourceItem::Ptr item = resourceDialog->selectedItem(); 0144 if (item) { 0145 const QString name = QString::fromLatin1(item->ldapObject().value(QStringLiteral("cn"))); 0146 const QString email = QString::fromLatin1(item->ldapObject().value(QStringLiteral("mail"))); 0147 KCalendarCore::Attendee attendee(name, email); 0148 attendee.setCuType(KCalendarCore::Attendee::Resource); 0149 dataModel->insertAttendee(dataModel->rowCount(), attendee); 0150 } 0151 } 0152 0153 void IncidenceResource::layoutChanged() 0154 { 0155 QHeaderView *headerView = mUi->mResourcesTable->horizontalHeader(); 0156 headerView->setSectionHidden(AttendeeTableModel::CuType, true); 0157 headerView->setSectionHidden(AttendeeTableModel::Name, true); 0158 headerView->setSectionHidden(AttendeeTableModel::Email, true); 0159 headerView->setSectionResizeMode(AttendeeTableModel::Role, QHeaderView::ResizeToContents); 0160 headerView->setSectionResizeMode(AttendeeTableModel::FullName, QHeaderView::Stretch); 0161 headerView->setSectionResizeMode(AttendeeTableModel::Available, QHeaderView::ResizeToContents); 0162 headerView->setSectionResizeMode(AttendeeTableModel::Status, QHeaderView::ResizeToContents); 0163 headerView->setSectionResizeMode(AttendeeTableModel::Response, QHeaderView::ResizeToContents); 0164 } 0165 0166 void IncidenceResource::updateCount() 0167 { 0168 Q_EMIT resourceCountChanged(resourceCount()); 0169 } 0170 0171 int IncidenceResource::resourceCount() const 0172 { 0173 int c = 0; 0174 QModelIndex index; 0175 QAbstractItemModel *model = mUi->mResourcesTable->model(); 0176 if (!model) { 0177 return 0; 0178 } 0179 const int nbRow = model->rowCount(QModelIndex()); 0180 for (int i = 0; i < nbRow; ++i) { 0181 index = model->index(i, AttendeeTableModel::FullName); 0182 if (!model->data(index).toString().isEmpty()) { 0183 ++c; 0184 } 0185 } 0186 return c; 0187 } 0188 0189 #include "moc_incidenceresource.cpp"