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"