File indexing completed on 2024-04-28 05:11:31
0001 /* 0002 * SPDX-FileCopyrightText: 2014 Sandro Knauß <knauss@kolabsys.com> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "attendeetablemodel.h" 0008 0009 #include <KEmailAddress> 0010 0011 #include <KLocalizedString> 0012 0013 using namespace IncidenceEditorNG; 0014 0015 AttendeeTableModel::AttendeeTableModel(QObject *parent) 0016 : QAbstractTableModel(parent) 0017 { 0018 } 0019 0020 int AttendeeTableModel::rowCount(const QModelIndex & /*parent*/) const 0021 { 0022 return mAttendeeList.count(); 0023 } 0024 0025 int AttendeeTableModel::columnCount(const QModelIndex & /*parent*/) const 0026 { 0027 return 8; 0028 } 0029 0030 Qt::ItemFlags AttendeeTableModel::flags(const QModelIndex &index) const 0031 { 0032 if (!index.isValid()) { 0033 return Qt::ItemIsEnabled; 0034 } 0035 if (index.column() == Available || index.column() == Name || index.column() == Email) { // Available is read only 0036 return QAbstractTableModel::flags(index); 0037 } else { 0038 return QAbstractTableModel::flags(index) | Qt::ItemIsEditable; 0039 } 0040 } 0041 0042 QVariant AttendeeTableModel::data(const QModelIndex &index, int role) const 0043 { 0044 if (!index.isValid()) { 0045 return {}; 0046 } 0047 0048 if (index.row() >= mAttendeeList.size()) { 0049 return {}; 0050 } 0051 0052 const KCalendarCore::Attendee attendee = mAttendeeList[index.row()]; 0053 if (role == Qt::DisplayRole || role == Qt::EditRole) { 0054 switch (index.column()) { 0055 case Role: 0056 return attendee.role(); 0057 case FullName: 0058 return attendee.fullName(); 0059 case Available: { 0060 AvailableStatus available = mAttendeeAvailable[index.row()]; 0061 if (role == Qt::DisplayRole) { 0062 switch (available) { 0063 case Free: 0064 return i18n("Free"); 0065 case Busy: 0066 return i18n("Busy"); 0067 case Accepted: 0068 return i18n("Accepted"); 0069 case Unknown: 0070 return i18n("Unknown"); 0071 default: 0072 return i18n("Unknown"); 0073 } 0074 } else { 0075 return available; 0076 } 0077 } 0078 case Status: 0079 return attendee.status(); 0080 case CuType: 0081 return attendee.cuType(); 0082 case Response: 0083 return attendee.RSVP(); 0084 case Name: 0085 return attendee.name(); 0086 case Email: 0087 return attendee.email(); 0088 } 0089 } 0090 if (role == AttendeeRole) { 0091 return QVariant::fromValue(attendee); 0092 } 0093 return {}; 0094 } 0095 0096 bool AttendeeTableModel::setData(const QModelIndex &index, const QVariant &value, int role) 0097 { 0098 QString email; 0099 QString name; 0100 if (index.isValid() && role == Qt::EditRole) { 0101 KCalendarCore::Attendee &attendee = mAttendeeList[index.row()]; // clazy:exclude=detaching-member 0102 switch (index.column()) { 0103 case Role: 0104 attendee.setRole(static_cast<KCalendarCore::Attendee::Role>(value.toInt())); 0105 break; 0106 case FullName: 0107 if (mRemoveEmptyLines && value.toString().trimmed().isEmpty()) { 0108 // Do not remove last empty line if mKeepEmpty==true 0109 // (only works if initially there is only one empty line) 0110 if (!mKeepEmpty || !(attendee.name().isEmpty() && attendee.email().isEmpty())) { 0111 removeRows(index.row(), 1); 0112 return true; 0113 } 0114 } 0115 KEmailAddress::extractEmailAddressAndName(value.toString(), email, name); 0116 attendee.setName(name); 0117 attendee.setEmail(email); 0118 0119 addEmptyAttendee(); 0120 break; 0121 case Available: 0122 mAttendeeAvailable[index.row()] = static_cast<AvailableStatus>(value.toInt()); 0123 break; 0124 case Status: 0125 attendee.setStatus(static_cast<KCalendarCore::Attendee::PartStat>(value.toInt())); 0126 break; 0127 case CuType: 0128 attendee.setCuType(static_cast<KCalendarCore::Attendee::CuType>(value.toInt())); 0129 break; 0130 case Response: 0131 attendee.setRSVP(value.toBool()); 0132 break; 0133 default: 0134 return false; 0135 } 0136 Q_EMIT dataChanged(index, index); 0137 return true; 0138 } 0139 return false; 0140 } 0141 0142 QVariant AttendeeTableModel::headerData(int section, Qt::Orientation orientation, int role) const 0143 { 0144 if (role != Qt::DisplayRole) { 0145 return {}; 0146 } 0147 0148 if (orientation == Qt::Horizontal) { 0149 switch (section) { 0150 case Role: 0151 return i18nc("vCard attendee role", "Role"); 0152 case FullName: 0153 return i18nc("Attendees (name+emailaddress)", "Name"); 0154 case Available: 0155 return i18nc("Is attendee available for incidence", "Available"); 0156 case Status: 0157 return i18nc("Status of attendee in an incidence (accepted, declined, delegated, ...)", "Status"); 0158 case CuType: 0159 return i18nc("Type of calendar user (vCard attribute)", "User Type"); 0160 case Response: 0161 return i18nc("Has attendee to respond to the invitation", "Response"); 0162 case Name: 0163 return i18nc("Attendee name", "Name"); 0164 case Email: 0165 return i18nc("Attendee email", "Email"); 0166 } 0167 } 0168 0169 return {}; 0170 } 0171 0172 bool AttendeeTableModel::insertRows(int position, int rows, const QModelIndex &parent) 0173 { 0174 beginInsertRows(parent, position, position + rows - 1); 0175 0176 for (int row = 0; row < rows; ++row) { 0177 KCalendarCore::Attendee attendee(QLatin1StringView(""), QLatin1StringView("")); 0178 mAttendeeList.insert(position, attendee); 0179 mAttendeeAvailable.insert(mAttendeeAvailable.begin() + position, AvailableStatus{}); 0180 } 0181 0182 endInsertRows(); 0183 return true; 0184 } 0185 0186 bool AttendeeTableModel::removeRows(int position, int rows, const QModelIndex &parent) 0187 { 0188 beginRemoveRows(parent, position, position + rows - 1); 0189 0190 for (int row = 0; row < rows; ++row) { 0191 mAttendeeAvailable.erase(mAttendeeAvailable.begin() + position); 0192 mAttendeeList.remove(position); 0193 } 0194 0195 endRemoveRows(); 0196 return true; 0197 } 0198 0199 bool AttendeeTableModel::insertAttendee(int position, const KCalendarCore::Attendee &attendee) 0200 { 0201 beginInsertRows(QModelIndex(), position, position); 0202 mAttendeeList.insert(position, attendee); 0203 mAttendeeAvailable.insert(mAttendeeAvailable.begin() + position, AvailableStatus{}); 0204 endInsertRows(); 0205 0206 addEmptyAttendee(); 0207 0208 return true; 0209 } 0210 0211 void AttendeeTableModel::setAttendees(const KCalendarCore::Attendee::List &attendees) 0212 { 0213 beginResetModel(); 0214 0215 mAttendeeList = attendees; 0216 mAttendeeAvailable.clear(); 0217 mAttendeeAvailable.resize(attendees.size()); 0218 0219 addEmptyAttendee(); 0220 0221 endResetModel(); 0222 } 0223 0224 KCalendarCore::Attendee::List AttendeeTableModel::attendees() const 0225 { 0226 return mAttendeeList; 0227 } 0228 0229 void AttendeeTableModel::addEmptyAttendee() 0230 { 0231 if (mKeepEmpty) { 0232 bool create = true; 0233 for (const KCalendarCore::Attendee &attendee : std::as_const(mAttendeeList)) { 0234 if (attendee.fullName().isEmpty()) { 0235 create = false; 0236 break; 0237 } 0238 } 0239 0240 if (create) { 0241 insertRows(rowCount(), 1); 0242 } 0243 } 0244 } 0245 0246 bool AttendeeTableModel::keepEmpty() const 0247 { 0248 return mKeepEmpty; 0249 } 0250 0251 void AttendeeTableModel::setKeepEmpty(bool keepEmpty) 0252 { 0253 if (keepEmpty != mKeepEmpty) { 0254 mKeepEmpty = keepEmpty; 0255 addEmptyAttendee(); 0256 } 0257 } 0258 0259 bool AttendeeTableModel::removeEmptyLines() const 0260 { 0261 return mRemoveEmptyLines; 0262 } 0263 0264 void AttendeeTableModel::setRemoveEmptyLines(bool removeEmptyLines) 0265 { 0266 mRemoveEmptyLines = removeEmptyLines; 0267 } 0268 0269 ResourceFilterProxyModel::ResourceFilterProxyModel(QObject *parent) 0270 : QSortFilterProxyModel(parent) 0271 { 0272 } 0273 0274 bool ResourceFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const 0275 { 0276 const QModelIndex cuTypeIndex = sourceModel()->index(sourceRow, AttendeeTableModel::CuType, sourceParent); 0277 KCalendarCore::Attendee::CuType cuType = static_cast<KCalendarCore::Attendee::CuType>(sourceModel()->data(cuTypeIndex).toUInt()); 0278 0279 return cuType == KCalendarCore::Attendee::Resource || cuType == KCalendarCore::Attendee::Room; 0280 } 0281 0282 AttendeeFilterProxyModel::AttendeeFilterProxyModel(QObject *parent) 0283 : QSortFilterProxyModel(parent) 0284 { 0285 } 0286 0287 bool AttendeeFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const 0288 { 0289 const QModelIndex cuTypeIndex = sourceModel()->index(sourceRow, AttendeeTableModel::CuType, sourceParent); 0290 KCalendarCore::Attendee::CuType cuType = static_cast<KCalendarCore::Attendee::CuType>(sourceModel()->data(cuTypeIndex).toUInt()); 0291 0292 return !(cuType == KCalendarCore::Attendee::Resource || cuType == KCalendarCore::Attendee::Room); 0293 } 0294 0295 #include "moc_attendeetablemodel.cpp"