1 /*
2 This file is part of Contact Editor.
3
4 SPDX-FileCopyrightText: 2009 Tobias Koenig <tokoe@kde.org>
5
6 SPDX-License-Identifier: LGPL-2.0-or-later
7 */
8
9 #include "contacteditorwidget.h"
10 #include "config-contact-editor.h"
11
12 #include "contacteditorpageplugin.h"
13 #include "contactmetadatabase_p.h"
14 #include "personaleditor/personaleditorwidget.h"
15
16 #include <KConfig>
17 #include <KLocalizedString>
18 #include <KTextEdit>
19 #include <QTabWidget>
20
21 #include "addresseditor/addresseslocationwidget.h"
22 #include "businesseditor/businesseditorwidget.h"
23 #include "customfieldeditor/customfieldswidget.h"
24 #include "generalinfoeditor/generalinfowidget.h"
25 #include <QDirIterator>
26 #include <QPluginLoader>
27 #include <QVBoxLayout>
28
29 class ContactEditorWidgetPrivate
30 {
31 public:
ContactEditorWidgetPrivate(ContactEditorWidget::DisplayMode displayMode,ContactEditorWidget * parent)32 ContactEditorWidgetPrivate(ContactEditorWidget::DisplayMode displayMode, ContactEditorWidget *parent)
33 : mDisplayMode(displayMode)
34 , mParent(parent)
35 {
36 }
37
38 void initGui();
39 void initGuiContactTab();
40 void initGuiLocationTab();
41 void initGuiBusinessTab();
42 void initGuiPersonalTab();
43 void initGuiNotesTab();
44 void initGuiCustomFieldsTab();
45
46 void loadCustomPages();
47
48 QString loadCustom(const KContacts::Addressee &contact, const QString &key) const;
49 void storeCustom(KContacts::Addressee &contact, const QString &key, const QString &value) const;
50
51 ContactEditorWidget::DisplayMode mDisplayMode;
52 ContactEditorWidget *const mParent;
53 QTabWidget *mTabWidget = nullptr;
54
55 ContactEditor::GeneralInfoWidget *mGeneralInfoWidget = nullptr;
56
57 // widgets from addresses group
58 ContactEditor::AddressesLocationWidget *mAddressesLocationWidget = nullptr;
59
60 ContactEditor::BusinessEditorWidget *mBusinessEditorWidget = nullptr;
61
62 // widgets from notes group
63 KTextEdit *mNotesWidget = nullptr;
64
65 ContactEditor::PersonalEditorWidget *mPersonalEditorWidget = nullptr;
66
67 // widgets from custom fields group
68 ContactEditor::CustomFieldsWidget *mCustomFieldsWidget = nullptr;
69
70 // custom editor pages
71 QList<ContactEditor::ContactEditorPagePlugin *> mCustomPages;
72 };
73
initGui()74 void ContactEditorWidgetPrivate::initGui()
75 {
76 auto layout = new QVBoxLayout(mParent);
77 layout->setContentsMargins({});
78
79 mTabWidget = new QTabWidget(mParent);
80 layout->addWidget(mTabWidget);
81
82 initGuiContactTab();
83 initGuiLocationTab();
84 initGuiBusinessTab();
85 initGuiPersonalTab();
86 initGuiNotesTab();
87 if (mDisplayMode == ContactEditorWidget::FullMode) {
88 initGuiCustomFieldsTab();
89 loadCustomPages();
90 }
91 }
92
initGuiContactTab()93 void ContactEditorWidgetPrivate::initGuiContactTab()
94 {
95 mGeneralInfoWidget = new ContactEditor::GeneralInfoWidget;
96 mTabWidget->addTab(mGeneralInfoWidget, i18nc("@title:tab", "Contact"));
97 }
98
initGuiLocationTab()99 void ContactEditorWidgetPrivate::initGuiLocationTab()
100 {
101 mAddressesLocationWidget = new ContactEditor::AddressesLocationWidget;
102 mTabWidget->addTab(mAddressesLocationWidget, i18nc("@title:tab", "Location"));
103 }
104
initGuiBusinessTab()105 void ContactEditorWidgetPrivate::initGuiBusinessTab()
106 {
107 mBusinessEditorWidget = new ContactEditor::BusinessEditorWidget();
108 mTabWidget->addTab(mBusinessEditorWidget, i18nc("@title:tab", "Business"));
109 }
110
initGuiPersonalTab()111 void ContactEditorWidgetPrivate::initGuiPersonalTab()
112 {
113 mPersonalEditorWidget = new ContactEditor::PersonalEditorWidget;
114 mTabWidget->addTab(mPersonalEditorWidget, i18nc("@title:tab Personal properties of a contact", "Personal"));
115 }
116
initGuiNotesTab()117 void ContactEditorWidgetPrivate::initGuiNotesTab()
118 {
119 auto widget = new QWidget;
120 auto layout = new QVBoxLayout(widget);
121
122 mTabWidget->addTab(widget, i18nc("@title:tab", "Notes"));
123
124 mNotesWidget = new KTextEdit;
125 mNotesWidget->setAcceptRichText(false);
126 layout->addWidget(mNotesWidget);
127 }
128
initGuiCustomFieldsTab()129 void ContactEditorWidgetPrivate::initGuiCustomFieldsTab()
130 {
131 mCustomFieldsWidget = new ContactEditor::CustomFieldsWidget(mParent);
132 mTabWidget->addTab(mCustomFieldsWidget, i18nc("@title:tab", "Custom Fields"));
133 }
134
loadCustomPages()135 void ContactEditorWidgetPrivate::loadCustomPages()
136 {
137 qDeleteAll(mCustomPages);
138 mCustomPages.clear();
139
140 const QString pluginDirectory = QStringLiteral("%1/contacteditor/editorpageplugins/").arg(QStringLiteral(EDITOR_CONTACT_LIB));
141 QDirIterator it(pluginDirectory, QDir::Files);
142
143 while (it.hasNext()) {
144 QPluginLoader loader(it.next());
145 if (!loader.load()) {
146 continue;
147 }
148
149 ContactEditor::ContactEditorPagePlugin *plugin = qobject_cast<ContactEditor::ContactEditorPagePlugin *>(loader.instance());
150 if (!plugin) {
151 continue;
152 }
153
154 mCustomPages.append(plugin);
155 }
156
157 for (ContactEditor::ContactEditorPagePlugin *plugin : std::as_const(mCustomPages)) {
158 mTabWidget->addTab(plugin, plugin->title());
159 }
160 }
161
loadCustom(const KContacts::Addressee & contact,const QString & key) const162 QString ContactEditorWidgetPrivate::loadCustom(const KContacts::Addressee &contact, const QString &key) const
163 {
164 return contact.custom(QStringLiteral("KADDRESSBOOK"), key);
165 }
166
storeCustom(KContacts::Addressee & contact,const QString & key,const QString & value) const167 void ContactEditorWidgetPrivate::storeCustom(KContacts::Addressee &contact, const QString &key, const QString &value) const
168 {
169 if (value.isEmpty()) {
170 contact.removeCustom(QStringLiteral("KADDRESSBOOK"), key);
171 } else {
172 contact.insertCustom(QStringLiteral("KADDRESSBOOK"), key, value);
173 }
174 }
175
ContactEditorWidget(QWidget * parent)176 ContactEditorWidget::ContactEditorWidget(QWidget *parent)
177 : d(new ContactEditorWidgetPrivate(FullMode, this))
178 {
179 Q_UNUSED(parent)
180 d->initGui();
181 }
182
ContactEditorWidget(ContactEditorWidget::DisplayMode displayMode,QWidget * parent)183 ContactEditorWidget::ContactEditorWidget(ContactEditorWidget::DisplayMode displayMode, QWidget *parent)
184 : d(new ContactEditorWidgetPrivate(displayMode, this))
185 {
186 Q_UNUSED(parent)
187 d->initGui();
188 }
189
190 ContactEditorWidget::~ContactEditorWidget() = default;
191
loadContact(const KContacts::Addressee & contact,const ContactEditor::ContactMetaDataBase & metaData)192 void ContactEditorWidget::loadContact(const KContacts::Addressee &contact, const ContactEditor::ContactMetaDataBase &metaData)
193 {
194 d->mGeneralInfoWidget->loadContact(contact);
195
196 // address group
197 d->mAddressesLocationWidget->loadContact(contact);
198
199 // general group
200 d->mBusinessEditorWidget->loadContact(contact);
201 // notes group
202 d->mNotesWidget->setPlainText(contact.note());
203
204 d->mPersonalEditorWidget->loadContact(contact);
205 d->mGeneralInfoWidget->setDisplayType((DisplayNameEditWidget::DisplayType)metaData.displayNameMode());
206 if (d->mDisplayMode == FullMode) {
207 // custom fields group
208 d->mCustomFieldsWidget->setLocalCustomFieldDescriptions(metaData.customFieldDescriptions());
209 d->mCustomFieldsWidget->loadContact(contact);
210
211 // custom pages
212 for (ContactEditor::ContactEditorPagePlugin *plugin : std::as_const(d->mCustomPages)) {
213 plugin->loadContact(contact);
214 }
215 }
216 }
217
storeContact(KContacts::Addressee & contact,ContactEditor::ContactMetaDataBase & metaData) const218 void ContactEditorWidget::storeContact(KContacts::Addressee &contact, ContactEditor::ContactMetaDataBase &metaData) const
219 {
220 d->mGeneralInfoWidget->storeContact(contact);
221
222 // address group
223 d->mAddressesLocationWidget->storeContact(contact);
224
225 // general group
226 d->mBusinessEditorWidget->storeContact(contact);
227
228 // notes group
229 contact.setNote(d->mNotesWidget->toPlainText());
230 d->mPersonalEditorWidget->storeContact(contact);
231
232 if (d->mDisplayMode == FullMode) {
233 // custom fields group
234 d->mCustomFieldsWidget->storeContact(contact);
235 metaData.setCustomFieldDescriptions(d->mCustomFieldsWidget->localCustomFieldDescriptions());
236
237 metaData.setDisplayNameMode(d->mGeneralInfoWidget->displayType());
238
239 // custom pages
240 for (ContactEditor::ContactEditorPagePlugin *plugin : std::as_const(d->mCustomPages)) {
241 plugin->storeContact(contact);
242 }
243 }
244 }
245
setReadOnly(bool readOnly)246 void ContactEditorWidget::setReadOnly(bool readOnly)
247 {
248 d->mGeneralInfoWidget->setReadOnly(readOnly);
249 // widgets from addresses group
250 d->mAddressesLocationWidget->setReadOnly(readOnly);
251
252 // widgets from general group
253 d->mBusinessEditorWidget->setReadOnly(readOnly);
254
255 // widgets from notes group
256 d->mNotesWidget->setReadOnly(readOnly);
257
258 d->mPersonalEditorWidget->setReadOnly(readOnly);
259 if (d->mDisplayMode == FullMode) {
260 // widgets from custom fields group
261 d->mCustomFieldsWidget->setReadOnly(readOnly);
262
263 // custom pages
264 for (ContactEditor::ContactEditorPagePlugin *plugin : std::as_const(d->mCustomPages)) {
265 plugin->setReadOnly(readOnly);
266 }
267 }
268 }
269
hasNoSavedData() const270 bool ContactEditorWidget::hasNoSavedData() const
271 {
272 return d->mAddressesLocationWidget->hasNoSavedData();
273 }
274