Branch 'kolab/integration/4.13.0' - 23 commits - incidenceeditor-ng/attendeecomboboxdelegate.cpp incidenceeditor-ng/attendeecomboboxdelegate.h incidenceeditor-ng/attendeeline.cpp incidenceeditor-ng/attendeetablemodel.cpp incidenceeditor-ng/attendeetablemodel.h incidenceeditor-ng/CMakeLists.txt incidenceeditor-ng/dialogdesktop.ui incidenceeditor-ng/incidenceattendee.cpp incidenceeditor-ng/incidenceattendee.h incidenceeditor-ng/incidencedialog.cpp incidenceeditor-ng/incidencedialog.h incidenceeditor-ng/incidenceresource.cpp incidenceeditor-ng/incidenceresource.h incidenceeditor-ng/ldaputils.cpp incidenceeditor-ng/ldaputils.h incidenceeditor-ng/resourceitem.cpp incidenceeditor-ng/resourceitem.h incidenceeditor-ng/resourcemanagement.cpp incidenceeditor-ng/resourcemanagement.h incidenceeditor-ng/resourcemanagement.ui incidenceeditor-ng/resourcemodel.cpp incidenceeditor-ng/resourcemodel.h incidenceeditor-ng/tests
Sandro Knauß
knauss at kolabsys.com
Mon Aug 11 14:54:31 CEST 2014
incidenceeditor-ng/CMakeLists.txt | 10
incidenceeditor-ng/attendeecomboboxdelegate.cpp | 250 ++++++++++++
incidenceeditor-ng/attendeecomboboxdelegate.h | 111 +++++
incidenceeditor-ng/attendeeline.cpp | 4
incidenceeditor-ng/attendeetablemodel.cpp | 276 +++++++++++++
incidenceeditor-ng/attendeetablemodel.h | 108 +++++
incidenceeditor-ng/dialogdesktop.ui | 150 ++++++-
incidenceeditor-ng/incidenceattendee.cpp | 429 ++++++++++++++++-----
incidenceeditor-ng/incidenceattendee.h | 32 +
incidenceeditor-ng/incidencedialog.cpp | 27 +
incidenceeditor-ng/incidencedialog.h | 1
incidenceeditor-ng/incidenceresource.cpp | 189 +++++++++
incidenceeditor-ng/incidenceresource.h | 84 ++++
incidenceeditor-ng/ldaputils.cpp | 62 +++
incidenceeditor-ng/ldaputils.h | 29 +
incidenceeditor-ng/resourceitem.cpp | 167 ++++++++
incidenceeditor-ng/resourceitem.h | 136 ++++++
incidenceeditor-ng/resourcemanagement.cpp | 349 +++++++++++++++++
incidenceeditor-ng/resourcemanagement.h | 87 ++++
incidenceeditor-ng/resourcemanagement.ui | 105 +++++
incidenceeditor-ng/resourcemodel.cpp | 246 ++++++++++++
incidenceeditor-ng/resourcemodel.h | 137 ++++++
incidenceeditor-ng/tests/CMakeLists.txt | 14
incidenceeditor-ng/tests/resourcemanagment_gui.cpp | 43 ++
24 files changed, 2925 insertions(+), 121 deletions(-)
New commits:
commit d3a296ef1fb14d22d5263ca70a368f192f3569eb
Author: Sandro Knauà <knauss at kolabsys.com>
Date: Mon Aug 11 13:55:51 2014 +0200
supress email address in resoucemangement
email addresses for resources are only answerd automatically and are
used by iTip, but they should not be uesed from a user to send mails to
it.
diff --git a/incidenceeditor-ng/resourcemanagement.cpp b/incidenceeditor-ng/resourcemanagement.cpp
index 781ae26..e9c31b0 100644
--- a/incidenceeditor-ng/resourcemanagement.cpp
+++ b/incidenceeditor-ng/resourcemanagement.cpp
@@ -242,7 +242,8 @@ void ResourceManagement::showDetails(const KLDAP::LdapObject &obj, const KLDAP::
// Fill formDetails with data
foreach(const QString & key, obj.attributes().keys()) {
- if (key == QLatin1String("objectClass")) {
+ if (key == QLatin1String("objectClass")
+ || key == QLatin1String("email")) {
continue;
} else if (key == QLatin1String("owner")) {
QStringList attrs;
commit 35ee7277a26efcda994bbda9f62a68736bb8b354
Author: Sandro Knauà <knauss at kolabsys.com>
Date: Wed Aug 6 15:20:09 2014 +0200
Fix column width for attendee/resource tab
diff --git a/incidenceeditor-ng/incidenceattendee.cpp b/incidenceeditor-ng/incidenceattendee.cpp
index 1dd0e12..56084af 100644
--- a/incidenceeditor-ng/incidenceattendee.cpp
+++ b/incidenceeditor-ng/incidenceattendee.cpp
@@ -150,8 +150,7 @@ IncidenceAttendee::IncidenceAttendee( QWidget *parent, IncidenceDateTime *dateTi
mAttendeeDelegate = new AttendeeLineEditDelegate(this);
mAttendeeDelegate->setCompletionMode( KGlobalSettings::self()->completionMode() );
- QHeaderView* headerView = mUi->mAttendeeTable->horizontalHeader();
- headerView->setResizeMode(QHeaderView::ResizeToContents);
+
mUi->mAttendeeTable->setItemDelegateForColumn(AttendeeTableModel::Role, roleDelegate());
mUi->mAttendeeTable->setItemDelegateForColumn(AttendeeTableModel::FullName, attendeeDelegate());
@@ -709,10 +708,15 @@ AttendeeLineEditDelegate *IncidenceAttendee::attendeeDelegate()
void IncidenceAttendee::filterLayoutChanged()
{
#ifndef KDEPIM_MOBILE_UI
- mUi->mAttendeeTable->setColumnHidden(AttendeeTableModel::CuType, true);
- mUi->mAttendeeTable->setColumnHidden(AttendeeTableModel::Name, true);
- mUi->mAttendeeTable->setColumnHidden(AttendeeTableModel::Email, true);
- mUi->mAttendeeTable->setColumnHidden(AttendeeTableModel::Available, true);
+ QHeaderView* headerView = mUi->mAttendeeTable->horizontalHeader();
+ headerView->setResizeMode(AttendeeTableModel::Role, QHeaderView::ResizeToContents);
+ headerView->setResizeMode(AttendeeTableModel::FullName, QHeaderView::Stretch);
+ headerView->setResizeMode(AttendeeTableModel::Status, QHeaderView::ResizeToContents);
+ headerView->setResizeMode(AttendeeTableModel::Response, QHeaderView::ResizeToContents);
+ headerView->setSectionHidden(AttendeeTableModel::CuType, true);
+ headerView->setSectionHidden(AttendeeTableModel::Name, true);
+ headerView->setSectionHidden(AttendeeTableModel::Email, true);
+ headerView->setSectionHidden(AttendeeTableModel::Available, true);
#endif
}
diff --git a/incidenceeditor-ng/incidenceresource.cpp b/incidenceeditor-ng/incidenceresource.cpp
index 5fc1a78..23e229b 100644
--- a/incidenceeditor-ng/incidenceresource.cpp
+++ b/incidenceeditor-ng/incidenceresource.cpp
@@ -92,8 +92,6 @@ IncidenceResource::IncidenceResource(IncidenceAttendee* ieAttendee, Ui::EventOrT
filterProxyModel->setDynamicSortFilter(true);
filterProxyModel->setSourceModel(dataModel);
- QHeaderView* headerView = mUi->mResourcesTable->horizontalHeader();
- headerView->setResizeMode(QHeaderView::ResizeToContents);
mUi->mResourcesTable->setModel(filterProxyModel);
mUi->mResourcesTable->setItemDelegateForColumn(AttendeeTableModel::Role, ieAttendee->roleDelegate());
@@ -149,9 +147,15 @@ void IncidenceResource::findResources()
void IncidenceResource::layoutChanged()
{
#ifndef KDEPIM_MOBILE_UI
- mUi->mResourcesTable->setColumnHidden(AttendeeTableModel::CuType, true);
- mUi->mResourcesTable->setColumnHidden(AttendeeTableModel::Name, true);
- mUi->mResourcesTable->setColumnHidden(AttendeeTableModel::Email, true);
+ QHeaderView* headerView = mUi->mResourcesTable->horizontalHeader();
+ headerView->setSectionHidden(AttendeeTableModel::CuType, true);
+ headerView->setSectionHidden(AttendeeTableModel::Name, true);
+ headerView->setSectionHidden(AttendeeTableModel::Email, true);
+ headerView->setResizeMode(AttendeeTableModel::Role, QHeaderView::ResizeToContents);
+ headerView->setResizeMode(AttendeeTableModel::FullName, QHeaderView::Stretch);
+ headerView->setResizeMode(AttendeeTableModel::Available, QHeaderView::ResizeToContents);
+ headerView->setResizeMode(AttendeeTableModel::Status, QHeaderView::ResizeToContents);
+ headerView->setResizeMode(AttendeeTableModel::Response, QHeaderView::ResizeToContents);
#endif
}
commit e1e1c407f0f8fa88c6199a274478c533ff65e902
Author: Sandro Knauà <knauss at kolabsys.com>
Date: Wed Aug 6 15:18:43 2014 +0200
dalogdesktop made book resource via Enter
diff --git a/incidenceeditor-ng/dialogdesktop.ui b/incidenceeditor-ng/dialogdesktop.ui
index 13ee780..a2a7063 100644
--- a/incidenceeditor-ng/dialogdesktop.ui
+++ b/incidenceeditor-ng/dialogdesktop.ui
@@ -858,6 +858,9 @@
<layout class="QHBoxLayout" name="horizontalLayout_11">
<item>
<widget class="KLineEdit" name="mNewResource">
+ <property name="trapEnterKeyEvent" stdset="0">
+ <bool>true</bool>
+ </property>
<property name="showClearButton" stdset="0">
<bool>true</bool>
</property>
@@ -868,6 +871,12 @@
<property name="text">
<string>Book resource</string>
</property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ <property name="default">
+ <bool>false</bool>
+ </property>
</widget>
</item>
<item>
@@ -875,10 +884,13 @@
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Preferred</enum>
+ </property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
- <height>20</height>
+ <height>0</height>
</size>
</property>
</spacer>
commit 6ee7e3d32d8accb844ead8df90c1f35dc799faa8
Author: Sandro Knauà <knauss at kolabsys.com>
Date: Wed Aug 6 15:17:25 2014 +0200
available status for attendeetablemodel
diff --git a/incidenceeditor-ng/attendeetablemodel.cpp b/incidenceeditor-ng/attendeetablemodel.cpp
index 4ad6b05..0fb3074 100644
--- a/incidenceeditor-ng/attendeetablemodel.cpp
+++ b/incidenceeditor-ng/attendeetablemodel.cpp
@@ -54,7 +54,11 @@ QVariant AttendeeTableModel::data(const QModelIndex &index, int role) const
case FullName:
return attendeeList[index.row()]->fullName();
case Available:
- return 0;//attendeeList.at(index.row()).available;
+ if (role == Qt::DisplayRole) {
+ return i18n("Unknown");
+ } else {
+ return 0; //attendeeList.at(index.row()).available;
+ }
case Status:
return attendeeList[index.row()]->status();
case CuType:
commit 3477ab400f59224e7c2051ee91e0604fc7f98b40
Author: Sandro Knauà <knauss at kolabsys.com>
Date: Wed Aug 6 13:26:20 2014 +0200
Localize resousemanagement
diff --git a/incidenceeditor-ng/CMakeLists.txt b/incidenceeditor-ng/CMakeLists.txt
index b184732..4b33d45 100644
--- a/incidenceeditor-ng/CMakeLists.txt
+++ b/incidenceeditor-ng/CMakeLists.txt
@@ -70,6 +70,7 @@ set(incidenceeditors_ng_shared_LIB_SRCS
resourcemanagement.cpp
resourceitem.cpp
resourcemodel.cpp
+ ldaputils.cpp
attendeetablemodel.cpp
attendeecomboboxdelegate.cpp
)
@@ -105,6 +106,7 @@ target_link_libraries(incidenceeditorsng
akonadi-kmime
${QT_QTCORE_LIBRARY}
${QT_QTGUI_LIBRARY}
+ ${QJSON_LIBRARIES}
${KDE4_KDEUI_LIBS}
${KDEPIMLIBS_KCALCORE_LIBS}
${KDEPIMLIBS_KCALUTILS_LIBS}
@@ -158,6 +160,7 @@ install(TARGETS incidenceeditorsng ${INSTALL_TARGETS_DEFAULT_ARGS})
${KDEPIMLIBS_KCALUTILS_LIBS}
${KDEPIMLIBS_KCALCORE_LIBS}
${KDEPIMLIBS_MAILTRANSPORT_LIBS}
+ ${QJSON_LIBRARIES}
)
set_target_properties(incidenceeditorsngmobile PROPERTIES
diff --git a/incidenceeditor-ng/attendeetablemodel.cpp b/incidenceeditor-ng/attendeetablemodel.cpp
index a3242e8..4ad6b05 100644
--- a/incidenceeditor-ng/attendeetablemodel.cpp
+++ b/incidenceeditor-ng/attendeetablemodel.cpp
@@ -1,5 +1,7 @@
#include "attendeetablemodel.h"
+#include <klocalizedstring.h>
+
#include <KCalCore/Attendee>
#include <KPIMUtils/Email>
@@ -125,21 +127,21 @@ QVariant AttendeeTableModel::headerData(int section, Qt::Orientation orientation
if (orientation == Qt::Horizontal) {
switch (section) {
case Role:
- return QString("role");
+ return i18nc("vcard attendee role", "Role");
case FullName:
- return QString("fullname");
+ return i18nc("attendees (name+emailaddress)", "Fullname");
case Available:
- return QString("available");
+ return i18nc("is attendee available for incidence", "Available");
case Status:
- return QString("status");
+ return i18nc("Status of attendee in an incidence (accepted, declined, delegated, ...)", "Status");
case CuType:
- return QString("cuType");
+ return i18nc("Type of resource (vCard attribute)", "cuType");
case Response:
- return QString("response");
+ return i18nc("has attendee to respond to the invitation", "Response");
case Name:
- return QString("name");
+ return i18nc("attendee name", "name");
case Email:
- return QString("email");
+ return i18nc("attendee email", "email");
}
}
diff --git a/incidenceeditor-ng/dialogdesktop.ui b/incidenceeditor-ng/dialogdesktop.ui
index 2a10c51..13ee780 100644
--- a/incidenceeditor-ng/dialogdesktop.ui
+++ b/incidenceeditor-ng/dialogdesktop.ui
@@ -13,16 +13,7 @@
<layout class="QVBoxLayout" name="mainVerticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
+ <property name="margin">
<number>0</number>
</property>
<item row="0" column="0">
@@ -50,16 +41,7 @@
<item row="1" column="1">
<widget class="QWidget" name="mInvitationBar" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_10">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
+ <property name="margin">
<number>0</number>
</property>
<item>
@@ -213,16 +195,7 @@
<item row="5" column="1">
<widget class="QWidget" name="mCompletionPriorityWidget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_8">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
+ <property name="margin">
<number>0</number>
</property>
<item>
@@ -809,16 +782,7 @@
</property>
<widget class="QWidget" name="page">
<layout class="QGridLayout" name="gridLayout_2">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
+ <property name="margin">
<number>0</number>
</property>
<item row="0" column="0">
@@ -841,16 +805,7 @@
</widget>
<widget class="QWidget" name="page_2">
<layout class="QGridLayout" name="gridLayout_3">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
+ <property name="margin">
<number>0</number>
</property>
<item row="0" column="0">
@@ -902,7 +857,11 @@
<item row="1" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_11">
<item>
- <widget class="KLineEdit" name="mNewResource"/>
+ <widget class="KLineEdit" name="mNewResource">
+ <property name="showClearButton" stdset="0">
+ <bool>true</bool>
+ </property>
+ </widget>
</item>
<item>
<widget class="QPushButton" name="mBookResourceButton">
@@ -1178,32 +1137,14 @@
<widget class="QWidget" name="never_page"/>
<widget class="QWidget" name="daily_page">
<layout class="QGridLayout" name="gridLayout_11">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
+ <property name="margin">
<number>0</number>
</property>
</layout>
</widget>
<widget class="QWidget" name="weekly_page">
<layout class="QGridLayout" name="gridLayout_4">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
+ <property name="margin">
<number>0</number>
</property>
<item row="0" column="0">
@@ -1223,16 +1164,7 @@
</widget>
<widget class="QWidget" name="Monthly">
<layout class="QGridLayout" name="gridLayout_6">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
+ <property name="margin">
<number>0</number>
</property>
<item row="0" column="0">
@@ -1265,16 +1197,7 @@
</widget>
<widget class="QWidget" name="yearly_page">
<layout class="QGridLayout" name="gridLayout_7">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
+ <property name="margin">
<number>0</number>
</property>
<item row="0" column="0">
@@ -1366,32 +1289,14 @@
</property>
<widget class="QWidget" name="no_end">
<layout class="QGridLayout" name="gridLayout_16">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
+ <property name="margin">
<number>0</number>
</property>
</layout>
</widget>
<widget class="QWidget" name="end_on">
<layout class="QGridLayout" name="gridLayout_14">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
+ <property name="margin">
<number>0</number>
</property>
<item row="0" column="0">
@@ -1424,19 +1329,10 @@
</widget>
<widget class="QWidget" name="end_after">
<layout class="QGridLayout" name="gridLayout_10">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
+ <property name="horizontalSpacing">
<number>0</number>
</property>
- <property name="horizontalSpacing">
+ <property name="margin">
<number>0</number>
</property>
<item row="0" column="0">
@@ -1662,6 +1558,21 @@
</widget>
<customwidgets>
<customwidget>
+ <class>KRichTextEdit</class>
+ <extends>KTextEdit</extends>
+ <header>krichtextedit.h</header>
+ </customwidget>
+ <customwidget>
+ <class>KTimeComboBox</class>
+ <extends>KComboBox</extends>
+ <header>ktimecombobox.h</header>
+ </customwidget>
+ <customwidget>
+ <class>KDateComboBox</class>
+ <extends>KComboBox</extends>
+ <header>kdatecombobox.h</header>
+ </customwidget>
+ <customwidget>
<class>KComboBox</class>
<extends>QComboBox</extends>
<header>kcombobox.h</header>
@@ -1683,6 +1594,11 @@
<header>ktextedit.h</header>
</customwidget>
<customwidget>
+ <class>KRichTextWidget</class>
+ <extends>KRichTextEdit</extends>
+ <header>krichtextwidget.h</header>
+ </customwidget>
+ <customwidget>
<class>KTabWidget</class>
<extends>QTabWidget</extends>
<header>ktabwidget.h</header>
@@ -1714,26 +1630,6 @@
<header>libkdepim/widgets/tagwidgets.h</header>
<container>1</container>
</customwidget>
- <customwidget>
- <class>KRichTextEdit</class>
- <extends>KTextEdit</extends>
- <header>krichtextedit.h</header>
- </customwidget>
- <customwidget>
- <class>KTimeComboBox</class>
- <extends>KComboBox</extends>
- <header>ktimecombobox.h</header>
- </customwidget>
- <customwidget>
- <class>KDateComboBox</class>
- <extends>KComboBox</extends>
- <header>kdatecombobox.h</header>
- </customwidget>
- <customwidget>
- <class>KRichTextWidget</class>
- <extends>KRichTextEdit</extends>
- <header>krichtextwidget.h</header>
- </customwidget>
</customwidgets>
<resources/>
<connections>
@@ -1744,12 +1640,12 @@
<slot>setCurrentIndex(int)</slot>
<hints>
<hint type="sourcelabel">
- <x>150</x>
- <y>298</y>
+ <x>144</x>
+ <y>314</y>
</hint>
<hint type="destinationlabel">
- <x>428</x>
- <y>298</y>
+ <x>144</x>
+ <y>314</y>
</hint>
</hints>
</connection>
@@ -1760,12 +1656,28 @@
<slot>setCurrentIndex(int)</slot>
<hints>
<hint type="sourcelabel">
- <x>133</x>
- <y>223</y>
+ <x>142</x>
+ <y>304</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>104</x>
+ <y>280</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>mNewResource</sender>
+ <signal>returnPressed()</signal>
+ <receiver>mBookResourceButton</receiver>
+ <slot>click()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>271</x>
+ <y>805</y>
</hint>
<hint type="destinationlabel">
- <x>143</x>
- <y>255</y>
+ <x>402</x>
+ <y>808</y>
</hint>
</hints>
</connection>
diff --git a/incidenceeditor-ng/incidenceresource.cpp b/incidenceeditor-ng/incidenceresource.cpp
index 1178a9e..5fc1a78 100644
--- a/incidenceeditor-ng/incidenceresource.cpp
+++ b/incidenceeditor-ng/incidenceresource.cpp
@@ -70,7 +70,7 @@ IncidenceResource::IncidenceResource(IncidenceAttendee* ieAttendee, Ui::EventOrT
#ifndef KDEPIM_MOBILE_UI
QStringList attrs;
- attrs << QLatin1String("cn");
+ attrs << QLatin1String("cn") << QLatin1String("mail");
completer = new QCompleter(this);
ResourceModel *model = new ResourceModel(attrs, this);
diff --git a/incidenceeditor-ng/ldaputils.cpp b/incidenceeditor-ng/ldaputils.cpp
new file mode 100644
index 0000000..89235ea
--- /dev/null
+++ b/incidenceeditor-ng/ldaputils.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2014 Sandro Knauà <knauss at kolabsys.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "ldaputils.h"
+#include <klocalizedstring.h>
+
+
+QString translateLDAPAttributeForDisplay(const QString &attribute)
+{
+ QString ret = attribute;
+ if (attribute == QLatin1String("cn")) {
+ ret = i18nc("ldap attribute cn", "Common name");
+ } else if (attribute == QLatin1String("mail")) {
+ ret = i18nc("ldap attribute mail", "Email");
+ } else if (attribute == QLatin1String("givenname")) {
+ ret = i18nc("ldap attribute givenname", "Given name");
+ } else if (attribute == QLatin1String("sn")) {
+ ret = i18nc("ldap attribute sn", "Surname");
+ } else if (attribute == QLatin1String("ou")) {
+ ret = i18nc("ldap attribute ou", "Organization");
+ } else if (attribute == QLatin1String("objectClass")) {
+ ret = i18nc("ldap attribute objectClass", "Object class");
+ } else if (attribute == QLatin1String("description")) {
+ ret = i18nc("ldap attribute description", "Description");
+ } else if (attribute == QLatin1String("telephoneNumber")) {
+ ret = i18nc("ldap attribute telephoneNumber", "Telephone");
+ } else if (attribute == QLatin1String("mobile")) {
+ ret = i18nc("ldap attribute mobile", "Mobile");
+ }
+ return ret;
+}
+
+QString translateKolabLDAPAttributeForDisplay(const QString &attribute)
+{
+ QString ret = attribute;
+ if (attribute == QLatin1String("numseats")) {
+ ret = i18nc("kolabldap", "Number of seats");
+ } else if (attribute == QLatin1String("beamer_present")) {
+ ret = i18nc("kolabldap", "Beamer");
+ } else if (attribute == QLatin1String("conf_phone_present")) {
+ ret = i18nc("kolabldap", "Conference phone");
+ }
+ return ret;
+}
diff --git a/incidenceeditor-ng/ldaputils.h b/incidenceeditor-ng/ldaputils.h
new file mode 100644
index 0000000..e89b9ca
--- /dev/null
+++ b/incidenceeditor-ng/ldaputils.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2014 Sandro Knauà <knauss at kolabsys.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef LDAPUTILS_H
+#define LDAPUTILS_H
+
+#include <QString>
+
+QString translateLDAPAttributeForDisplay(const QString &attribute);
+QString translateKolabLDAPAttributeForDisplay(const QString &attribute);
+#endif //LDAPUTLS_H
\ No newline at end of file
diff --git a/incidenceeditor-ng/resourceitem.cpp b/incidenceeditor-ng/resourceitem.cpp
index 7089ea3..08961ad 100644
--- a/incidenceeditor-ng/resourceitem.cpp
+++ b/incidenceeditor-ng/resourceitem.cpp
@@ -163,4 +163,5 @@ void ResourceItem::slotLDAPResult(const KLDAP::LdapClient &/*client*/,
itemData << "";
}
}
+ emit searchFinished();
}
\ No newline at end of file
diff --git a/incidenceeditor-ng/resourceitem.h b/incidenceeditor-ng/resourceitem.h
index 3c04373..e5997ca 100644
--- a/incidenceeditor-ng/resourceitem.h
+++ b/incidenceeditor-ng/resourceitem.h
@@ -67,6 +67,9 @@ private:
QVector<QVariant> itemData;
ResourceItem::Ptr parentItem;
+signals:
+ void searchFinished();
+
public:
/* Returns the attributes of the requested ldapObject.
*
diff --git a/incidenceeditor-ng/resourcemanagement.cpp b/incidenceeditor-ng/resourcemanagement.cpp
index e33349a..781ae26 100644
--- a/incidenceeditor-ng/resourcemanagement.cpp
+++ b/incidenceeditor-ng/resourcemanagement.cpp
@@ -25,6 +25,7 @@
#include "ui_resourcemanagement.h"
#include "resourcemodel.h"
#include "freebusyitem.h"
+#include "ldaputils.h"
#include "freebusyganttproxymodel.h"
@@ -36,6 +37,8 @@
#include <akonadi/calendar/freebusymanager.h>
#include <kldap/ldapobject.h>
+#include <qjson/parser.h>
+
#include <QPointer>
#include <QSplitter>
#include <QStringList>
@@ -141,12 +144,12 @@ public:
{
}
- QSize sizeHint() const
- {
- QSize s = QHeaderView::sizeHint();
- s.rheight() *= 2;
- return s;
- }
+ QSize sizeHint() const
+ {
+ QSize s = QHeaderView::sizeHint();
+ s.rheight() *= 2;
+ return s;
+ }
};
@@ -160,10 +163,6 @@ ResourceManagement::ResourceManagement()
setMainWidget( w );
QVariantList list;
- //QGridLayout *layout = new QGridLayout( resourceCalender );
- //layout->setSpacing( 0 );
- //KOrganizerPart *view = new KOrganizerPart(resourceCalender, this, list);
- //resourceCalender = view->topLevelWidget();
mModel = new FreeBusyItemModel;
#ifndef KDEPIM_MOBILE_UI
@@ -196,8 +195,9 @@ ResourceManagement::ResourceManagement()
#endif
QStringList attrs;
- attrs << QLatin1String("cn") << QLatin1String("mail") << QLatin1String("givenname") << QLatin1String("sn");
-
+ attrs << QLatin1String("cn") << QLatin1String("mail")
+ << QLatin1String("owner") << QLatin1String("givenname") << QLatin1String("sn")
+ << QLatin1String("kolabDescAttribute") << QLatin1String("description");
ResourceModel *resourcemodel = new ResourceModel(attrs);
mUi->treeResults->setModel(resourcemodel);
@@ -226,11 +226,11 @@ void ResourceManagement::slotStartSearch(const QString &text)
void ResourceManagement::slotShowDetails(const QModelIndex & current)
{
ResourceItem::Ptr item = current.model()->data(current, ResourceModel::Resource).value<ResourceItem::Ptr>();
- showDetails(item->ldapObject());
+ showDetails(item->ldapObject(), item->ldapClient());
}
-void ResourceManagement::showDetails(const KLDAP::LdapObject &obj)
+void ResourceManagement::showDetails(const KLDAP::LdapObject &obj, const KLDAP::LdapClient &client)
{
// Clean up formDetails
QLayoutItem *child;
@@ -238,20 +238,49 @@ void ResourceManagement::showDetails(const KLDAP::LdapObject &obj)
delete child->widget();
delete child;
}
+ mUi->groupOwner->setHidden(true);
// Fill formDetails with data
foreach(const QString & key, obj.attributes().keys()) {
+ if (key == QLatin1String("objectClass")) {
+ continue;
+ } else if (key == QLatin1String("owner")) {
+ QStringList attrs;
+ attrs << QLatin1String("cn") << QLatin1String("mail")
+ << QLatin1String("mobile") << QLatin1String("telephoneNumber")
+ << QLatin1String("kolabDescAttribute") << QLatin1String("description");
+ mOwnerItem = ResourceItem::Ptr(new ResourceItem(KLDAP::LdapDN(QString::fromUtf8(obj.attributes().value(key).at(0))),
+ attrs, client));
+ connect(mOwnerItem.data(), SIGNAL(searchFinished()), SLOT(slotOwnerSearchFinished()));
+ mOwnerItem->startSearch();
+ continue;
+ }
QStringList list;
foreach(const QByteArray & value, obj.attributes().value(key)) {
list << QString::fromUtf8(value);
}
- kDebug() << key << list;
- mUi->formDetails->addRow(key, new QLabel(list.join("\n")));
+ if (key == QLatin1String("kolabDescAttribute")) {
+ QJson::Parser parser;
+ foreach(const QString &attr, list) {
+ bool ok;
+ QMap <QString, QVariant > map = parser.parse(attr.toUtf8(), &ok).toMap();
+ foreach(const QString &pKey, map.keys()) {
+ QString value;
+ if (map.value(pKey).type() == QVariant::Bool) {
+ value = map.value(pKey).toBool() ? i18n("yes") : i18n("no");
+ } else {
+ value = map.value(pKey).toString();
+ }
+ mUi->formDetails->addRow(translateKolabLDAPAttributeForDisplay(pKey), new QLabel(value));
+ }
+ }
+ } else {
+ mUi->formDetails->addRow(translateLDAPAttributeForDisplay(key), new QLabel(list.join("\n")));
+ }
}
QString name = QString::fromUtf8(obj.attributes().value("cn")[0]);
QString email = QString::fromUtf8(obj.attributes().value("mail")[0]);
- kDebug() << name << email;
KCalCore::Attendee::Ptr attendee(new KCalCore::Attendee(name, email));
FreeBusyItem::Ptr freebusy( new FreeBusyItem( attendee, this ));
mModel->clear();
@@ -271,4 +300,49 @@ void ResourceManagement::slotLayoutChanged()
}
}
+void ResourceManagement::slotOwnerSearchFinished()
+{
+ // Clean up formDetails
+ QLayoutItem *child;
+ while ((child = mUi->formOwner->takeAt(0)) != 0) {
+ delete child->widget();
+ delete child;
+ }
+ mUi->groupOwner->setHidden(false);
+
+ const KLDAP::LdapObject &obj = mOwnerItem->ldapObject();
+ foreach(const QString & key, obj.attributes().keys()) {
+ if (key == QLatin1String("objectClass")
+ || key == QLatin1String("owner")
+ || key == QLatin1String("givenname")
+ || key == QLatin1String("sn")) {
+ continue;
+ }
+ QStringList list;
+ foreach(const QByteArray & value, obj.attributes().value(key)) {
+ list << QString::fromUtf8(value);
+ }
+ if (key == QLatin1String("kolabDescAttribute")) {
+ QJson::Parser parser;
+ foreach(const QString &attr, list) {
+ bool ok;
+ QMap <QString, QVariant > map = parser.parse(attr.toUtf8(), &ok).toMap();
+ foreach(const QString &pKey, map.keys()) {
+ QString value;
+ if (map.value(pKey).type() == QVariant::Bool) {
+ value = map.value(pKey).toBool() ? i18n("yes") : i18n("no");
+ } else {
+ value = map.value(pKey).toString();
+ }
+ mUi->formOwner->addRow(translateKolabLDAPAttributeForDisplay(pKey), new QLabel(value));
+ }
+ }
+ } else {
+ mUi->formOwner->addRow(translateLDAPAttributeForDisplay(key), new QLabel(list.join("\n")));
+ }
+ }
+
+}
+
+
#include "resourcemanagement.moc"
diff --git a/incidenceeditor-ng/resourcemanagement.h b/incidenceeditor-ng/resourcemanagement.h
index c6dea43..8dedb4f 100644
--- a/incidenceeditor-ng/resourcemanagement.h
+++ b/incidenceeditor-ng/resourcemanagement.h
@@ -28,6 +28,7 @@
#include <ldap/ldapclientsearch.h>
#include "freebusyitemmodel.h"
+#include "resourceitem.h"
# include <KCalCore/FreeBusy>
#include <KDialog>
@@ -52,7 +53,7 @@ private:
/* Shows the details of a resource
*
*/
- void showDetails(const KLDAP::LdapObject&);
+ void showDetails(const KLDAP::LdapObject&, const KLDAP::LdapClient &client);
QItemSelectionModel *selectionModel;
@@ -66,6 +67,11 @@ private slots:
*
*/
void slotShowDetails(const QModelIndex & current);
+
+ /**
+ * The Owner search is done
+ */
+ void slotOwnerSearchFinished();
void slotInsertFreeBusy( const KCalCore::FreeBusy::Ptr &fb, const QString &email );
@@ -73,6 +79,7 @@ private slots:
private:
FreeBusyItemModel *mModel;
+ ResourceItem::Ptr mOwnerItem;
Ui_resourceManagement *mUi;
};
diff --git a/incidenceeditor-ng/resourcemanagement.ui b/incidenceeditor-ng/resourcemanagement.ui
index 09d6f37..dd3746f 100644
--- a/incidenceeditor-ng/resourcemanagement.ui
+++ b/incidenceeditor-ng/resourcemanagement.ui
@@ -6,89 +6,90 @@
<rect>
<x>0</x>
<y>0</y>
- <width>916</width>
- <height>782</height>
+ <width>552</width>
+ <height>566</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <property name="spacing">
- <number>6</number>
- </property>
+ <layout class="QVBoxLayout" name="verticalLayout_5">
<item>
- <layout class="QVBoxLayout" name="verticalLayout" stretch="0,0">
- <property name="spacing">
- <number>2</number>
+ <widget class="QSplitter" name="splitter_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
</property>
- <item>
- <widget class="KLineEdit" name="resourceSearch">
- <property name="maximumSize">
- <size>
- <width>400</width>
- <height>16777215</height>
- </size>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QTreeView" name="treeResults">
- <property name="minimumSize">
- <size>
- <width>200</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>400</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="alternatingRowColors">
- <bool>true</bool>
- </property>
- <property name="selectionBehavior">
- <enum>QAbstractItemView::SelectRows</enum>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <property name="spacing">
- <number>2</number>
- </property>
- <item>
- <widget class="QGroupBox" name="groupDetails">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="title">
- <string>Details</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_4">
- <property name="rightMargin">
- <number>4</number>
- </property>
+ <widget class="QWidget" name="">
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="KLineEdit" name="resourceSearch">
+ <property name="showClearButton" stdset="0">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTreeView" name="treeResults">
+ <property name="alternatingRowColors">
+ <bool>true</bool>
+ </property>
+ <property name="selectionBehavior">
+ <enum>QAbstractItemView::SelectRows</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QSplitter" name="splitter">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <widget class="QWidget" name="">
+ <layout class="QVBoxLayout" name="verticalLayout_3">
<item>
- <layout class="QFormLayout" name="formDetails"/>
+ <widget class="QGroupBox" name="groupDetails">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="title">
+ <string>Details</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <property name="rightMargin">
+ <number>4</number>
+ </property>
+ <item>
+ <layout class="QFormLayout" name="formDetails"/>
+ </item>
+ </layout>
+ </widget>
</item>
+ <item>
+ <widget class="QGroupBox" name="groupOwner">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="title">
+ <string>Owner</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <layout class="QFormLayout" name="formOwner"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="">
+ <layout class="QHBoxLayout" name="resourceCalender">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetDefaultConstraint</enum>
+ </property>
</layout>
</widget>
- </item>
- <item>
- <layout class="QHBoxLayout" name="resourceCalender"/>
- </item>
- </layout>
+ </widget>
+ </widget>
</item>
</layout>
</widget>
diff --git a/incidenceeditor-ng/resourcemodel.cpp b/incidenceeditor-ng/resourcemodel.cpp
index 274dee0..d4f8346 100644
--- a/incidenceeditor-ng/resourcemodel.cpp
+++ b/incidenceeditor-ng/resourcemodel.cpp
@@ -19,6 +19,7 @@
*
*/
#include "resourcemodel.h"
+#include "ldaputils.h"
#include <KPIMUtils/Email>
#include <KDebug>
@@ -43,6 +44,7 @@ ResourceModel::ResourceModel(const QStringList &headers,
QStringList attrs = ldapSearchCollections.attributes();
attrs << QLatin1String("uniqueMember");
ldapSearchCollections.setAttributes(attrs);
+ ldapSearch.setAttributes(headers);
connect(&ldapSearchCollections, SIGNAL(searchData(const QList<KLDAP::LdapResultObject> &)),
SLOT(slotLDAPCollectionData(const QList<KLDAP::LdapResultObject> &)));
@@ -105,7 +107,7 @@ QVariant ResourceModel::headerData(int section, Qt::Orientation orientation,
int role) const
{
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
- return rootItem->data(section);
+ return translateLDAPAttributeForDisplay(rootItem->data(section).toString());
}
return QVariant();
commit 50a757920cef55b555b78e3fc5a5b61fb554bf51
Author: Sandro Knauà <knauss at kolabsys.com>
Date: Sat Jul 5 12:54:38 2014 +0200
foo
diff --git a/incidenceeditor-ng/resourcemanagement.cpp b/incidenceeditor-ng/resourcemanagement.cpp
index 4da6343..e33349a 100644
--- a/incidenceeditor-ng/resourcemanagement.cpp
+++ b/incidenceeditor-ng/resourcemanagement.cpp
@@ -19,6 +19,8 @@
*
*/
+//http://stackoverflow.com/questions/18831242/qt-start-editing-of-cell-after-one-click
+
#include "resourcemanagement.h"
#include "ui_resourcemanagement.h"
#include "resourcemodel.h"
commit f2afb5543f5f3e1878f7741cb84a69ad0ea9719e
Author: Sandro Knauà <knauss at kolabsys.com>
Date: Tue Jun 24 14:48:53 2014 +0200
completionbox for resources also activate
diff --git a/incidenceeditor-ng/incidenceattendee.cpp b/incidenceeditor-ng/incidenceattendee.cpp
index e10c2cf..1dd0e12 100644
--- a/incidenceeditor-ng/incidenceattendee.cpp
+++ b/incidenceeditor-ng/incidenceattendee.cpp
@@ -147,14 +147,14 @@ IncidenceAttendee::IncidenceAttendee( QWidget *parent, IncidenceDateTime *dateTi
#else
mUi->mAttendeeTable->setModel(filterProxyModel);
- AttendeeLineEditDelegate *attendeeDelegate = new AttendeeLineEditDelegate(this);
- attendeeDelegate->setCompletionMode( KGlobalSettings::self()->completionMode() );
+ mAttendeeDelegate = new AttendeeLineEditDelegate(this);
+ mAttendeeDelegate->setCompletionMode( KGlobalSettings::self()->completionMode() );
QHeaderView* headerView = mUi->mAttendeeTable->horizontalHeader();
headerView->setResizeMode(QHeaderView::ResizeToContents);
mUi->mAttendeeTable->setItemDelegateForColumn(AttendeeTableModel::Role, roleDelegate());
- mUi->mAttendeeTable->setItemDelegateForColumn(AttendeeTableModel::FullName, attendeeDelegate);
+ mUi->mAttendeeTable->setItemDelegateForColumn(AttendeeTableModel::FullName, attendeeDelegate());
mUi->mAttendeeTable->setItemDelegateForColumn(AttendeeTableModel::Status, stateDelegate());
mUi->mAttendeeTable->setItemDelegateForColumn(AttendeeTableModel::Response, responseDelegate());
#endif
@@ -700,6 +700,12 @@ AttendeeComboBoxDelegate* IncidenceAttendee::stateDelegate()
return mStateDelegate;
}
+AttendeeLineEditDelegate *IncidenceAttendee::attendeeDelegate()
+{
+ return mAttendeeDelegate;
+}
+
+
void IncidenceAttendee::filterLayoutChanged()
{
#ifndef KDEPIM_MOBILE_UI
diff --git a/incidenceeditor-ng/incidenceattendee.h b/incidenceeditor-ng/incidenceattendee.h
index 46d47bc..cf07170 100644
--- a/incidenceeditor-ng/incidenceattendee.h
+++ b/incidenceeditor-ng/incidenceattendee.h
@@ -44,6 +44,7 @@ namespace IncidenceEditorNG {
class AttendeeEditor;
class AttendeeComboBoxDelegate;
+class AttendeeLineEditDelegate;
class ConflictResolver;
class IncidenceDateTime;
@@ -67,6 +68,7 @@ class INCIDENCEEDITORS_NG_EXPORT IncidenceAttendee : public IncidenceEditor
AttendeeComboBoxDelegate *stateDelegate();
AttendeeComboBoxDelegate *roleDelegate();
AttendeeComboBoxDelegate *responseDelegate();
+ AttendeeLineEditDelegate *attendeeDelegate();
int attendeeCount() const;
@@ -130,6 +132,7 @@ class INCIDENCEEDITORS_NG_EXPORT IncidenceAttendee : public IncidenceEditor
/** used dataModel to rely on*/
AttendeeTableModel *mDataModel;
+ AttendeeLineEditDelegate *mAttendeeDelegate;
AttendeeComboBoxDelegate *mStateDelegate;
AttendeeComboBoxDelegate *mRoleDelegate;
AttendeeComboBoxDelegate *mResponseDelegate;
diff --git a/incidenceeditor-ng/incidenceresource.cpp b/incidenceeditor-ng/incidenceresource.cpp
index a8830e0..1178a9e 100644
--- a/incidenceeditor-ng/incidenceresource.cpp
+++ b/incidenceeditor-ng/incidenceresource.cpp
@@ -86,6 +86,7 @@ IncidenceResource::IncidenceResource(IncidenceAttendee* ieAttendee, Ui::EventOrT
mUi->mNewResource->setCompleter(completer);
AttendeeLineEditDelegate *attendeeDelegate = new AttendeeLineEditDelegate(this);
+ attendeeDelegate->setCompletionMode( KGlobalSettings::self()->completionMode() );
ResourceFilterProxyModel *filterProxyModel = new ResourceFilterProxyModel(this);
filterProxyModel->setDynamicSortFilter(true);
commit 0fc0ad295a9eac93fbe4470aebef1ec333c707c5
Author: Sandro Knauà <knauss at kolabsys.com>
Date: Tue Jun 24 09:59:17 2014 +0200
using KLineEdit for resourcemanagment
diff --git a/incidenceeditor-ng/resourcemanagement.ui b/incidenceeditor-ng/resourcemanagement.ui
index cf6b003..09d6f37 100644
--- a/incidenceeditor-ng/resourcemanagement.ui
+++ b/incidenceeditor-ng/resourcemanagement.ui
@@ -23,7 +23,14 @@
<number>2</number>
</property>
<item>
- <widget class="QLineEdit" name="resourceSearch"/>
+ <widget class="KLineEdit" name="resourceSearch">
+ <property name="maximumSize">
+ <size>
+ <width>400</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ </widget>
</item>
<item>
<widget class="QTreeView" name="treeResults">
@@ -33,6 +40,12 @@
<height>0</height>
</size>
</property>
+ <property name="maximumSize">
+ <size>
+ <width>400</width>
+ <height>16777215</height>
+ </size>
+ </property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
@@ -79,6 +92,13 @@
</item>
</layout>
</widget>
+ <customwidgets>
+ <customwidget>
+ <class>KLineEdit</class>
+ <extends>QLineEdit</extends>
+ <header>klineedit.h</header>
+ </customwidget>
+ </customwidgets>
<resources/>
<connections/>
</ui>
commit fc094d53c38c6a92e40ed1ad43a5cddf6dac9365
Author: Sandro Knauà <knauss at kolabsys.com>
Date: Thu Jun 19 12:27:36 2014 +0200
only show first column in treeView
diff --git a/incidenceeditor-ng/resourcemanagement.cpp b/incidenceeditor-ng/resourcemanagement.cpp
index 0097208..4da6343 100644
--- a/incidenceeditor-ng/resourcemanagement.cpp
+++ b/incidenceeditor-ng/resourcemanagement.cpp
@@ -212,6 +212,8 @@ ResourceManagement::ResourceManagement()
Akonadi::FreeBusyManager *m = Akonadi::FreeBusyManager::self();
connect( m, SIGNAL(freeBusyRetrieved(KCalCore::FreeBusy::Ptr,QString)),
SLOT(slotInsertFreeBusy(KCalCore::FreeBusy::Ptr,QString)) );
+
+ connect(resourcemodel,SIGNAL(layoutChanged()),SLOT(slotLayoutChanged()));
}
void ResourceManagement::slotStartSearch(const QString &text)
@@ -260,5 +262,11 @@ void ResourceManagement::slotInsertFreeBusy(const KCalCore::FreeBusy::Ptr &fb, c
}
+void ResourceManagement::slotLayoutChanged()
+{
+ for(int i = 1; i < mUi->treeResults->model()->columnCount(QModelIndex());i++) {
+ mUi->treeResults->setColumnHidden(i, true);
+ }
+}
#include "resourcemanagement.moc"
diff --git a/incidenceeditor-ng/resourcemanagement.h b/incidenceeditor-ng/resourcemanagement.h
index 893deac..c6dea43 100644
--- a/incidenceeditor-ng/resourcemanagement.h
+++ b/incidenceeditor-ng/resourcemanagement.h
@@ -69,6 +69,8 @@ private slots:
void slotInsertFreeBusy( const KCalCore::FreeBusy::Ptr &fb, const QString &email );
+ void slotLayoutChanged();
+
private:
FreeBusyItemModel *mModel;
Ui_resourceManagement *mUi;
commit ff9b4bf71630462d362eb52fadac5f671bc3aec8
Author: Sandro Knauà <knauss at kolabsys.com>
Date: Thu Jun 19 12:26:57 2014 +0200
removed QSharedPointer me
diff --git a/incidenceeditor-ng/resourceitem.cpp b/incidenceeditor-ng/resourceitem.cpp
index d93da1c..7089ea3 100644
--- a/incidenceeditor-ng/resourceitem.cpp
+++ b/incidenceeditor-ng/resourceitem.cpp
@@ -68,7 +68,13 @@ int ResourceItem::childCount() const
int ResourceItem::childNumber() const
{
if (parentItem) {
- return parentItem->childItems.indexOf(me);
+ int i = 0;
+ foreach (ResourceItem::Ptr child, parentItem->childItems){
+ if (child == this) {
+ return i;
+ }
+ i++;
+ }
}
return 0;
@@ -98,7 +104,6 @@ bool ResourceItem::insertChild(int position, ResourceItem::Ptr item)
return false;
}
- item->me = item;
childItems.insert(position, item);
return true;
diff --git a/incidenceeditor-ng/resourceitem.h b/incidenceeditor-ng/resourceitem.h
index 70ab212..3c04373 100644
--- a/incidenceeditor-ng/resourceitem.h
+++ b/incidenceeditor-ng/resourceitem.h
@@ -95,8 +95,6 @@ public:
*/
void startSearch();
- Ptr me;
-
private:
/* data source
*
diff --git a/incidenceeditor-ng/resourcemodel.cpp b/incidenceeditor-ng/resourcemodel.cpp
index 6cfa9c2..274dee0 100644
--- a/incidenceeditor-ng/resourcemodel.cpp
+++ b/incidenceeditor-ng/resourcemodel.cpp
@@ -34,7 +34,6 @@ ResourceModel::ResourceModel(const QStringList &headers,
this->headers = headers;
rootItem = ResourceItem::Ptr(new ResourceItem(KLDAP::LdapDN(), headers, KLDAP::LdapClient(0)));
- rootItem->me = rootItem;
ldapSearchCollections.setFilter(QString::fromLatin1("&(objectClass=kolabGroupOfUniqueNames)(mail=*)"
"(|(cn=%1)(givenName=%1)(sn=%1))"));
commit cf61af1fb293c1338d99bb203eca1ada6da7892b
Author: Sandro Knauà <knauss at kolabsys.com>
Date: Thu Jun 19 11:56:29 2014 +0200
no dataChanged is needed when new row is added
diff --git a/incidenceeditor-ng/attendeetablemodel.cpp b/incidenceeditor-ng/attendeetablemodel.cpp
index 66ca10b..a3242e8 100644
--- a/incidenceeditor-ng/attendeetablemodel.cpp
+++ b/incidenceeditor-ng/attendeetablemodel.cpp
@@ -92,7 +92,7 @@ bool AttendeeTableModel::setData(const QModelIndex& index, const QVariant& value
attendeeList[index.row()]->setName(name);
attendeeList[index.row()]->setEmail(email);
- addEmptyAttendee(true);
+ addEmptyAttendee();
break;
case Available:
//attendeeList[index.row()].available = value.toBool();
@@ -179,11 +179,7 @@ bool AttendeeTableModel::insertAttendee(int position, const KCalCore::Attendee::
endInsertRows();
- QModelIndex topLeft = index(position, 0);
- QModelIndex bottomRight = index(position, columnCount()-1);
- emit dataChanged(topLeft, bottomRight);
-
- addEmptyAttendee(true);
+ addEmptyAttendee();
return true;
}
@@ -194,7 +190,7 @@ void AttendeeTableModel::setAttendees(const KCalCore::Attendee::List attendees)
attendeeList = attendees;
- addEmptyAttendee(false);
+ addEmptyAttendee();
emit layoutChanged();
}
@@ -205,7 +201,7 @@ KCalCore::Attendee::List AttendeeTableModel::attendees() const
return attendeeList;
}
-void AttendeeTableModel::addEmptyAttendee(bool emitDataChanged)
+void AttendeeTableModel::addEmptyAttendee()
{
if (mKeepEmpty) {
bool create=true;
@@ -218,11 +214,6 @@ void AttendeeTableModel::addEmptyAttendee(bool emitDataChanged)
if (create) {
insertRows(rowCount(),1);
- if (emitDataChanged) {
- QModelIndex topLeft = index(rowCount()-1, 0);
- QModelIndex bottomRight = index(rowCount()-1, columnCount()-1);
- emit dataChanged(topLeft, bottomRight);
- }
}
}
}
@@ -237,7 +228,7 @@ void AttendeeTableModel::setKeepEmpty(bool keepEmpty)
{
if (keepEmpty != mKeepEmpty) {
mKeepEmpty = keepEmpty;
- addEmptyAttendee(true);
+ addEmptyAttendee();
}
}
diff --git a/incidenceeditor-ng/attendeetablemodel.h b/incidenceeditor-ng/attendeetablemodel.h
index 356230a..01599a4 100644
--- a/incidenceeditor-ng/attendeetablemodel.h
+++ b/incidenceeditor-ng/attendeetablemodel.h
@@ -77,7 +77,7 @@ public:
void setRemoveEmptyLines(bool removeEmptyLines);
bool removeEmptyLines();
private:
- void addEmptyAttendee(bool emitDataChanged);
+ void addEmptyAttendee();
KCalCore::Attendee::List attendeeList;
bool mKeepEmpty;
commit d58bf16de26ae96a6a455cb075f6f35160574026
Author: Sandro Knauà <knauss at kolabsys.com>
Date: Thu Jun 19 11:53:01 2014 +0200
only shoing freebusy File not all other widgets
(copied from VisualFreeBusyWidget)
diff --git a/incidenceeditor-ng/resourcemanagement.cpp b/incidenceeditor-ng/resourcemanagement.cpp
index e81f6e0..0097208 100644
--- a/incidenceeditor-ng/resourcemanagement.cpp
+++ b/incidenceeditor-ng/resourcemanagement.cpp
@@ -24,20 +24,130 @@
#include "resourcemodel.h"
#include "freebusyitem.h"
-//#include "korganizer/korganizer_part.h"
-#include "visualfreebusywidget.h"
+#include "freebusyganttproxymodel.h"
+
+#include <kdgantt2/kdganttgraphicsview.h>
+#include <kdgantt2/kdganttview.h>
+#include <kdgantt2/kdganttdatetimegrid.h>
+#include <kdgantt2/kdganttabstractrowcontroller.h>
#include <akonadi/calendar/freebusymanager.h>
#include <kldap/ldapobject.h>
+#include <QPointer>
+#include <QSplitter>
#include <QStringList>
#include <QLabel>
+
#include <KDebug>
using namespace IncidenceEditorNG;
+class RowController : public KDGantt::AbstractRowController
+{
+ private:
+ static const int ROW_HEIGHT ;
+ QPointer<QAbstractItemModel> m_model;
+
+ public:
+ RowController()
+ {
+ mRowHeight = 20;
+ }
+
+ void setModel( QAbstractItemModel *model )
+ {
+ m_model = model;
+ }
+
+ /*reimp*/
+ int headerHeight() const
+ {
+ return 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
+ {
+ return mRowHeight*6/8;
+ }
+
+ /*reimp*/
+ int totalHeight() const
+ {
+ return m_model->rowCount() * mRowHeight;
+ }
+
+ /*reimp*/
+ QModelIndex indexAt( int height ) const
+ {
+ return m_model->index( height / mRowHeight, 0 );
+ }
+
+ /*reimp*/
+ QModelIndex indexBelow( const QModelIndex &idx ) const
+ {
+ if ( !idx.isValid() ) {
+ return QModelIndex();
+ }
+ return idx.model()->index( idx.row() + 1, idx.column(), idx.parent() );
+ }
+
+ /*reimp*/
+ QModelIndex indexAbove( const QModelIndex &idx ) const
+ {
+ if ( !idx.isValid() ) {
+ return QModelIndex();
+ }
+ return idx.model()->index( idx.row() - 1, idx.column(), idx.parent() );
+ }
+
+ void setRowHeight( int height )
+ {
+ mRowHeight = height;
+ }
+
+ private:
+ int mRowHeight;
+
+};
+
+class GanttHeaderView : public QHeaderView
+{
+public:
+ explicit GanttHeaderView( QWidget *parent = 0 ) : QHeaderView( Qt::Horizontal, parent )
+ {
+ }
+
+ QSize sizeHint() const
+ {
+ QSize s = QHeaderView::sizeHint();
+ s.rheight() *= 2;
+ return s;
+ }
+};
+
+
ResourceManagement::ResourceManagement()
{
@@ -54,15 +164,40 @@ ResourceManagement::ResourceManagement()
//resourceCalender = view->topLevelWidget();
mModel = new FreeBusyItemModel;
#ifndef KDEPIM_MOBILE_UI
- VisualFreeBusyWidget *mVisualWidget = new VisualFreeBusyWidget( mModel, 8, this );
- mUi->resourceCalender->addWidget( mVisualWidget );
+
+ KDGantt::GraphicsView *mGanttGraphicsView = new KDGantt::GraphicsView( this );
+ mGanttGraphicsView->setObjectName( "mGanttGraphicsView" );
+ mGanttGraphicsView->setToolTip(
+ i18nc( "@info:tooltip",
+ "Shows the Free/Busy status of a resource.") );
+ mGanttGraphicsView->setWhatsThis(
+ i18nc( "@info:whatsthis",
+ "Shows the Free/Busy status of a resource.") );
+ FreeBusyGanttProxyModel *model = new FreeBusyGanttProxyModel( this );
+ model->setSourceModel( mModel );
+
+ RowController *mRowController = new RowController;
+ mRowController->setRowHeight( fontMetrics().height()*4 ); //TODO: detect
+
+ mRowController->setModel( model );
+ mGanttGraphicsView->setRowController( mRowController );
+
+ KDGantt::DateTimeGrid *mGanttGrid = new KDGantt::DateTimeGrid;
+ mGanttGrid->setScale( KDGantt::DateTimeGrid::ScaleDay );
+ mGanttGrid->setDayWidth( 300 );
+ mGanttGrid->setRowSeparators( true );
+ mGanttGraphicsView->setGrid( mGanttGrid );
+ mGanttGraphicsView->setModel( model );
+ mGanttGraphicsView->viewport()->setFixedWidth( 300 * 30 );
+
+ mUi->resourceCalender->addWidget( mGanttGraphicsView );
#endif
QStringList attrs;
attrs << QLatin1String("cn") << QLatin1String("mail") << QLatin1String("givenname") << QLatin1String("sn");
- ResourceModel *model = new ResourceModel(attrs);
- mUi->treeResults->setModel(model);
+ ResourceModel *resourcemodel = new ResourceModel(attrs);
+ mUi->treeResults->setModel(resourcemodel);
// This doesn't work till now :( -> that's why i use the clieck signal
mUi->treeResults->setSelectionMode(QAbstractItemView::SingleSelection);
commit 3ba3df6da9bda3a9f71e518cf4e103aed0cc7971
Author: Sandro Knauà <knauss at kolabsys.com>
Date: Thu Jun 19 11:52:29 2014 +0200
showing fb object
diff --git a/incidenceeditor-ng/resourcemanagement.cpp b/incidenceeditor-ng/resourcemanagement.cpp
index 8b884ed..e81f6e0 100644
--- a/incidenceeditor-ng/resourcemanagement.cpp
+++ b/incidenceeditor-ng/resourcemanagement.cpp
@@ -22,45 +22,71 @@
#include "resourcemanagement.h"
#include "ui_resourcemanagement.h"
#include "resourcemodel.h"
+#include "freebusyitem.h"
+//#include "korganizer/korganizer_part.h"
+#include "visualfreebusywidget.h"
+
+#include <akonadi/calendar/freebusymanager.h>
#include <kldap/ldapobject.h>
#include <QStringList>
#include <QLabel>
+#include <KDebug>
+
+
using namespace IncidenceEditorNG;
ResourceManagement::ResourceManagement()
{
- ui = new Ui::ResourceManagement;
- ui->setupUi(this);
+
+ mUi = new Ui_resourceManagement;
+
+ QWidget *w = new QWidget( this );
+ mUi->setupUi( w );
+ setMainWidget( w );
+
+ QVariantList list;
+ //QGridLayout *layout = new QGridLayout( resourceCalender );
+ //layout->setSpacing( 0 );
+ //KOrganizerPart *view = new KOrganizerPart(resourceCalender, this, list);
+ //resourceCalender = view->topLevelWidget();
+ mModel = new FreeBusyItemModel;
+#ifndef KDEPIM_MOBILE_UI
+ VisualFreeBusyWidget *mVisualWidget = new VisualFreeBusyWidget( mModel, 8, this );
+ mUi->resourceCalender->addWidget( mVisualWidget );
+#endif
QStringList attrs;
attrs << QLatin1String("cn") << QLatin1String("mail") << QLatin1String("givenname") << QLatin1String("sn");
ResourceModel *model = new ResourceModel(attrs);
- ui->treeResults->setModel(model);
+ mUi->treeResults->setModel(model);
// This doesn't work till now :( -> that's why i use the clieck signal
- ui->treeResults->setSelectionMode(QAbstractItemView::SingleSelection);
- selectionModel = ui->treeResults->selectionModel();
+ mUi->treeResults->setSelectionMode(QAbstractItemView::SingleSelection);
+ selectionModel = mUi->treeResults->selectionModel();
- connect(ui->resourceSearch, SIGNAL(textChanged(const QString&)),
+ connect(mUi->resourceSearch, SIGNAL(textChanged(const QString&)),
SLOT(slotStartSearch(const QString&)));
- connect(ui->treeResults, SIGNAL(clicked(const QModelIndex &)),
+ connect(mUi->treeResults, SIGNAL(clicked(const QModelIndex &)),
SLOT(slotShowDetails(const QModelIndex &)));
+ Akonadi::FreeBusyManager *m = Akonadi::FreeBusyManager::self();
+ connect( m, SIGNAL(freeBusyRetrieved(KCalCore::FreeBusy::Ptr,QString)),
+ SLOT(slotInsertFreeBusy(KCalCore::FreeBusy::Ptr,QString)) );
}
void ResourceManagement::slotStartSearch(const QString &text)
{
- ((ResourceModel*)ui->treeResults->model())->startSearch(text);
+ ((ResourceModel*)mUi->treeResults->model())->startSearch(text);
}
void ResourceManagement::slotShowDetails(const QModelIndex & current)
{
- ResourceItem *item = ((ResourceModel*)current.model())->getItem(current);
+ ResourceItem::Ptr item = current.model()->data(current, ResourceModel::Resource).value<ResourceItem::Ptr>();
showDetails(item->ldapObject());
}
@@ -69,7 +95,7 @@ void ResourceManagement::showDetails(const KLDAP::LdapObject &obj)
{
// Clean up formDetails
QLayoutItem *child;
- while ((child = ui->formDetails->takeAt(0)) != 0) {
+ while ((child = mUi->formDetails->takeAt(0)) != 0) {
delete child->widget();
delete child;
}
@@ -80,21 +106,24 @@ void ResourceManagement::showDetails(const KLDAP::LdapObject &obj)
foreach(const QByteArray & value, obj.attributes().value(key)) {
list << QString::fromUtf8(value);
}
- ui->formDetails->addRow(key, new QLabel(list.join("\n")));
+ kDebug() << key << list;
+ mUi->formDetails->addRow(key, new QLabel(list.join("\n")));
}
- /*
- * TODO: Has to be needed and tested : )
- KUrl httpUrl;
- httpUrl.setUser( userName );
- httpUrl.setPassword( password );
- httpUrl.setHost( host );
- httpUrl.setProtocol( QLatin1String( "https" ) );
- httpUrl.setPath( QLatin1String( "/freebusy/" ) + user + QLatin1String( ".ifb" ) );
+ QString name = QString::fromUtf8(obj.attributes().value("cn")[0]);
+ QString email = QString::fromUtf8(obj.attributes().value("mail")[0]);
+ kDebug() << name << email;
+ KCalCore::Attendee::Ptr attendee(new KCalCore::Attendee(name, email));
+ FreeBusyItem::Ptr freebusy( new FreeBusyItem( attendee, this ));
+ mModel->clear();
+ mModel->addItem(freebusy);
+}
- KIO::Job *job = KIO::get( url, KIO::NoReload, KIO::HideProgressInfo );
- */
+void ResourceManagement::slotInsertFreeBusy(const KCalCore::FreeBusy::Ptr &fb, const QString &email)
+{
+ kDebug() << fb << email;
}
+
#include "resourcemanagement.moc"
diff --git a/incidenceeditor-ng/resourcemanagement.h b/incidenceeditor-ng/resourcemanagement.h
index 3749db6..893deac 100644
--- a/incidenceeditor-ng/resourcemanagement.h
+++ b/incidenceeditor-ng/resourcemanagement.h
@@ -27,15 +27,15 @@
#include <ldap/ldapclient.h>
#include <ldap/ldapclientsearch.h>
+#include "freebusyitemmodel.h"
+
+# include <KCalCore/FreeBusy>
#include <KDialog>
#include <QStringList>
#include <QStringListModel>
-namespace Ui
-{
-class ResourceManagement;
-}
+class Ui_resourceManagement;
namespace IncidenceEditorNG
{
@@ -54,8 +54,6 @@ private:
*/
void showDetails(const KLDAP::LdapObject&);
- Ui::ResourceManagement* ui;
-
QItemSelectionModel *selectionModel;
private slots:
@@ -68,6 +66,12 @@ private slots:
*
*/
void slotShowDetails(const QModelIndex & current);
+
+ void slotInsertFreeBusy( const KCalCore::FreeBusy::Ptr &fb, const QString &email );
+
+private:
+ FreeBusyItemModel *mModel;
+ Ui_resourceManagement *mUi;
};
}
diff --git a/incidenceeditor-ng/resourcemanagement.ui b/incidenceeditor-ng/resourcemanagement.ui
index 38002e1..cf6b003 100644
--- a/incidenceeditor-ng/resourcemanagement.ui
+++ b/incidenceeditor-ng/resourcemanagement.ui
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
- <class>ResourceManagement</class>
+ <class>resourceManagement</class>
<widget class="QWidget" name="resourceManagement">
<property name="geometry">
<rect>
@@ -15,7 +15,7 @@
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
- <number>-1</number>
+ <number>6</number>
</property>
<item>
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,0">
@@ -27,6 +27,12 @@
</item>
<item>
<widget class="QTreeView" name="treeResults">
+ <property name="minimumSize">
+ <size>
+ <width>200</width>
+ <height>0</height>
+ </size>
+ </property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
@@ -67,14 +73,7 @@
</widget>
</item>
<item>
- <widget class="QWidget" name="resourceCalender" native="true">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
+ <layout class="QHBoxLayout" name="resourceCalender"/>
</item>
</layout>
</item>
commit c7ff61eedf0b77929c24def37fe9dbecd7e13f0a
Author: Sandro Knauà <knauss at kolabsys.com>
Date: Thu Jun 19 10:27:34 2014 +0200
showing "name <mail>" for resource completion box
diff --git a/incidenceeditor-ng/incidenceresource.cpp b/incidenceeditor-ng/incidenceresource.cpp
index 9839929..a8830e0 100644
--- a/incidenceeditor-ng/incidenceresource.cpp
+++ b/incidenceeditor-ng/incidenceresource.cpp
@@ -37,6 +37,25 @@
#include <QCompleter>
using namespace IncidenceEditorNG;
+class SwitchRoleProxy:public QSortFilterProxyModel {
+
+public:
+ SwitchRoleProxy(QObject *parent = 0)
+ : QSortFilterProxyModel(parent) {
+
+ }
+
+ virtual QVariant data(const QModelIndex& index, int role) const {
+ QVariant d;
+ if (role == Qt::DisplayRole || role == Qt::EditRole) {
+ d = QSortFilterProxyModel::data(index, ResourceModel::FullName);
+ return d;
+ }
+ d = QSortFilterProxyModel::data(index, role);
+ return d;
+ }
+};
+
#ifdef KDEPIM_MOBILE_UI
IncidenceResource::IncidenceResource(IncidenceAttendee* ieAttendee, Ui::EventOrTodoMore *ui)
#else
@@ -58,8 +77,11 @@ IncidenceResource::IncidenceResource(IncidenceAttendee* ieAttendee, Ui::EventOrT
KDescendantsProxyModel *proxyModel = new KDescendantsProxyModel( this );
proxyModel->setSourceModel( model );
+ SwitchRoleProxy *proxyModel2 = new SwitchRoleProxy(this);
+ proxyModel2->setSourceModel(proxyModel);
- completer->setModel(proxyModel);
+ completer->setModel(proxyModel2);
+ completer->setCompletionRole(ResourceModel::FullName);
completer->setWrapAround(false);
mUi->mNewResource->setCompleter(completer);
diff --git a/incidenceeditor-ng/resourceitem.cpp b/incidenceeditor-ng/resourceitem.cpp
index 09de7b6..d93da1c 100644
--- a/incidenceeditor-ng/resourceitem.cpp
+++ b/incidenceeditor-ng/resourceitem.cpp
@@ -28,10 +28,8 @@ ResourceItem::ResourceItem(const KLDAP::LdapDN &dn, QStringList attrs, const KLD
: dn(dn)
, attrs(attrs)
, mLdapClient(0, this)
+ , parentItem(parent)
{
- parentItem = parent;
-
-
if (!dn.isEmpty()) {
KLDAP::LdapServer server = ldapClient.server();
@@ -86,6 +84,14 @@ QVariant ResourceItem::data(int column) const
return itemData.value(column);
}
+QVariant ResourceItem::data(const QString &column) const
+{
+ if (mLdapObject.attributes()[column].count() > 0) {
+ return QString::fromUtf8(mLdapObject.attributes()[column][0]);
+ }
+ return QVariant();
+}
+
bool ResourceItem::insertChild(int position, ResourceItem::Ptr item)
{
if (position < 0 || position > childItems.size()) {
diff --git a/incidenceeditor-ng/resourceitem.h b/incidenceeditor-ng/resourceitem.h
index 621fb4a..70ab212 100644
--- a/incidenceeditor-ng/resourceitem.h
+++ b/incidenceeditor-ng/resourceitem.h
@@ -56,6 +56,7 @@ public:
int childCount() const;
int columnCount() const;
QVariant data(int column) const;
+ QVariant data(const QString &column) const;
bool insertChild(int position, ResourceItem::Ptr item);
ResourceItem::Ptr parent();
bool removeChildren(int position, int count);
diff --git a/incidenceeditor-ng/resourcemodel.cpp b/incidenceeditor-ng/resourcemodel.cpp
index 534515c..6cfa9c2 100644
--- a/incidenceeditor-ng/resourcemodel.cpp
+++ b/incidenceeditor-ng/resourcemodel.cpp
@@ -59,7 +59,7 @@ ResourceModel::~ResourceModel()
int ResourceModel::columnCount(const QModelIndex & /* parent */) const
{
- return 1;
+ return rootItem->columnCount();
}
QVariant ResourceModel::data(const QModelIndex &index, int role) const
@@ -68,13 +68,18 @@ QVariant ResourceModel::data(const QModelIndex &index, int role) const
return QVariant();
}
- if (role != Qt::DisplayRole && role != Qt::EditRole) {
- return QVariant();
- }
+ if ( role == Qt::EditRole || role == Qt::DisplayRole ) {
+ return getItem(index)->data(index.column());
+ } else if (role == Resource) {
+ ResourceItem *p = getItem(parent(index));
+ return QVariant::fromValue(p->child(index.row()));
+ } else if (role == FullName ) {
+ ResourceItem *item = getItem(index);
+ return KPIMUtils::normalizedAddress(item->data("cn").toString(), item->data("mail").toString());
- ResourceItem *item = getItem(index);
+ }
- return item->data(index.column());
+ return QVariant();
}
Qt::ItemFlags ResourceModel::flags(const QModelIndex &index) const
@@ -166,16 +171,19 @@ void ResourceModel::startSearch(const QString &query)
void ResourceModel::startSearch()
{
- emit layoutAboutToBeChanged();
// Delete all resources -> only collection elements are shown
for (int i = 0; i < rootItem->childCount(); i++) {
if (ldapCollections.contains(rootItem->child(i))) {
+ QModelIndex parentIndex = index(i, 0, QModelIndex());
+ beginRemoveRows(parentIndex, 0, rootItem->child(i)->childCount()-1);
rootItem->child(i)->removeChildren(0, rootItem->child(i)->childCount());
+ endRemoveRows();
} else {
+ beginRemoveRows(QModelIndex(), i, i);
rootItem->removeChildren(i, 1);
+ endRemoveRows();
}
}
- emit layoutChanged();
if (searchString.count() > 0) {
ldapSearch.startSearch("*" + searchString + "*");
@@ -186,15 +194,18 @@ void ResourceModel::startSearch()
void ResourceModel::slotLDAPCollectionData(const QList<KLDAP::LdapResultObject> &results)
{
+ emit layoutAboutToBeChanged();
+
foundCollection = true;
ldapCollectionsMap.clear();
ldapCollections.clear();
- emit layoutAboutToBeChanged();
+ kDebug() << "Found ldapCollections";
foreach(const KLDAP::LdapResultObject & result, results) {
ResourceItem::Ptr item(new ResourceItem(result.object.dn(), headers, *result.client, rootItem));
item->setLdapObject(result.object);
+
rootItem->insertChild(rootItem->childCount(), item);
ldapCollections.insert(item);
@@ -211,8 +222,6 @@ void ResourceModel::slotLDAPCollectionData(const QList<KLDAP::LdapResultObject>
void ResourceModel::slotLDAPSearchData(const QList<KLDAP::LdapResultObject> &results)
{
- emit layoutAboutToBeChanged();
-
foreach(const KLDAP::LdapResultObject & result, results) {
//Add the found items to all collections, where it is member
QList<ResourceItem::Ptr> parents = ldapCollectionsMap.values(result.object.dn().toString());
@@ -223,9 +232,14 @@ void ResourceModel::slotLDAPSearchData(const QList<KLDAP::LdapResultObject> &res
foreach(ResourceItem::Ptr parent, parents) {
ResourceItem::Ptr item(new ResourceItem(result.object.dn(), headers, *result.client, parent));
item->setLdapObject(result.object);
+
+ QModelIndex parentIndex;
+ if (parent != rootItem) {
+ parentIndex = index(parent->childNumber(), 0, parentIndex);
+ }
+ beginInsertRows(parentIndex, parent->childCount(), parent->childCount());
parent->insertChild(parent->childCount(), item);
+ endInsertRows();
}
}
-
- emit layoutChanged();
}
diff --git a/incidenceeditor-ng/resourcemodel.h b/incidenceeditor-ng/resourcemodel.h
index 90f964d..1814aad 100644
--- a/incidenceeditor-ng/resourcemodel.h
+++ b/incidenceeditor-ng/resourcemodel.h
@@ -41,6 +41,11 @@ public:
/* Copied from http://qt-project.org/doc/qt-4.8/itemviews-editabletreemodel.html:
* QT 4.8: Editable Tree Model Example
*/
+ enum Roles {
+ Resource = Qt::UserRole,
+ FullName
+ };
+
ResourceModel(const QStringList &headers,
QObject *parent = 0);
~ResourceModel();
@@ -60,10 +65,9 @@ public:
bool removeRows(int position, int rows,
const QModelIndex &parent = QModelIndex());
-
- ResourceItem *getItem(const QModelIndex &index) const;
-
private:
+ ResourceItem* getItem(const QModelIndex &index) const;
+
ResourceItem::Ptr rootItem;
commit 44d16b1139aff39243d6679a570cb1af4b73e1aa
Author: Sandro Knauà <knauss at kolabsys.com>
Date: Thu Jun 19 10:25:18 2014 +0200
ResourceItem* -> ResourceItem::Ptr
diff --git a/incidenceeditor-ng/resourceitem.cpp b/incidenceeditor-ng/resourceitem.cpp
index a57c826..09de7b6 100644
--- a/incidenceeditor-ng/resourceitem.cpp
+++ b/incidenceeditor-ng/resourceitem.cpp
@@ -24,7 +24,7 @@
using namespace IncidenceEditorNG;
-ResourceItem::ResourceItem(const KLDAP::LdapDN &dn, QStringList attrs, const KLDAP::LdapClient &ldapClient, ResourceItem *parent)
+ResourceItem::ResourceItem(const KLDAP::LdapDN &dn, QStringList attrs, const KLDAP::LdapClient &ldapClient, ResourceItem::Ptr parent)
: dn(dn)
, attrs(attrs)
, mLdapClient(0, this)
@@ -53,11 +53,10 @@ ResourceItem::ResourceItem(const KLDAP::LdapDN &dn, QStringList attrs, const KLD
ResourceItem::~ResourceItem()
{
- qDeleteAll(childItems);
}
-ResourceItem *ResourceItem::child(int number)
+ResourceItem::Ptr ResourceItem::child(int number)
{
return childItems.value(number);
}
@@ -71,7 +70,7 @@ int ResourceItem::childCount() const
int ResourceItem::childNumber() const
{
if (parentItem) {
- return parentItem->childItems.indexOf(const_cast<ResourceItem*>(this));
+ return parentItem->childItems.indexOf(me);
}
return 0;
@@ -87,18 +86,19 @@ QVariant ResourceItem::data(int column) const
return itemData.value(column);
}
-bool ResourceItem::insertChild(int position, ResourceItem *item)
+bool ResourceItem::insertChild(int position, ResourceItem::Ptr item)
{
if (position < 0 || position > childItems.size()) {
return false;
}
+ item->me = item;
childItems.insert(position, item);
return true;
}
-ResourceItem *ResourceItem::parent()
+ResourceItem::Ptr ResourceItem::parent()
{
return parentItem;
}
@@ -110,7 +110,7 @@ bool ResourceItem::removeChildren(int position, int count)
}
for (int row = 0; row < count; ++row) {
- delete childItems.takeAt(position);
+ childItems.removeAt(position);
}
return true;
diff --git a/incidenceeditor-ng/resourceitem.h b/incidenceeditor-ng/resourceitem.h
index d0aea66..621fb4a 100644
--- a/incidenceeditor-ng/resourceitem.h
+++ b/incidenceeditor-ng/resourceitem.h
@@ -22,8 +22,10 @@
#ifndef RESOURCEITEM_H
#define RESOURCEITEM_H
-#include <QObject>
#include <QList>
+#include <QMetaType>
+#include <QSharedPointer>
+#include <QObject>
#include <QStringList>
#include <QVariant>
#include <QVector>
@@ -41,22 +43,28 @@ public:
/* Copied from http://qt-project.org/doc/qt-4.8/itemviews-editabletreemodel.html:
* QT 4.8: Editable Tree Model Example
*/
- ResourceItem(const KLDAP::LdapDN &dn, QStringList attrs, const KLDAP::LdapClient &ldapClient, ResourceItem *parent = 0);
+
+ /**
+ A shared pointer to an ResourceItem object.
+ */
+ typedef QSharedPointer<ResourceItem> Ptr;
+
+ ResourceItem(const KLDAP::LdapDN &dn, QStringList attrs, const KLDAP::LdapClient &ldapClient, ResourceItem::Ptr parent = ResourceItem::Ptr());
~ResourceItem();
- ResourceItem *child(int number);
+ ResourceItem::Ptr child(int number);
int childCount() const;
int columnCount() const;
QVariant data(int column) const;
- bool insertChild(int position, ResourceItem *item);
- ResourceItem *parent();
+ bool insertChild(int position, ResourceItem::Ptr item);
+ ResourceItem::Ptr parent();
bool removeChildren(int position, int count);
int childNumber() const;
private:
- QList<ResourceItem*> childItems;
+ QList<ResourceItem::Ptr> childItems;
QVector<QVariant> itemData;
- ResourceItem *parentItem;
+ ResourceItem::Ptr parentItem;
public:
/* Returns the attributes of the requested ldapObject.
@@ -86,6 +94,8 @@ public:
*/
void startSearch();
+ Ptr me;
+
private:
/* data source
*
@@ -116,4 +126,9 @@ private slots:
};
}
+
+//@cond PRIVATE
+ Q_DECLARE_TYPEINFO(IncidenceEditorNG::ResourceItem::Ptr, Q_MOVABLE_TYPE);
+ Q_DECLARE_METATYPE(IncidenceEditorNG::ResourceItem::Ptr)
+//@endcond
#endif // RESOURCEITEM_H
diff --git a/incidenceeditor-ng/resourcemodel.cpp b/incidenceeditor-ng/resourcemodel.cpp
index 829e0e0..534515c 100644
--- a/incidenceeditor-ng/resourcemodel.cpp
+++ b/incidenceeditor-ng/resourcemodel.cpp
@@ -20,6 +20,9 @@
*/
#include "resourcemodel.h"
+#include <KPIMUtils/Email>
+#include <KDebug>
+
using namespace IncidenceEditorNG;
@@ -30,7 +33,8 @@ ResourceModel::ResourceModel(const QStringList &headers,
{
this->headers = headers;
- rootItem = new ResourceItem(KLDAP::LdapDN(), headers, KLDAP::LdapClient(0), 0);
+ rootItem = ResourceItem::Ptr(new ResourceItem(KLDAP::LdapDN(), headers, KLDAP::LdapClient(0)));
+ rootItem->me = rootItem;
ldapSearchCollections.setFilter(QString::fromLatin1("&(objectClass=kolabGroupOfUniqueNames)(mail=*)"
"(|(cn=%1)(givenName=%1)(sn=%1))"));
@@ -51,7 +55,6 @@ ResourceModel::ResourceModel(const QStringList &headers,
ResourceModel::~ResourceModel()
{
- delete rootItem;
}
int ResourceModel::columnCount(const QModelIndex & /* parent */) const
@@ -91,7 +94,7 @@ ResourceItem *ResourceModel::getItem(const QModelIndex &index) const
return item;
}
}
- return rootItem;
+ return rootItem.data();
}
QVariant ResourceModel::headerData(int section, Qt::Orientation orientation,
@@ -106,14 +109,11 @@ QVariant ResourceModel::headerData(int section, Qt::Orientation orientation,
QModelIndex ResourceModel::index(int row, int column, const QModelIndex &parent) const
{
- if (parent.isValid() && parent.column() != 0) {
- return QModelIndex();
- }
ResourceItem *parentItem = getItem(parent);
- ResourceItem *childItem = parentItem->child(row);
- if (childItem) {
- return createIndex(row, column, childItem);
+ ResourceItem::Ptr childItem = parentItem->child(row);
+ if (row < parentItem->childCount() && childItem) {
+ return createIndex(row, column, childItem.data());
} else {
return QModelIndex();
}
@@ -125,14 +125,14 @@ QModelIndex ResourceModel::parent(const QModelIndex &index) const
if (!index.isValid()) {
return QModelIndex();
}
- ResourceItem *childItem = getItem(index);
- ResourceItem *parentItem = childItem->parent();
+ ResourceItem* childItem = getItem(index);
+ ResourceItem::Ptr parentItem = childItem->parent();
if (parentItem == rootItem) {
return QModelIndex();
}
- return createIndex(parentItem->childNumber(), 0, parentItem);
+ return createIndex(parentItem->childNumber(), index.column(), parentItem.data());
}
@@ -193,7 +193,7 @@ void ResourceModel::slotLDAPCollectionData(const QList<KLDAP::LdapResultObject>
emit layoutAboutToBeChanged();
foreach(const KLDAP::LdapResultObject & result, results) {
- ResourceItem *item = new ResourceItem(result.object.dn(), headers, *result.client, rootItem);
+ ResourceItem::Ptr item(new ResourceItem(result.object.dn(), headers, *result.client, rootItem));
item->setLdapObject(result.object);
rootItem->insertChild(rootItem->childCount(), item);
ldapCollections.insert(item);
@@ -215,13 +215,13 @@ void ResourceModel::slotLDAPSearchData(const QList<KLDAP::LdapResultObject> &res
foreach(const KLDAP::LdapResultObject & result, results) {
//Add the found items to all collections, where it is member
- QList<ResourceItem*> parents = ldapCollectionsMap.values(result.object.dn().toString());
+ QList<ResourceItem::Ptr> parents = ldapCollectionsMap.values(result.object.dn().toString());
if (parents.count() == 0) {
parents << rootItem;
}
- foreach(ResourceItem * parent, parents) {
- ResourceItem *item = new ResourceItem(result.object.dn(), headers, *result.client, parent);
+ foreach(ResourceItem::Ptr parent, parents) {
+ ResourceItem::Ptr item(new ResourceItem(result.object.dn(), headers, *result.client, parent));
item->setLdapObject(result.object);
parent->insertChild(parent->childCount(), item);
}
diff --git a/incidenceeditor-ng/resourcemodel.h b/incidenceeditor-ng/resourcemodel.h
index 4eb8a33..90f964d 100644
--- a/incidenceeditor-ng/resourcemodel.h
+++ b/incidenceeditor-ng/resourcemodel.h
@@ -64,7 +64,7 @@ public:
ResourceItem *getItem(const QModelIndex &index) const;
private:
- ResourceItem *rootItem;
+ ResourceItem::Ptr rootItem;
public:
@@ -94,12 +94,12 @@ private:
* A Resource can be part of different collection, so a QMuliMap is needed
*
*/
- QMultiMap<QString, ResourceItem*> ldapCollectionsMap;
+ QMultiMap<QString, ResourceItem::Ptr> ldapCollectionsMap;
/* A Set of all collection ResourceItems
*
*/
- QSet <ResourceItem*> ldapCollections;
+ QSet <ResourceItem::Ptr> ldapCollections;
/* Cached searchString (setted by startSearch(QString))
*
commit bfb208aa8aa048308558f4e25dfee9eea7d6ae88
Author: Sandro Knauà <knauss at kolabsys.com>
Date: Wed Jun 18 19:12:12 2014 +0200
make incedentAttendee workable
diff --git a/incidenceeditor-ng/attendeetablemodel.cpp b/incidenceeditor-ng/attendeetablemodel.cpp
index 78c21bd..66ca10b 100644
--- a/incidenceeditor-ng/attendeetablemodel.cpp
+++ b/incidenceeditor-ng/attendeetablemodel.cpp
@@ -3,8 +3,6 @@
#include <KCalCore/Attendee>
#include <KPIMUtils/Email>
-#include <KDebug>
-
using namespace IncidenceEditorNG;
AttendeeTableModel::AttendeeTableModel(const KCalCore::Attendee::List &attendees, QObject *parent)
@@ -68,6 +66,9 @@ QVariant AttendeeTableModel::data(const QModelIndex &index, int role) const
}
}
+ if (role == AttendeeRole) {
+ return QVariant::fromValue(attendeeList[index.row()]);
+ }
return QVariant();
}
@@ -80,6 +81,13 @@ bool AttendeeTableModel::setData(const QModelIndex& index, const QVariant& value
attendeeList[index.row()]->setRole(static_cast<KCalCore::Attendee::Role>(value.toInt()));
break;
case FullName:
+ if (mRemoveEmptyLines && value.toString().trimmed().isEmpty()) {
+ // Do not remove last empty line if mKeepEmpty==true (only works if initaly there is only one empty line)
+ if (!mKeepEmpty || !(attendeeList[index.row()]->name().isEmpty() && attendeeList[index.row()]->email().isEmpty())) {
+ removeRows(index.row(), 1);
+ return true;
+ }
+ }
KPIMUtils::extractEmailAddressAndName(value.toString(), email, name);
attendeeList[index.row()]->setName(name);
attendeeList[index.row()]->setEmail(email);
@@ -140,7 +148,7 @@ QVariant AttendeeTableModel::headerData(int section, Qt::Orientation orientation
bool AttendeeTableModel::insertRows(int position, int rows, const QModelIndex &parent)
{
- beginInsertRows(QModelIndex(), position, position + rows);
+ beginInsertRows(parent, position, position + rows-1);
for (int row = 0; row < rows; ++row) {
KCalCore::Attendee::Ptr attendee(new KCalCore::Attendee("", ""));
@@ -153,7 +161,7 @@ bool AttendeeTableModel::insertRows(int position, int rows, const QModelIndex &p
bool AttendeeTableModel::removeRows(int position, int rows, const QModelIndex &parent)
{
- beginRemoveRows(QModelIndex(), position, position + rows);
+ beginRemoveRows(parent, position, position + rows-1);
for (int row = 0; row < rows; ++row) {
attendeeList.remove(position);
@@ -171,6 +179,12 @@ bool AttendeeTableModel::insertAttendee(int position, const KCalCore::Attendee::
endInsertRows();
+ QModelIndex topLeft = index(position, 0);
+ QModelIndex bottomRight = index(position, columnCount()-1);
+ emit dataChanged(topLeft, bottomRight);
+
+ addEmptyAttendee(true);
+
return true;
}
@@ -191,7 +205,7 @@ KCalCore::Attendee::List AttendeeTableModel::attendees() const
return attendeeList;
}
-void AttendeeTableModel::addEmptyAttendee(bool layoutChange)
+void AttendeeTableModel::addEmptyAttendee(bool emitDataChanged)
{
if (mKeepEmpty) {
bool create=true;
@@ -203,14 +217,11 @@ void AttendeeTableModel::addEmptyAttendee(bool layoutChange)
}
if (create) {
- if (layoutChange) {
- emit layoutAboutToBeChanged();
- }
-
insertRows(rowCount(),1);
-
- if (layoutChange) {
- emit layoutChanged();
+ if (emitDataChanged) {
+ QModelIndex topLeft = index(rowCount()-1, 0);
+ QModelIndex bottomRight = index(rowCount()-1, columnCount()-1);
+ emit dataChanged(topLeft, bottomRight);
}
}
}
@@ -230,6 +241,16 @@ void AttendeeTableModel::setKeepEmpty(bool keepEmpty)
}
}
+bool AttendeeTableModel::removeEmptyLines()
+{
+ return mRemoveEmptyLines;
+}
+
+void AttendeeTableModel::setRemoveEmptyLines(bool removeEmptyLines)
+{
+ mRemoveEmptyLines = removeEmptyLines;
+}
+
ResourceFilterProxyModel::ResourceFilterProxyModel(QObject *parent)
: QSortFilterProxyModel(parent)
diff --git a/incidenceeditor-ng/attendeetablemodel.h b/incidenceeditor-ng/attendeetablemodel.h
index dce56f0..356230a 100644
--- a/incidenceeditor-ng/attendeetablemodel.h
+++ b/incidenceeditor-ng/attendeetablemodel.h
@@ -36,6 +36,9 @@ class AttendeeTableModel : public QAbstractTableModel
Q_OBJECT
public:
+ enum Roles {
+ AttendeeRole = Qt::UserRole
+ };
enum Columns {
CuType,
@@ -52,7 +55,7 @@ public:
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
- QVariant data(const QModelIndex &index, int role) const;
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const;
@@ -70,11 +73,15 @@ public:
void setKeepEmpty(bool keepEmpty);
bool keepEmpty();
+
+ void setRemoveEmptyLines(bool removeEmptyLines);
+ bool removeEmptyLines();
private:
- void addEmptyAttendee(bool layoutChange);
+ void addEmptyAttendee(bool emitDataChanged);
KCalCore::Attendee::List attendeeList;
bool mKeepEmpty;
+ bool mRemoveEmptyLines;
};
class ResourceFilterProxyModel : public QSortFilterProxyModel
diff --git a/incidenceeditor-ng/incidenceattendee.cpp b/incidenceeditor-ng/incidenceattendee.cpp
index 02a1ea7..e10c2cf 100644
--- a/incidenceeditor-ng/incidenceattendee.cpp
+++ b/incidenceeditor-ng/incidenceattendee.cpp
@@ -90,6 +90,7 @@ IncidenceAttendee::IncidenceAttendee( QWidget *parent, IncidenceDateTime *dateTi
attendees.append(attendee);
mDataModel = new AttendeeTableModel(attendees, this);
mDataModel->setKeepEmpty(true);
+ mDataModel->setRemoveEmptyLines(true);
#ifdef KDEPIM_MOBILE_UI
mRoleDelegate->addItem(DesktopIcon("meeting-participant", 48),
@@ -197,17 +198,22 @@ IncidenceAttendee::IncidenceAttendee( QWidget *parent, IncidenceDateTime *dateTi
connect( mAttendeeEditor, SIGNAL(editingFinished(KPIM::MultiplyingLine*)),
SLOT(checkIfExpansionIsNeeded(KPIM::MultiplyingLine*)) );
- connect( mAttendeeEditor, SIGNAL(changed(KCalCore::Attendee::Ptr,KCalCore::Attendee::Ptr)),
- SLOT(slotAttendeeChanged(KCalCore::Attendee::Ptr,KCalCore::Attendee::Ptr)) );
- connect(mDataModel, SIGNAL(layoutChanged()), SLOT(layoutChanged()));
- connect(mDataModel, SIGNAL(rowsInserted(const QModelIndex&, int , int)), SLOT(updateCount()));
- connect(mDataModel, SIGNAL(rowsRemoved(const QModelIndex&, int , int)), SLOT(updateCount()));
+ connect(mDataModel, SIGNAL(layoutChanged()), SLOT(slotAttendeeLayoutChanged()));
+ connect(mDataModel, SIGNAL(rowsAboutToBeRemoved(const QModelIndex&, int , int)), SLOT(slotAttendeeRemoved(const QModelIndex&,int,int)));
+ connect(mDataModel, SIGNAL(rowsInserted(const QModelIndex&, int , int)), SLOT(slotAttendeeAdded(const QModelIndex&,int,int)));
+ connect(mDataModel, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), SLOT(slotAttendeeChanged(const QModelIndex&, const QModelIndex&)));
+
+ connect(filterProxyModel, SIGNAL(rowsInserted(const QModelIndex&, int , int)), SLOT(updateCount()));
+ connect(filterProxyModel, SIGNAL(rowsRemoved(const QModelIndex&, int , int)), SLOT(updateCount()));
+ // only update when FullName is changed
+ connect(filterProxyModel, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), SLOT(updateCount()));
+ connect(filterProxyModel, SIGNAL(layoutChanged()), SLOT(updateCount()));
+ connect(filterProxyModel, SIGNAL(layoutChanged()), SLOT(filterLayoutChanged()));
}
IncidenceAttendee::~IncidenceAttendee()
{
- delete mDataModel;
}
void IncidenceAttendee::load( const KCalCore::Incidence::Ptr &incidence )
@@ -242,6 +248,7 @@ void IncidenceAttendee::load( const KCalCore::Incidence::Ptr &incidence )
}
mDataModel->setAttendees(incidence->attendees());
+ slotUpdateConflictLabel(0);
setActions( incidence->type() );
@@ -343,7 +350,6 @@ void IncidenceAttendee::changeStatusForMe( KCalCore::Attendee::PartStat stat )
const IncidenceEditorNG::EditorConfig *config = IncidenceEditorNG::EditorConfig::instance();
Q_ASSERT( config );
- KCalCore::Attendee::List attendees = mDataModel->attendees();
for (int i=0;i<mDataModel->rowCount();i++) {
QModelIndex index = mDataModel->index(i, AttendeeTableModel::Email);
if ( config->thatIsMe( mDataModel->data(index, Qt::DisplayRole).toString() ) ) {
@@ -492,21 +498,65 @@ void IncidenceEditorNG::IncidenceAttendee::slotSolveConflictPressed()
}
}
-void IncidenceAttendee::slotAttendeeChanged( const KCalCore::Attendee::Ptr &oldAttendee,
- const KCalCore::Attendee::Ptr &newAttendee )
+void IncidenceAttendee::slotAttendeeChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
{
- // if newAttendee's email is empty, we are probably removing an attendee
- if ( mConflictResolver->containsAttendee( oldAttendee ) ) {
- mConflictResolver->removeAttendee( oldAttendee );
- }
- if ( !mConflictResolver->containsAttendee( newAttendee ) && !newAttendee->email().isEmpty() ) {
- mConflictResolver->insertAttendee( newAttendee );
+#ifndef KDEPIM_MOBILE_UI
+ if (AttendeeTableModel::FullName <= bottomRight.column() && AttendeeTableModel::FullName >= topLeft.column()) {
+ for (int i = topLeft.row(); i <= bottomRight.row(); i++) {
+ kDebug() << i;
+ QModelIndex index = dataModel()->index(i, AttendeeTableModel::Email);
+ KCalCore::Attendee::Ptr attendee = dataModel()->data(index, AttendeeTableModel::AttendeeRole).value<KCalCore::Attendee::Ptr>();
+ if (mConflictResolver->containsAttendee(attendee)) {
+ mConflictResolver->removeAttendee(attendee);
+ }
+ if (!dataModel()->data(index).toString().isEmpty()) {
+ mConflictResolver->insertAttendee( attendee );
+ }
+ }
}
checkDirtyStatus();
+#endif
}
+void IncidenceAttendee::slotAttendeeAdded(const QModelIndex &index, int first, int last)
+{
+ for (int i = first; i <= last; i++) {
+ QModelIndex email = dataModel()->index(i, AttendeeTableModel::Email, index);
+ if (!dataModel()->data(email).toString().isEmpty()) {
+ mConflictResolver->insertAttendee( dataModel()->data(email, AttendeeTableModel::AttendeeRole).value<KCalCore::Attendee::Ptr>() );
+ }
+ }
+ checkDirtyStatus();
+}
+
+void IncidenceAttendee::slotAttendeeRemoved(const QModelIndex &index, int first, int last)
+{
+ for (int i = first; i <= last; i++) {
+ kDebug() << i;
+ QModelIndex email = dataModel()->index(i, AttendeeTableModel::Email, index);
+ if (!dataModel()->data(email).toString().isEmpty()) {
+ mConflictResolver->removeAttendee( dataModel()->data(email, AttendeeTableModel::AttendeeRole).value<KCalCore::Attendee::Ptr>() );
+ }
+ }
+ checkDirtyStatus();
+}
+
+void IncidenceAttendee::slotAttendeeLayoutChanged()
+{
+ KCalCore::Attendee::List attendees = mDataModel->attendees();
+ mConflictResolver->clearAttendees();
+ foreach(KCalCore::Attendee::Ptr attendee, attendees) {
+ if (! attendee->email().isEmpty()) {
+ mConflictResolver->insertAttendee(attendee);
+ }
+ }
+ checkDirtyStatus();
+}
+
+
void IncidenceAttendee::slotUpdateConflictLabel( int count )
{
+ kDebug() << "slotUpdateConflictLabel";
if ( attendeeCount() > 0 ) {
mUi->mSolveButton->setEnabled( true );
if ( count > 0 ) {
@@ -650,7 +700,7 @@ AttendeeComboBoxDelegate* IncidenceAttendee::stateDelegate()
return mStateDelegate;
}
-void IncidenceAttendee::layoutChanged()
+void IncidenceAttendee::filterLayoutChanged()
{
#ifndef KDEPIM_MOBILE_UI
mUi->mAttendeeTable->setColumnHidden(AttendeeTableModel::CuType, true);
@@ -658,8 +708,6 @@ void IncidenceAttendee::layoutChanged()
mUi->mAttendeeTable->setColumnHidden(AttendeeTableModel::Email, true);
mUi->mAttendeeTable->setColumnHidden(AttendeeTableModel::Available, true);
#endif
-
- updateCount();
}
diff --git a/incidenceeditor-ng/incidenceattendee.h b/incidenceeditor-ng/incidenceattendee.h
index 60c05ae..46d47bc 100644
--- a/incidenceeditor-ng/incidenceattendee.h
+++ b/incidenceeditor-ng/incidenceattendee.h
@@ -86,16 +86,19 @@ class INCIDENCEEDITORS_NG_EXPORT IncidenceAttendee : public IncidenceEditor
void slotSelectAddresses();
void slotSolveConflictPressed();
void slotUpdateConflictLabel( int );
- void slotAttendeeChanged( const KCalCore::Attendee::Ptr &oldAttendee,
- const KCalCore::Attendee::Ptr &newAttendee );
void slotOrganizerChanged( const QString &organizer );
// wrapper for the conflict resolver
void slotEventDurationChanged();
- void layoutChanged();
+ void filterLayoutChanged();
void updateCount();
+ void slotAttendeeAdded(const QModelIndex &index, int first, int last);
+ void slotAttendeeRemoved(const QModelIndex &index, int first, int last);
+ void slotAttendeeChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+ void slotAttendeeLayoutChanged();
+
private:
void changeStatusForMe( KCalCore::Attendee::PartStat );
diff --git a/incidenceeditor-ng/incidenceresource.cpp b/incidenceeditor-ng/incidenceresource.cpp
index 1b0781a..9839929 100644
--- a/incidenceeditor-ng/incidenceresource.cpp
+++ b/incidenceeditor-ng/incidenceresource.cpp
@@ -80,9 +80,12 @@ IncidenceResource::IncidenceResource(IncidenceAttendee* ieAttendee, Ui::EventOrT
connect(mUi->mFindResourcesButton, SIGNAL(clicked()), SLOT(findResources()));
connect(mUi->mBookResourceButton, SIGNAL(clicked()), SLOT(bookResource()));
- connect(dataModel, SIGNAL(layoutChanged()), SLOT(layoutChanged()));
- connect(dataModel, SIGNAL(rowsInserted(const QModelIndex&, int , int)), SLOT(updateCount()));
- connect(dataModel, SIGNAL(rowsRemoved(const QModelIndex&, int , int)), SLOT(updateCount()));
+ connect(filterProxyModel, SIGNAL(layoutChanged()), SLOT(layoutChanged()));
+ connect(filterProxyModel, SIGNAL(layoutChanged()), SLOT(updateCount()));
+ connect(filterProxyModel, SIGNAL(rowsInserted(const QModelIndex&, int , int)), SLOT(updateCount()));
+ connect(filterProxyModel, SIGNAL(rowsRemoved(const QModelIndex&, int , int)), SLOT(updateCount()));
+ // only update when FullName is changed
+ connect(filterProxyModel, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), SLOT(updateCount()));
#endif
}
@@ -122,14 +125,11 @@ void IncidenceResource::findResources()
void IncidenceResource::layoutChanged()
{
-
#ifndef KDEPIM_MOBILE_UI
mUi->mResourcesTable->setColumnHidden(AttendeeTableModel::CuType, true);
mUi->mResourcesTable->setColumnHidden(AttendeeTableModel::Name, true);
mUi->mResourcesTable->setColumnHidden(AttendeeTableModel::Email, true);
#endif
-
- updateCount();
}
@@ -141,7 +141,20 @@ void IncidenceResource::updateCount()
int IncidenceResource::resourceCount() const
{
#ifndef KDEPIM_MOBILE_UI
- return mUi->mResourcesTable->model()->rowCount(QModelIndex());
+ int c=0;
+ QModelIndex index;
+ QAbstractItemModel *model = mUi->mResourcesTable->model();
+ if (!model ) {
+ return 0;
+ }
+ for(int i=0;i< model->rowCount(QModelIndex());i++) {
+ index = model->index(i,AttendeeTableModel::FullName);
+ if (!model->data(index).toString().isEmpty()) {
+ c++;
+ }
+ }
+ return c;
+
#endif
return 0;
}
commit 03f0b80cb957ea0b4f320033f044397ec816a3ca
Author: Sandro Knauà <knauss at kolabsys.com>
Date: Tue Jun 17 10:12:00 2014 +0200
Moved logic from IncidenceResource -> IncidenceAttendee
diff --git a/incidenceeditor-ng/incidencedialog.cpp b/incidenceeditor-ng/incidencedialog.cpp
index 9b96a3c..b8dec82 100644
--- a/incidenceeditor-ng/incidencedialog.cpp
+++ b/incidenceeditor-ng/incidencedialog.cpp
@@ -166,9 +166,6 @@ IncidenceDialogPrivate::IncidenceDialogPrivate( Akonadi::IncidenceChanger *chang
mIeRecurrence = new IncidenceRecurrence( mIeDateTime, mUi );
mEditor->combine( mIeRecurrence );
- mIeResource = new IncidenceResource( mUi );
- mEditor->combine( mIeResource );
-
IncidenceSecrecy *ieSecrecy = new IncidenceSecrecy( mUi );
mEditor->combine( ieSecrecy );
@@ -176,6 +173,9 @@ IncidenceDialogPrivate::IncidenceDialogPrivate( Akonadi::IncidenceChanger *chang
mIeAttendee->setParent(qq);
mEditor->combine( mIeAttendee );
+ mIeResource = new IncidenceResource( mIeAttendee, mUi );
+ mEditor->combine( mIeResource );
+
q->connect( mEditor, SIGNAL(showMessage(QString,KMessageWidget::MessageType)),
SLOT(showMessage(QString,KMessageWidget::MessageType)) );
q->connect( mEditor, SIGNAL(dirtyStatusChanged(bool)),
@@ -584,7 +584,8 @@ void IncidenceDialogPrivate::load( const Akonadi::Item &item )
// Initialize tab's titles
updateAttachmentCount( incidence->attachments().size() );
- updateResourceCount( mIeResource->resourcesCount() );
+ updateResourceCount( mIeResource->resourceCount() );
+ updateAttendeeCount( mIeAttendee->attendeeCount() );
handleRecurrenceChange( mIeRecurrence->currentRecurrenceType() );
handleAlarmCountChange( incidence->alarms().count() );
diff --git a/incidenceeditor-ng/incidenceresource.cpp b/incidenceeditor-ng/incidenceresource.cpp
index f718e6b..1b0781a 100644
--- a/incidenceeditor-ng/incidenceresource.cpp
+++ b/incidenceeditor-ng/incidenceresource.cpp
@@ -32,82 +32,22 @@
#include <KDescendantsProxyModel>
#include <KMessageBox>
-#include <KCalUtils/Stringify>
#include <KPIMUtils/Email>
-
#include <QCompleter>
using namespace IncidenceEditorNG;
#ifdef KDEPIM_MOBILE_UI
-IncidenceResource::IncidenceResource(Ui::EventOrTodoMore *ui)
+IncidenceResource::IncidenceResource(IncidenceAttendee* ieAttendee, Ui::EventOrTodoMore *ui)
#else
-IncidenceResource::IncidenceResource(Ui::EventOrTodoDesktop *ui)
+IncidenceResource::IncidenceResource(IncidenceAttendee* ieAttendee, Ui::EventOrTodoDesktop *ui)
#endif
: IncidenceEditor(0)
, mUi(ui)
+ , dataModel(ieAttendee->dataModel())
{
setObjectName("IncidenceResource");
- AttendeeComboBoxDelegate* roleDelegate(new AttendeeComboBoxDelegate(this));
- AttendeeComboBoxDelegate* responseDelegate(new AttendeeComboBoxDelegate(this));
-#ifdef KDEPIM_MOBILE_UI
- roleDelegate->addItem(DesktopIcon("meeting-participant", 48),
- KCalUtils::Stringify::attendeeRole(KCalCore::Attendee::ReqParticipant));
- roleDelegate->addItem(DesktopIcon("meeting-participant-optional", 48),
- KCalUtils::Stringify::attendeeRole(KCalCore::Attendee::OptParticipant));
- roleDelegate->addItem(DesktopIcon("meeting-observer", 48),
- KCalUtils::Stringify::attendeeRole(KCalCore::Attendee::NonParticipant));
- roleDelegate->addItem(DesktopIcon("meeting-chair", 48),
- KCalUtils::Stringify::attendeeRole(KCalCore::Attendee::Chair));
-
- responseDelegate->addItem( DesktopIcon( "meeting-participant-request-response", 48 ),
- i18nc( "@item:inlistbox", "Request Response" ) );
- responseDelegate->addItem( DesktopIcon( "meeting-participant-no-response", 48 ),
- i18nc( "@item:inlistbox", "Request No Response" ) );
-
-#else
- roleDelegate->addItem(SmallIcon("meeting-participant"),
- KCalUtils::Stringify::attendeeRole(KCalCore::Attendee::ReqParticipant));
- roleDelegate->addItem(SmallIcon("meeting-participant-optional"),
- KCalUtils::Stringify::attendeeRole(KCalCore::Attendee::OptParticipant));
- roleDelegate->addItem(SmallIcon("meeting-observer"),
- KCalUtils::Stringify::attendeeRole(KCalCore::Attendee::NonParticipant));
- roleDelegate->addItem(SmallIcon("meeting-chair"),
- KCalUtils::Stringify::attendeeRole(KCalCore::Attendee::Chair));
-
- responseDelegate->addItem( SmallIcon( "meeting-participant-request-response" ),
- i18nc( "@item:inlistbox", "Request Response" ) );
- responseDelegate->addItem( SmallIcon( "meeting-participant-no-response" ),
- i18nc( "@item:inlistbox", "Request No Response" ) );
-
-#endif
-
- AttendeeComboBoxDelegate *stateDelegate(new AttendeeComboBoxDelegate(this));
-
-#ifdef KDEPIM_MOBILE_UI
- stateDelegate->addItem(DesktopIcon("task-attention", 48),
- KCalUtils::Stringify::attendeeStatus(KCalCore::Attendee::NeedsAction));
- stateDelegate->addItem(DesktopIcon("task-accepted", 48),
- KCalUtils::Stringify::attendeeStatus(KCalCore::Attendee::Accepted));
- stateDelegate->addItem(DesktopIcon("task-reject", 48),
- KCalUtils::Stringify::attendeeStatus(KCalCore::Attendee::Declined));
- stateDelegate->addItem(DesktopIcon("task-attempt", 48),
- KCalUtils::Stringify::attendeeStatus(KCalCore::Attendee::Tentative));
- stateDelegate->addItem(DesktopIcon("task-delegate", 48),
- KCalUtils::Stringify::attendeeStatus(KCalCore::Attendee::Delegated));
-#else
- stateDelegate->addItem(SmallIcon("task-attention"),
- KCalUtils::Stringify::attendeeStatus(KCalCore::Attendee::NeedsAction));
- stateDelegate->addItem(SmallIcon("task-accepted"),
- KCalUtils::Stringify::attendeeStatus(KCalCore::Attendee::Accepted));
- stateDelegate->addItem(SmallIcon("task-reject"),
- KCalUtils::Stringify::attendeeStatus(KCalCore::Attendee::Declined));
- stateDelegate->addItem(SmallIcon("task-attempt"),
- KCalUtils::Stringify::attendeeStatus(KCalCore::Attendee::Tentative));
- stateDelegate->addItem(SmallIcon("task-delegate"),
- KCalUtils::Stringify::attendeeStatus(KCalCore::Attendee::Delegated));
-#endif
#ifndef KDEPIM_MOBILE_UI
QStringList attrs;
@@ -123,10 +63,8 @@ IncidenceResource::IncidenceResource(Ui::EventOrTodoDesktop *ui)
completer->setWrapAround(false);
mUi->mNewResource->setCompleter(completer);
- KCalCore::Attendee::List resources;
AttendeeLineEditDelegate *attendeeDelegate = new AttendeeLineEditDelegate(this);
- dataModel = new AttendeeTableModel(resources, this);
ResourceFilterProxyModel *filterProxyModel = new ResourceFilterProxyModel(this);
filterProxyModel->setDynamicSortFilter(true);
filterProxyModel->setSourceModel(dataModel);
@@ -135,97 +73,33 @@ IncidenceResource::IncidenceResource(Ui::EventOrTodoDesktop *ui)
headerView->setResizeMode(QHeaderView::ResizeToContents);
mUi->mResourcesTable->setModel(filterProxyModel);
- mUi->mResourcesTable->setColumnHidden(AttendeeTableModel::CuType, true);
- mUi->mResourcesTable->setItemDelegateForColumn(AttendeeTableModel::Role, roleDelegate);
- mUi->mResourcesTable->setItemDelegateForColumn(AttendeeTableModel::Name, attendeeDelegate);
- mUi->mResourcesTable->setItemDelegateForColumn(AttendeeTableModel::Status, stateDelegate);
- mUi->mResourcesTable->setItemDelegateForColumn(AttendeeTableModel::Response, responseDelegate);
-
-
- AttendeeFilterProxyModel *attendeeProxyModel = new AttendeeFilterProxyModel(this);
- attendeeProxyModel->setDynamicSortFilter(true);
- attendeeProxyModel->setSourceModel(dataModel);
- mUi->mAttendeeTable->setModel(attendeeProxyModel);
- mUi->mAttendeeTable->setItemDelegateForColumn(AttendeeTableModel::Role, roleDelegate);
- mUi->mAttendeeTable->setItemDelegateForColumn(AttendeeTableModel::Name, attendeeDelegate);
- mUi->mAttendeeTable->setItemDelegateForColumn(AttendeeTableModel::Status, stateDelegate);
- mUi->mAttendeeTable->setItemDelegateForColumn(AttendeeTableModel::Response, responseDelegate);
+ mUi->mResourcesTable->setItemDelegateForColumn(AttendeeTableModel::Role, ieAttendee->roleDelegate());
+ mUi->mResourcesTable->setItemDelegateForColumn(AttendeeTableModel::FullName, attendeeDelegate);
+ mUi->mResourcesTable->setItemDelegateForColumn(AttendeeTableModel::Status, ieAttendee->stateDelegate());
+ mUi->mResourcesTable->setItemDelegateForColumn(AttendeeTableModel::Response, ieAttendee->responseDelegate());
connect(mUi->mFindResourcesButton, SIGNAL(clicked()), SLOT(findResources()));
connect(mUi->mBookResourceButton, SIGNAL(clicked()), SLOT(bookResource()));
connect(dataModel, SIGNAL(layoutChanged()), SLOT(layoutChanged()));
- connect(dataModel, SIGNAL(rowsInserted(const QModelIndex&, int , int)), SLOT(layoutChanged()));
- connect(dataModel, SIGNAL(rowsRemoved(const QModelIndex&, int , int)), SLOT(layoutChanged()));
+ connect(dataModel, SIGNAL(rowsInserted(const QModelIndex&, int , int)), SLOT(updateCount()));
+ connect(dataModel, SIGNAL(rowsRemoved(const QModelIndex&, int , int)), SLOT(updateCount()));
#endif
}
void IncidenceResource::load(const KCalCore::Incidence::Ptr &incidence)
{
- mLoadedIncidence = incidence;
- dataModel->setAttendees(incidence->attendees());
+ //all logic inside IncidenceAtendee (using same model)
}
void IncidenceResource::save(const KCalCore::Incidence::Ptr &incidence)
{
- incidence->clearAttendees();
- KCalCore::Attendee::List attendees = dataModel->attendees();
-
- foreach(KCalCore::Attendee::Ptr attendee, attendees) {
- Q_ASSERT(attendee);
-
- bool skip = false;
- if (KPIMUtils::isValidAddress(attendee->email())) {
- if (KMessageBox::warningYesNo(
- 0,
- i18nc("@info",
- "%1 does not look like a valid email address. "
- "Are you sure you want to invite this participant?",
- attendee->email()),
- i18nc("@title:window", "Invalid Email Address")) != KMessageBox::Yes) {
- skip = true;
- }
- }
- if (!skip) {
- incidence->addAttendee(attendee);
- }
- }
-
- // Must not have an organizer for items without attendees
- if (!incidence->attendeeCount()) {
- return;
- }
+ //all logic inside IncidenceAtendee (using same model)
}
bool IncidenceResource::isDirty() const
{
- const KCalCore::Attendee::List originalList = mLoadedIncidence->attendees();
- KCalCore::Attendee::List newList = dataModel->attendees();
-
- // The lists sizes *must* be the same. When the organizer is attending the
- // event as well, he should be in the attendees list as well.
- if (originalList.size() != newList.size()) {
- return true;
- }
-
- // Okay, again not the most efficient algorithm, but I'm assuming that in the
- // bulk of the use cases, the number of attendees is not much higher than 10 or so.
- foreach(const KCalCore::Attendee::Ptr & attendee, originalList) {
- bool found = false;
- for (int i = 0; i < newList.count(); ++i) {
- if (newList[i] == attendee) {
- newList.remove(i);
- found = true;
- break;
- }
- }
-
- if (!found) {
- // One of the attendees in the original list was not found in the new list.
- return true;
- }
- }
-
- return false;
+ //all logic inside IncidenceAtendee (using same model)
+ return false;
}
void IncidenceResource::bookResource()
@@ -248,10 +122,23 @@ void IncidenceResource::findResources()
void IncidenceResource::layoutChanged()
{
- emit resourceCountChanged(resourcesCount());
+
+#ifndef KDEPIM_MOBILE_UI
+ mUi->mResourcesTable->setColumnHidden(AttendeeTableModel::CuType, true);
+ mUi->mResourcesTable->setColumnHidden(AttendeeTableModel::Name, true);
+ mUi->mResourcesTable->setColumnHidden(AttendeeTableModel::Email, true);
+#endif
+
+ updateCount();
+}
+
+
+void IncidenceResource::updateCount()
+{
+ emit resourceCountChanged(resourceCount());
}
-int IncidenceResource::resourcesCount() const
+int IncidenceResource::resourceCount() const
{
#ifndef KDEPIM_MOBILE_UI
return mUi->mResourcesTable->model()->rowCount(QModelIndex());
diff --git a/incidenceeditor-ng/incidenceresource.h b/incidenceeditor-ng/incidenceresource.h
index 7208015..11ac84e 100644
--- a/incidenceeditor-ng/incidenceresource.h
+++ b/incidenceeditor-ng/incidenceresource.h
@@ -21,6 +21,7 @@
#define INCIDENCEEDITOR_INCIDENCERESOURCE_H
#include "incidenceeditor-ng.h"
+#include "incidenceattendee.h"
#include "attendeetablemodel.h"
#include <QModelIndex>
@@ -40,9 +41,9 @@ class INCIDENCEEDITORS_NG_EXPORT IncidenceResource : public IncidenceEditor
Q_OBJECT
public:
#ifdef KDEPIM_MOBILE_UI
- explicit IncidenceResource(Ui::EventOrTodoMore *ui);
+ explicit IncidenceResource(IncidenceAttendee* mIeAttendee, Ui::EventOrTodoMore *ui);
#else
- explicit IncidenceResource(Ui::EventOrTodoDesktop *ui);
+ explicit IncidenceResource(IncidenceAttendee* mIeAttendee, Ui::EventOrTodoDesktop *ui);
#endif
void load(const KCalCore::Incidence::Ptr &incidence);
@@ -50,7 +51,7 @@ public:
bool isDirty() const;
/** resturn the count of resources */
- int resourcesCount() const;
+ int resourceCount() const;
signals:
/** is emitted it the count of the resources is changed.
@@ -62,6 +63,7 @@ private slots:
void findResources();
void bookResource();
void layoutChanged();
+ void updateCount();
private:
#ifdef KDEPIM_MOBILE_UI
commit 6e0b6f5fb5059e77ba69f7c0faae8cb18e03dfb3
Author: Sandro Knauà <knauss at kolabsys.com>
Date: Tue Jun 17 10:08:24 2014 +0200
replacing mAttendeeEditor with TableView
diff --git a/incidenceeditor-ng/dialogdesktop.ui b/incidenceeditor-ng/dialogdesktop.ui
index 3f8f53b..2a10c51 100644
--- a/incidenceeditor-ng/dialogdesktop.ui
+++ b/incidenceeditor-ng/dialogdesktop.ui
@@ -716,6 +716,16 @@
<string comment="@title:tab attendees of this event or to-do">Attendees</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_15">
+ <item row="3" column="0" colspan="3">
+ <widget class="QTableView" name="mAttendeeTable">
+ <property name="editTriggers">
+ <set>QAbstractItemView::AllEditTriggers</set>
+ </property>
+ <attribute name="verticalHeaderVisible">
+ <bool>false</bool>
+ </attribute>
+ </widget>
+ </item>
<item row="1" column="0" colspan="2">
<widget class="QLabel" name="label_3">
<property name="text">
@@ -786,16 +796,6 @@
</item>
</layout>
</item>
- <item row="3" column="0" colspan="3">
- <widget class="QWidget" name="mAttendeWidgetPlaceHolder" native="true">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
<item row="1" column="2">
<widget class="QStackedWidget" name="mOrganizerStack">
<property name="sizePolicy">
@@ -883,7 +883,7 @@
<set>QAbstractItemView::AllEditTriggers</set>
</property>
<property name="showGrid">
- <bool>false</bool>
+ <bool>true</bool>
</property>
<property name="gridStyle">
<enum>Qt::SolidLine</enum>
@@ -894,6 +894,9 @@
<attribute name="horizontalHeaderHighlightSections">
<bool>false</bool>
</attribute>
+ <attribute name="verticalHeaderVisible">
+ <bool>false</bool>
+ </attribute>
</widget>
</item>
<item row="1" column="0">
@@ -930,25 +933,6 @@
</item>
</layout>
</item>
- <item row="2" column="0">
- <widget class="QTableView" name="mAttendeeTable">
- <property name="frameShadow">
- <enum>QFrame::Plain</enum>
- </property>
- <property name="editTriggers">
- <set>QAbstractItemView::AllEditTriggers</set>
- </property>
- <property name="showGrid">
- <bool>false</bool>
- </property>
- <attribute name="horizontalHeaderVisible">
- <bool>false</bool>
- </attribute>
- <attribute name="horizontalHeaderCascadingSectionResizes">
- <bool>false</bool>
- </attribute>
- </widget>
- </item>
</layout>
</widget>
<widget class="QWidget" name="mReminderTab">
diff --git a/incidenceeditor-ng/incidenceattendee.cpp b/incidenceeditor-ng/incidenceattendee.cpp
index 32d7f04..02a1ea7 100644
--- a/incidenceeditor-ng/incidenceattendee.cpp
+++ b/incidenceeditor-ng/incidenceattendee.cpp
@@ -29,6 +29,7 @@
#include "editorconfig.h"
#include "incidencedatetime.h"
#include "schedulingdialog.h"
+#include "attendeecomboboxdelegate.h"
#ifdef KDEPIM_MOBILE_UI
#include "ui_dialogmoremobile.h"
#else
@@ -39,6 +40,7 @@
#include <Akonadi/Contact/ContactGroupSearchJob>
#include <Akonadi/Contact/EmailAddressSelectionDialog>
+#include <KCalUtils/Stringify>
#include <KPIMUtils/Email>
#include <KDebug>
@@ -78,25 +80,83 @@ IncidenceAttendee::IncidenceAttendee( QWidget *parent, IncidenceDateTime *dateTi
: mUi( ui ),
mParentWidget( parent ),
mAttendeeEditor( new AttendeeEditor ),
+ mStateDelegate(new AttendeeComboBoxDelegate(this)),
+ mRoleDelegate(new AttendeeComboBoxDelegate(this)),
+ mResponseDelegate(new AttendeeComboBoxDelegate(this)),
mConflictResolver( 0 ), mDateTime( dateTime )
{
- setObjectName( "IncidenceAttendee" );
+ KCalCore::Attendee::List attendees;
+ KCalCore::Attendee::Ptr attendee(new KCalCore::Attendee("", ""));
+ attendees.append(attendee);
+ mDataModel = new AttendeeTableModel(attendees, this);
+ mDataModel->setKeepEmpty(true);
+
+ #ifdef KDEPIM_MOBILE_UI
+ mRoleDelegate->addItem(DesktopIcon("meeting-participant", 48),
+ KCalUtils::Stringify::attendeeRole(KCalCore::Attendee::ReqParticipant));
+ mRoleDelegate->addItem(DesktopIcon("meeting-participant-optional", 48),
+ KCalUtils::Stringify::attendeeRole(KCalCore::Attendee::OptParticipant));
+ mRoleDelegate->addItem(DesktopIcon("meeting-observer", 48),
+ KCalUtils::Stringify::attendeeRole(KCalCore::Attendee::NonParticipant));
+ mRoleDelegate->addItem(DesktopIcon("meeting-chair", 48),
+ KCalUtils::Stringify::attendeeRole(KCalCore::Attendee::Chair));
+
+ mResponseDelegate->addItem( DesktopIcon( "meeting-participant-request-response", 48 ),
+ i18nc( "@item:inlistbox", "Request Response" ) );
+ mResponseDelegate->addItem( DesktopIcon( "meeting-participant-no-response", 48 ),
+ i18nc( "@item:inlistbox", "Request No Response" ) );
+
+ #else
+ mRoleDelegate->addItem(SmallIcon("meeting-participant"),
+ KCalUtils::Stringify::attendeeRole(KCalCore::Attendee::ReqParticipant));
+ mRoleDelegate->addItem(SmallIcon("meeting-participant-optional"),
+ KCalUtils::Stringify::attendeeRole(KCalCore::Attendee::OptParticipant));
+ mRoleDelegate->addItem(SmallIcon("meeting-observer"),
+ KCalUtils::Stringify::attendeeRole(KCalCore::Attendee::NonParticipant));
+ mRoleDelegate->addItem(SmallIcon("meeting-chair"),
+ KCalUtils::Stringify::attendeeRole(KCalCore::Attendee::Chair));
+
+ mResponseDelegate->addItem( SmallIcon( "meeting-participant-request-response" ),
+ i18nc( "@item:inlistbox", "Request Response" ) );
+ mResponseDelegate->addItem( SmallIcon( "meeting-participant-no-response" ),
+ i18nc( "@item:inlistbox", "Request No Response" ) );
+
+ #endif
+
+ mStateDelegate->setWhatsThis( i18nc( "@info:whatsthis",
+ "Edits the current attendance status of the attendee." ) );
+
+ mRoleDelegate->setWhatsThis( i18nc( "@info:whatsthis",
+ "Edits the role of the attendee." ) );
+
+ mResponseDelegate->setToolTip( i18nc( "@info:tooltip", "Request a response from the attendee" ) );
+ mResponseDelegate->setWhatsThis( i18nc( "@info:whatsthis",
+ "Edits whether to send an email to the "
+ "attendee to request a response concerning "
+ "attendance." ) );
+
- QGridLayout *layout = new QGridLayout( mUi->mAttendeWidgetPlaceHolder );
- layout->setSpacing( 0 );
- layout->addWidget( mAttendeeEditor );
+ setObjectName( "IncidenceAttendee" );
- mAttendeeEditor->setCompletionMode( KGlobalSettings::self()->completionMode() );
- mAttendeeEditor->setFrameStyle( QFrame::Sunken | QFrame::StyledPanel );
+ AttendeeFilterProxyModel *filterProxyModel = new AttendeeFilterProxyModel(this);
+ filterProxyModel->setDynamicSortFilter(true);
+ filterProxyModel->setSourceModel(mDataModel);
#ifdef KDEPIM_MOBILE_UI
- mAttendeeEditor->setDynamicSizeHint( false );
-#endif
+#else
+ mUi->mAttendeeTable->setModel(filterProxyModel);
- connect( mAttendeeEditor, SIGNAL(countChanged(int)),
- SIGNAL(attendeeCountChanged(int)) );
- connect( mAttendeeEditor, SIGNAL(editingFinished(KPIM::MultiplyingLine*)),
- SLOT(checkIfExpansionIsNeeded(KPIM::MultiplyingLine*)) );
+ AttendeeLineEditDelegate *attendeeDelegate = new AttendeeLineEditDelegate(this);
+ attendeeDelegate->setCompletionMode( KGlobalSettings::self()->completionMode() );
+
+ QHeaderView* headerView = mUi->mAttendeeTable->horizontalHeader();
+ headerView->setResizeMode(QHeaderView::ResizeToContents);
+
+ mUi->mAttendeeTable->setItemDelegateForColumn(AttendeeTableModel::Role, roleDelegate());
+ mUi->mAttendeeTable->setItemDelegateForColumn(AttendeeTableModel::FullName, attendeeDelegate);
+ mUi->mAttendeeTable->setItemDelegateForColumn(AttendeeTableModel::Status, stateDelegate());
+ mUi->mAttendeeTable->setItemDelegateForColumn(AttendeeTableModel::Response, responseDelegate());
+#endif
mUi->mOrganizerStack->setCurrentIndex( 0 );
@@ -139,9 +199,16 @@ IncidenceAttendee::IncidenceAttendee( QWidget *parent, IncidenceDateTime *dateTi
SLOT(checkIfExpansionIsNeeded(KPIM::MultiplyingLine*)) );
connect( mAttendeeEditor, SIGNAL(changed(KCalCore::Attendee::Ptr,KCalCore::Attendee::Ptr)),
SLOT(slotAttendeeChanged(KCalCore::Attendee::Ptr,KCalCore::Attendee::Ptr)) );
+
+ connect(mDataModel, SIGNAL(layoutChanged()), SLOT(layoutChanged()));
+ connect(mDataModel, SIGNAL(rowsInserted(const QModelIndex&, int , int)), SLOT(updateCount()));
+ connect(mDataModel, SIGNAL(rowsRemoved(const QModelIndex&, int , int)), SLOT(updateCount()));
}
-IncidenceAttendee::~IncidenceAttendee() {}
+IncidenceAttendee::~IncidenceAttendee()
+{
+ delete mDataModel;
+}
void IncidenceAttendee::load( const KCalCore::Incidence::Ptr &incidence )
{
@@ -174,54 +241,45 @@ void IncidenceAttendee::load( const KCalCore::Incidence::Ptr &incidence )
mUi->mOrganizerLabel->setVisible( true );
}
- mAttendeeEditor->clear();
- // NOTE: Do this *before* adding the attendees, otherwise the status of the
- // attendee in the line will be 0 after when returning from load()
- if ( incidence->type() == KCalCore::Incidence::TypeEvent ) {
- mAttendeeEditor->setActions( AttendeeLine::EventActions );
- } else {
- mAttendeeEditor->setActions( AttendeeLine::TodoActions );
- }
+ mDataModel->setAttendees(incidence->attendees());
- const KCalCore::Attendee::List attendees = incidence->attendees();
- foreach ( const KCalCore::Attendee::Ptr &a, attendees ) {
- if (!(a->cuType() == KCalCore::Attendee::Resource || a->cuType() == KCalCore::Attendee::Room)) {
- mAttendeeEditor->addAttendee( a );
- }
- }
+ setActions( incidence->type() );
mWasDirty = false;
}
void IncidenceAttendee::save( const KCalCore::Incidence::Ptr &incidence )
{
- /*incidence->clearAttendees();
- AttendeeData::List attendees = mAttendeeEditor->attendees();
+ incidence->clearAttendees();
+ KCalCore::Attendee::List attendees = mDataModel->attendees();
- foreach ( AttendeeData::Ptr attendee, attendees ) {
- Q_ASSERT( attendee );
+ foreach(KCalCore::Attendee::Ptr attendee, attendees) {
+ Q_ASSERT(attendee);
bool skip = false;
- if ( KPIMUtils::isValidAddress( attendee->email() ) ) {
- if ( KMessageBox::warningYesNo(
- 0,
- i18nc( "@info",
- "%1 does not look like a valid email address. "
- "Are you sure you want to invite this participant?",
- attendee->email() ),
- i18nc( "@title:window", "Invalid Email Address" ) ) != KMessageBox::Yes ) {
+ if (attendee->fullName().isEmpty()) {
+ continue;
+ }
+ if (KPIMUtils::isValidAddress(attendee->email())) {
+ if (KMessageBox::warningYesNo(
+ 0,
+ i18nc("@info",
+ "%1 does not look like a valid email address. "
+ "Are you sure you want to invite this participant?",
+ attendee->email()),
+ i18nc("@title:window", "Invalid Email Address")) != KMessageBox::Yes) {
skip = true;
}
}
- if ( !skip ) {
- incidence->addAttendee( attendee );
+ if (!skip) {
+ incidence->addAttendee(attendee);
}
}
// Must not have an organizer for items without attendees
- if ( !incidence->attendeeCount() ) {
+ if (!incidence->attendeeCount()) {
return;
- }*/
+ }
if ( mUi->mOrganizerStack->currentIndex() == 0 ) {
incidence->setOrganizer( mUi->mOrganizerCombo->currentText() );
@@ -245,32 +303,34 @@ bool IncidenceAttendee::isDirty() const
}
const KCalCore::Attendee::List originalList = mLoadedIncidence->attendees();
- AttendeeData::List newList = mAttendeeEditor->attendees();
+ KCalCore::Attendee::List newList;
+
+ foreach(KCalCore::Attendee::Ptr attendee, mDataModel->attendees()) {
+ if (!attendee->fullName().isEmpty()) {
+ newList.append(attendee);
+ }
+ }
// The lists sizes *must* be the same. When the organizer is attending the
// event as well, he should be in the attendees list as well.
- /*if ( originalList.size() != newList.size() ) {
+ if (originalList.size() != newList.size()) {
return true;
- }*/
+ }
// Okay, again not the most efficient algorithm, but I'm assuming that in the
// bulk of the use cases, the number of attendees is not much higher than 10 or so.
- foreach ( const KCalCore::Attendee::Ptr &attendee, originalList ) {
- if (attendee->cuType() == KCalCore::Attendee::Resource || attendee->cuType() == KCalCore::Attendee::Room) {
- continue;
- }
+ foreach(const KCalCore::Attendee::Ptr & attendee, originalList) {
bool found = false;
- for ( int i = 0; i < newList.size(); ++i ) {
- if ( compareAttendees( newList.at( i )->attendee(), attendee) ) {
- newList.removeAt( i );
+ for (int i = 0; i < newList.count(); ++i) {
+ if (newList[i] == attendee) {
+ newList.remove(i);
found = true;
break;
}
}
- if ( !found ) {
+ if (!found) {
// One of the attendees in the original list was not found in the new list.
- kDebug() << "One of the attendees in the original list was not found in the new list";
return true;
}
}
@@ -283,14 +343,14 @@ void IncidenceAttendee::changeStatusForMe( KCalCore::Attendee::PartStat stat )
const IncidenceEditorNG::EditorConfig *config = IncidenceEditorNG::EditorConfig::instance();
Q_ASSERT( config );
- AttendeeData::List attendees = mAttendeeEditor->attendees();
- mAttendeeEditor->clear();
-
- foreach ( const AttendeeData::Ptr &attendee, attendees ) {
- if ( config->thatIsMe( attendee->email() ) ) {
- attendee->setStatus( stat );
+ KCalCore::Attendee::List attendees = mDataModel->attendees();
+ for (int i=0;i<mDataModel->rowCount();i++) {
+ QModelIndex index = mDataModel->index(i, AttendeeTableModel::Email);
+ if ( config->thatIsMe( mDataModel->data(index, Qt::DisplayRole).toString() ) ) {
+ index = mDataModel->index(i, AttendeeTableModel::Status);
+ mDataModel->setData(index, stat);
+ break;
}
- mAttendeeEditor->addAttendee( attendee );
}
checkDirtyStatus();
@@ -378,13 +438,8 @@ void IncidenceAttendee::groupSearchResult( KJob *job )
void IncidenceAttendee::slotSelectAddresses()
{
-#ifndef KDEPIM_MOBILE_UI
- QWidget *dialogParent = mAttendeeEditor;
-#else
- QWidget *dialogParent = 0;
-#endif
QWeakPointer<Akonadi::EmailAddressSelectionDialog> dialog(
- new Akonadi::EmailAddressSelectionDialog( dialogParent ) );
+ new Akonadi::EmailAddressSelectionDialog( ) );
dialog.data()->view()->view()->setSelectionMode( QAbstractItemView::ExtendedSelection );
if ( dialog.data()->exec() == QDialog::Accepted ) {
@@ -452,7 +507,7 @@ void IncidenceAttendee::slotAttendeeChanged( const KCalCore::Attendee::Ptr &oldA
void IncidenceAttendee::slotUpdateConflictLabel( int count )
{
- if ( mAttendeeEditor->attendees().count() > 0 ) {
+ if ( attendeeCount() > 0 ) {
mUi->mSolveButton->setEnabled( true );
if ( count > 0 ) {
QString label = i18ncp( "@label Shows the number of scheduling conflicts",
@@ -498,7 +553,7 @@ void IncidenceAttendee::insertAttendeeFromAddressee( const KABC::Addressee &a )
KCalCore::Attendee::ReqParticipant,
a.uid() ) );
- mAttendeeEditor->addAttendee( newAt );
+ mDataModel->insertAttendee(mDataModel->rowCount(), newAt);
}
void IncidenceAttendee::slotEventDurationChanged()
@@ -529,21 +584,23 @@ void IncidenceAttendee::slotOrganizerChanged( const QString &newOrganizer )
return;
}
- AttendeeData::Ptr currentOrganizerAttendee;
- AttendeeData::Ptr newOrganizerAttendee;
+ int currentOrganizerAttendee = -1;
+ int newOrganizerAttendee = -1;
- Q_FOREACH ( AttendeeData::Ptr attendee, mAttendeeEditor->attendees() ) {
- if ( attendee->fullName() == mOrganizer ) {
- currentOrganizerAttendee = attendee;
+ for(int i=0; i<mDataModel->rowCount(); i++) {
+ QModelIndex index = mDataModel->index(i,AttendeeTableModel::FullName);
+ QString fullName = mDataModel->data(index,Qt::DisplayRole).toString();
+ if ( fullName == mOrganizer ) {
+ currentOrganizerAttendee = i;
}
- if ( attendee->fullName() == newOrganizer ) {
- newOrganizerAttendee = attendee;
+ if ( fullName == newOrganizer ) {
+ newOrganizerAttendee = i;
}
}
int answer = KMessageBox::No;
- if ( currentOrganizerAttendee ) {
+ if ( currentOrganizerAttendee > -1) {
answer = KMessageBox::questionYesNo(
mParentWidget,
i18nc( "@option",
@@ -555,11 +612,11 @@ void IncidenceAttendee::slotOrganizerChanged( const QString &newOrganizer )
}
if ( answer == KMessageBox::Yes ) {
- if ( currentOrganizerAttendee ) {
- mAttendeeEditor->removeAttendee( currentOrganizerAttendee );
+ if ( currentOrganizerAttendee > -1 ) {
+ mDataModel->removeRows(currentOrganizerAttendee,1);
}
- if ( !newOrganizerAttendee ) {
+ if ( newOrganizerAttendee == -1 ) {
bool rsvp = !iAmOrganizer(); // if it is the user, don't make him rsvp.
KCalCore::Attendee::PartStat status = iAmOrganizer() ? KCalCore::Attendee::Accepted
: KCalCore::Attendee::NeedsAction;
@@ -567,12 +624,135 @@ void IncidenceAttendee::slotOrganizerChanged( const QString &newOrganizer )
KCalCore::Attendee::Ptr newAt(
new KCalCore::Attendee( name, email, rsvp, status, KCalCore::Attendee::ReqParticipant ) );
- mAttendeeEditor->addAttendee( newAt );
+ mDataModel->insertAttendee(mDataModel->rowCount(), newAt);
}
}
mOrganizer = newOrganizer;
}
+AttendeeTableModel* IncidenceAttendee::dataModel()
+{
+ return mDataModel;
+}
+
+AttendeeComboBoxDelegate* IncidenceAttendee::responseDelegate()
+{
+ return mResponseDelegate;
+}
+
+AttendeeComboBoxDelegate* IncidenceAttendee::roleDelegate()
+{
+ return mRoleDelegate;
+}
+
+AttendeeComboBoxDelegate* IncidenceAttendee::stateDelegate()
+{
+ return mStateDelegate;
+}
+
+void IncidenceAttendee::layoutChanged()
+{
+#ifndef KDEPIM_MOBILE_UI
+ mUi->mAttendeeTable->setColumnHidden(AttendeeTableModel::CuType, true);
+ mUi->mAttendeeTable->setColumnHidden(AttendeeTableModel::Name, true);
+ mUi->mAttendeeTable->setColumnHidden(AttendeeTableModel::Email, true);
+ mUi->mAttendeeTable->setColumnHidden(AttendeeTableModel::Available, true);
+#endif
+
+ updateCount();
+}
+
+
+void IncidenceAttendee::updateCount()
+{
+ emit attendeeCountChanged(attendeeCount());
+
+ checkDirtyStatus();
+}
+
+int IncidenceAttendee::attendeeCount() const
+{
+#ifndef KDEPIM_MOBILE_UI
+ int c=0;
+ QModelIndex index;
+ QAbstractItemModel *model = mUi->mAttendeeTable->model();
+ if (!model ) {
+ return 0;
+ }
+ for(int i=0;i< model->rowCount(QModelIndex());i++) {
+ index = model->index(i,AttendeeTableModel::FullName);
+ if (!model->data(index).toString().isEmpty()) {
+ c++;
+ }
+ }
+ return c;
+#endif
+ return 0;
+}
+
+void IncidenceAttendee::setActions( KCalCore::Incidence::IncidenceType actions )
+{
+ mStateDelegate->clear();
+ if ( actions == KCalCore::Incidence::TypeEvent ) {
+#ifdef KDEPIM_MOBILE_UI
+ mStateDelegate->addItem( DesktopIcon( "task-attention", 48 ),
+ KCalUtils::Stringify::attendeeStatus( AttendeeData::NeedsAction ) );
+ mStateDelegate->addItem( DesktopIcon( "task-accepted", 48 ),
+ KCalUtils::Stringify::attendeeStatus( AttendeeData::Accepted ) );
+ mStateDelegate->addItem( DesktopIcon( "task-reject", 48 ),
+ KCalUtils::Stringify::attendeeStatus( AttendeeData::Declined ) );
+ mStateDelegate->addItem( DesktopIcon( "task-attempt", 48 ),
+ KCalUtils::Stringify::attendeeStatus( AttendeeData::Tentative ) );
+ mStateDelegate->addItem( DesktopIcon( "task-delegate", 48 ),
+ KCalUtils::Stringify::attendeeStatus( AttendeeData::Delegated ) );
+#else
+ mStateDelegate->addItem( SmallIcon( "task-attention" ),
+ KCalUtils::Stringify::attendeeStatus( AttendeeData::NeedsAction ) );
+ mStateDelegate->addItem( SmallIcon( "task-accepted" ),
+ KCalUtils::Stringify::attendeeStatus( AttendeeData::Accepted ) );
+ mStateDelegate->addItem( SmallIcon( "task-reject" ),
+ KCalUtils::Stringify::attendeeStatus( AttendeeData::Declined ) );
+ mStateDelegate->addItem( SmallIcon( "task-attempt" ),
+ KCalUtils::Stringify::attendeeStatus( AttendeeData::Tentative ) );
+ mStateDelegate->addItem( SmallIcon( "task-delegate" ),
+ KCalUtils::Stringify::attendeeStatus( AttendeeData::Delegated ) );
+#endif
+ } else {
+#ifdef KDEPIM_MOBILE_UI
+ mStateDelegate->addItem( DesktopIcon( "task-attention", 48 ),
+ KCalUtils::Stringify::attendeeStatus( AttendeeData::NeedsAction ) );
+ mStateDelegate->addItem( DesktopIcon( "task-accepted", 48 ),
+ KCalUtils::Stringify::attendeeStatus( AttendeeData::Accepted ) );
+ mStateDelegate->addItem( DesktopIcon( "task-reject", 48 ),
+ KCalUtils::Stringify::attendeeStatus( AttendeeData::Declined ) );
+ mStateDelegate->addItem( DesktopIcon( "task-attempt", 48 ),
+ KCalUtils::Stringify::attendeeStatus( AttendeeData::Tentative ) );
+ mStateDelegate->addItem( DesktopIcon( "task-delegate", 48 ),
+ KCalUtils::Stringify::attendeeStatus( AttendeeData::Delegated ) );
+ mStateDelegate->addItem( DesktopIcon( "task-complete", 48 ),
+ KCalUtils::Stringify::attendeeStatus( AttendeeData::Completed ) );
+ mStateDelegate->addItem( DesktopIcon( "task-ongoing", 48 ),
+ KCalUtils::Stringify::attendeeStatus( AttendeeData::InProcess ) );
+#else
+ mStateDelegate->addItem( SmallIcon( "task-attention" ),
+ KCalUtils::Stringify::attendeeStatus( AttendeeData::NeedsAction ) );
+ mStateDelegate->addItem( SmallIcon( "task-accepted" ),
+ KCalUtils::Stringify::attendeeStatus( AttendeeData::Accepted ) );
+ mStateDelegate->addItem( SmallIcon( "task-reject" ),
+ KCalUtils::Stringify::attendeeStatus( AttendeeData::Declined ) );
+ mStateDelegate->addItem( SmallIcon( "task-attempt" ),
+ KCalUtils::Stringify::attendeeStatus( AttendeeData::Tentative ) );
+ mStateDelegate->addItem( SmallIcon( "task-delegate" ),
+ KCalUtils::Stringify::attendeeStatus( AttendeeData::Delegated ) );
+ mStateDelegate->addItem( SmallIcon( "task-complete" ),
+ KCalUtils::Stringify::attendeeStatus( AttendeeData::Completed ) );
+ mStateDelegate->addItem( SmallIcon( "task-ongoing" ),
+ KCalUtils::Stringify::attendeeStatus( AttendeeData::InProcess ) );
+#endif
+ }
+}
+
+
void IncidenceAttendee::printDebugInfo() const
{
kDebug() << "I'm organizer : " << iAmOrganizer();
@@ -585,11 +765,12 @@ void IncidenceAttendee::printDebugInfo() const
}
const KCalCore::Attendee::List originalList = mLoadedIncidence->attendees();
- AttendeeData::List newList = mAttendeeEditor->attendees();
- kDebug() << "List sizes: " << originalList.count() << newList.count();
+ KCalCore::Attendee::List newList;
- if ( originalList.count() != newList.count() ) {
- return;
+ foreach(KCalCore::Attendee::Ptr attendee, mDataModel->attendees()) {
+ if (!attendee->fullName().isEmpty()) {
+ newList.append(attendee);
+ }
}
// Okay, again not the most efficient algorithm, but I'm assuming that in the
@@ -597,8 +778,8 @@ void IncidenceAttendee::printDebugInfo() const
foreach ( const KCalCore::Attendee::Ptr &attendee, originalList ) {
bool found = false;
for ( int i = 0; i < newList.count(); ++i ) {
- if ( *newList.at( i )->attendee() == *attendee ) {
- newList.removeAt( i );
+ if ( newList[i] == attendee ) {
+ newList.remove(i);
found = true;
break;
}
@@ -616,7 +797,7 @@ void IncidenceAttendee::printDebugInfo() const
<< attendee->delegator()
<< "; we have:";
for ( int i = 0; i < newList.count(); ++i ) {
- KCalCore::Attendee::Ptr attendee = newList.at( i )->attendee();
+ KCalCore::Attendee::Ptr attendee = newList[i];
kDebug() << "Attendee: " << attendee->email()
<< attendee->name()
<< attendee->status()
@@ -631,4 +812,4 @@ void IncidenceAttendee::printDebugInfo() const
return;
}
}
-}
+}
\ No newline at end of file
diff --git a/incidenceeditor-ng/incidenceattendee.h b/incidenceeditor-ng/incidenceattendee.h
index c7ba4e5..60c05ae 100644
--- a/incidenceeditor-ng/incidenceattendee.h
+++ b/incidenceeditor-ng/incidenceattendee.h
@@ -22,6 +22,8 @@
#define INCIDENCEEDITOR_INCIDENCEATTENDEE_H
#include "incidenceeditor-ng.h"
+#include "attendeetablemodel.h"
+
namespace Ui {
class EventOrTodoDesktop;
@@ -41,6 +43,7 @@ class KJob;
namespace IncidenceEditorNG {
class AttendeeEditor;
+class AttendeeComboBoxDelegate;
class ConflictResolver;
class IncidenceDateTime;
@@ -60,6 +63,13 @@ class INCIDENCEEDITORS_NG_EXPORT IncidenceAttendee : public IncidenceEditor
virtual bool isDirty() const;
virtual void printDebugInfo() const;
+ AttendeeTableModel * dataModel();
+ AttendeeComboBoxDelegate *stateDelegate();
+ AttendeeComboBoxDelegate *roleDelegate();
+ AttendeeComboBoxDelegate *responseDelegate();
+
+ int attendeeCount() const;
+
signals:
void attendeeCountChanged( int );
@@ -83,6 +93,10 @@ class INCIDENCEEDITORS_NG_EXPORT IncidenceAttendee : public IncidenceEditor
// wrapper for the conflict resolver
void slotEventDurationChanged();
+ void layoutChanged();
+ void updateCount();
+
+
private:
void changeStatusForMe( KCalCore::Attendee::PartStat );
@@ -97,6 +111,7 @@ class INCIDENCEEDITORS_NG_EXPORT IncidenceAttendee : public IncidenceEditor
*/
void insertAttendeeFromAddressee( const KABC::Addressee &a );
void fillOrganizerCombo();
+ void setActions( KCalCore::Incidence::IncidenceType actions );
#ifdef KDEPIM_MOBILE_UI
Ui::EventOrTodoMore *mUi;
@@ -109,6 +124,13 @@ class INCIDENCEEDITORS_NG_EXPORT IncidenceAttendee : public IncidenceEditor
QMap<KJob *,QWeakPointer<KPIM::MultiplyingLine> > mMightBeGroupLines;
IncidenceDateTime *mDateTime;
QString mOrganizer;
+
+ /** used dataModel to rely on*/
+ AttendeeTableModel *mDataModel;
+ AttendeeComboBoxDelegate *mStateDelegate;
+ AttendeeComboBoxDelegate *mRoleDelegate;
+ AttendeeComboBoxDelegate *mResponseDelegate;
+
};
}
commit 18698ce7a5cf6c996080b5804e276d01082de6ee
Author: Sandro Knauà <knauss at kolabsys.com>
Date: Tue Jun 17 10:01:59 2014 +0200
Added keepEmptyLines to model
diff --git a/incidenceeditor-ng/attendeetablemodel.cpp b/incidenceeditor-ng/attendeetablemodel.cpp
index 242976a..78c21bd 100644
--- a/incidenceeditor-ng/attendeetablemodel.cpp
+++ b/incidenceeditor-ng/attendeetablemodel.cpp
@@ -10,8 +10,9 @@ using namespace IncidenceEditorNG;
AttendeeTableModel::AttendeeTableModel(const KCalCore::Attendee::List &attendees, QObject *parent)
: QAbstractTableModel(parent)
, attendeeList(attendees)
+ , mKeepEmpty(false)
{
- insertRows(0,1);
+
}
int AttendeeTableModel::rowCount(const QModelIndex &/*parent*/) const
@@ -21,7 +22,7 @@ int AttendeeTableModel::rowCount(const QModelIndex &/*parent*/) const
int AttendeeTableModel::columnCount(const QModelIndex &/*parent*/) const
{
- return 6;
+ return 8;
}
Qt::ItemFlags AttendeeTableModel::flags(const QModelIndex &index) const
@@ -29,10 +30,10 @@ Qt::ItemFlags AttendeeTableModel::flags(const QModelIndex &index) const
if (!index.isValid()) {
return Qt::ItemIsEnabled;
}
- if (index.column() == Available) { //Available is read only
- return QAbstractTableModel::flags(index);
+ if (index.column() == Available || index.column() == Name || index.column() == Email) { //Available is read only
+ return QAbstractTableModel::flags(index);
} else {
- return QAbstractTableModel::flags(index) | Qt::ItemIsEditable;
+ return QAbstractTableModel::flags(index) | Qt::ItemIsEditable;
}
}
@@ -50,7 +51,7 @@ QVariant AttendeeTableModel::data(const QModelIndex &index, int role) const
switch (index.column()) {
case Role:
return attendeeList[index.row()]->role();
- case Name:
+ case FullName:
return attendeeList[index.row()]->fullName();
case Available:
return 0;//attendeeList.at(index.row()).available;
@@ -60,6 +61,10 @@ QVariant AttendeeTableModel::data(const QModelIndex &index, int role) const
return attendeeList[index.row()]->cuType();
case Response:
return attendeeList[index.row()]->RSVP();
+ case Name:
+ return attendeeList[index.row()]->name();
+ case Email:
+ return attendeeList[index.row()]->email();
}
}
@@ -74,10 +79,12 @@ bool AttendeeTableModel::setData(const QModelIndex& index, const QVariant& value
case Role:
attendeeList[index.row()]->setRole(static_cast<KCalCore::Attendee::Role>(value.toInt()));
break;
- case Name:
+ case FullName:
KPIMUtils::extractEmailAddressAndName(value.toString(), email, name);
attendeeList[index.row()]->setName(name);
attendeeList[index.row()]->setEmail(email);
+
+ addEmptyAttendee(true);
break;
case Available:
//attendeeList[index.row()].available = value.toBool();
@@ -111,8 +118,8 @@ QVariant AttendeeTableModel::headerData(int section, Qt::Orientation orientation
switch (section) {
case Role:
return QString("role");
- case Name:
- return QString("name");
+ case FullName:
+ return QString("fullname");
case Available:
return QString("available");
case Status:
@@ -121,6 +128,10 @@ QVariant AttendeeTableModel::headerData(int section, Qt::Orientation orientation
return QString("cuType");
case Response:
return QString("response");
+ case Name:
+ return QString("name");
+ case Email:
+ return QString("email");
}
}
@@ -169,6 +180,8 @@ void AttendeeTableModel::setAttendees(const KCalCore::Attendee::List attendees)
attendeeList = attendees;
+ addEmptyAttendee(false);
+
emit layoutChanged();
}
@@ -178,6 +191,46 @@ KCalCore::Attendee::List AttendeeTableModel::attendees() const
return attendeeList;
}
+void AttendeeTableModel::addEmptyAttendee(bool layoutChange)
+{
+ if (mKeepEmpty) {
+ bool create=true;
+ foreach(KCalCore::Attendee::Ptr attendee, attendeeList) {
+ if (attendee->fullName().isEmpty()) {
+ create=false;
+ break;
+ }
+ }
+
+ if (create) {
+ if (layoutChange) {
+ emit layoutAboutToBeChanged();
+ }
+
+ insertRows(rowCount(),1);
+
+ if (layoutChange) {
+ emit layoutChanged();
+ }
+ }
+ }
+}
+
+
+bool AttendeeTableModel::keepEmpty()
+{
+ return mKeepEmpty;
+}
+
+void AttendeeTableModel::setKeepEmpty(bool keepEmpty)
+{
+ if (keepEmpty != mKeepEmpty) {
+ mKeepEmpty = keepEmpty;
+ addEmptyAttendee(true);
+ }
+}
+
+
ResourceFilterProxyModel::ResourceFilterProxyModel(QObject *parent)
: QSortFilterProxyModel(parent)
{
diff --git a/incidenceeditor-ng/attendeetablemodel.h b/incidenceeditor-ng/attendeetablemodel.h
index ea525e1..dce56f0 100644
--- a/incidenceeditor-ng/attendeetablemodel.h
+++ b/incidenceeditor-ng/attendeetablemodel.h
@@ -40,7 +40,9 @@ public:
enum Columns {
CuType,
Role,
+ FullName,
Name,
+ Email,
Available,
Status,
Response
@@ -66,8 +68,13 @@ public:
void setAttendees(const KCalCore::Attendee::List resources);
KCalCore::Attendee::List attendees() const;
+ void setKeepEmpty(bool keepEmpty);
+ bool keepEmpty();
private:
+ void addEmptyAttendee(bool layoutChange);
+
KCalCore::Attendee::List attendeeList;
+ bool mKeepEmpty;
};
class ResourceFilterProxyModel : public QSortFilterProxyModel
commit 967420d0905500477ae67cca0b76fb84a0165328
Author: Sandro Knauà <knauss at kolabsys.com>
Date: Tue Jun 17 09:55:10 2014 +0200
add tooltip&whatsthis to Attendee*Delegators
diff --git a/incidenceeditor-ng/attendeecomboboxdelegate.cpp b/incidenceeditor-ng/attendeecomboboxdelegate.cpp
index d90d3fc..d2fc767 100644
--- a/incidenceeditor-ng/attendeecomboboxdelegate.cpp
+++ b/incidenceeditor-ng/attendeecomboboxdelegate.cpp
@@ -2,8 +2,15 @@
#include "attendeeline.h"
+#include <QAbstractItemView>
#include <QApplication>
#include <QMenu>
+#include <QHelpEvent>
+#include <QToolTip>
+#include <QWhatsThis>
+
+#include <KDebug>
+#include <KLocalizedString>
using namespace IncidenceEditorNG;
@@ -22,6 +29,22 @@ void AttendeeComboBoxDelegate::addItem(const QIcon &icon, const QString &text)
entries << pair;
}
+void AttendeeComboBoxDelegate::clear()
+{
+ entries.clear();
+}
+
+
+void AttendeeComboBoxDelegate::setToolTip(const QString& tT)
+{
+ toolTip = tT;
+}
+
+void AttendeeComboBoxDelegate::setWhatsThis(const QString& wT)
+{
+ whatsThis = wT;
+}
+
void AttendeeComboBoxDelegate::setStandardIndex(int index)
{
standardIndex = index;
@@ -40,6 +63,8 @@ QWidget *AttendeeComboBoxDelegate::createEditor(QWidget *parent, const QStyleOpt
connect(editor,SIGNAL(rightPressed()),SLOT(rightPressed()));
editor->setPopupMode( QToolButton::MenuButtonPopup);
+ editor->setToolTip(toolTip);
+ editor->setWhatsThis(whatsThis);
return editor;
}
@@ -67,7 +92,7 @@ void AttendeeComboBoxDelegate::updateEditorGeometry(QWidget *editor, const QStyl
void AttendeeComboBoxDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
- QStyleOptionToolButton myOption;
+ QStyleOptionButton myOption;;
int value = index.model()->data(index).toUInt();
if (value >= entries.count()) {
@@ -77,15 +102,12 @@ void AttendeeComboBoxDelegate::paint(QPainter *painter, const QStyleOptionViewIt
myOption.rect = option.rect;
myOption.state = option.state;
myOption.icon = entries[value].first;
- myOption.iconSize = QSize(48,48);
- //myOption.features |= QStyleOptionToolButton::MenuButtonPopup;
- QApplication::style()->drawComplexControl(QStyle::CC_ToolButton, &myOption, painter);
+ QApplication::style()->drawControl(QStyle::CE_PushButton, &myOption, painter);
}
bool AttendeeComboBoxDelegate::eventFilter ( QObject * editor, QEvent * event )
{
-
if (event->type() == QEvent::Enter) {
AttendeeComboBox *comboBox = static_cast<AttendeeComboBox*>(editor);
comboBox->showMenu();
@@ -111,10 +133,45 @@ void AttendeeComboBoxDelegate::rightPressed()
emit closeEditor(static_cast<QWidget*>(QObject::sender()),QAbstractItemDelegate::EditNextItem);
}
+
+bool AttendeeComboBoxDelegate::helpEvent( QHelpEvent* event, QAbstractItemView* view,
+ const QStyleOptionViewItem& option, const QModelIndex& index )
+{
+ if (!event || !view) {
+ return false;
+ }
+ switch (event->type()) {
+#ifndef QT_NO_TOOLTIP
+ case QEvent::ToolTip: {
+ QHelpEvent *he = static_cast<QHelpEvent*>(event);
+ QToolTip::showText(he->globalPos(), toolTip, view);
+ return true;
+ break;}
+#endif
+#ifndef QT_NO_WHATSTHIS
+ case QEvent::QueryWhatsThis:
+ return true;
+ break;
+ case QEvent::WhatsThis: {
+ QHelpEvent *he = static_cast<QHelpEvent*>(event);
+ QWhatsThis::showText(he->globalPos(), whatsThis, view);
+ return true;
+ break ; }
+#endif
+ default:
+ break;
+ }
+ return QStyledItemDelegate::helpEvent( event, view, option, index );
+}
+
AttendeeLineEditDelegate::AttendeeLineEditDelegate(QObject* parent)
: QStyledItemDelegate(parent)
{
-
+ toolTip = i18nc( "@info:tooltip",
+ "Enter the name or email address of the attendee." );
+ whatsThis = i18nc( "@info:whatsthis",
+ "The email address or name of the attendee. An invitation "
+ "can be sent to the user if an email address is provided." );
}
QWidget *AttendeeLineEditDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &/* option */, const QModelIndex &/* index */) const
@@ -122,6 +179,11 @@ QWidget *AttendeeLineEditDelegate::createEditor(QWidget *parent, const QStyleOpt
AttendeeLineEdit* editor = new AttendeeLineEdit(parent);
connect(editor,SIGNAL(leftPressed()),SLOT(leftPressed()));
connect(editor,SIGNAL(rightPressed()),SLOT(rightPressed()));
+ editor->setToolTip(toolTip);
+ editor->setWhatsThis(whatsThis);
+ editor->setCompletionMode(completionMode);
+ editor->setClearButtonShown( true );
+
return editor;
}
@@ -151,3 +213,38 @@ void AttendeeLineEditDelegate::rightPressed()
{
emit closeEditor(static_cast<QWidget*>(QObject::sender()),QAbstractItemDelegate::EditNextItem);
}
+
+void AttendeeLineEditDelegate::setCompletionMode(KGlobalSettings::Completion mode)
+{
+ completionMode = mode;
+}
+
+bool AttendeeLineEditDelegate::helpEvent( QHelpEvent* event, QAbstractItemView* view,
+ const QStyleOptionViewItem& option, const QModelIndex& index )
+{
+ if (!event || !view) {
+ return false;
+ }
+ switch (event->type()) {
+#ifndef QT_NO_TOOLTIP
+ case QEvent::ToolTip: {
+ QHelpEvent *he = static_cast<QHelpEvent*>(event);
+ QToolTip::showText(he->globalPos(), toolTip, view);
+ return true;
+ break;}
+#endif
+#ifndef QT_NO_WHATSTHIS
+ case QEvent::QueryWhatsThis:
+ return true;
+ break;
+ case QEvent::WhatsThis: {
+ QHelpEvent *he = static_cast<QHelpEvent*>(event);
+ QWhatsThis::showText(he->globalPos(), whatsThis, view);
+ return true;
+ break ; }
+#endif
+ default:
+ break;
+ }
+ return QStyledItemDelegate::helpEvent( event, view, option, index );
+}
diff --git a/incidenceeditor-ng/attendeecomboboxdelegate.h b/incidenceeditor-ng/attendeecomboboxdelegate.h
index caedc50..f61233d 100644
--- a/incidenceeditor-ng/attendeecomboboxdelegate.h
+++ b/incidenceeditor-ng/attendeecomboboxdelegate.h
@@ -22,6 +22,8 @@
#ifndef INCIDENCEEDITOR_ATTENDEECOMBOBOXDELEGATE_H
#define INCIDENCEEDITOR_ATTENDEECOMBOBOXDELEGATE_H
+#include <kglobalsettings.h>
+
#include <QStyledItemDelegate>
#include <QModelIndex>
#include <QIcon>
@@ -51,11 +53,18 @@ public:
bool eventFilter ( QObject * editor, QEvent * event );
void addItem(const QIcon&, const QString&);
+ void clear();
+
+ void setToolTip(const QString&);
+ void setWhatsThis(const QString&);
/** choose this index, if the item in the model is unknown
*/
void setStandardIndex(int);
+public slots:
+ bool helpEvent( QHelpEvent* event, QAbstractItemView* view, const QStyleOptionViewItem& option, const QModelIndex& index );
+
private slots:
void doCloseEditor(QWidget *editor);
void rightPressed();
@@ -66,6 +75,8 @@ private:
QList<QPair<QIcon, QString> > entries;
/**fallback index */
int standardIndex;
+ QString toolTip;
+ QString whatsThis;
};
/** show a AttendeeLineEdit as editor */
@@ -80,9 +91,19 @@ public:
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;
+ void setCompletionMode( KGlobalSettings::Completion mode);
+
+public slots:
+ bool helpEvent( QHelpEvent* event, QAbstractItemView* view, const QStyleOptionViewItem& option, const QModelIndex& index );
+
private slots:
- void rightPressed();
- void leftPressed();
+ void rightPressed();
+ void leftPressed();
+
+private:
+ QString toolTip;
+ QString whatsThis;
+ KGlobalSettings::Completion completionMode;
};
}
commit 3ff3388b814c860c17ea96aacf070672f22c0b50
Author: Sandro Knauà <knauss at kolabsys.com>
Date: Sat Jun 14 19:17:30 2014 +0200
have a nice tableView
diff --git a/incidenceeditor-ng/attendeecomboboxdelegate.cpp b/incidenceeditor-ng/attendeecomboboxdelegate.cpp
index 21ec3f8..d90d3fc 100644
--- a/incidenceeditor-ng/attendeecomboboxdelegate.cpp
+++ b/incidenceeditor-ng/attendeecomboboxdelegate.cpp
@@ -3,6 +3,7 @@
#include "attendeeline.h"
#include <QApplication>
+#include <QMenu>
using namespace IncidenceEditorNG;
@@ -10,7 +11,7 @@ AttendeeComboBoxDelegate::AttendeeComboBoxDelegate(QObject *parent)
: QStyledItemDelegate(parent)
, standardIndex(0)
{
-
+ connect(this, SIGNAL(closeEditor(QWidget*)), SLOT(doCloseEditor(QWidget*)));
}
void AttendeeComboBoxDelegate::addItem(const QIcon &icon, const QString &text)
@@ -26,7 +27,6 @@ void AttendeeComboBoxDelegate::setStandardIndex(int index)
standardIndex = index;
}
-
QWidget *AttendeeComboBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &/* option */, const QModelIndex &/* index */) const
{
AttendeeComboBox* editor = new AttendeeComboBox(parent);
@@ -36,6 +36,10 @@ QWidget *AttendeeComboBoxDelegate::createEditor(QWidget *parent, const QStyleOpt
editor->addItem(pair.first, pair.second);
}
+ connect(editor,SIGNAL(leftPressed()),SLOT(leftPressed()));
+ connect(editor,SIGNAL(rightPressed()),SLOT(rightPressed()));
+
+ editor->setPopupMode( QToolButton::MenuButtonPopup);
return editor;
}
@@ -53,6 +57,7 @@ void AttendeeComboBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel
{
AttendeeComboBox *comboBox = static_cast<AttendeeComboBox*>(editor);
model->setData(index, comboBox->currentIndex(), Qt::EditRole);
+ comboBox->menu()->close();
}
void AttendeeComboBoxDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
@@ -62,16 +67,48 @@ void AttendeeComboBoxDelegate::updateEditorGeometry(QWidget *editor, const QStyl
void AttendeeComboBoxDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
- QStyleOptionButton pushButton;
+ QStyleOptionToolButton myOption;
+
int value = index.model()->data(index).toUInt();
- pushButton.rect = option.rect;
- pushButton.features |= QStyleOptionButton::HasMenu;
if (value >= entries.count()) {
value = standardIndex;
}
- pushButton.icon = entries[value].first;
- QApplication::style()->drawControl(QStyle::CE_PushButton, &pushButton, painter);
+ myOption.rect = option.rect;
+ myOption.state = option.state;
+ myOption.icon = entries[value].first;
+ myOption.iconSize = QSize(48,48);
+ //myOption.features |= QStyleOptionToolButton::MenuButtonPopup;
+
+ QApplication::style()->drawComplexControl(QStyle::CC_ToolButton, &myOption, painter);
+}
+
+bool AttendeeComboBoxDelegate::eventFilter ( QObject * editor, QEvent * event )
+{
+
+ if (event->type() == QEvent::Enter) {
+ AttendeeComboBox *comboBox = static_cast<AttendeeComboBox*>(editor);
+ comboBox->showMenu();
+ return editor->eventFilter(editor, event);
+ }
+
+ return QStyledItemDelegate::eventFilter(editor, event);
+}
+
+void AttendeeComboBoxDelegate::doCloseEditor(QWidget* editor)
+{
+ AttendeeComboBox *comboBox = static_cast<AttendeeComboBox*>(editor);
+ comboBox->menu()->close();
+}
+
+void AttendeeComboBoxDelegate::leftPressed()
+{
+ emit closeEditor(static_cast<QWidget*>(QObject::sender()),QAbstractItemDelegate::EditPreviousItem);
+}
+
+void AttendeeComboBoxDelegate::rightPressed()
+{
+ emit closeEditor(static_cast<QWidget*>(QObject::sender()),QAbstractItemDelegate::EditNextItem);
}
AttendeeLineEditDelegate::AttendeeLineEditDelegate(QObject* parent)
@@ -80,22 +117,23 @@ AttendeeLineEditDelegate::AttendeeLineEditDelegate(QObject* parent)
}
-
QWidget *AttendeeLineEditDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &/* option */, const QModelIndex &/* index */) const
{
- KPIM::AddresseeLineEdit* editor = new KPIM::AddresseeLineEdit(parent);
+ AttendeeLineEdit* editor = new AttendeeLineEdit(parent);
+ connect(editor,SIGNAL(leftPressed()),SLOT(leftPressed()));
+ connect(editor,SIGNAL(rightPressed()),SLOT(rightPressed()));
return editor;
}
void AttendeeLineEditDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
- KPIM::AddresseeLineEdit *lineedit = static_cast<KPIM::AddresseeLineEdit*>(editor);
+ AttendeeLineEdit *lineedit = static_cast<AttendeeLineEdit*>(editor);
lineedit->setText(index.model()->data(index, Qt::EditRole).toString());
}
void AttendeeLineEditDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
- KPIM::AddresseeLineEdit *lineedit = static_cast<KPIM::AddresseeLineEdit*>(editor);
+ AttendeeLineEdit *lineedit = static_cast<AttendeeLineEdit*>(editor);
model->setData(index, lineedit->text(), Qt::EditRole);
}
@@ -103,3 +141,13 @@ void AttendeeLineEditDelegate::updateEditorGeometry(QWidget *editor, const QStyl
{
editor->setGeometry(option.rect);
}
+
+void AttendeeLineEditDelegate::leftPressed()
+{
+ emit closeEditor(static_cast<QWidget*>(QObject::sender()),QAbstractItemDelegate::EditPreviousItem);
+}
+
+void AttendeeLineEditDelegate::rightPressed()
+{
+ emit closeEditor(static_cast<QWidget*>(QObject::sender()),QAbstractItemDelegate::EditNextItem);
+}
diff --git a/incidenceeditor-ng/attendeecomboboxdelegate.h b/incidenceeditor-ng/attendeecomboboxdelegate.h
index 6d4b4a5..caedc50 100644
--- a/incidenceeditor-ng/attendeecomboboxdelegate.h
+++ b/incidenceeditor-ng/attendeecomboboxdelegate.h
@@ -33,7 +33,7 @@ namespace IncidenceEditorNG
/**
* class to show a Icon and Text for an Attendee
- * you have to set the Items via adItem to have a list to choose from.
+ * you have to set the Items via addItem to have a list to choose from.
* saves the option as int in the model
*/
class AttendeeComboBoxDelegate : public QStyledItemDelegate
@@ -48,21 +48,27 @@ public:
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
+ bool eventFilter ( QObject * editor, QEvent * event );
+
void addItem(const QIcon&, const QString&);
/** choose this index, if the item in the model is unknown
*/
void setStandardIndex(int);
+private slots:
+ void doCloseEditor(QWidget *editor);
+ void rightPressed();
+ void leftPressed();
+
private:
/** all entries to choose from */
QList<QPair<QIcon, QString> > entries;
/**fallback index */
int standardIndex;
-
};
-/** show a KPIM::AddressLineEdit as editor */
+/** show a AttendeeLineEdit as editor */
class AttendeeLineEditDelegate : public QStyledItemDelegate
{
Q_OBJECT
@@ -73,6 +79,10 @@ public:
void setEditorData(QWidget *editor, const QModelIndex &index) const;
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;
+
+private slots:
+ void rightPressed();
+ void leftPressed();
};
}
diff --git a/incidenceeditor-ng/attendeeline.cpp b/incidenceeditor-ng/attendeeline.cpp
index 8d624b5..6fe34dd 100644
--- a/incidenceeditor-ng/attendeeline.cpp
+++ b/incidenceeditor-ng/attendeeline.cpp
@@ -103,6 +103,10 @@ void AttendeeComboBox::keyPressEvent( QKeyEvent *ev )
emit leftPressed();
} else if ( ev->key() == Qt::Key_Right ) {
emit rightPressed();
+ } else if ( !mMenu->isVisible() && (
+ ev->key() == Qt::Key_Down ||
+ ev->key() == Qt::Key_Space ) ) {
+ showMenu();
} else {
QToolButton::keyPressEvent( ev );
}
diff --git a/incidenceeditor-ng/attendeetablemodel.cpp b/incidenceeditor-ng/attendeetablemodel.cpp
index b947aac..242976a 100644
--- a/incidenceeditor-ng/attendeetablemodel.cpp
+++ b/incidenceeditor-ng/attendeetablemodel.cpp
@@ -11,7 +11,7 @@ AttendeeTableModel::AttendeeTableModel(const KCalCore::Attendee::List &attendees
: QAbstractTableModel(parent)
, attendeeList(attendees)
{
-
+ insertRows(0,1);
}
int AttendeeTableModel::rowCount(const QModelIndex &/*parent*/) const
@@ -21,7 +21,7 @@ int AttendeeTableModel::rowCount(const QModelIndex &/*parent*/) const
int AttendeeTableModel::columnCount(const QModelIndex &/*parent*/) const
{
- return 5;
+ return 6;
}
Qt::ItemFlags AttendeeTableModel::flags(const QModelIndex &index) const
@@ -29,8 +29,11 @@ Qt::ItemFlags AttendeeTableModel::flags(const QModelIndex &index) const
if (!index.isValid()) {
return Qt::ItemIsEnabled;
}
-
- return QAbstractTableModel::flags(index) | Qt::ItemIsEditable;
+ if (index.column() == Available) { //Available is read only
+ return QAbstractTableModel::flags(index);
+ } else {
+ return QAbstractTableModel::flags(index) | Qt::ItemIsEditable;
+ }
}
QVariant AttendeeTableModel::data(const QModelIndex &index, int role) const
@@ -45,16 +48,18 @@ QVariant AttendeeTableModel::data(const QModelIndex &index, int role) const
if (role == Qt::DisplayRole || role == Qt::EditRole) {
switch (index.column()) {
- case 0:
+ case Role:
return attendeeList[index.row()]->role();
- case 1:
+ case Name:
return attendeeList[index.row()]->fullName();
- case 2:
+ case Available:
return 0;//attendeeList.at(index.row()).available;
- case 3:
+ case Status:
return attendeeList[index.row()]->status();
- case 4:
+ case CuType:
return attendeeList[index.row()]->cuType();
+ case Response:
+ return attendeeList[index.row()]->RSVP();
}
}
@@ -66,23 +71,26 @@ bool AttendeeTableModel::setData(const QModelIndex& index, const QVariant& value
QString email, name;
if (index.isValid() && role == Qt::EditRole) {
switch (index.column()) {
- case 0:
+ case Role:
attendeeList[index.row()]->setRole(static_cast<KCalCore::Attendee::Role>(value.toInt()));
break;
- case 1:
+ case Name:
KPIMUtils::extractEmailAddressAndName(value.toString(), email, name);
attendeeList[index.row()]->setName(name);
attendeeList[index.row()]->setEmail(email);
break;
- case 2:
+ case Available:
//attendeeList[index.row()].available = value.toBool();
break;
- case 3:
+ case Status:
attendeeList[index.row()]->setStatus(static_cast<KCalCore::Attendee::PartStat>(value.toInt()));
break;
- case 4:
+ case CuType:
attendeeList[index.row()]->setCuType(static_cast<KCalCore::Attendee::CuType>(value.toInt()));
break;
+ case Response:
+ attendeeList[index.row()]->setRSVP(value.toBool());
+ break;
default:
return false;
}
@@ -101,16 +109,18 @@ QVariant AttendeeTableModel::headerData(int section, Qt::Orientation orientation
if (orientation == Qt::Horizontal) {
switch (section) {
- case 0:
+ case Role:
return QString("role");
- case 1:
+ case Name:
return QString("name");
- case 2:
+ case Available:
return QString("available");
- case 3:
+ case Status:
return QString("status");
- case 4:
+ case CuType:
return QString("cuType");
+ case Response:
+ return QString("response");
}
}
@@ -175,7 +185,7 @@ ResourceFilterProxyModel::ResourceFilterProxyModel(QObject *parent)
bool ResourceFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{
- QModelIndex cuTypeIndex = sourceModel()->index(sourceRow, 4, sourceParent);
+ QModelIndex cuTypeIndex = sourceModel()->index(sourceRow, AttendeeTableModel::CuType, sourceParent);
KCalCore::Attendee::CuType cuType = static_cast<KCalCore::Attendee::CuType>(sourceModel()->data(cuTypeIndex).toUInt());
return (cuType == KCalCore::Attendee::Resource || cuType == KCalCore::Attendee::Room);
@@ -188,7 +198,7 @@ AttendeeFilterProxyModel::AttendeeFilterProxyModel(QObject *parent)
bool AttendeeFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{
- QModelIndex cuTypeIndex = sourceModel()->index(sourceRow, 4, sourceParent);
+ QModelIndex cuTypeIndex = sourceModel()->index(sourceRow, AttendeeTableModel::CuType, sourceParent);
KCalCore::Attendee::CuType cuType = static_cast<KCalCore::Attendee::CuType>(sourceModel()->data(cuTypeIndex).toUInt());
return !(cuType == KCalCore::Attendee::Resource || cuType == KCalCore::Attendee::Room);
diff --git a/incidenceeditor-ng/attendeetablemodel.h b/incidenceeditor-ng/attendeetablemodel.h
index d234b36..ea525e1 100644
--- a/incidenceeditor-ng/attendeetablemodel.h
+++ b/incidenceeditor-ng/attendeetablemodel.h
@@ -31,19 +31,21 @@
namespace IncidenceEditorNG
{
-/* TableView for the Resource Tab
- * 0 = role
- * 1 = name
- * 2 = available
- * 3 = status
- * 4 = cutype
- */
-
class AttendeeTableModel : public QAbstractTableModel
{
Q_OBJECT
public:
+
+ enum Columns {
+ CuType,
+ Role,
+ Name,
+ Available,
+ Status,
+ Response
+ };
+
AttendeeTableModel(const KCalCore::Attendee::List &resources, QObject *parent = 0);
int rowCount(const QModelIndex &parent = QModelIndex()) const;
diff --git a/incidenceeditor-ng/dialogdesktop.ui b/incidenceeditor-ng/dialogdesktop.ui
index f17885e..3f8f53b 100644
--- a/incidenceeditor-ng/dialogdesktop.ui
+++ b/incidenceeditor-ng/dialogdesktop.ui
@@ -13,7 +13,16 @@
<layout class="QVBoxLayout" name="mainVerticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout">
- <property name="margin">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
@@ -41,7 +50,16 @@
<item row="1" column="1">
<widget class="QWidget" name="mInvitationBar" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_10">
- <property name="margin">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
<number>0</number>
</property>
<item>
@@ -195,7 +213,16 @@
<item row="5" column="1">
<widget class="QWidget" name="mCompletionPriorityWidget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_8">
- <property name="margin">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
<number>0</number>
</property>
<item>
@@ -778,11 +805,20 @@
</sizepolicy>
</property>
<property name="currentIndex">
- <number>0</number>
+ <number>1</number>
</property>
<widget class="QWidget" name="page">
<layout class="QGridLayout" name="gridLayout_2">
- <property name="margin">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
@@ -805,7 +841,16 @@
</widget>
<widget class="QWidget" name="page_2">
<layout class="QGridLayout" name="gridLayout_3">
- <property name="margin">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
@@ -831,68 +876,80 @@
<attribute name="title">
<string>Resources</string>
</attribute>
- <widget class="QWidget" name="horizontalLayoutWidget">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>230</y>
- <width>641</width>
- <height>31</height>
- </rect>
- </property>
- <layout class="QHBoxLayout" name="horizontalLayout_11">
- <item>
- <widget class="KLineEdit" name="mNewResource"/>
- </item>
- <item>
- <widget class="QPushButton" name="mBookResourceButton">
- <property name="text">
- <string>Book resource</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer_14">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QPushButton" name="mFindResourcesButton">
- <property name="text">
- <string>Find Resources...</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QTableView" name="mResourcesTable">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>10</y>
- <width>631</width>
- <height>211</height>
- </rect>
- </property>
- </widget>
- <widget class="QTableView" name="mAttendeeTable">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>260</y>
- <width>631</width>
- <height>211</height>
- </rect>
- </property>
- </widget>
+ <layout class="QGridLayout" name="gridLayout_5">
+ <item row="0" column="0">
+ <widget class="QTableView" name="mResourcesTable">
+ <property name="editTriggers">
+ <set>QAbstractItemView::AllEditTriggers</set>
+ </property>
+ <property name="showGrid">
+ <bool>false</bool>
+ </property>
+ <property name="gridStyle">
+ <enum>Qt::SolidLine</enum>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ <attribute name="horizontalHeaderHighlightSections">
+ <bool>false</bool>
+ </attribute>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <layout class="QHBoxLayout" name="horizontalLayout_11">
+ <item>
+ <widget class="KLineEdit" name="mNewResource"/>
+ </item>
+ <item>
+ <widget class="QPushButton" name="mBookResourceButton">
+ <property name="text">
+ <string>Book resource</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_14">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="mFindResourcesButton">
+ <property name="text">
+ <string>Find Resources...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="2" column="0">
+ <widget class="QTableView" name="mAttendeeTable">
+ <property name="frameShadow">
+ <enum>QFrame::Plain</enum>
+ </property>
+ <property name="editTriggers">
+ <set>QAbstractItemView::AllEditTriggers</set>
+ </property>
+ <property name="showGrid">
+ <bool>false</bool>
+ </property>
+ <attribute name="horizontalHeaderVisible">
+ <bool>false</bool>
+ </attribute>
+ <attribute name="horizontalHeaderCascadingSectionResizes">
+ <bool>false</bool>
+ </attribute>
+ </widget>
+ </item>
+ </layout>
</widget>
<widget class="QWidget" name="mReminderTab">
<attribute name="title">
@@ -1137,14 +1194,32 @@
<widget class="QWidget" name="never_page"/>
<widget class="QWidget" name="daily_page">
<layout class="QGridLayout" name="gridLayout_11">
- <property name="margin">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
<number>0</number>
</property>
</layout>
</widget>
<widget class="QWidget" name="weekly_page">
<layout class="QGridLayout" name="gridLayout_4">
- <property name="margin">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
@@ -1164,7 +1239,16 @@
</widget>
<widget class="QWidget" name="Monthly">
<layout class="QGridLayout" name="gridLayout_6">
- <property name="margin">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
@@ -1197,7 +1281,16 @@
</widget>
<widget class="QWidget" name="yearly_page">
<layout class="QGridLayout" name="gridLayout_7">
- <property name="margin">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
@@ -1289,14 +1382,32 @@
</property>
<widget class="QWidget" name="no_end">
<layout class="QGridLayout" name="gridLayout_16">
- <property name="margin">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
<number>0</number>
</property>
</layout>
</widget>
<widget class="QWidget" name="end_on">
<layout class="QGridLayout" name="gridLayout_14">
- <property name="margin">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
@@ -1329,10 +1440,19 @@
</widget>
<widget class="QWidget" name="end_after">
<layout class="QGridLayout" name="gridLayout_10">
- <property name="horizontalSpacing">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
<number>0</number>
</property>
- <property name="margin">
+ <property name="horizontalSpacing">
<number>0</number>
</property>
<item row="0" column="0">
@@ -1558,21 +1678,6 @@
</widget>
<customwidgets>
<customwidget>
- <class>KRichTextEdit</class>
- <extends>KTextEdit</extends>
- <header>krichtextedit.h</header>
- </customwidget>
- <customwidget>
- <class>KTimeComboBox</class>
- <extends>KComboBox</extends>
- <header>ktimecombobox.h</header>
- </customwidget>
- <customwidget>
- <class>KDateComboBox</class>
- <extends>KComboBox</extends>
- <header>kdatecombobox.h</header>
- </customwidget>
- <customwidget>
<class>KComboBox</class>
<extends>QComboBox</extends>
<header>kcombobox.h</header>
@@ -1586,6 +1691,7 @@
<class>KSeparator</class>
<extends>QFrame</extends>
<header>kseparator.h</header>
+ <container>1</container>
</customwidget>
<customwidget>
<class>KTextEdit</class>
@@ -1593,11 +1699,6 @@
<header>ktextedit.h</header>
</customwidget>
<customwidget>
- <class>KRichTextWidget</class>
- <extends>KRichTextEdit</extends>
- <header>krichtextwidget.h</header>
- </customwidget>
- <customwidget>
<class>KTabWidget</class>
<extends>QTabWidget</extends>
<header>ktabwidget.h</header>
@@ -1629,6 +1730,26 @@
<header>libkdepim/widgets/tagwidgets.h</header>
<container>1</container>
</customwidget>
+ <customwidget>
+ <class>KRichTextEdit</class>
+ <extends>KTextEdit</extends>
+ <header>krichtextedit.h</header>
+ </customwidget>
+ <customwidget>
+ <class>KTimeComboBox</class>
+ <extends>KComboBox</extends>
+ <header>ktimecombobox.h</header>
+ </customwidget>
+ <customwidget>
+ <class>KDateComboBox</class>
+ <extends>KComboBox</extends>
+ <header>kdatecombobox.h</header>
+ </customwidget>
+ <customwidget>
+ <class>KRichTextWidget</class>
+ <extends>KRichTextEdit</extends>
+ <header>krichtextwidget.h</header>
+ </customwidget>
</customwidgets>
<resources/>
<connections>
diff --git a/incidenceeditor-ng/incidenceresource.cpp b/incidenceeditor-ng/incidenceresource.cpp
index 5969c86..f718e6b 100644
--- a/incidenceeditor-ng/incidenceresource.cpp
+++ b/incidenceeditor-ng/incidenceresource.cpp
@@ -50,6 +50,7 @@ IncidenceResource::IncidenceResource(Ui::EventOrTodoDesktop *ui)
setObjectName("IncidenceResource");
AttendeeComboBoxDelegate* roleDelegate(new AttendeeComboBoxDelegate(this));
+ AttendeeComboBoxDelegate* responseDelegate(new AttendeeComboBoxDelegate(this));
#ifdef KDEPIM_MOBILE_UI
roleDelegate->addItem(DesktopIcon("meeting-participant", 48),
KCalUtils::Stringify::attendeeRole(KCalCore::Attendee::ReqParticipant));
@@ -60,6 +61,11 @@ IncidenceResource::IncidenceResource(Ui::EventOrTodoDesktop *ui)
roleDelegate->addItem(DesktopIcon("meeting-chair", 48),
KCalUtils::Stringify::attendeeRole(KCalCore::Attendee::Chair));
+ responseDelegate->addItem( DesktopIcon( "meeting-participant-request-response", 48 ),
+ i18nc( "@item:inlistbox", "Request Response" ) );
+ responseDelegate->addItem( DesktopIcon( "meeting-participant-no-response", 48 ),
+ i18nc( "@item:inlistbox", "Request No Response" ) );
+
#else
roleDelegate->addItem(SmallIcon("meeting-participant"),
KCalUtils::Stringify::attendeeRole(KCalCore::Attendee::ReqParticipant));
@@ -69,6 +75,12 @@ IncidenceResource::IncidenceResource(Ui::EventOrTodoDesktop *ui)
KCalUtils::Stringify::attendeeRole(KCalCore::Attendee::NonParticipant));
roleDelegate->addItem(SmallIcon("meeting-chair"),
KCalUtils::Stringify::attendeeRole(KCalCore::Attendee::Chair));
+
+ responseDelegate->addItem( SmallIcon( "meeting-participant-request-response" ),
+ i18nc( "@item:inlistbox", "Request Response" ) );
+ responseDelegate->addItem( SmallIcon( "meeting-participant-no-response" ),
+ i18nc( "@item:inlistbox", "Request No Response" ) );
+
#endif
AttendeeComboBoxDelegate *stateDelegate(new AttendeeComboBoxDelegate(this));
@@ -119,20 +131,25 @@ IncidenceResource::IncidenceResource(Ui::EventOrTodoDesktop *ui)
filterProxyModel->setDynamicSortFilter(true);
filterProxyModel->setSourceModel(dataModel);
+ QHeaderView* headerView = mUi->mResourcesTable->horizontalHeader();
+ headerView->setResizeMode(QHeaderView::ResizeToContents);
+
mUi->mResourcesTable->setModel(filterProxyModel);
- mUi->mResourcesTable->setColumnHidden(4, true);
- mUi->mResourcesTable->setItemDelegateForColumn(0, roleDelegate);
- mUi->mResourcesTable->setItemDelegateForColumn(1, attendeeDelegate);
- mUi->mResourcesTable->setItemDelegateForColumn(3, stateDelegate);
+ mUi->mResourcesTable->setColumnHidden(AttendeeTableModel::CuType, true);
+ mUi->mResourcesTable->setItemDelegateForColumn(AttendeeTableModel::Role, roleDelegate);
+ mUi->mResourcesTable->setItemDelegateForColumn(AttendeeTableModel::Name, attendeeDelegate);
+ mUi->mResourcesTable->setItemDelegateForColumn(AttendeeTableModel::Status, stateDelegate);
+ mUi->mResourcesTable->setItemDelegateForColumn(AttendeeTableModel::Response, responseDelegate);
AttendeeFilterProxyModel *attendeeProxyModel = new AttendeeFilterProxyModel(this);
attendeeProxyModel->setDynamicSortFilter(true);
attendeeProxyModel->setSourceModel(dataModel);
mUi->mAttendeeTable->setModel(attendeeProxyModel);
- mUi->mAttendeeTable->setItemDelegateForColumn(0, roleDelegate);
- mUi->mAttendeeTable->setItemDelegateForColumn(1, attendeeDelegate);
- mUi->mAttendeeTable->setItemDelegateForColumn(3, stateDelegate);
+ mUi->mAttendeeTable->setItemDelegateForColumn(AttendeeTableModel::Role, roleDelegate);
+ mUi->mAttendeeTable->setItemDelegateForColumn(AttendeeTableModel::Name, attendeeDelegate);
+ mUi->mAttendeeTable->setItemDelegateForColumn(AttendeeTableModel::Status, stateDelegate);
+ mUi->mAttendeeTable->setItemDelegateForColumn(AttendeeTableModel::Response, responseDelegate);
connect(mUi->mFindResourcesButton, SIGNAL(clicked()), SLOT(findResources()));
connect(mUi->mBookResourceButton, SIGNAL(clicked()), SLOT(bookResource()));
commit 3db976be01f161ecc45e666baa2897e1d8c01191
Author: Sandro Knauà <knauss at kolabsys.com>
Date: Tue Jun 3 17:34:50 2014 +0200
adding TODO: for showing ifb
diff --git a/incidenceeditor-ng/resourcemanagement.cpp b/incidenceeditor-ng/resourcemanagement.cpp
index 48a55d7..8b884ed 100644
--- a/incidenceeditor-ng/resourcemanagement.cpp
+++ b/incidenceeditor-ng/resourcemanagement.cpp
@@ -82,6 +82,19 @@ void ResourceManagement::showDetails(const KLDAP::LdapObject &obj)
}
ui->formDetails->addRow(key, new QLabel(list.join("\n")));
}
+
+ /*
+ * TODO: Has to be needed and tested : )
+ KUrl httpUrl;
+ httpUrl.setUser( userName );
+ httpUrl.setPassword( password );
+ httpUrl.setHost( host );
+ httpUrl.setProtocol( QLatin1String( "https" ) );
+ httpUrl.setPath( QLatin1String( "/freebusy/" ) + user + QLatin1String( ".ifb" ) );
+
+ KIO::Job *job = KIO::get( url, KIO::NoReload, KIO::HideProgressInfo );
+ */
+
}
#include "resourcemanagement.moc"
commit 9922c32a2b4d82c1772bda881947f58a04a89dcd
Author: Sandro Knauà <mail at sandroknauss.de>
Date: Mon Apr 21 00:17:01 2014 +0200
Added resourcemanagement files and tab in EventEditor
The ResourceManager can now ask a LDAP Server for collection and
resources that match a queryString.
* show details on a single resource
* show the resources in a treeview
* a resourcemodel and a resourceitem to use it in a model/view env.
* ResourceTab in EventEditor
diff --git a/incidenceeditor-ng/CMakeLists.txt b/incidenceeditor-ng/CMakeLists.txt
index 219b242..b184732 100644
--- a/incidenceeditor-ng/CMakeLists.txt
+++ b/incidenceeditor-ng/CMakeLists.txt
@@ -43,6 +43,7 @@ set(incidenceeditors_ng_shared_LIB_SRCS
incidencewhatwhere.cpp
incidencedatetime.cpp
incidencerecurrence.cpp
+ incidenceresource.cpp
incidencesecrecy.cpp
freebusyitem.cpp
@@ -66,6 +67,11 @@ set(incidenceeditors_ng_shared_LIB_SRCS
individualmailcomponentfactory.cpp
individualmaildialog.cpp
opencomposerjob.cpp
+ resourcemanagement.cpp
+ resourceitem.cpp
+ resourcemodel.cpp
+ attendeetablemodel.cpp
+ attendeecomboboxdelegate.cpp
)
kde4_add_kcfg_files(incidenceeditors_ng_shared_LIB_SRCS globalsettings_base.kcfgc)
@@ -89,6 +95,7 @@ kde4_add_ui_files(incidenceeditors_ng_desktop_LIB_SRCS
alarmdialog.ui
attachmenteditdialog.ui
schedulingdialog.ui
+ resourcemanagement.ui
)
kde4_add_library(incidenceeditorsng ${LIBRARY_TYPE} ${incidenceeditors_ng_desktop_LIB_SRCS})
diff --git a/incidenceeditor-ng/attendeecomboboxdelegate.cpp b/incidenceeditor-ng/attendeecomboboxdelegate.cpp
new file mode 100644
index 0000000..21ec3f8
--- /dev/null
+++ b/incidenceeditor-ng/attendeecomboboxdelegate.cpp
@@ -0,0 +1,105 @@
+#include "attendeecomboboxdelegate.h"
+
+#include "attendeeline.h"
+
+#include <QApplication>
+
+using namespace IncidenceEditorNG;
+
+AttendeeComboBoxDelegate::AttendeeComboBoxDelegate(QObject *parent)
+ : QStyledItemDelegate(parent)
+ , standardIndex(0)
+{
+
+}
+
+void AttendeeComboBoxDelegate::addItem(const QIcon &icon, const QString &text)
+{
+ QPair<QIcon, QString> pair;
+ pair.first = icon;
+ pair.second = text;
+ entries << pair;
+}
+
+void AttendeeComboBoxDelegate::setStandardIndex(int index)
+{
+ standardIndex = index;
+}
+
+
+QWidget *AttendeeComboBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &/* option */, const QModelIndex &/* index */) const
+{
+ AttendeeComboBox* editor = new AttendeeComboBox(parent);
+ QPair<QIcon, QString> pair;
+
+ foreach(pair, entries) {
+ editor->addItem(pair.first, pair.second);
+ }
+
+ return editor;
+}
+
+void AttendeeComboBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
+{
+ AttendeeComboBox *comboBox = static_cast<AttendeeComboBox*>(editor);
+ int value = index.model()->data(index, Qt::EditRole).toUInt();
+ if (value >= entries.count()) {
+ value = standardIndex;
+ }
+ comboBox->setCurrentIndex(value);
+}
+
+void AttendeeComboBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
+{
+ AttendeeComboBox *comboBox = static_cast<AttendeeComboBox*>(editor);
+ model->setData(index, comboBox->currentIndex(), Qt::EditRole);
+}
+
+void AttendeeComboBoxDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
+{
+ editor->setGeometry(option.rect);
+}
+
+void AttendeeComboBoxDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+ QStyleOptionButton pushButton;
+ int value = index.model()->data(index).toUInt();
+ pushButton.rect = option.rect;
+ pushButton.features |= QStyleOptionButton::HasMenu;
+ if (value >= entries.count()) {
+ value = standardIndex;
+ }
+ pushButton.icon = entries[value].first;
+
+ QApplication::style()->drawControl(QStyle::CE_PushButton, &pushButton, painter);
+}
+
+AttendeeLineEditDelegate::AttendeeLineEditDelegate(QObject* parent)
+ : QStyledItemDelegate(parent)
+{
+
+}
+
+
+QWidget *AttendeeLineEditDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &/* option */, const QModelIndex &/* index */) const
+{
+ KPIM::AddresseeLineEdit* editor = new KPIM::AddresseeLineEdit(parent);
+ return editor;
+}
+
+void AttendeeLineEditDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
+{
+ KPIM::AddresseeLineEdit *lineedit = static_cast<KPIM::AddresseeLineEdit*>(editor);
+ lineedit->setText(index.model()->data(index, Qt::EditRole).toString());
+}
+
+void AttendeeLineEditDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
+{
+ KPIM::AddresseeLineEdit *lineedit = static_cast<KPIM::AddresseeLineEdit*>(editor);
+ model->setData(index, lineedit->text(), Qt::EditRole);
+}
+
+void AttendeeLineEditDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
+{
+ editor->setGeometry(option.rect);
+}
diff --git a/incidenceeditor-ng/attendeecomboboxdelegate.h b/incidenceeditor-ng/attendeecomboboxdelegate.h
new file mode 100644
index 0000000..6d4b4a5
--- /dev/null
+++ b/incidenceeditor-ng/attendeecomboboxdelegate.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2014 Sandro Knauà <knauss at kolabsys.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef INCIDENCEEDITOR_ATTENDEECOMBOBOXDELEGATE_H
+#define INCIDENCEEDITOR_ATTENDEECOMBOBOXDELEGATE_H
+
+#include <QStyledItemDelegate>
+#include <QModelIndex>
+#include <QIcon>
+#include <QString>
+
+
+namespace IncidenceEditorNG
+{
+
+ /**
+ * class to show a Icon and Text for an Attendee
+ * you have to set the Items via adItem to have a list to choose from.
+ * saves the option as int in the model
+ */
+class AttendeeComboBoxDelegate : public QStyledItemDelegate
+{
+ Q_OBJECT
+public:
+ AttendeeComboBoxDelegate(QObject *parent = 0);
+
+ QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
+ void setEditorData(QWidget *editor, const QModelIndex &index) const;
+ void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
+ void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;
+ void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
+
+ void addItem(const QIcon&, const QString&);
+
+ /** choose this index, if the item in the model is unknown
+ */
+ void setStandardIndex(int);
+
+private:
+ /** all entries to choose from */
+ QList<QPair<QIcon, QString> > entries;
+ /**fallback index */
+ int standardIndex;
+
+};
+
+/** show a KPIM::AddressLineEdit as editor */
+class AttendeeLineEditDelegate : public QStyledItemDelegate
+{
+ Q_OBJECT
+public:
+ AttendeeLineEditDelegate(QObject *parent = 0);
+
+ QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
+ void setEditorData(QWidget *editor, const QModelIndex &index) const;
+ void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
+ void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;
+};
+
+}
+
+#endif
\ No newline at end of file
diff --git a/incidenceeditor-ng/attendeetablemodel.cpp b/incidenceeditor-ng/attendeetablemodel.cpp
new file mode 100644
index 0000000..b947aac
--- /dev/null
+++ b/incidenceeditor-ng/attendeetablemodel.cpp
@@ -0,0 +1,195 @@
+#include "attendeetablemodel.h"
+
+#include <KCalCore/Attendee>
+#include <KPIMUtils/Email>
+
+#include <KDebug>
+
+using namespace IncidenceEditorNG;
+
+AttendeeTableModel::AttendeeTableModel(const KCalCore::Attendee::List &attendees, QObject *parent)
+ : QAbstractTableModel(parent)
+ , attendeeList(attendees)
+{
+
+}
+
+int AttendeeTableModel::rowCount(const QModelIndex &/*parent*/) const
+{
+ return attendeeList.count();
+}
+
+int AttendeeTableModel::columnCount(const QModelIndex &/*parent*/) const
+{
+ return 5;
+}
+
+Qt::ItemFlags AttendeeTableModel::flags(const QModelIndex &index) const
+{
+ if (!index.isValid()) {
+ return Qt::ItemIsEnabled;
+ }
+
+ return QAbstractTableModel::flags(index) | Qt::ItemIsEditable;
+}
+
+QVariant AttendeeTableModel::data(const QModelIndex &index, int role) const
+{
+ if (!index.isValid()) {
+ return QVariant();
+ }
+
+ if (index.row() >= attendeeList.size()) {
+ return QVariant();
+ }
+
+ if (role == Qt::DisplayRole || role == Qt::EditRole) {
+ switch (index.column()) {
+ case 0:
+ return attendeeList[index.row()]->role();
+ case 1:
+ return attendeeList[index.row()]->fullName();
+ case 2:
+ return 0;//attendeeList.at(index.row()).available;
+ case 3:
+ return attendeeList[index.row()]->status();
+ case 4:
+ return attendeeList[index.row()]->cuType();
+ }
+
+ }
+ return QVariant();
+}
+
+bool AttendeeTableModel::setData(const QModelIndex& index, const QVariant& value, int role)
+{
+ QString email, name;
+ if (index.isValid() && role == Qt::EditRole) {
+ switch (index.column()) {
+ case 0:
+ attendeeList[index.row()]->setRole(static_cast<KCalCore::Attendee::Role>(value.toInt()));
+ break;
+ case 1:
+ KPIMUtils::extractEmailAddressAndName(value.toString(), email, name);
+ attendeeList[index.row()]->setName(name);
+ attendeeList[index.row()]->setEmail(email);
+ break;
+ case 2:
+ //attendeeList[index.row()].available = value.toBool();
+ break;
+ case 3:
+ attendeeList[index.row()]->setStatus(static_cast<KCalCore::Attendee::PartStat>(value.toInt()));
+ break;
+ case 4:
+ attendeeList[index.row()]->setCuType(static_cast<KCalCore::Attendee::CuType>(value.toInt()));
+ break;
+ default:
+ return false;
+ }
+ emit dataChanged(index, index);
+ return true;
+ }
+ return false;
+}
+
+QVariant AttendeeTableModel::headerData(int section, Qt::Orientation orientation,
+ int role) const
+{
+ if (role != Qt::DisplayRole) {
+ return QVariant();
+ }
+
+ if (orientation == Qt::Horizontal) {
+ switch (section) {
+ case 0:
+ return QString("role");
+ case 1:
+ return QString("name");
+ case 2:
+ return QString("available");
+ case 3:
+ return QString("status");
+ case 4:
+ return QString("cuType");
+ }
+ }
+
+ return QVariant();
+}
+
+bool AttendeeTableModel::insertRows(int position, int rows, const QModelIndex &parent)
+{
+ beginInsertRows(QModelIndex(), position, position + rows);
+
+ for (int row = 0; row < rows; ++row) {
+ KCalCore::Attendee::Ptr attendee(new KCalCore::Attendee("", ""));
+ attendeeList.insert(position, attendee);
+ }
+
+ endInsertRows();
+ return true;
+}
+
+bool AttendeeTableModel::removeRows(int position, int rows, const QModelIndex &parent)
+{
+ beginRemoveRows(QModelIndex(), position, position + rows);
+
+ for (int row = 0; row < rows; ++row) {
+ attendeeList.remove(position);
+ }
+
+ endRemoveRows();
+ return true;
+}
+
+bool AttendeeTableModel::insertAttendee(int position, const KCalCore::Attendee::Ptr& attendee)
+{
+ beginInsertRows(QModelIndex(), position, position);
+
+ attendeeList.insert(position, attendee);
+
+ endInsertRows();
+
+ return true;
+}
+
+void AttendeeTableModel::setAttendees(const KCalCore::Attendee::List attendees)
+{
+ emit layoutAboutToBeChanged();
+
+ attendeeList = attendees;
+
+ emit layoutChanged();
+}
+
+
+KCalCore::Attendee::List AttendeeTableModel::attendees() const
+{
+ return attendeeList;
+}
+
+ResourceFilterProxyModel::ResourceFilterProxyModel(QObject *parent)
+ : QSortFilterProxyModel(parent)
+{
+}
+
+bool ResourceFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
+{
+ QModelIndex cuTypeIndex = sourceModel()->index(sourceRow, 4, sourceParent);
+ KCalCore::Attendee::CuType cuType = static_cast<KCalCore::Attendee::CuType>(sourceModel()->data(cuTypeIndex).toUInt());
+
+ return (cuType == KCalCore::Attendee::Resource || cuType == KCalCore::Attendee::Room);
+}
+
+AttendeeFilterProxyModel::AttendeeFilterProxyModel(QObject *parent)
+ : QSortFilterProxyModel(parent)
+{
+}
+
+bool AttendeeFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
+{
+ QModelIndex cuTypeIndex = sourceModel()->index(sourceRow, 4, sourceParent);
+ KCalCore::Attendee::CuType cuType = static_cast<KCalCore::Attendee::CuType>(sourceModel()->data(cuTypeIndex).toUInt());
+
+ return !(cuType == KCalCore::Attendee::Resource || cuType == KCalCore::Attendee::Room);
+}
diff --git a/incidenceeditor-ng/attendeetablemodel.h b/incidenceeditor-ng/attendeetablemodel.h
new file mode 100644
index 0000000..d234b36
--- /dev/null
+++ b/incidenceeditor-ng/attendeetablemodel.h
@@ -0,0 +1,92 @@
+
+/*
+ Copyright (C) 2014 Sandro Knauà <knauss at kolabsys.com>
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ This library is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+*/
+
+#ifndef INCIDENCEEDITOR_INCIDENCERESOURCETABLEMODEL_H
+#define INCIDENCEEDITOR_INCIDENCERESOURCETABLEMODEL_H
+
+#include <KCalCore/Attendee>
+
+#include <QAbstractTableModel>
+#include <QSortFilterProxyModel>
+#include <QModelIndex>
+#include <QVector>
+
+namespace IncidenceEditorNG
+{
+
+/* TableView for the Resource Tab
+ * 0 = role
+ * 1 = name
+ * 2 = available
+ * 3 = status
+ * 4 = cutype
+ */
+
+class AttendeeTableModel : public QAbstractTableModel
+{
+ Q_OBJECT
+
+public:
+ AttendeeTableModel(const KCalCore::Attendee::List &resources, QObject *parent = 0);
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ int columnCount(const QModelIndex &parent = QModelIndex()) const;
+ QVariant data(const QModelIndex &index, int role) const;
+ QVariant headerData(int section, Qt::Orientation orientation,
+ int role = Qt::DisplayRole) const;
+
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+ bool setData(const QModelIndex &index, const QVariant &value,
+ int role = Qt::EditRole);
+
+ bool insertRows(int position, int rows, const QModelIndex &index = QModelIndex());
+ bool removeRows(int position, int rows, const QModelIndex &index = QModelIndex());
+
+ bool insertAttendee(int position, const KCalCore::Attendee::Ptr &attendee);
+
+ void setAttendees(const KCalCore::Attendee::List resources);
+ KCalCore::Attendee::List attendees() const;
+
+private:
+ KCalCore::Attendee::List attendeeList;
+};
+
+class ResourceFilterProxyModel : public QSortFilterProxyModel
+{
+ Q_OBJECT
+public:
+ ResourceFilterProxyModel(QObject *parent = 0);
+ bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
+};
+
+class AttendeeFilterProxyModel : public QSortFilterProxyModel
+{
+ Q_OBJECT
+public:
+ AttendeeFilterProxyModel(QObject *parent = 0);
+ bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
+};
+
+
+}
+
+#endif
+
+
diff --git a/incidenceeditor-ng/dialogdesktop.ui b/incidenceeditor-ng/dialogdesktop.ui
index 45ebb20..f17885e 100644
--- a/incidenceeditor-ng/dialogdesktop.ui
+++ b/incidenceeditor-ng/dialogdesktop.ui
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>661</width>
- <height>551</height>
+ <width>909</width>
+ <height>833</height>
</rect>
</property>
<layout class="QVBoxLayout" name="mainVerticalLayout">
@@ -578,7 +578,7 @@
<item row="12" column="0" colspan="2">
<widget class="KTabWidget" name="mTabWidget">
<property name="currentIndex">
- <number>0</number>
+ <number>2</number>
</property>
<widget class="QWidget" name="mGeneralTab">
<attribute name="title">
@@ -827,6 +827,73 @@
</item>
</layout>
</widget>
+ <widget class="QWidget" name="mResourceTab">
+ <attribute name="title">
+ <string>Resources</string>
+ </attribute>
+ <widget class="QWidget" name="horizontalLayoutWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>230</y>
+ <width>641</width>
+ <height>31</height>
+ </rect>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout_11">
+ <item>
+ <widget class="KLineEdit" name="mNewResource"/>
+ </item>
+ <item>
+ <widget class="QPushButton" name="mBookResourceButton">
+ <property name="text">
+ <string>Book resource</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_14">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="mFindResourcesButton">
+ <property name="text">
+ <string>Find Resources...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QTableView" name="mResourcesTable">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>10</y>
+ <width>631</width>
+ <height>211</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QTableView" name="mAttendeeTable">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>260</y>
+ <width>631</width>
+ <height>211</height>
+ </rect>
+ </property>
+ </widget>
+ </widget>
<widget class="QWidget" name="mReminderTab">
<attribute name="title">
<string comment="@title:tab Tab to configure reminders for events or to-do">Reminder</string>
@@ -1491,11 +1558,6 @@
</widget>
<customwidgets>
<customwidget>
- <class>KPIM::KCheckComboBox</class>
- <extends>KComboBox</extends>
- <header>libkdepim/widgets/kcheckcombobox.h</header>
- </customwidget>
- <customwidget>
<class>KRichTextEdit</class>
<extends>KTextEdit</extends>
<header>krichtextedit.h</header>
@@ -1542,6 +1604,11 @@
<container>1</container>
</customwidget>
<customwidget>
+ <class>KPIM::KCheckComboBox</class>
+ <extends>KComboBox</extends>
+ <header>libkdepim/widgets/kcheckcombobox.h</header>
+ </customwidget>
+ <customwidget>
<class>KPIM::KWeekdayCheckCombo</class>
<extends>KPIM::KCheckComboBox</extends>
<header>libkdepim/widgets/kweekdaycheckcombo.h</header>
diff --git a/incidenceeditor-ng/incidenceattendee.cpp b/incidenceeditor-ng/incidenceattendee.cpp
index fa1811f..32d7f04 100644
--- a/incidenceeditor-ng/incidenceattendee.cpp
+++ b/incidenceeditor-ng/incidenceattendee.cpp
@@ -185,7 +185,9 @@ void IncidenceAttendee::load( const KCalCore::Incidence::Ptr &incidence )
const KCalCore::Attendee::List attendees = incidence->attendees();
foreach ( const KCalCore::Attendee::Ptr &a, attendees ) {
- mAttendeeEditor->addAttendee( a );
+ if (!(a->cuType() == KCalCore::Attendee::Resource || a->cuType() == KCalCore::Attendee::Room)) {
+ mAttendeeEditor->addAttendee( a );
+ }
}
mWasDirty = false;
@@ -193,7 +195,7 @@ void IncidenceAttendee::load( const KCalCore::Incidence::Ptr &incidence )
void IncidenceAttendee::save( const KCalCore::Incidence::Ptr &incidence )
{
- incidence->clearAttendees();
+ /*incidence->clearAttendees();
AttendeeData::List attendees = mAttendeeEditor->attendees();
foreach ( AttendeeData::Ptr attendee, attendees ) {
@@ -219,7 +221,7 @@ void IncidenceAttendee::save( const KCalCore::Incidence::Ptr &incidence )
// Must not have an organizer for items without attendees
if ( !incidence->attendeeCount() ) {
return;
- }
+ }*/
if ( mUi->mOrganizerStack->currentIndex() == 0 ) {
incidence->setOrganizer( mUi->mOrganizerCombo->currentText() );
@@ -247,13 +249,16 @@ bool IncidenceAttendee::isDirty() const
// The lists sizes *must* be the same. When the organizer is attending the
// event as well, he should be in the attendees list as well.
- if ( originalList.size() != newList.size() ) {
+ /*if ( originalList.size() != newList.size() ) {
return true;
- }
+ }*/
// Okay, again not the most efficient algorithm, but I'm assuming that in the
// bulk of the use cases, the number of attendees is not much higher than 10 or so.
foreach ( const KCalCore::Attendee::Ptr &attendee, originalList ) {
+ if (attendee->cuType() == KCalCore::Attendee::Resource || attendee->cuType() == KCalCore::Attendee::Room) {
+ continue;
+ }
bool found = false;
for ( int i = 0; i < newList.size(); ++i ) {
if ( compareAttendees( newList.at( i )->attendee(), attendee) ) {
@@ -265,6 +270,7 @@ bool IncidenceAttendee::isDirty() const
if ( !found ) {
// One of the attendees in the original list was not found in the new list.
+ kDebug() << "One of the attendees in the original list was not found in the new list";
return true;
}
}
@@ -605,6 +611,7 @@ void IncidenceAttendee::printDebugInfo() const
<< attendee->RSVP()
<< attendee->role()
<< attendee->uid()
+ << attendee->cuType()
<< attendee->delegate()
<< attendee->delegator()
<< "; we have:";
@@ -616,6 +623,7 @@ void IncidenceAttendee::printDebugInfo() const
<< attendee->RSVP()
<< attendee->role()
<< attendee->uid()
+ << attendee->cuType()
<< attendee->delegate()
<< attendee->delegator();
}
diff --git a/incidenceeditor-ng/incidencedialog.cpp b/incidenceeditor-ng/incidencedialog.cpp
index dad6e77..9b96a3c 100644
--- a/incidenceeditor-ng/incidencedialog.cpp
+++ b/incidenceeditor-ng/incidencedialog.cpp
@@ -30,6 +30,7 @@
#include "incidencedatetime.h"
#include "incidencedescription.h"
#include "incidencerecurrence.h"
+#include "incidenceresource.h"
#include "incidencesecrecy.h"
#include "incidencewhatwhere.h"
#include "templatemanagementdialog.h"
@@ -59,6 +60,7 @@ namespace IncidenceEditorNG {
enum Tabs {
GeneralTab = 0,
AttendeesTab,
+ ResourcesTab,
AlarmsTab,
RecurrenceTab,
AttachmentsTab
@@ -79,6 +81,7 @@ class IncidenceDialogPrivate : public ItemEditorUi
IncidenceDateTime *mIeDateTime;
IncidenceAttendee *mIeAttendee;
IncidenceRecurrence *mIeRecurrence;
+ IncidenceResource *mIeResource;
bool mInitiallyDirty;
Akonadi::Item mItem;
QString typeToString( const int type ) const;
@@ -96,6 +99,7 @@ class IncidenceDialogPrivate : public ItemEditorUi
void storeTemplatesInConfig( const QStringList &newTemplates );
void updateAttachmentCount( int newCount );
void updateAttendeeCount( int newCount );
+ void updateResourceCount( int newCount );
void updateButtonStatus( bool isDirty );
void showMessage( const QString &text, KMessageWidget::MessageType type );
@@ -162,6 +166,9 @@ IncidenceDialogPrivate::IncidenceDialogPrivate( Akonadi::IncidenceChanger *chang
mIeRecurrence = new IncidenceRecurrence( mIeDateTime, mUi );
mEditor->combine( mIeRecurrence );
+ mIeResource = new IncidenceResource( mUi );
+ mEditor->combine( mIeResource );
+
IncidenceSecrecy *ieSecrecy = new IncidenceSecrecy( mUi );
mEditor->combine( ieSecrecy );
@@ -187,6 +194,8 @@ IncidenceDialogPrivate::IncidenceDialogPrivate( Akonadi::IncidenceChanger *chang
SLOT(updateAttachmentCount(int)) );
q->connect( mIeAttendee, SIGNAL(attendeeCountChanged(int)),
SLOT(updateAttendeeCount(int)) );
+ q->connect( mIeResource, SIGNAL(resourceCountChanged(int)),
+ SLOT(updateResourceCount(int)) );
}
IncidenceDialogPrivate::~IncidenceDialogPrivate()
@@ -415,6 +424,21 @@ void IncidenceDialogPrivate::updateAttendeeCount( int newCount )
}
}
+void IncidenceDialogPrivate::updateResourceCount( int newCount )
+{
+ if ( newCount > 0 ) {
+ mUi->mTabWidget->setTabText(
+ ResourcesTab,
+ i18nc( "@title:tab Tab to modify attendees of an event or todo",
+ "&Resources (%1)", newCount ) );
+ } else {
+ mUi->mTabWidget->setTabText(
+ ResourcesTab,
+ i18nc( "@title:tab Tab to modify attendees of an event or todo",
+ "&Resources" ) );
+ }
+}
+
void IncidenceDialogPrivate::updateButtonStatus( bool isDirty )
{
Q_Q( IncidenceDialog );
@@ -518,6 +542,7 @@ void IncidenceDialogPrivate::load( const Akonadi::Item &item )
mUi->mTabWidget->removeTab( RecurrenceTab );
mUi->mTabWidget->removeTab( AlarmsTab );
mUi->mTabWidget->removeTab( AttendeesTab );
+ mUi->mTabWidget->removeTab( ResourcesTab );
}
mEditor->load( CalendarSupport::incidence( item ) );
@@ -559,6 +584,7 @@ void IncidenceDialogPrivate::load( const Akonadi::Item &item )
// Initialize tab's titles
updateAttachmentCount( incidence->attachments().size() );
+ updateResourceCount( mIeResource->resourcesCount() );
handleRecurrenceChange( mIeRecurrence->currentRecurrenceType() );
handleAlarmCountChange( incidence->alarms().count() );
diff --git a/incidenceeditor-ng/incidencedialog.h b/incidenceeditor-ng/incidencedialog.h
index 7d7c36c..4d22699 100644
--- a/incidenceeditor-ng/incidencedialog.h
+++ b/incidenceeditor-ng/incidencedialog.h
@@ -108,6 +108,7 @@ class INCIDENCEEDITORS_NG_EXPORT IncidenceDialog : public KDialog
Q_PRIVATE_SLOT( d_ptr, void storeTemplatesInConfig(QStringList) )
Q_PRIVATE_SLOT( d_ptr, void updateAttachmentCount(int) )
Q_PRIVATE_SLOT( d_ptr, void updateAttendeeCount(int) )
+ Q_PRIVATE_SLOT( d_ptr, void updateResourceCount(int) )
Q_PRIVATE_SLOT( d_ptr, void updateButtonStatus(bool) )
Q_PRIVATE_SLOT( d_ptr, void showMessage(QString,KMessageWidget::MessageType) )
};
diff --git a/incidenceeditor-ng/incidenceresource.cpp b/incidenceeditor-ng/incidenceresource.cpp
new file mode 100644
index 0000000..5969c86
--- /dev/null
+++ b/incidenceeditor-ng/incidenceresource.cpp
@@ -0,0 +1,245 @@
+/*
+ Copyright (C) 2014 Sandro Knauà <knauss at kolabsys.com>
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ This library is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+*/
+
+#include "incidenceresource.h"
+#include "resourcemanagement.h"
+#include "resourcemodel.h"
+#include "attendeecomboboxdelegate.h"
+
+#ifdef KDEPIM_MOBILE_UI
+#include "ui_dialogmoremobile.h"
+#else
+#include "ui_dialogdesktop.h"
+#endif
+
+#include <KDebug>
+#include <KDescendantsProxyModel>
+#include <KMessageBox>
+
+#include <KCalUtils/Stringify>
+#include <KPIMUtils/Email>
+
+
+#include <QCompleter>
+using namespace IncidenceEditorNG;
+
+#ifdef KDEPIM_MOBILE_UI
+IncidenceResource::IncidenceResource(Ui::EventOrTodoMore *ui)
+#else
+IncidenceResource::IncidenceResource(Ui::EventOrTodoDesktop *ui)
+#endif
+ : IncidenceEditor(0)
+ , mUi(ui)
+{
+ setObjectName("IncidenceResource");
+
+ AttendeeComboBoxDelegate* roleDelegate(new AttendeeComboBoxDelegate(this));
+#ifdef KDEPIM_MOBILE_UI
+ roleDelegate->addItem(DesktopIcon("meeting-participant", 48),
+ KCalUtils::Stringify::attendeeRole(KCalCore::Attendee::ReqParticipant));
+ roleDelegate->addItem(DesktopIcon("meeting-participant-optional", 48),
+ KCalUtils::Stringify::attendeeRole(KCalCore::Attendee::OptParticipant));
+ roleDelegate->addItem(DesktopIcon("meeting-observer", 48),
+ KCalUtils::Stringify::attendeeRole(KCalCore::Attendee::NonParticipant));
+ roleDelegate->addItem(DesktopIcon("meeting-chair", 48),
+ KCalUtils::Stringify::attendeeRole(KCalCore::Attendee::Chair));
+
+#else
+ roleDelegate->addItem(SmallIcon("meeting-participant"),
+ KCalUtils::Stringify::attendeeRole(KCalCore::Attendee::ReqParticipant));
+ roleDelegate->addItem(SmallIcon("meeting-participant-optional"),
+ KCalUtils::Stringify::attendeeRole(KCalCore::Attendee::OptParticipant));
+ roleDelegate->addItem(SmallIcon("meeting-observer"),
+ KCalUtils::Stringify::attendeeRole(KCalCore::Attendee::NonParticipant));
+ roleDelegate->addItem(SmallIcon("meeting-chair"),
+ KCalUtils::Stringify::attendeeRole(KCalCore::Attendee::Chair));
+#endif
+
+ AttendeeComboBoxDelegate *stateDelegate(new AttendeeComboBoxDelegate(this));
+
+#ifdef KDEPIM_MOBILE_UI
+ stateDelegate->addItem(DesktopIcon("task-attention", 48),
+ KCalUtils::Stringify::attendeeStatus(KCalCore::Attendee::NeedsAction));
+ stateDelegate->addItem(DesktopIcon("task-accepted", 48),
+ KCalUtils::Stringify::attendeeStatus(KCalCore::Attendee::Accepted));
+ stateDelegate->addItem(DesktopIcon("task-reject", 48),
+ KCalUtils::Stringify::attendeeStatus(KCalCore::Attendee::Declined));
+ stateDelegate->addItem(DesktopIcon("task-attempt", 48),
+ KCalUtils::Stringify::attendeeStatus(KCalCore::Attendee::Tentative));
+ stateDelegate->addItem(DesktopIcon("task-delegate", 48),
+ KCalUtils::Stringify::attendeeStatus(KCalCore::Attendee::Delegated));
+#else
+ stateDelegate->addItem(SmallIcon("task-attention"),
+ KCalUtils::Stringify::attendeeStatus(KCalCore::Attendee::NeedsAction));
+ stateDelegate->addItem(SmallIcon("task-accepted"),
+ KCalUtils::Stringify::attendeeStatus(KCalCore::Attendee::Accepted));
+ stateDelegate->addItem(SmallIcon("task-reject"),
+ KCalUtils::Stringify::attendeeStatus(KCalCore::Attendee::Declined));
+ stateDelegate->addItem(SmallIcon("task-attempt"),
+ KCalUtils::Stringify::attendeeStatus(KCalCore::Attendee::Tentative));
+ stateDelegate->addItem(SmallIcon("task-delegate"),
+ KCalUtils::Stringify::attendeeStatus(KCalCore::Attendee::Delegated));
+#endif
+
+#ifndef KDEPIM_MOBILE_UI
+ QStringList attrs;
+ attrs << QLatin1String("cn");
+
+ completer = new QCompleter(this);
+ ResourceModel *model = new ResourceModel(attrs, this);
+
+ KDescendantsProxyModel *proxyModel = new KDescendantsProxyModel( this );
+ proxyModel->setSourceModel( model );
+
+ completer->setModel(proxyModel);
+ completer->setWrapAround(false);
+ mUi->mNewResource->setCompleter(completer);
+
+ KCalCore::Attendee::List resources;
+ AttendeeLineEditDelegate *attendeeDelegate = new AttendeeLineEditDelegate(this);
+
+ dataModel = new AttendeeTableModel(resources, this);
+ ResourceFilterProxyModel *filterProxyModel = new ResourceFilterProxyModel(this);
+ filterProxyModel->setDynamicSortFilter(true);
+ filterProxyModel->setSourceModel(dataModel);
+
+ mUi->mResourcesTable->setModel(filterProxyModel);
+ mUi->mResourcesTable->setColumnHidden(4, true);
+ mUi->mResourcesTable->setItemDelegateForColumn(0, roleDelegate);
+ mUi->mResourcesTable->setItemDelegateForColumn(1, attendeeDelegate);
+ mUi->mResourcesTable->setItemDelegateForColumn(3, stateDelegate);
+
+
+ AttendeeFilterProxyModel *attendeeProxyModel = new AttendeeFilterProxyModel(this);
+ attendeeProxyModel->setDynamicSortFilter(true);
+ attendeeProxyModel->setSourceModel(dataModel);
+ mUi->mAttendeeTable->setModel(attendeeProxyModel);
+ mUi->mAttendeeTable->setItemDelegateForColumn(0, roleDelegate);
+ mUi->mAttendeeTable->setItemDelegateForColumn(1, attendeeDelegate);
+ mUi->mAttendeeTable->setItemDelegateForColumn(3, stateDelegate);
+
+ connect(mUi->mFindResourcesButton, SIGNAL(clicked()), SLOT(findResources()));
+ connect(mUi->mBookResourceButton, SIGNAL(clicked()), SLOT(bookResource()));
+ connect(dataModel, SIGNAL(layoutChanged()), SLOT(layoutChanged()));
+ connect(dataModel, SIGNAL(rowsInserted(const QModelIndex&, int , int)), SLOT(layoutChanged()));
+ connect(dataModel, SIGNAL(rowsRemoved(const QModelIndex&, int , int)), SLOT(layoutChanged()));
+#endif
+}
+
+void IncidenceResource::load(const KCalCore::Incidence::Ptr &incidence)
+{
+ mLoadedIncidence = incidence;
+ dataModel->setAttendees(incidence->attendees());
+}
+
+void IncidenceResource::save(const KCalCore::Incidence::Ptr &incidence)
+{
+ incidence->clearAttendees();
+ KCalCore::Attendee::List attendees = dataModel->attendees();
+
+ foreach(KCalCore::Attendee::Ptr attendee, attendees) {
+ Q_ASSERT(attendee);
+
+ bool skip = false;
+ if (KPIMUtils::isValidAddress(attendee->email())) {
+ if (KMessageBox::warningYesNo(
+ 0,
+ i18nc("@info",
+ "%1 does not look like a valid email address. "
+ "Are you sure you want to invite this participant?",
+ attendee->email()),
+ i18nc("@title:window", "Invalid Email Address")) != KMessageBox::Yes) {
+ skip = true;
+ }
+ }
+ if (!skip) {
+ incidence->addAttendee(attendee);
+ }
+ }
+
+ // Must not have an organizer for items without attendees
+ if (!incidence->attendeeCount()) {
+ return;
+ }
+}
+
+bool IncidenceResource::isDirty() const
+{
+ const KCalCore::Attendee::List originalList = mLoadedIncidence->attendees();
+ KCalCore::Attendee::List newList = dataModel->attendees();
+
+ // The lists sizes *must* be the same. When the organizer is attending the
+ // event as well, he should be in the attendees list as well.
+ if (originalList.size() != newList.size()) {
+ return true;
+ }
+
+ // Okay, again not the most efficient algorithm, but I'm assuming that in the
+ // bulk of the use cases, the number of attendees is not much higher than 10 or so.
+ foreach(const KCalCore::Attendee::Ptr & attendee, originalList) {
+ bool found = false;
+ for (int i = 0; i < newList.count(); ++i) {
+ if (newList[i] == attendee) {
+ newList.remove(i);
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ // One of the attendees in the original list was not found in the new list.
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void IncidenceResource::bookResource()
+{
+#ifndef KDEPIM_MOBILE_UI
+ QString name, email;
+
+ KPIMUtils::extractEmailAddressAndName(mUi->mNewResource->text(), email, name);
+ KCalCore::Attendee::Ptr attendee(new KCalCore::Attendee(name, email));
+ attendee->setCuType(KCalCore::Attendee::Resource);
+ dataModel->insertAttendee(dataModel->rowCount(), attendee);
+#endif
+}
+
+void IncidenceResource::findResources()
+{
+ ResourceManagement* dialog = new ResourceManagement();
+ dialog->show();
+}
+
+void IncidenceResource::layoutChanged()
+{
+ emit resourceCountChanged(resourcesCount());
+}
+
+int IncidenceResource::resourcesCount() const
+{
+#ifndef KDEPIM_MOBILE_UI
+ return mUi->mResourcesTable->model()->rowCount(QModelIndex());
+#endif
+ return 0;
+}
+
+#include "incidenceresource.moc"
diff --git a/incidenceeditor-ng/incidenceresource.h b/incidenceeditor-ng/incidenceresource.h
new file mode 100644
index 0000000..7208015
--- /dev/null
+++ b/incidenceeditor-ng/incidenceresource.h
@@ -0,0 +1,82 @@
+/*
+ Copyright (C) 2014 Sandro Knauà <knauss at kolabsys.com>
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ This library is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+*/
+
+#ifndef INCIDENCEEDITOR_INCIDENCERESOURCE_H
+#define INCIDENCEEDITOR_INCIDENCERESOURCE_H
+
+#include "incidenceeditor-ng.h"
+#include "attendeetablemodel.h"
+
+#include <QModelIndex>
+#include <QCompleter>
+
+namespace Ui
+{
+class EventOrTodoDesktop;
+class EventOrTodoMore;
+}
+
+namespace IncidenceEditorNG
+{
+
+class INCIDENCEEDITORS_NG_EXPORT IncidenceResource : public IncidenceEditor
+{
+ Q_OBJECT
+public:
+#ifdef KDEPIM_MOBILE_UI
+ explicit IncidenceResource(Ui::EventOrTodoMore *ui);
+#else
+ explicit IncidenceResource(Ui::EventOrTodoDesktop *ui);
+#endif
+
+ void load(const KCalCore::Incidence::Ptr &incidence);
+ void save(const KCalCore::Incidence::Ptr &incidence);
+ bool isDirty() const;
+
+ /** resturn the count of resources */
+ int resourcesCount() const;
+
+signals:
+ /** is emitted it the count of the resources is changed.
+ * @arg: new count of resources.
+ */
+ void resourceCountChanged(int);
+
+private slots:
+ void findResources();
+ void bookResource();
+ void layoutChanged();
+
+private:
+#ifdef KDEPIM_MOBILE_UI
+ Ui::EventOrTodoMore *mUi;
+#else
+ Ui::EventOrTodoDesktop *mUi;
+#endif
+
+ /** completer for findResources */
+ QCompleter *completer;
+
+ /** used dataModel to rely on*/
+ AttendeeTableModel *dataModel;
+};
+
+}
+
+#endif
\ No newline at end of file
diff --git a/incidenceeditor-ng/resourceitem.cpp b/incidenceeditor-ng/resourceitem.cpp
new file mode 100644
index 0000000..a57c826
--- /dev/null
+++ b/incidenceeditor-ng/resourceitem.cpp
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2014 Sandro Knauà <knauss at kolabsys.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+#include "resourceitem.h"
+
+#include <kldap/ldapserver.h>
+
+using namespace IncidenceEditorNG;
+
+ResourceItem::ResourceItem(const KLDAP::LdapDN &dn, QStringList attrs, const KLDAP::LdapClient &ldapClient, ResourceItem *parent)
+ : dn(dn)
+ , attrs(attrs)
+ , mLdapClient(0, this)
+{
+ parentItem = parent;
+
+
+ if (!dn.isEmpty()) {
+ KLDAP::LdapServer server = ldapClient.server();
+
+ server.setScope(KLDAP::LdapUrl::Base);
+ server.setBaseDn(dn);
+ mLdapClient.setServer(server);
+
+ connect(&mLdapClient, SIGNAL(result(KLDAP::LdapClient, KLDAP::LdapObject)),
+ SLOT(slotLDAPResult(KLDAP::LdapClient, KLDAP::LdapObject)));
+
+ attrs << QLatin1String("uniqueMember");
+ mLdapClient.setAttributes(attrs);
+ } else {
+ foreach(QString header, attrs) {
+ itemData << header;
+ }
+ }
+}
+
+ResourceItem::~ResourceItem()
+{
+ qDeleteAll(childItems);
+}
+
+
+ResourceItem *ResourceItem::child(int number)
+{
+ return childItems.value(number);
+}
+
+
+int ResourceItem::childCount() const
+{
+ return childItems.count();
+}
+
+int ResourceItem::childNumber() const
+{
+ if (parentItem) {
+ return parentItem->childItems.indexOf(const_cast<ResourceItem*>(this));
+ }
+
+ return 0;
+}
+
+int ResourceItem::columnCount() const
+{
+ return itemData.count();
+}
+
+QVariant ResourceItem::data(int column) const
+{
+ return itemData.value(column);
+}
+
+bool ResourceItem::insertChild(int position, ResourceItem *item)
+{
+ if (position < 0 || position > childItems.size()) {
+ return false;
+ }
+
+ childItems.insert(position, item);
+
+ return true;
+}
+
+ResourceItem *ResourceItem::parent()
+{
+ return parentItem;
+}
+
+bool ResourceItem::removeChildren(int position, int count)
+{
+ if (position < 0 || position + count > childItems.size()) {
+ return false;
+ }
+
+ for (int row = 0; row < count; ++row) {
+ delete childItems.takeAt(position);
+ }
+
+ return true;
+}
+
+const QStringList& ResourceItem::attributes() const
+{
+ return attrs;
+}
+
+const KLDAP::LdapObject& ResourceItem::ldapObject() const
+{
+ return mLdapObject;
+}
+
+void ResourceItem::startSearch()
+{
+ mLdapClient.startQuery("objectclass=*");
+}
+
+void ResourceItem::setLdapObject(const KLDAP::LdapObject& obj)
+{
+ slotLDAPResult(mLdapClient, obj);
+}
+
+const KLDAP::LdapClient& ResourceItem::ldapClient() const
+{
+ return mLdapClient;
+}
+
+void ResourceItem::slotLDAPResult(const KLDAP::LdapClient &/*client*/,
+ const KLDAP::LdapObject &obj)
+{
+ mLdapObject = obj;
+ foreach(QString header, attrs) {
+ if (obj.attributes()[header].count() > 0) {
+ itemData << QString::fromUtf8(obj.attributes()[header][0]);
+ } else {
+ itemData << "";
+ }
+ }
+}
\ No newline at end of file
diff --git a/incidenceeditor-ng/resourceitem.h b/incidenceeditor-ng/resourceitem.h
new file mode 100644
index 0000000..d0aea66
--- /dev/null
+++ b/incidenceeditor-ng/resourceitem.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2014 Sandro Knauà <knauss at kolabsys.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef RESOURCEITEM_H
+#define RESOURCEITEM_H
+
+#include <QObject>
+#include <QList>
+#include <QStringList>
+#include <QVariant>
+#include <QVector>
+
+#include <ldap/ldapclient.h>
+#include <kldap/ldapobject.h>
+
+namespace IncidenceEditorNG
+{
+
+class ResourceItem : public QObject
+{
+ Q_OBJECT
+public:
+ /* Copied from http://qt-project.org/doc/qt-4.8/itemviews-editabletreemodel.html:
+ * QT 4.8: Editable Tree Model Example
+ */
+ ResourceItem(const KLDAP::LdapDN &dn, QStringList attrs, const KLDAP::LdapClient &ldapClient, ResourceItem *parent = 0);
+ ~ResourceItem();
+
+ ResourceItem *child(int number);
+ int childCount() const;
+ int columnCount() const;
+ QVariant data(int column) const;
+ bool insertChild(int position, ResourceItem *item);
+ ResourceItem *parent();
+ bool removeChildren(int position, int count);
+ int childNumber() const;
+
+private:
+ QList<ResourceItem*> childItems;
+ QVector<QVariant> itemData;
+ ResourceItem *parentItem;
+
+public:
+ /* Returns the attributes of the requested ldapObject.
+ *
+ */
+ const QStringList &attributes() const;
+
+ /* Returns the ldapObject, that is used as data source.
+ *
+ */
+ const KLDAP::LdapObject& ldapObject() const;
+
+ /* Set the ldapObject, either directy via this function
+ * or use startSearch to request the ldapServer for the ldapObject
+ * with the dn specified via the constructor.
+ *
+ */
+ void setLdapObject(const KLDAP::LdapObject&);
+
+ /* The used ldapClient.
+ *
+ */
+ const KLDAP::LdapClient& ldapClient() const;
+
+ /* Start querying the ldapServer for a object that name is dn
+ *
+ */
+ void startSearch();
+
+private:
+ /* data source
+ *
+ */
+ KLDAP::LdapObject mLdapObject;
+
+ /* dn of the ldapObject
+ *
+ */
+ const KLDAP::LdapDN dn;
+
+ /* Attributes of the ldapObject to request and the header of the Item
+ *
+ */
+ QStringList attrs;
+
+ /* ldapClient to request
+ *
+ */
+ KLDAP::LdapClient mLdapClient;
+
+
+private slots:
+ /* Answer of the LdapServer for the given dn
+ *
+ */
+ void slotLDAPResult(const KLDAP::LdapClient&, const KLDAP::LdapObject&);
+
+};
+}
+#endif // RESOURCEITEM_H
diff --git a/incidenceeditor-ng/resourcemanagement.cpp b/incidenceeditor-ng/resourcemanagement.cpp
new file mode 100644
index 0000000..48a55d7
--- /dev/null
+++ b/incidenceeditor-ng/resourcemanagement.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2014 Sandro Knauà <knauss at kolabsys.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "resourcemanagement.h"
+#include "ui_resourcemanagement.h"
+#include "resourcemodel.h"
+
+#include <kldap/ldapobject.h>
+
+#include <QStringList>
+#include <QLabel>
+
+using namespace IncidenceEditorNG;
+
+ResourceManagement::ResourceManagement()
+{
+ ui = new Ui::ResourceManagement;
+ ui->setupUi(this);
+
+ QStringList attrs;
+ attrs << QLatin1String("cn") << QLatin1String("mail") << QLatin1String("givenname") << QLatin1String("sn");
+
+ ResourceModel *model = new ResourceModel(attrs);
+ ui->treeResults->setModel(model);
+
+ // This doesn't work till now :( -> that's why i use the clieck signal
+ ui->treeResults->setSelectionMode(QAbstractItemView::SingleSelection);
+ selectionModel = ui->treeResults->selectionModel();
+
+ connect(ui->resourceSearch, SIGNAL(textChanged(const QString&)),
+ SLOT(slotStartSearch(const QString&)));
+
+ connect(ui->treeResults, SIGNAL(clicked(const QModelIndex &)),
+ SLOT(slotShowDetails(const QModelIndex &)));
+
+}
+
+void ResourceManagement::slotStartSearch(const QString &text)
+{
+ ((ResourceModel*)ui->treeResults->model())->startSearch(text);
+}
+
+void ResourceManagement::slotShowDetails(const QModelIndex & current)
+{
+ ResourceItem *item = ((ResourceModel*)current.model())->getItem(current);
+ showDetails(item->ldapObject());
+}
+
+
+void ResourceManagement::showDetails(const KLDAP::LdapObject &obj)
+{
+ // Clean up formDetails
+ QLayoutItem *child;
+ while ((child = ui->formDetails->takeAt(0)) != 0) {
+ delete child->widget();
+ delete child;
+ }
+
+ // Fill formDetails with data
+ foreach(const QString & key, obj.attributes().keys()) {
+ QStringList list;
+ foreach(const QByteArray & value, obj.attributes().value(key)) {
+ list << QString::fromUtf8(value);
+ }
+ ui->formDetails->addRow(key, new QLabel(list.join("\n")));
+ }
+}
+
+#include "resourcemanagement.moc"
diff --git a/incidenceeditor-ng/resourcemanagement.h b/incidenceeditor-ng/resourcemanagement.h
new file mode 100644
index 0000000..3749db6
--- /dev/null
+++ b/incidenceeditor-ng/resourcemanagement.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2014 Sandro Knauà <knauss at kolabsys.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef RESOURCEMANAGEMENT_H
+#define RESOURCEMANAGEMENT_H
+
+#include "incidenceeditors-ng_export.h"
+
+#include <ldap/ldapclient.h>
+#include <ldap/ldapclientsearch.h>
+
+#include <KDialog>
+
+#include <QStringList>
+#include <QStringListModel>
+
+namespace Ui
+{
+class ResourceManagement;
+}
+
+namespace IncidenceEditorNG
+{
+
+class QTreeModel;
+
+class INCIDENCEEDITORS_NG_EXPORT ResourceManagement : public KDialog
+{
+ Q_OBJECT
+public:
+ ResourceManagement();
+
+private:
+ /* Shows the details of a resource
+ *
+ */
+ void showDetails(const KLDAP::LdapObject&);
+
+ Ui::ResourceManagement* ui;
+
+ QItemSelectionModel *selectionModel;
+
+private slots:
+ /* A new searchString is entered
+ *
+ */
+ void slotStartSearch(const QString&);
+
+ /* A detail view is requested
+ *
+ */
+ void slotShowDetails(const QModelIndex & current);
+};
+
+}
+#endif // RESOURCEMANAGEMENT_H
diff --git a/incidenceeditor-ng/resourcemanagement.ui b/incidenceeditor-ng/resourcemanagement.ui
new file mode 100644
index 0000000..38002e1
--- /dev/null
+++ b/incidenceeditor-ng/resourcemanagement.ui
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ResourceManagement</class>
+ <widget class="QWidget" name="resourceManagement">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>916</width>
+ <height>782</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <property name="spacing">
+ <number>-1</number>
+ </property>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout" stretch="0,0">
+ <property name="spacing">
+ <number>2</number>
+ </property>
+ <item>
+ <widget class="QLineEdit" name="resourceSearch"/>
+ </item>
+ <item>
+ <widget class="QTreeView" name="treeResults">
+ <property name="alternatingRowColors">
+ <bool>true</bool>
+ </property>
+ <property name="selectionBehavior">
+ <enum>QAbstractItemView::SelectRows</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <property name="spacing">
+ <number>2</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="groupDetails">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Details</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <property name="rightMargin">
+ <number>4</number>
+ </property>
+ <item>
+ <layout class="QFormLayout" name="formDetails"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QWidget" name="resourceCalender" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/incidenceeditor-ng/resourcemodel.cpp b/incidenceeditor-ng/resourcemodel.cpp
new file mode 100644
index 0000000..829e0e0
--- /dev/null
+++ b/incidenceeditor-ng/resourcemodel.cpp
@@ -0,0 +1,231 @@
+/*
+ * Copyright 2014 Sandro Knauà <knauss at kolabsys.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+#include "resourcemodel.h"
+
+
+using namespace IncidenceEditorNG;
+
+ResourceModel::ResourceModel(const QStringList &headers,
+ QObject *parent)
+ : QAbstractItemModel(parent)
+ , foundCollection(false)
+{
+
+ this->headers = headers;
+ rootItem = new ResourceItem(KLDAP::LdapDN(), headers, KLDAP::LdapClient(0), 0);
+
+ ldapSearchCollections.setFilter(QString::fromLatin1("&(objectClass=kolabGroupOfUniqueNames)(mail=*)"
+ "(|(cn=%1)(givenName=%1)(sn=%1))"));
+ ldapSearch.setFilter(QString::fromLatin1("&(objectClass=kolabSharedFolder)(kolabFolderType=event)(mail=*)"
+ "(|(cn=%1)(givenName=%1)(sn=%1))"));
+
+ QStringList attrs = ldapSearchCollections.attributes();
+ attrs << QLatin1String("uniqueMember");
+ ldapSearchCollections.setAttributes(attrs);
+
+ connect(&ldapSearchCollections, SIGNAL(searchData(const QList<KLDAP::LdapResultObject> &)),
+ SLOT(slotLDAPCollectionData(const QList<KLDAP::LdapResultObject> &)));
+ connect(&ldapSearch, SIGNAL(searchData(const QList<KLDAP::LdapResultObject> &)),
+ SLOT(slotLDAPSearchData(const QList<KLDAP::LdapResultObject> &)));
+
+ ldapSearchCollections.startSearch("*");
+}
+
+ResourceModel::~ResourceModel()
+{
+ delete rootItem;
+}
+
+int ResourceModel::columnCount(const QModelIndex & /* parent */) const
+{
+ return 1;
+}
+
+QVariant ResourceModel::data(const QModelIndex &index, int role) const
+{
+ if (!index.isValid()) {
+ return QVariant();
+ }
+
+ if (role != Qt::DisplayRole && role != Qt::EditRole) {
+ return QVariant();
+ }
+
+ ResourceItem *item = getItem(index);
+
+ return item->data(index.column());
+}
+
+Qt::ItemFlags ResourceModel::flags(const QModelIndex &index) const
+{
+ if (!index.isValid()) {
+ return 0;
+ }
+
+ return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+}
+
+ResourceItem *ResourceModel::getItem(const QModelIndex &index) const
+{
+ if (index.isValid()) {
+ ResourceItem *item = static_cast<ResourceItem*>(index.internalPointer());
+ if (item) {
+ return item;
+ }
+ }
+ return rootItem;
+}
+
+QVariant ResourceModel::headerData(int section, Qt::Orientation orientation,
+ int role) const
+{
+ if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
+ return rootItem->data(section);
+ }
+
+ return QVariant();
+}
+
+QModelIndex ResourceModel::index(int row, int column, const QModelIndex &parent) const
+{
+ if (parent.isValid() && parent.column() != 0) {
+ return QModelIndex();
+ }
+ ResourceItem *parentItem = getItem(parent);
+
+ ResourceItem *childItem = parentItem->child(row);
+ if (childItem) {
+ return createIndex(row, column, childItem);
+ } else {
+ return QModelIndex();
+ }
+}
+
+
+QModelIndex ResourceModel::parent(const QModelIndex &index) const
+{
+ if (!index.isValid()) {
+ return QModelIndex();
+ }
+ ResourceItem *childItem = getItem(index);
+ ResourceItem *parentItem = childItem->parent();
+
+ if (parentItem == rootItem) {
+ return QModelIndex();
+ }
+
+ return createIndex(parentItem->childNumber(), 0, parentItem);
+}
+
+
+bool ResourceModel::removeRows(int position, int rows, const QModelIndex &parent)
+{
+ ResourceItem *parentItem = getItem(parent);
+ bool success = true;
+
+ beginRemoveRows(parent, position, position + rows - 1);
+ success = parentItem->removeChildren(position, rows);
+ endRemoveRows();
+
+ return success;
+}
+
+int ResourceModel::rowCount(const QModelIndex &parent) const
+{
+ ResourceItem *parentItem = getItem(parent);
+
+ return parentItem->childCount();
+}
+
+void ResourceModel::startSearch(const QString &query)
+{
+ searchString = query;
+
+ if (foundCollection) {
+ startSearch();
+ }
+}
+
+void ResourceModel::startSearch()
+{
+ emit layoutAboutToBeChanged();
+ // Delete all resources -> only collection elements are shown
+ for (int i = 0; i < rootItem->childCount(); i++) {
+ if (ldapCollections.contains(rootItem->child(i))) {
+ rootItem->child(i)->removeChildren(0, rootItem->child(i)->childCount());
+ } else {
+ rootItem->removeChildren(i, 1);
+ }
+ }
+ emit layoutChanged();
+
+ if (searchString.count() > 0) {
+ ldapSearch.startSearch("*" + searchString + "*");
+ } else {
+ ldapSearch.startSearch("*");
+ }
+}
+
+void ResourceModel::slotLDAPCollectionData(const QList<KLDAP::LdapResultObject> &results)
+{
+ foundCollection = true;
+ ldapCollectionsMap.clear();
+ ldapCollections.clear();
+
+ emit layoutAboutToBeChanged();
+
+ foreach(const KLDAP::LdapResultObject & result, results) {
+ ResourceItem *item = new ResourceItem(result.object.dn(), headers, *result.client, rootItem);
+ item->setLdapObject(result.object);
+ rootItem->insertChild(rootItem->childCount(), item);
+ ldapCollections.insert(item);
+
+ // Resources in a collection add this link into ldapCollectionsMap
+ foreach(const QByteArray & member, result.object.attributes()["uniqueMember"]) {
+ ldapCollectionsMap.insert(QString::fromLatin1(member), item);
+ }
+ }
+
+ emit layoutChanged();
+
+ startSearch();
+}
+
+void ResourceModel::slotLDAPSearchData(const QList<KLDAP::LdapResultObject> &results)
+{
+ emit layoutAboutToBeChanged();
+
+ foreach(const KLDAP::LdapResultObject & result, results) {
+ //Add the found items to all collections, where it is member
+ QList<ResourceItem*> parents = ldapCollectionsMap.values(result.object.dn().toString());
+ if (parents.count() == 0) {
+ parents << rootItem;
+ }
+
+ foreach(ResourceItem * parent, parents) {
+ ResourceItem *item = new ResourceItem(result.object.dn(), headers, *result.client, parent);
+ item->setLdapObject(result.object);
+ parent->insertChild(parent->childCount(), item);
+ }
+ }
+
+ emit layoutChanged();
+}
diff --git a/incidenceeditor-ng/resourcemodel.h b/incidenceeditor-ng/resourcemodel.h
new file mode 100644
index 0000000..4eb8a33
--- /dev/null
+++ b/incidenceeditor-ng/resourcemodel.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2014 Sandro Knauà <knauss at kolabsys.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License or (at your option) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef RESOURCEMODEL_H
+#define RESOURCEMODEL_H
+
+#include "resourceitem.h"
+
+#include <libkdepim/ldap/ldapclientsearch.h>
+
+#include <QAbstractItemModel>
+#include <QModelIndex>
+#include <QSet>
+
+namespace IncidenceEditorNG
+{
+
+class ResourceModel : public QAbstractItemModel
+{
+ Q_OBJECT
+
+public:
+ /* Copied from http://qt-project.org/doc/qt-4.8/itemviews-editabletreemodel.html:
+ * QT 4.8: Editable Tree Model Example
+ */
+ ResourceModel(const QStringList &headers,
+ QObject *parent = 0);
+ ~ResourceModel();
+
+ QVariant data(const QModelIndex &index, int role) const;
+ QVariant headerData(int section, Qt::Orientation orientation,
+ int role = Qt::DisplayRole) const;
+
+ QModelIndex index(int row, int column,
+ const QModelIndex &parent = QModelIndex()) const;
+ QModelIndex parent(const QModelIndex &index) const;
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ int columnCount(const QModelIndex &parent = QModelIndex()) const;
+
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+
+ bool removeRows(int position, int rows,
+ const QModelIndex &parent = QModelIndex());
+
+ ResourceItem *getItem(const QModelIndex &index) const;
+
+private:
+ ResourceItem *rootItem;
+
+
+public:
+
+ /* Start search on LDAP Server with the given string.
+ * If the model is not ready to search, the string is cached and is executed afterwards.
+ */
+ void startSearch(const QString&);
+private:
+
+ /* Start search with cached string (stored in searchString)
+ *
+ */
+ void startSearch();
+
+ /* Search for collections of resources
+ *
+ */
+ KLDAP::LdapClientSearch ldapSearchCollections;
+
+ /* Search for matching resources
+ *
+ */
+ KLDAP::LdapClientSearch ldapSearch;
+
+ /* Map from dn of resource -> collectionItem
+ * A Resource can be part of different collection, so a QMuliMap is needed
+ *
+ */
+ QMultiMap<QString, ResourceItem*> ldapCollectionsMap;
+
+ /* A Set of all collection ResourceItems
+ *
+ */
+ QSet <ResourceItem*> ldapCollections;
+
+ /* Cached searchString (setted by startSearch(QString))
+ *
+ */
+ QString searchString;
+
+ /* Is the search of collections ended
+ *
+ */
+ bool foundCollection;
+
+ /* List of all attributes in LDAP an the headers of the model
+ *
+ */
+ QStringList headers;
+
+
+private slots:
+ /* Slot for founded collections
+ *
+ */
+ void slotLDAPCollectionData(const QList<KLDAP::LdapResultObject> &);
+
+ /* Slot for matching resources
+ *
+ */
+ void slotLDAPSearchData(const QList<KLDAP::LdapResultObject> &);
+};
+
+}
+#endif // RESOURCEMODEL_H
diff --git a/incidenceeditor-ng/tests/CMakeLists.txt b/incidenceeditor-ng/tests/CMakeLists.txt
index 5b0c4cd..e248660 100644
--- a/incidenceeditor-ng/tests/CMakeLists.txt
+++ b/incidenceeditor-ng/tests/CMakeLists.txt
@@ -48,4 +48,16 @@ target_link_libraries(testindividualmaildialog
${QT_QTGUI_LIBRARY}
${KDE4_KDECORE_LIBS}
${KDE4_KDEUI_LIBS}
- )
\ No newline at end of file
+ )
+
+set(resourcemanagement_gui_SRCS resourcemanagment_gui.cpp)
+kde4_add_executable(resourcemanagement_gui TEST ${resourcemanagement_gui_SRCS})
+target_link_libraries(resourcemanagement_gui
+ ${QT_QTCORE_LIBRARY}
+ ${QT_QTGUI_LIBRARY}
+ ${QT_QTWEBKIT_LIBRARY}
+ ${KDE4_KDECORE_LIBS}
+ ${KDE4_KDEUI_LIBS}
+ ${KDEPIMLIBS_KMIME_LIBS}
+ incidenceeditorsng
+)
diff --git a/incidenceeditor-ng/tests/resourcemanagment_gui.cpp b/incidenceeditor-ng/tests/resourcemanagment_gui.cpp
new file mode 100644
index 0000000..a991ed8
--- /dev/null
+++ b/incidenceeditor-ng/tests/resourcemanagment_gui.cpp
@@ -0,0 +1,43 @@
+/* Copyright 2014 Sandro Knauà <knauss at kolabsys.com>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License or (at your option) version 3 or any later version
+ accepted by the membership of KDE e.V. (or its successor approved
+ by the membership of KDE e.V.), which shall act as a proxy
+ defined in Section 14 of version 3 of the license.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <QFile>
+#include "resourcemanagement.h"
+
+#include <kdebug.h>
+#include <kcmdlineargs.h>
+#include <kapplication.h>
+
+using namespace IncidenceEditorNG;
+
+int main (int argc, char **argv)
+{
+ KCmdLineArgs::init(argc, argv, "resourcemanagement_gui", 0, ki18n("resourcemanagement_Gui"),
+ "1.0", ki18n("Test for resourceManagement"));
+
+ KCmdLineArgs::addStdCmdLineOptions();
+
+ KApplication app;
+
+ ResourceManagement* dialog = new ResourceManagement();
+
+ dialog->show();
+
+ return app.exec();
+}
More information about the commits
mailing list