aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMontel Laurent <[email protected]>2017-06-20 09:04:07 +0200
committerMontel Laurent <[email protected]>2017-06-20 09:04:07 +0200
commit7bd1664414c9fc43db563d042ec17e7b873fd64a (patch)
tree49c8ae1899b031ad316470cc1c718fff46ee7cb1
parent03067153145eabac11cb71871a7ef98121126b57 (diff)
Create contacteditor lib
-rw-r--r--CMakeLists.txt2
-rw-r--r--src/akonadi-contacts/CMakeLists.txt118
-rw-r--r--src/contact-editor/CMakeLists.txt250
-rw-r--r--src/contact-editor/KF5ContactEditorConfig.cmake.in7
-rw-r--r--src/contact-editor/abstractcontacteditorwidget_p.h75
-rw-r--r--src/contact-editor/autoqpointer_p.h65
-rw-r--r--src/contact-editor/config-contact-editor.h.cmake1
-rw-r--r--src/contact-editor/contacteditor_private_export.h35
-rw-r--r--src/contact-editor/contacteditorpageplugin.h69
-rw-r--r--src/contact-editor/contactmetadatabase.cpp86
-rw-r--r--src/contact-editor/contactmetadatabase_p.h106
-rw-r--r--src/contact-editor/customfieldmanager.cpp68
-rw-r--r--src/contact-editor/customfieldmanager_p.h38
-rw-r--r--src/contact-editor/customfields.cpp152
-rw-r--r--src/contact-editor/customfields_p.h102
-rw-r--r--src/contact-editor/editor/addresseditor/addresseslocationgrantleeformater.cpp89
-rw-r--r--src/contact-editor/editor/addresseditor/addresseslocationgrantleeformater.h56
-rw-r--r--src/contact-editor/editor/addresseditor/addresseslocationwidget.cpp79
-rw-r--r--src/contact-editor/editor/addresseditor/addresseslocationwidget.h48
-rw-r--r--src/contact-editor/editor/addresseditor/addressgrantleeobject.cpp129
-rw-r--r--src/contact-editor/editor/addresseditor/addressgrantleeobject.h69
-rw-r--r--src/contact-editor/editor/addresseditor/addresslocationwidget.cpp295
-rw-r--r--src/contact-editor/editor/addresseditor/addresslocationwidget.h86
-rw-r--r--src/contact-editor/editor/addresseditor/addresstypedialog.cpp92
-rw-r--r--src/contact-editor/editor/addresseditor/addresstypedialog.h51
-rw-r--r--src/contact-editor/editor/addresseditor/autotests/CMakeLists.txt31
-rw-r--r--src/contact-editor/editor/addresseditor/autotests/addresseslocationviewertest.cpp45
-rw-r--r--src/contact-editor/editor/addresseditor/autotests/addresseslocationviewertest.h38
-rw-r--r--src/contact-editor/editor/addresseditor/autotests/addresseslocationwidgettest.cpp53
-rw-r--r--src/contact-editor/editor/addresseditor/autotests/addresseslocationwidgettest.h39
-rw-r--r--src/contact-editor/editor/addresseditor/autotests/addresslocationwidgettest.cpp123
-rw-r--r--src/contact-editor/editor/addresseditor/autotests/addresslocationwidgettest.h40
-rw-r--r--src/contact-editor/editor/addresseditor/html/CMakeLists.txt1
-rw-r--r--src/contact-editor/editor/addresseditor/html/default/addresseslocation.css16
-rw-r--r--src/contact-editor/editor/addresseditor/html/default/addresseslocation.html29
-rw-r--r--src/contact-editor/editor/addresseditor/iconnamecache.cpp55
-rw-r--r--src/contact-editor/editor/addresseditor/iconnamecache_p.h54
-rw-r--r--src/contact-editor/editor/addresseditor/selectaddresstypecombobox.cpp112
-rw-r--r--src/contact-editor/editor/addresseditor/selectaddresstypecombobox.h74
-rw-r--r--src/contact-editor/editor/addresseditor/tests/CMakeLists.txt34
-rw-r--r--src/contact-editor/editor/addresseditor/tests/main.cpp35
-rw-r--r--src/contact-editor/editor/addresseditor/webengine/addresseslocationenginepage.cpp66
-rw-r--r--src/contact-editor/editor/addresseditor/webengine/addresseslocationenginepage.h44
-rw-r--r--src/contact-editor/editor/addresseditor/webengine/addresseslocationengineviewer.cpp145
-rw-r--r--src/contact-editor/editor/addresseditor/webengine/addresseslocationengineviewer.h61
-rw-r--r--src/contact-editor/editor/businesseditor/businesseditorwidget.cpp179
-rw-r--r--src/contact-editor/editor/businesseditor/businesseditorwidget.h59
-rw-r--r--src/contact-editor/editor/businesseditor/freebusyeditwidget.cpp81
-rw-r--r--src/contact-editor/editor/businesseditor/freebusyeditwidget.h52
-rw-r--r--src/contact-editor/editor/contacteditorwidget.cpp287
-rw-r--r--src/contact-editor/editor/contacteditorwidget.h82
-rw-r--r--src/contact-editor/editor/customfieldeditor/autotests/CMakeLists.txt20
-rw-r--r--src/contact-editor/editor/customfieldeditor/autotests/customfieldeditorwidgettest.cpp91
-rw-r--r--src/contact-editor/editor/customfieldeditor/autotests/customfieldeditorwidgettest.h41
-rw-r--r--src/contact-editor/editor/customfieldeditor/autotests/customfieldslistwidgettest.cpp35
-rw-r--r--src/contact-editor/editor/customfieldeditor/autotests/customfieldslistwidgettest.h35
-rw-r--r--src/contact-editor/editor/customfieldeditor/autotests/customfieldswidgettest.cpp50
-rw-r--r--src/contact-editor/editor/customfieldeditor/autotests/customfieldswidgettest.h38
-rw-r--r--src/contact-editor/editor/customfieldeditor/customfieldeditorwidget.cpp125
-rw-r--r--src/contact-editor/editor/customfieldeditor/customfieldeditorwidget.h55
-rw-r--r--src/contact-editor/editor/customfieldeditor/customfieldslistdelegate.cpp242
-rw-r--r--src/contact-editor/editor/customfieldeditor/customfieldslistdelegate.h52
-rw-r--r--src/contact-editor/editor/customfieldeditor/customfieldslistwidget.cpp236
-rw-r--r--src/contact-editor/editor/customfieldeditor/customfieldslistwidget.h57
-rw-r--r--src/contact-editor/editor/customfieldeditor/customfieldsmodel.cpp284
-rw-r--r--src/contact-editor/editor/customfieldeditor/customfieldsmodel.h60
-rw-r--r--src/contact-editor/editor/customfieldeditor/customfieldswidget.cpp75
-rw-r--r--src/contact-editor/editor/customfieldeditor/customfieldswidget.h55
-rw-r--r--src/contact-editor/editor/customfieldeditor/tests/CMakeLists.txt24
-rw-r--r--src/contact-editor/editor/customfieldeditor/tests/main.cpp32
-rw-r--r--src/contact-editor/editor/data/zone.tab434
-rw-r--r--src/contact-editor/editor/generalinfoeditor/akonadicontactselecttypecombobox.cpp55
-rw-r--r--src/contact-editor/editor/generalinfoeditor/akonadicontactselecttypecombobox.h45
-rw-r--r--src/contact-editor/editor/generalinfoeditor/autotests/CMakeLists.txt40
-rw-r--r--src/contact-editor/editor/generalinfoeditor/autotests/akonadicontactselecttypecomboboxtest.cpp44
-rw-r--r--src/contact-editor/editor/generalinfoeditor/autotests/akonadicontactselecttypecomboboxtest.h37
-rw-r--r--src/contact-editor/editor/generalinfoeditor/autotests/mailwidgettest.cpp57
-rw-r--r--src/contact-editor/editor/generalinfoeditor/autotests/mailwidgettest.h37
-rw-r--r--src/contact-editor/editor/generalinfoeditor/autotests/messageformattingwidgettest.cpp54
-rw-r--r--src/contact-editor/editor/generalinfoeditor/autotests/messageformattingwidgettest.h37
-rw-r--r--src/contact-editor/editor/generalinfoeditor/autotests/messagingwidgettest.cpp56
-rw-r--r--src/contact-editor/editor/generalinfoeditor/autotests/messagingwidgettest.h37
-rw-r--r--src/contact-editor/editor/generalinfoeditor/autotests/nicknamewidgettest.cpp33
-rw-r--r--src/contact-editor/editor/generalinfoeditor/autotests/nicknamewidgettest.h36
-rw-r--r--src/contact-editor/editor/generalinfoeditor/autotests/phonewidgettest.cpp56
-rw-r--r--src/contact-editor/editor/generalinfoeditor/autotests/phonewidgettest.h37
-rw-r--r--src/contact-editor/editor/generalinfoeditor/categorieseditwidget.cpp73
-rw-r--r--src/contact-editor/editor/generalinfoeditor/categorieseditwidget.h54
-rw-r--r--src/contact-editor/editor/generalinfoeditor/displaynameeditwidget.cpp258
-rw-r--r--src/contact-editor/editor/generalinfoeditor/displaynameeditwidget.h84
-rw-r--r--src/contact-editor/editor/generalinfoeditor/generalinfowidget.cpp154
-rw-r--r--src/contact-editor/editor/generalinfoeditor/generalinfowidget.h70
-rw-r--r--src/contact-editor/editor/generalinfoeditor/mail/maillistwidget.cpp65
-rw-r--r--src/contact-editor/editor/generalinfoeditor/mail/maillistwidget.h47
-rw-r--r--src/contact-editor/editor/generalinfoeditor/mail/mailwidget.cpp150
-rw-r--r--src/contact-editor/editor/generalinfoeditor/mail/mailwidget.h63
-rw-r--r--src/contact-editor/editor/generalinfoeditor/mail/mailwidgetlister.cpp129
-rw-r--r--src/contact-editor/editor/generalinfoeditor/mail/mailwidgetlister.h57
-rw-r--r--src/contact-editor/editor/generalinfoeditor/messageformattingwidget.cpp100
-rw-r--r--src/contact-editor/editor/generalinfoeditor/messageformattingwidget.h48
-rw-r--r--src/contact-editor/editor/generalinfoeditor/messaging/messaginglistwidget.cpp65
-rw-r--r--src/contact-editor/editor/generalinfoeditor/messaging/messaginglistwidget.h49
-rw-r--r--src/contact-editor/editor/generalinfoeditor/messaging/messagingwidget.cpp123
-rw-r--r--src/contact-editor/editor/generalinfoeditor/messaging/messagingwidget.h63
-rw-r--r--src/contact-editor/editor/generalinfoeditor/messaging/messagingwidgetlister.cpp173
-rw-r--r--src/contact-editor/editor/generalinfoeditor/messaging/messagingwidgetlister.h56
-rw-r--r--src/contact-editor/editor/generalinfoeditor/nameeditdialog.cpp180
-rw-r--r--src/contact-editor/editor/generalinfoeditor/nameeditdialog.h68
-rw-r--r--src/contact-editor/editor/generalinfoeditor/namewidget.cpp127
-rw-r--r--src/contact-editor/editor/generalinfoeditor/namewidget.h60
-rw-r--r--src/contact-editor/editor/generalinfoeditor/nicknamewidget.cpp65
-rw-r--r--src/contact-editor/editor/generalinfoeditor/nicknamewidget.h47
-rw-r--r--src/contact-editor/editor/generalinfoeditor/phone/phonecomboboxtype.cpp118
-rw-r--r--src/contact-editor/editor/generalinfoeditor/phone/phonecomboboxtype.h73
-rw-r--r--src/contact-editor/editor/generalinfoeditor/phone/phonelistwidget.cpp65
-rw-r--r--src/contact-editor/editor/generalinfoeditor/phone/phonelistwidget.h48
-rw-r--r--src/contact-editor/editor/generalinfoeditor/phone/phonetypedialog.cpp86
-rw-r--r--src/contact-editor/editor/generalinfoeditor/phone/phonetypedialog.h58
-rw-r--r--src/contact-editor/editor/generalinfoeditor/phone/phonewidget.cpp119
-rw-r--r--src/contact-editor/editor/generalinfoeditor/phone/phonewidget.h66
-rw-r--r--src/contact-editor/editor/generalinfoeditor/phone/phonewidgetlister.cpp129
-rw-r--r--src/contact-editor/editor/generalinfoeditor/phone/phonewidgetlister.h58
-rw-r--r--src/contact-editor/editor/generalinfoeditor/tests/CMakeLists.txt44
-rw-r--r--src/contact-editor/editor/generalinfoeditor/tests/main.cpp33
-rw-r--r--src/contact-editor/editor/generalinfoeditor/web/weblistwidget.cpp66
-rw-r--r--src/contact-editor/editor/generalinfoeditor/web/weblistwidget.h48
-rw-r--r--src/contact-editor/editor/generalinfoeditor/web/webwidget.cpp162
-rw-r--r--src/contact-editor/editor/generalinfoeditor/web/webwidget.h66
-rw-r--r--src/contact-editor/editor/generalinfoeditor/web/webwidgetlister.cpp131
-rw-r--r--src/contact-editor/editor/generalinfoeditor/web/webwidgetlister.h56
-rw-r--r--src/contact-editor/editor/im/CMakeLists.txt3
-rw-r--r--src/contact-editor/editor/im/imaddress.cpp64
-rw-r--r--src/contact-editor/editor/im/imaddress.h52
-rw-r--r--src/contact-editor/editor/im/improtocols.cpp115
-rw-r--r--src/contact-editor/editor/im/improtocols.h70
-rw-r--r--src/contact-editor/editor/im/kaddressbookimprotocol.desktop55
-rw-r--r--src/contact-editor/editor/im/protocols/CMakeLists.txt16
-rw-r--r--src/contact-editor/editor/im/protocols/aimprotocol.desktop109
-rw-r--r--src/contact-editor/editor/im/protocols/facebookprotocol.desktop68
-rw-r--r--src/contact-editor/editor/im/protocols/gaduprotocol.desktop108
-rw-r--r--src/contact-editor/editor/im/protocols/googletalkprotocol.desktop90
-rw-r--r--src/contact-editor/editor/im/protocols/groupwiseprotocol.desktop107
-rw-r--r--src/contact-editor/editor/im/protocols/icqprotocol.desktop107
-rw-r--r--src/contact-editor/editor/im/protocols/ircprotocol.desktop106
-rw-r--r--src/contact-editor/editor/im/protocols/jabberprotocol.desktop108
-rw-r--r--src/contact-editor/editor/im/protocols/meanwhileprotocol.desktop105
-rw-r--r--src/contact-editor/editor/im/protocols/msnprotocol.desktop107
-rw-r--r--src/contact-editor/editor/im/protocols/skypeprotocol.desktop105
-rw-r--r--src/contact-editor/editor/im/protocols/smsprotocol.desktop106
-rw-r--r--src/contact-editor/editor/im/protocols/twitterprotocol.desktop69
-rw-r--r--src/contact-editor/editor/im/protocols/yahooprotocol.desktop108
-rw-r--r--src/contact-editor/editor/personaleditor/dateeditwidget.cpp149
-rw-r--r--src/contact-editor/editor/personaleditor/dateeditwidget.h84
-rw-r--r--src/contact-editor/editor/personaleditor/kdatepickerpopup.cpp150
-rw-r--r--src/contact-editor/editor/personaleditor/kdatepickerpopup_p.h113
-rw-r--r--src/contact-editor/editor/personaleditor/personaleditorwidget.cpp100
-rw-r--r--src/contact-editor/editor/personaleditor/personaleditorwidget.h50
-rw-r--r--src/contact-editor/editor/pics/world.jpgbin0 -> 28526 bytes
-rw-r--r--src/contact-editor/editor/utils/utils.cpp53
-rw-r--r--src/contact-editor/editor/utils/utils.h40
-rw-r--r--src/contact-editor/editor/widgets/akonadicontactcombobox.cpp40
-rw-r--r--src/contact-editor/editor/widgets/akonadicontactcombobox.h40
-rw-r--r--src/contact-editor/editor/widgets/autotests/CMakeLists.txt5
-rw-r--r--src/contact-editor/editor/widgets/autotests/preferredlineeditwidgettest.cpp64
-rw-r--r--src/contact-editor/editor/widgets/autotests/preferredlineeditwidgettest.h39
-rw-r--r--src/contact-editor/editor/widgets/imagewidget.cpp356
-rw-r--r--src/contact-editor/editor/widgets/imagewidget.h84
-rw-r--r--src/contact-editor/editor/widgets/kwidgetlister.cpp225
-rw-r--r--src/contact-editor/editor/widgets/kwidgetlister_p.h212
-rw-r--r--src/contact-editor/editor/widgets/preferredlineeditwidget.cpp74
-rw-r--r--src/contact-editor/editor/widgets/preferredlineeditwidget.h55
171 files changed, 14152 insertions, 118 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index fff125d..e162574 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.0)
-set(PIM_VERSION "5.5.41")
+set(PIM_VERSION "5.5.42")
project(Akonadi-Contact VERSION ${PIM_VERSION})
diff --git a/src/akonadi-contacts/CMakeLists.txt b/src/akonadi-contacts/CMakeLists.txt
index 0e44d30..ed6430e 100644
--- a/src/akonadi-contacts/CMakeLists.txt
+++ b/src/akonadi-contacts/CMakeLists.txt
@@ -27,13 +27,10 @@ install(FILES
COMPONENT Devel
)
-install(EXPORT KF5AkonadiContactTargets DESTINATION "${CMAKECONFIG_INSTALL_DIR}" FILE KF5AkonadiContactTargets.cmake NAMESPACE KF5::)
-
set( AKONADI_PHONE_DIAL_DEFAULT "UseSkype" )
set( AKONADI_SEND_SMS_DEFAULT "UseSkypeSms" )
-add_subdirectory(editor/im)
########### next target ###############
set(akonadicontact_actions_SRCS
@@ -52,101 +49,6 @@ configure_file(config-akonadi-contact.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config
configure_file( actions/contactactionssettings.kcfg.cmake ${CMAKE_CURRENT_BINARY_DIR}/contactactionssettings.kcfg @ONLY)
kconfig_add_kcfg_files(akonadicontact_actions_SRCS actions/contactactionssettings.kcfgc)
-set(akonadicontact_customfieldseditor_SRCS
- editor/customfieldeditor/customfieldswidget.cpp
- editor/customfieldeditor/customfieldeditorwidget.cpp
- editor/customfieldeditor/customfieldslistwidget.cpp
- editor/customfieldeditor/customfieldslistdelegate.cpp
- editor/customfieldeditor/customfieldsmodel.cpp
- )
-
-set(akonadicontact_editor_utils_SRCS
- editor/utils/utils.cpp
- )
-
-set(akonadicontact_editor_widgets_SRCS
- editor/widgets/kwidgetlister.cpp
- editor/widgets/akonadicontactcombobox.cpp
- )
-
-set(akonadicontact_editor_generalinfo_phone_SRCS
- editor/generalinfoeditor/phone/phonewidgetlister.cpp
- editor/generalinfoeditor/phone/phonewidget.cpp
- editor/generalinfoeditor/phone/phonelistwidget.cpp
- editor/generalinfoeditor/phone/phonecomboboxtype.cpp
- editor/generalinfoeditor/phone/phonetypedialog.cpp
- )
-
-set(akonadicontact_editor_generalinfo_web_SRCS
- editor/generalinfoeditor/web/webwidgetlister.cpp
- editor/generalinfoeditor/web/weblistwidget.cpp
- editor/generalinfoeditor/web/webwidget.cpp
- )
-set(akonadicontact_editor_generalinfo_mail_SRCS
- editor/generalinfoeditor/mail/maillistwidget.cpp
- editor/generalinfoeditor/mail/mailwidget.cpp
- editor/generalinfoeditor/mail/mailwidgetlister.cpp
- )
-
-set(akonadicontact_editor_generalinfo_messaging_SRCS
- editor/generalinfoeditor/messaging/messaginglistwidget.cpp
- editor/generalinfoeditor/messaging/messagingwidget.cpp
- editor/generalinfoeditor/messaging/messagingwidgetlister.cpp
- )
-
-
-set(akonadicontact_editor_generalinfo_SRCS
- editor/generalinfoeditor/generalinfowidget.cpp
- editor/generalinfoeditor/namewidget.cpp
- editor/generalinfoeditor/nicknamewidget.cpp
- editor/generalinfoeditor/categorieseditwidget.cpp
- editor/generalinfoeditor/nameeditdialog.cpp
- editor/generalinfoeditor/displaynameeditwidget.cpp
- editor/generalinfoeditor/akonadicontactselecttypecombobox.cpp
- editor/generalinfoeditor/messageformattingwidget.cpp
- ${akonadicontact_editor_generalinfo_messaging_SRCS}
- ${akonadicontact_editor_generalinfo_phone_SRCS}
- ${akonadicontact_editor_generalinfo_web_SRCS}
- ${akonadicontact_editor_generalinfo_mail_SRCS}
- )
-
-set(akonadicontact_addresslocation_web_editor_SRCS
- editor/addresseditor/webengine/addresseslocationengineviewer.cpp
- editor/addresseditor/webengine/addresseslocationenginepage.cpp
- )
-
-set(akonadicontact_addresslocation_editor_SRCS
- ${akonadicontact_addresslocation_web_editor_SRCS}
- editor/addresseditor/addresslocationwidget.cpp
- editor/addresseditor/addresseslocationgrantleeformater.cpp
- editor/addresseditor/addressgrantleeobject.cpp
- editor/addresseditor/iconnamecache.cpp
- editor/addresseditor/addresseslocationwidget.cpp
- editor/addresseditor/selectaddresstypecombobox.cpp
- editor/addresseditor/addresstypedialog.cpp
- )
-
-set(akonadicontact_personal_editor_SRCS
- editor/personaleditor/personaleditorwidget.cpp
- editor/personaleditor/dateeditwidget.cpp
- editor/personaleditor/kdatepickerpopup.cpp
- )
-
-set(akonadicontact_business_editor_SRCS
- editor/businesseditor/businesseditorwidget.cpp
- editor/businesseditor/freebusyeditwidget.cpp
- )
-
-set(akonadicontact_editor_SRCS
- ${akonadicontact_personal_editor_SRCS}
- ${akonadicontact_editor_utils_SRCS}
- ${akonadicontact_business_editor_SRCS}
- editor/contacteditorwidget.cpp
- editor/im/imaddress.cpp
- editor/im/improtocols.cpp
- editor/widgets/imagewidget.cpp
- editor/widgets/preferredlineeditwidget.cpp
- )
set(akonadicontact_attributes_SRCS
attributes/contactmetadataattribute.cpp
@@ -160,9 +62,6 @@ set(akonadicontact_job_SRCS
)
set(akonadicontact_LIB_SRC
- ${akonadicontact_addresslocation_editor_SRCS}
- ${akonadicontact_editor_widgets_SRCS}
- ${akonadicontact_editor_generalinfo_SRCS}
${akonadicontact_customfieldseditor_SRCS}
${akonadicontact_attributes_SRCS}
${akonadicontact_job_SRCS}
@@ -180,14 +79,11 @@ set(akonadicontact_LIB_SRC
contactgroupviewer.cpp
contactgroupviewerdialog.cpp
contactmetadataakonadi.cpp
- contactmetadatabase.cpp
contactparts.cpp
contactsfilterproxymodel.cpp
contactstreemodel.cpp
contactviewer.cpp
contactviewerdialog.cpp
- customfields.cpp
- customfieldmanager.cpp
emailaddressselection.cpp
emailaddressselectiondialog.cpp
emailaddressselectionproxymodel.cpp
@@ -208,7 +104,6 @@ ecm_qt_declare_logging_category(akonadicontact_LIB_SRC HEADER akonadi_contact_de
set(akonadicontact_LIB_SRC
${akonadicontact_LIB_SRC}
- ${akonadicontact_editor_SRCS}
)
ki18n_wrap_ui(akonadicontact_LIB_SRC contactgroupeditor.ui)
@@ -247,6 +142,7 @@ target_link_libraries(KF5AkonadiContact
Grantlee5::Templates
Qt5::WebEngine
Qt5::WebEngineWidgets
+ KF5::ContactEditor
)
if(KF5Prison_FOUND)
@@ -332,21 +228,9 @@ install( FILES
DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5}/akonadi/contact COMPONENT Devel
)
-if (BUILD_TESTING)
- add_subdirectory(editor/addresseditor/autotests/)
- add_subdirectory(editor/addresseditor/tests)
- add_subdirectory(editor/generalinfoeditor/autotests/)
- add_subdirectory(editor/generalinfoeditor/tests)
- add_subdirectory(editor/customfieldeditor/autotests/)
- add_subdirectory(editor/customfieldeditor/tests)
- add_subdirectory(editor/widgets/autotests/)
-endif()
if (BUILD_TESTING)
add_subdirectory(autotests)
add_subdirectory(tests)
endif()
-
-add_subdirectory(editor/addresseditor/html)
-
diff --git a/src/contact-editor/CMakeLists.txt b/src/contact-editor/CMakeLists.txt
index e69de29..fe4aff6 100644
--- a/src/contact-editor/CMakeLists.txt
+++ b/src/contact-editor/CMakeLists.txt
@@ -0,0 +1,250 @@
+add_definitions(-DTRANSLATION_DOMAIN=\"akonadicontact5\")
+set(CMAKECONFIG_INSTALL_DIR "${KDE_INSTALL_CMAKEPACKAGEDIR}/KF5ContactEditor")
+
+ecm_setup_version(PROJECT VARIABLE_PREFIX CONTACTEDITOR
+ VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/contact-editor_version.h"
+ PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/KF5ContactEditorConfigVersion.cmake"
+ SOVERSION 5
+ )
+configure_package_config_file(
+ "${CMAKE_CURRENT_SOURCE_DIR}/KF5ContactEditorConfig.cmake.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/KF5ContactEditorConfig.cmake"
+ INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR}
+ )
+install(FILES
+ "${CMAKE_CURRENT_BINARY_DIR}/KF5ContactEditorConfig.cmake"
+ "${CMAKE_CURRENT_BINARY_DIR}/KF5ContactEditorConfigVersion.cmake"
+ DESTINATION "${CMAKECONFIG_INSTALL_DIR}"
+ COMPONENT Devel
+ )
+
+install(EXPORT KF5ContactEditorTargets DESTINATION "${CMAKECONFIG_INSTALL_DIR}" FILE KF5ContactEditorTargets.cmake NAMESPACE KF5::)
+
+install(FILES
+ "${CMAKE_CURRENT_BINARY_DIR}/KF5ContactEditorConfig.cmake"
+ "${CMAKE_CURRENT_BINARY_DIR}/KF5ContactEditorConfigVersion.cmake"
+ DESTINATION "${CMAKECONFIG_INSTALL_DIR}"
+ COMPONENT Devel
+ )
+
+set( AKONADI_PHONE_DIAL_DEFAULT "UseSkype" )
+set( AKONADI_SEND_SMS_DEFAULT "UseSkypeSms" )
+
+configure_file(config-contact-editor.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-contact-editor.h)
+
+add_subdirectory(editor/im)
+
+set(contacteditor_customfieldseditor_SRCS
+ editor/customfieldeditor/customfieldswidget.cpp
+ editor/customfieldeditor/customfieldeditorwidget.cpp
+ editor/customfieldeditor/customfieldslistwidget.cpp
+ editor/customfieldeditor/customfieldslistdelegate.cpp
+ editor/customfieldeditor/customfieldsmodel.cpp
+ )
+
+set(contacteditor_editor_utils_SRCS
+ editor/utils/utils.cpp
+ )
+
+set(contacteditor_editor_widgets_SRCS
+ editor/widgets/kwidgetlister.cpp
+ editor/widgets/akonadicontactcombobox.cpp
+ )
+
+set(contacteditor_editor_generalinfo_phone_SRCS
+ editor/generalinfoeditor/phone/phonewidgetlister.cpp
+ editor/generalinfoeditor/phone/phonewidget.cpp
+ editor/generalinfoeditor/phone/phonelistwidget.cpp
+ editor/generalinfoeditor/phone/phonecomboboxtype.cpp
+ editor/generalinfoeditor/phone/phonetypedialog.cpp
+ )
+
+set(contacteditor_editor_generalinfo_web_SRCS
+ editor/generalinfoeditor/web/webwidgetlister.cpp
+ editor/generalinfoeditor/web/weblistwidget.cpp
+ editor/generalinfoeditor/web/webwidget.cpp
+ )
+set(contacteditor_editor_generalinfo_mail_SRCS
+ editor/generalinfoeditor/mail/maillistwidget.cpp
+ editor/generalinfoeditor/mail/mailwidget.cpp
+ editor/generalinfoeditor/mail/mailwidgetlister.cpp
+ )
+
+set(contacteditor_editor_generalinfo_messaging_SRCS
+ editor/generalinfoeditor/messaging/messaginglistwidget.cpp
+ editor/generalinfoeditor/messaging/messagingwidget.cpp
+ editor/generalinfoeditor/messaging/messagingwidgetlister.cpp
+ )
+
+
+set(contacteditor_editor_generalinfo_SRCS
+ editor/generalinfoeditor/generalinfowidget.cpp
+ editor/generalinfoeditor/namewidget.cpp
+ editor/generalinfoeditor/nicknamewidget.cpp
+ editor/generalinfoeditor/categorieseditwidget.cpp
+ editor/generalinfoeditor/nameeditdialog.cpp
+ editor/generalinfoeditor/displaynameeditwidget.cpp
+ editor/generalinfoeditor/akonadicontactselecttypecombobox.cpp
+ editor/generalinfoeditor/messageformattingwidget.cpp
+ ${contacteditor_editor_generalinfo_messaging_SRCS}
+ ${contacteditor_editor_generalinfo_phone_SRCS}
+ ${contacteditor_editor_generalinfo_web_SRCS}
+ ${contacteditor_editor_generalinfo_mail_SRCS}
+ )
+
+set(contacteditor_addresslocation_web_editor_SRCS
+ editor/addresseditor/webengine/addresseslocationengineviewer.cpp
+ editor/addresseditor/webengine/addresseslocationenginepage.cpp
+ )
+
+set(contacteditor_addresslocation_editor_SRCS
+ ${contacteditor_addresslocation_web_editor_SRCS}
+ editor/addresseditor/addresslocationwidget.cpp
+ editor/addresseditor/addresseslocationgrantleeformater.cpp
+ editor/addresseditor/addressgrantleeobject.cpp
+ editor/addresseditor/iconnamecache.cpp
+ editor/addresseditor/addresseslocationwidget.cpp
+ editor/addresseditor/selectaddresstypecombobox.cpp
+ editor/addresseditor/addresstypedialog.cpp
+ )
+
+set(contacteditor_personal_editor_SRCS
+ editor/personaleditor/personaleditorwidget.cpp
+ editor/personaleditor/dateeditwidget.cpp
+ editor/personaleditor/kdatepickerpopup.cpp
+ )
+
+set(contacteditor_business_editor_SRCS
+ editor/businesseditor/businesseditorwidget.cpp
+ editor/businesseditor/freebusyeditwidget.cpp
+ )
+
+set(contacteditor_editor_SRCS
+ ${contacteditor_personal_editor_SRCS}
+ ${contacteditor_editor_utils_SRCS}
+ ${contacteditor_business_editor_SRCS}
+ editor/contacteditorwidget.cpp
+ editor/im/imaddress.cpp
+ editor/im/improtocols.cpp
+ editor/widgets/imagewidget.cpp
+ editor/widgets/preferredlineeditwidget.cpp
+ customfields.cpp
+ customfieldmanager.cpp
+ contactmetadatabase.cpp
+)
+
+set(contacteditor_LIB_SRC
+ ${contacteditor_addresslocation_editor_SRCS}
+ ${contacteditor_editor_widgets_SRCS}
+ ${contacteditor_editor_generalinfo_SRCS}
+ ${contacteditor_customfieldseditor_SRCS}
+ ${contacteditor_attributes_SRCS}
+ ${contacteditor_job_SRCS}
+ )
+
+ecm_qt_declare_logging_category(contacteditor_LIB_SRC HEADER akonadi_contact_debug.h IDENTIFIER AKONADICONTACT_LOG CATEGORY_NAME org.kde.pim.akonadicontact)
+
+set(contacteditor_LIB_SRC
+ ${contacteditor_LIB_SRC}
+ ${contacteditor_editor_SRCS}
+ )
+
+
+
+add_library(KF5ContactEditor ${contacteditor_LIB_SRC})
+
+generate_export_header(KF5ContactEditor BASE_NAME contacteditor)
+
+add_library(KF5::ContactEditor ALIAS KF5ContactEditor)
+
+target_include_directories(KF5ContactEditor INTERFACE "$<INSTALL_INTERFACE:${KDE_INSTALL_INCLUDEDIR_KF5}/ContactEditor;${KDE_INSTALL_INCLUDEDIR_KF5}>")
+target_include_directories(KF5ContactEditor INTERFACE "$<INSTALL_INTERFACE:${KDE_INSTALL_INCLUDEDIR_KF5}/contacteditor>")
+target_include_directories(KF5ContactEditor PUBLIC "$<BUILD_INTERFACE:${Akonadi-Contact_SOURCE_DIR}/src/contact-editor;${Akonadi-Contact_BINARY_DIR}/src/contact-editor>")
+
+target_link_libraries(KF5ContactEditor
+ PUBLIC
+ KF5::AkonadiCore
+ KF5::Contacts
+ KF5::AkonadiWidgets
+ Qt5::Widgets
+ PRIVATE
+ KF5::Completion
+ KF5::ConfigCore
+ KF5::ConfigWidgets
+ KF5::IconThemes
+ KF5::KIOWidgets
+ KF5::Mime
+ KF5::Codecs
+ KF5::DBusAddons
+ KF5::I18n
+ KF5::Service
+ KF5::TextWidgets
+ KF5::WidgetsAddons
+ KF5::XmlGui
+ Grantlee5::Templates
+ Qt5::WebEngine
+ Qt5::WebEngineWidgets
+ )
+
+if(KF5Prison_FOUND)
+ target_link_libraries(KF5ContactEditor PRIVATE KF5::Prison)
+endif()
+
+
+set_target_properties(KF5ContactEditor PROPERTIES
+ VERSION ${AKONADICONTACT_VERSION_STRING}
+ SOVERSION ${AKONADICONTACT_SOVERSION}
+ EXPORT_NAME ContactEditor
+ )
+
+install(TARGETS
+ KF5ContactEditor
+ EXPORT KF5ContactEditorTargets ${KF5_INSTALL_TARGETS_DEFAULT_ARGS}
+ )
+
+ecm_generate_pri_file(BASE_NAME ContactEditor
+ LIB_NAME KF5ContactEditor
+ DEPS "AkonadiCore Contacts" FILENAME_VAR PRI_FILENAME INCLUDE_INSTALL_DIR ${KDE_INSTALL_INCLUDEDIR_KF5}/Akonadi/Contact
+ )
+
+install(FILES ${PRI_FILENAME} DESTINATION ${ECM_MKSPECS_INSTALL_DIR})
+
+ecm_generate_headers(ContactEditor_CamelCase_HEADERS
+ HEADER_NAMES
+ ContactEditorPagePlugin
+ REQUIRED_HEADERS ContactEditor_HEADERS
+ PREFIX ContactEditor
+ )
+
+install( FILES
+ ${ContactEditor_CamelCase_HEADERS}
+ DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5}/ContactEditor COMPONENT Devel
+ )
+
+install( FILES
+ ${ContactEditor_HEADERS}
+ ${CMAKE_CURRENT_BINARY_DIR}/contacteditor_export.h
+ editor/im/improtocols.h
+ DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5}/contacteditor COMPONENT Devel
+ )
+
+
+
+install( FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/akonadi-contact_export.h
+ DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5}/akonadi/contact COMPONENT Devel
+ )
+
+if (BUILD_TESTING)
+ add_subdirectory(editor/addresseditor/autotests/)
+ add_subdirectory(editor/addresseditor/tests)
+ add_subdirectory(editor/generalinfoeditor/autotests/)
+ add_subdirectory(editor/generalinfoeditor/tests)
+ #Laurent reactivate it
+ #add_subdirectory(editor/customfieldeditor/autotests/)
+ #add_subdirectory(editor/customfieldeditor/tests)
+ add_subdirectory(editor/widgets/autotests/)
+endif()
+
+add_subdirectory(editor/addresseditor/html)
+
diff --git a/src/contact-editor/KF5ContactEditorConfig.cmake.in b/src/contact-editor/KF5ContactEditorConfig.cmake.in
new file mode 100644
index 0000000..dfe888f
--- /dev/null
+++ b/src/contact-editor/KF5ContactEditorConfig.cmake.in
@@ -0,0 +1,7 @@
+include(CMakeFindDependencyMacro)
+find_dependency(KF5Akonadi "@[email protected]")
+find_dependency(KF5Contacts "@[email protected]")
+
+
+include("${CMAKE_CURRENT_LIST_DIR}/KF5ContactEditorTargets.cmake")
diff --git a/src/contact-editor/abstractcontacteditorwidget_p.h b/src/contact-editor/abstractcontacteditorwidget_p.h
new file mode 100644
index 0000000..28df363
--- /dev/null
+++ b/src/contact-editor/abstractcontacteditorwidget_p.h
@@ -0,0 +1,75 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (c) 2009 Tobias Koenig <[email protected]>
+
+ 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 AKONADI_ABSTRACTCONTACTEDITORWIDGET_P_H
+#define AKONADI_ABSTRACTCONTACTEDITORWIDGET_P_H
+
+#include <QWidget>
+
+namespace KContacts
+{
+class Addressee;
+}
+
+namespace Akonadi
+{
+
+class ContactMetaDataBase;
+
+class AbstractContactEditorWidget : public QWidget
+{
+public:
+ /**
+ * Creates a new abstract contact editor widget.
+ *
+ * @param parent The parent widget.
+ */
+ explicit AbstractContactEditorWidget(QWidget *parent = nullptr)
+ : QWidget(parent)
+ {
+ }
+
+ /**
+ * Destroys the abstract contact editor widget.
+ */
+ ~AbstractContactEditorWidget()
+ {
+ }
+
+ /**
+ * @param contact loads the given contact into the editor widget
+ */
+ virtual void loadContact(const KContacts::Addressee &contact, const Akonadi::ContactMetaDataBase &metaData) = 0;
+
+ /**
+ * @param contact store the given contact into the editor widget
+ */
+ virtual void storeContact(KContacts::Addressee &contact, Akonadi::ContactMetaDataBase &metaData) const = 0;
+
+ /**
+ * @param readOnly set read-only mode
+ */
+ virtual void setReadOnly(bool readOnly) = 0;
+};
+
+}
+
+#endif
diff --git a/src/contact-editor/autoqpointer_p.h b/src/contact-editor/autoqpointer_p.h
new file mode 100644
index 0000000..6a371a6
--- /dev/null
+++ b/src/contact-editor/autoqpointer_p.h
@@ -0,0 +1,65 @@
+/*
+ * autoqpointer.h - QPointer which on destruction deletes object
+ * This is a (mostly) verbatim, private copy of kdepim/kalarm/lib/autoqpointer.h
+ *
+ * Copyright © 2009 by David Jarvie <[email protected]>
+ *
+ * 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 AUTOQPOINTER_H
+#define AUTOQPOINTER_H
+
+#include <QPointer>
+
+/**
+ * A QPointer which when destructed, deletes the object it points to.
+ *
+ * @author David Jarvie <[email protected]>
+ */
+template <class T>
+class AutoQPointer : public QPointer<T>
+{
+public:
+ inline AutoQPointer()
+ : QPointer<T>()
+ {
+ }
+ inline AutoQPointer(T *p)
+ : QPointer<T>(p)
+ {
+ }
+ inline AutoQPointer(const QPointer<T> &p)
+ : QPointer<T>(p)
+ {
+ }
+ inline ~AutoQPointer()
+ {
+ delete this->data();
+ }
+ inline AutoQPointer<T> &operator=(const AutoQPointer<T> &p)
+ {
+ QPointer<T>::operator=(p);
+ return *this;
+ }
+ inline AutoQPointer<T> &operator=(T *p)
+ {
+ QPointer<T>::operator=(p);
+ return *this;
+ }
+};
+
+#endif // AUTOQPOINTER_H
diff --git a/src/contact-editor/config-contact-editor.h.cmake b/src/contact-editor/config-contact-editor.h.cmake
new file mode 100644
index 0000000..1b213de
--- /dev/null
+++ b/src/contact-editor/config-contact-editor.h.cmake
@@ -0,0 +1 @@
+#define AKONADI_CONTACT_LIB "${KDE_INSTALL_FULL_LIBDIR}"
diff --git a/src/contact-editor/contacteditor_private_export.h b/src/contact-editor/contacteditor_private_export.h
new file mode 100644
index 0000000..9ee5be3
--- /dev/null
+++ b/src/contact-editor/contacteditor_private_export.h
@@ -0,0 +1,35 @@
+/* This file is part of the KDE project
+ Copyright (C) 2017 Laurent Montel <[email protected]>
+
+ 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 AKONADI_CONTACTSPRIVATE_EXPORT_H
+#define AKONADI_CONTACTSPRIVATE_EXPORT_H
+
+#include "akonadi-contact_export.h"
+
+/* Classes which are exported only for unit tests */
+#ifdef BUILD_TESTING
+# ifndef AKONADI_CONTACTS_TESTS_EXPORT
+# define AKONADI_CONTACTS_TESTS_EXPORT AKONADI_CONTACT_EXPORT
+# endif
+#else /* not compiling tests */
+# define AKONADI_CONTACTS_TESTS_EXPORT
+#endif
+
+#endif
+
diff --git a/src/contact-editor/contacteditorpageplugin.h b/src/contact-editor/contacteditorpageplugin.h
new file mode 100644
index 0000000..a3a6f73
--- /dev/null
+++ b/src/contact-editor/contacteditorpageplugin.h
@@ -0,0 +1,69 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (c) 2009 Tobias Koenig <[email protected]>
+
+ 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 AKONADI_CONTACTEDITORPAGEPLUGIN_H
+#define AKONADI_CONTACTEDITORPAGEPLUGIN_H
+
+#include <QWidget>
+
+namespace KContacts
+{
+class Addressee;
+}
+
+namespace Akonadi
+{
+
+/**
+ * @short The base class for custom ContactEditor page plugins.
+ *
+ * @author Tobias Koenig <[email protected]>
+ * @since 4.4
+ */
+class ContactEditorPagePlugin : public QWidget
+{
+public:
+ /**
+ * Returns the i18n'd page title.
+ */
+ virtual QString title() const = 0;
+
+ /**
+ * This method is called to fill the editor widget with the data from @p contact.
+ */
+ virtual void loadContact(const KContacts::Addressee &contact) = 0;
+
+ /**
+ * This method is called to store the data from the editor widget into @p contact.
+ */
+ virtual void storeContact(KContacts::Addressee &contact) const = 0;
+
+ /**
+ * This method is called to set the editor widget @p readOnly.
+ */
+ virtual void setReadOnly(bool readOnly) = 0;
+};
+
+}
+
+Q_DECLARE_INTERFACE(Akonadi::ContactEditorPagePlugin, "org.freedesktop.Akonadi.ContactEditorPagePlugin/1.0")
+
+#endif
diff --git a/src/contact-editor/contactmetadatabase.cpp b/src/contact-editor/contactmetadatabase.cpp
new file mode 100644
index 0000000..61f67ac
--- /dev/null
+++ b/src/contact-editor/contactmetadatabase.cpp
@@ -0,0 +1,86 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (c) 2017 Laurent Montel <[email protected]>
+
+ 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 "contactmetadatabase_p.h"
+
+using namespace Akonadi;
+
+class Q_DECL_HIDDEN ContactMetaDataBase::Private
+{
+public:
+ Private()
+ : mDisplayNameMode(-1)
+ {
+ }
+
+ int mDisplayNameMode;
+ QVariantList mCustomFieldDescriptions;
+};
+
+ContactMetaDataBase::ContactMetaDataBase()
+ : d(new Private)
+{
+}
+
+ContactMetaDataBase::~ContactMetaDataBase()
+{
+ delete d;
+}
+
+void ContactMetaDataBase::loadMetaData(const QVariantMap &metaData)
+{
+ d->mDisplayNameMode = metaData.value(QStringLiteral("DisplayNameMode"), -1).toInt();
+
+ d->mCustomFieldDescriptions = metaData.value(QStringLiteral("CustomFieldDescriptions")).toList();
+}
+
+QVariantMap ContactMetaDataBase::storeMetaData() const
+{
+ QVariantMap metaData;
+ if (d->mDisplayNameMode != -1) {
+ metaData.insert(QStringLiteral("DisplayNameMode"), QVariant(d->mDisplayNameMode));
+ }
+
+ if (!d->mCustomFieldDescriptions.isEmpty()) {
+ metaData.insert(QStringLiteral("CustomFieldDescriptions"), d->mCustomFieldDescriptions);
+ }
+ return metaData;
+}
+
+void ContactMetaDataBase::setDisplayNameMode(int mode)
+{
+ d->mDisplayNameMode = mode;
+}
+
+int ContactMetaDataBase::displayNameMode() const
+{
+ return d->mDisplayNameMode;
+}
+
+void ContactMetaDataBase::setCustomFieldDescriptions(const QVariantList &descriptions)
+{
+ d->mCustomFieldDescriptions = descriptions;
+}
+
+QVariantList ContactMetaDataBase::customFieldDescriptions() const
+{
+ return d->mCustomFieldDescriptions;
+}
diff --git a/src/contact-editor/contactmetadatabase_p.h b/src/contact-editor/contactmetadatabase_p.h
new file mode 100644
index 0000000..2338067
--- /dev/null
+++ b/src/contact-editor/contactmetadatabase_p.h
@@ -0,0 +1,106 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (c) 2017 Laurent Montel <[email protected]>
+
+ 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 AKONADI_CONTACTMETADATABASE_P_H
+#define AKONADI_CONTACTMETADATABASE_P_H
+
+#include "contacteditor_export.h"
+#include <QStringList>
+#include <QVariant>
+
+namespace Akonadi
+{
+
+
+/**
+ * @short A helper class for storing contact specific settings.
+ */
+class CONTACTEDITOR_EXPORT ContactMetaDataBase
+{
+public:
+ /**
+ * Creates a contact meta data object.
+ */
+ ContactMetaDataBase();
+
+ /**
+ * Destroys the contact meta data object.
+ */
+ ~ContactMetaDataBase();
+
+ /**
+ * Loads the meta data for the given @p contact.
+ */
+ void loadMetaData(const QVariantMap &metaData);
+
+ /**
+ * Stores the meta data to the given @p contact.
+ */
+ QVariantMap storeMetaData() const;
+
+
+ /**
+ * Sets the mode that is used for the display
+ * name of that contact.
+ */
+ void setDisplayNameMode(int mode);
+
+ /**
+ * Returns the mode that is used for the display
+ * name of that contact.
+ */
+ int displayNameMode() const;
+
+ /**
+ * Sets the @p descriptions of the custom fields of that contact.
+ * @param descriptions the descriptions to set
+ * The description list contains a QVariantMap for each custom field
+ * with the following keys:
+ * - key (string) The identifier of the field
+ * - title (string) The i18n'ed title of the field
+ * - type (string) The type description of the field
+ * Possible values for type description are
+ * - text
+ * - numeric
+ * - boolean
+ * - date
+ * - time
+ * - datetime
+ */
+ void setCustomFieldDescriptions(const QVariantList &descriptions);
+
+ /**
+ * Returns the descriptions of the custom fields of the contact.
+ */
+ QVariantList customFieldDescriptions() const;
+
+private:
+ //@cond PRIVATE
+ Q_DISABLE_COPY(ContactMetaDataBase)
+
+ class Private;
+ Private *const d;
+ //@endcond
+};
+
+}
+
+#endif
diff --git a/src/contact-editor/customfieldmanager.cpp b/src/contact-editor/customfieldmanager.cpp
new file mode 100644
index 0000000..80eba4f
--- /dev/null
+++ b/src/contact-editor/customfieldmanager.cpp
@@ -0,0 +1,68 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (c) 2010 Tobias Koenig <[email protected]>
+
+ 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 "customfieldmanager_p.h"
+
+#include <kconfig.h>
+#include <kconfiggroup.h>
+
+#include <QVector>
+
+void CustomFieldManager::setGlobalCustomFieldDescriptions(const CustomField::List &customFields)
+{
+ KConfig config(QStringLiteral("akonadi_contactrc"));
+ KConfigGroup group(&config, QStringLiteral("GlobalCustomFields"));
+
+ group.deleteGroup();
+ for (const CustomField &field : customFields) {
+ const QString key = field.key();
+ const QString value = CustomField::typeToString(field.type()) + QLatin1Char(':') + field.title();
+
+ group.writeEntry(key, value);
+ }
+}
+
+CustomField::List CustomFieldManager::globalCustomFieldDescriptions()
+{
+ KConfig config(QStringLiteral("akonadi_contactrc"));
+ const KConfigGroup group(&config, QStringLiteral("GlobalCustomFields"));
+
+ CustomField::List customFields;
+
+ const QStringList keys = group.keyList();
+ customFields.reserve(keys.count());
+ for (const QString &key : keys) {
+ CustomField field;
+ field.setKey(key);
+ field.setScope(CustomField::GlobalScope);
+
+ const QString value = group.readEntry(key, QString());
+ const int pos = value.indexOf(QLatin1Char(':'));
+ if (pos != -1) {
+ field.setType(CustomField::stringToType(value.left(pos - 1)));
+ field.setTitle(value.mid(pos + 1));
+ }
+
+ customFields << field;
+ }
+
+ return customFields;
+}
diff --git a/src/contact-editor/customfieldmanager_p.h b/src/contact-editor/customfieldmanager_p.h
new file mode 100644
index 0000000..bac5c9a
--- /dev/null
+++ b/src/contact-editor/customfieldmanager_p.h
@@ -0,0 +1,38 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (c) 2010 Tobias Koenig <[email protected]>
+
+ 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 CUSTOMFIELDMANAGER_P_H
+#define CUSTOMFIELDMANAGER_P_H
+
+#include "customfields_p.h"
+#include "contacteditor_export.h"
+
+/**
+ * @short A class that manages the descriptions of all custom fields with global scope.
+ */
+class CustomFieldManager
+{
+public:
+ CONTACTEDITOR_EXPORT static void setGlobalCustomFieldDescriptions(const CustomField::List &customFields);
+ CONTACTEDITOR_EXPORT static CustomField::List globalCustomFieldDescriptions();
+};
+
+#endif
diff --git a/src/contact-editor/customfields.cpp b/src/contact-editor/customfields.cpp
new file mode 100644
index 0000000..4645181
--- /dev/null
+++ b/src/contact-editor/customfields.cpp
@@ -0,0 +1,152 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (c) 2010 Tobias Koenig <[email protected]>
+
+ 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 "customfields_p.h"
+
+CustomField::CustomField()
+ : mType(TextType)
+ , mScope(LocalScope)
+{
+}
+
+CustomField::CustomField(const QString &key, const QString &title, Type type, Scope scope)
+ : mKey(key)
+ , mTitle(title)
+ , mType(type)
+ , mScope(scope)
+{
+}
+
+CustomField CustomField::fromVariantMap(const QVariantMap &map, Scope scope)
+{
+ return CustomField(map.value(QStringLiteral("key")).toString(),
+ map.value(QStringLiteral("title")).toString(),
+ stringToType(map.value(QStringLiteral("type")).toString()),
+ scope);
+}
+
+void CustomField::setKey(const QString &key)
+{
+ mKey = key;
+}
+
+QString CustomField::key() const
+{
+ return mKey;
+}
+
+void CustomField::setTitle(const QString &title)
+{
+ mTitle = title;
+}
+
+QString CustomField::title() const
+{
+ return mTitle;
+}
+
+void CustomField::setType(Type type)
+{
+ mType = type;
+}
+
+CustomField::Type CustomField::type() const
+{
+ return mType;
+}
+
+void CustomField::setScope(Scope scope)
+{
+ mScope = scope;
+}
+
+CustomField::Scope CustomField::scope() const
+{
+ return mScope;
+}
+
+void CustomField::setValue(const QString &value)
+{
+ mValue = value;
+}
+
+QString CustomField::value() const
+{
+ return mValue;
+}
+
+QVariantMap CustomField::toVariantMap() const
+{
+ QVariantMap map;
+ map.insert(QStringLiteral("key"), mKey);
+ map.insert(QStringLiteral("title"), mTitle);
+ map.insert(QStringLiteral("type"), typeToString(mType));
+
+ return map;
+}
+
+CustomField::Type CustomField::stringToType(const QString &type)
+{
+ if (type == QLatin1String("text")) {
+ return CustomField::TextType;
+ }
+ if (type == QLatin1String("numeric")) {
+ return CustomField::NumericType;
+ }
+ if (type == QLatin1String("boolean")) {
+ return CustomField::BooleanType;
+ }
+ if (type == QLatin1String("date")) {
+ return CustomField::DateType;
+ }
+ if (type == QLatin1String("time")) {
+ return CustomField::TimeType;
+ }
+ if (type == QLatin1String("datetime")) {
+ return CustomField::DateTimeType;
+ }
+ if (type == QLatin1String("url")) {
+ return CustomField::UrlType;
+ }
+
+ return CustomField::TextType;
+}
+
+QString CustomField::typeToString(CustomField::Type type)
+{
+ switch (type) {
+ case CustomField::TextType:
+ default:
+ return QStringLiteral("text");
+ case CustomField::NumericType:
+ return QStringLiteral("numeric");
+ case CustomField::BooleanType:
+ return QStringLiteral("boolean");
+ case CustomField::DateType:
+ return QStringLiteral("date");
+ case CustomField::TimeType:
+ return QStringLiteral("time");
+ case CustomField::DateTimeType:
+ return QStringLiteral("datetime");
+ case CustomField::UrlType:
+ return QStringLiteral("url");
+ }
+}
diff --git a/src/contact-editor/customfields_p.h b/src/contact-editor/customfields_p.h
new file mode 100644
index 0000000..24b00f8
--- /dev/null
+++ b/src/contact-editor/customfields_p.h
@@ -0,0 +1,102 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (c) 2010 Tobias Koenig <[email protected]>
+
+ 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 CUSTOMFIELDS_P_H
+#define CUSTOMFIELDS_P_H
+
+#include <QString>
+#include <QVariant>
+#include "contacteditor_export.h"
+
+template <typename T>
+class QVector;
+
+/**
+ * @short A class that represents non-standard contact fields.
+ *
+ * There exists three scopes of fields. To the local scope belong all
+ * custom fields that are defined by the user and that exists only for one
+ * contact. The description for these fields are stored inside ContactMetaData
+ * as custom attribute of the Akonadi item that represents the contact.
+ * To the global scope belong all custom fields that are defined by the user but
+ * shall be available in all contacts of the address book. Their description
+ * is stored by CustomFieldManager in $HOME/.kde/share/config/akonadi_contactrc.
+ * All other custom fields belong to the external scope, they come with import
+ * of contacts from other PIM applications (e.g. further X- entries in vCards).
+ * Their description is created on the fly when editing the custom fields.
+ *
+ * The description of a custom field covers the key, title and type.
+ */
+class CONTACTEDITOR_EXPORT CustomField
+{
+public:
+ typedef QVector<CustomField> List;
+
+ enum Type {
+ TextType,
+ NumericType,
+ BooleanType,
+ DateType,
+ TimeType,
+ DateTimeType,
+ UrlType
+ };
+
+ enum Scope {
+ LocalScope, ///< Field has been defined by user for one contact
+ GlobalScope, ///< Field has been defined by user for all contacts
+ ExternalScope ///< Field has been defined by the external data source (e.g. vCard)
+ };
+
+ CustomField();
+ CustomField(const QString &key, const QString &title, Type type, Scope scope);
+
+ static CustomField fromVariantMap(const QVariantMap &map, Scope scope);
+
+ void setKey(const QString &key);
+ QString key() const;
+
+ void setTitle(const QString &title);
+ QString title() const;
+
+ void setType(Type type);
+ Type type() const;
+
+ void setScope(Scope scope);
+ Scope scope() const;
+
+ void setValue(const QString &value);
+ QString value() const;
+
+ QVariantMap toVariantMap() const;
+
+ static QString typeToString(Type type);
+ static Type stringToType(const QString &type);
+
+private:
+ QString mKey;
+ QString mTitle;
+ Type mType;
+ Scope mScope;
+ QString mValue;
+};
+
+#endif
diff --git a/src/contact-editor/editor/addresseditor/addresseslocationgrantleeformater.cpp b/src/contact-editor/editor/addresseditor/addresseslocationgrantleeformater.cpp
new file mode 100644
index 0000000..3b25d26
--- /dev/null
+++ b/src/contact-editor/editor/addresseditor/addresseslocationgrantleeformater.cpp
@@ -0,0 +1,89 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "addresseslocationgrantleeformater.h"
+#include "addressgrantleeobject.h"
+#include <grantlee/engine.h>
+#include <QVariantList>
+#include <QStandardPaths>
+
+using namespace Akonadi;
+
+AddressesLocationGrantleeFormater::AddressesLocationGrantleeFormater(QObject *parent)
+ : QObject(parent),
+ mEngine(new Grantlee::Engine),
+ mReadOnly(false)
+{
+ mTemplateLoader = QSharedPointer<Grantlee::FileSystemTemplateLoader>(new Grantlee::FileSystemTemplateLoader);
+ mGrantleeThemePath = QStandardPaths::locate(QStandardPaths::GenericDataLocation,
+ QStringLiteral("akonadicontact/grantleetheme/default/"),
+ QStandardPaths::LocateDirectory);
+ changeGrantleePath(mGrantleeThemePath);
+}
+
+AddressesLocationGrantleeFormater::~AddressesLocationGrantleeFormater()
+{
+ delete mEngine;
+ mTemplateLoader.clear();
+}
+
+QString AddressesLocationGrantleeFormater::formatAddresses(const KContacts::Address::List &addresses)
+{
+ QVariantList addressList;
+ const int nbAddress(addresses.count());
+ addressList.reserve(nbAddress);
+ QList<AddressGrantleeObject *> lstAddress;
+ lstAddress.reserve(nbAddress);
+ for (int i = 0; i < nbAddress; ++i) {
+ AddressGrantleeObject *addressObj = new AddressGrantleeObject(addresses.at(i), i);
+ addressList << QVariant::fromValue(static_cast<QObject *>(addressObj));
+ lstAddress.append(addressObj);
+ }
+ QVariantHash addressHash;
+ addressHash.insert(QStringLiteral("addresses"), addressList);
+ addressHash.insert(QStringLiteral("absoluteThemePath"), mGrantleeThemePath);
+ addressHash.insert(QStringLiteral("readOnly"), mReadOnly);
+
+ Grantlee::Context context(addressHash);
+ const QString contentHtml = mSelfcontainedTemplate->render(&context);
+ qDeleteAll(lstAddress);
+ return contentHtml;
+}
+
+void AddressesLocationGrantleeFormater::setReadOnly(bool readOnly)
+{
+ mReadOnly = readOnly;
+}
+
+void AddressesLocationGrantleeFormater::changeGrantleePath(const QString &path)
+{
+ if (!mTemplateLoader) {
+ mTemplateLoader = QSharedPointer<Grantlee::FileSystemTemplateLoader>(new Grantlee::FileSystemTemplateLoader);
+ }
+ mTemplateLoader->setTemplateDirs(QStringList() << path);
+ mEngine->addTemplateLoader(mTemplateLoader);
+
+ mSelfcontainedTemplate = mEngine->loadByName(QStringLiteral("addresseslocation.html"));
+ if (mSelfcontainedTemplate->error()) {
+ mErrorMessage += mSelfcontainedTemplate->errorString() + QLatin1String("<br>");
+ }
+}
diff --git a/src/contact-editor/editor/addresseditor/addresseslocationgrantleeformater.h b/src/contact-editor/editor/addresseditor/addresseslocationgrantleeformater.h
new file mode 100644
index 0000000..1522968
--- /dev/null
+++ b/src/contact-editor/editor/addresseditor/addresseslocationgrantleeformater.h
@@ -0,0 +1,56 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 ADDRESSESLOCATIONGRANTLEEFORMATER_H
+#define ADDRESSESLOCATIONGRANTLEEFORMATER_H
+
+#include <QObject>
+
+#include <KContacts/Address>
+#include <QSharedPointer>
+#include <grantlee/templateloader.h>
+namespace Grantlee
+{
+class Engine;
+}
+namespace Akonadi
+{
+class AddressesLocationGrantleeFormater : public QObject
+{
+ Q_OBJECT
+public:
+ explicit AddressesLocationGrantleeFormater(QObject *parent = nullptr);
+ ~AddressesLocationGrantleeFormater();
+
+ QString formatAddresses(const KContacts::Address::List &addresses);
+ void setReadOnly(bool readOnly);
+private:
+ void changeGrantleePath(const QString &path);
+ Grantlee::Engine *mEngine;
+ QString mErrorMessage;
+ QString mGrantleeThemePath;
+ QSharedPointer<Grantlee::FileSystemTemplateLoader> mTemplateLoader;
+ Grantlee::Template mSelfcontainedTemplate;
+ bool mReadOnly;
+};
+}
+#endif // ADDRESSESLOCATIONGRANTLEEFORMATER_H
diff --git a/src/contact-editor/editor/addresseditor/addresseslocationwidget.cpp b/src/contact-editor/editor/addresseditor/addresseslocationwidget.cpp
new file mode 100644
index 0000000..a54d8af
--- /dev/null
+++ b/src/contact-editor/editor/addresseditor/addresseslocationwidget.cpp
@@ -0,0 +1,79 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "addresseslocationwidget.h"
+#include "webengine/addresseslocationengineviewer.h"
+#include "addresslocationwidget.h"
+using namespace Akonadi;
+
+AddressesLocationWidget::AddressesLocationWidget(QWidget *parent)
+ : QSplitter(parent)
+{
+ setChildrenCollapsible(false);
+ mAddressLocationWidget = new AddressLocationWidget(this);
+ mAddressLocationWidget->setObjectName(QStringLiteral("addresslocationwidget"));
+ addWidget(mAddressLocationWidget);
+ mAddressesLocationViewer = new AddressesLocationEngineViewer(this);
+ mAddressesLocationViewer->setObjectName(QStringLiteral("addresseslocationviewer"));
+ addWidget(mAddressesLocationViewer);
+ connect(mAddressesLocationViewer, &AddressesLocationEngineViewer::modifyAddress, mAddressLocationWidget, &AddressLocationWidget::slotModifyAddress);
+ connect(mAddressLocationWidget, &AddressLocationWidget::addNewAddress, mAddressesLocationViewer, &AddressesLocationEngineViewer::addAddress);
+ connect(mAddressLocationWidget, &AddressLocationWidget::updateAddressCanceled, mAddressesLocationViewer, &AddressesLocationEngineViewer::updateAddressCanceled);
+ connect(mAddressLocationWidget, &AddressLocationWidget::updateAddress, mAddressesLocationViewer, &AddressesLocationEngineViewer::replaceAddress);
+ setSizes(QList<int>() << 400 << 300);
+}
+
+AddressesLocationWidget::~AddressesLocationWidget()
+{
+
+}
+
+void AddressesLocationWidget::loadContact(const KContacts::Addressee &contact)
+{
+ mAddressesLocationViewer->setAddresses(contact.addresses());
+}
+
+void AddressesLocationWidget::storeContact(KContacts::Addressee &contact) const
+{
+ // delete all previous addresses
+ const KContacts::Address::List oldAddresses = contact.addresses();
+ const int numberOfOldAddresses(oldAddresses.count());
+ for (int i = 0; i < numberOfOldAddresses; ++i) {
+ contact.removeAddress(oldAddresses.at(i));
+ }
+
+ const KContacts::Address::List addressList = mAddressesLocationViewer->addresses();
+ // insert the new ones
+ const int numberOfAddress(addressList.count());
+ for (int i = 0; i < numberOfAddress; ++i) {
+ const KContacts::Address address(addressList.at(i));
+ if (!address.isEmpty()) {
+ contact.insertAddress(address);
+ }
+ }
+}
+
+void AddressesLocationWidget::setReadOnly(bool readOnly)
+{
+ mAddressesLocationViewer->setReadOnly(readOnly);
+ mAddressLocationWidget->setReadOnly(readOnly);
+}
diff --git a/src/contact-editor/editor/addresseditor/addresseslocationwidget.h b/src/contact-editor/editor/addresseditor/addresseslocationwidget.h
new file mode 100644
index 0000000..1eff9c9
--- /dev/null
+++ b/src/contact-editor/editor/addresseditor/addresseslocationwidget.h
@@ -0,0 +1,48 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 ADDRESSESLOCATIONWIDGET_H
+#define ADDRESSESLOCATIONWIDGET_H
+
+#include <QSplitter>
+#include <KContacts/Addressee>
+namespace Akonadi
+{
+class AddressLocationWidget;
+class AddressesLocationEngineViewer;
+class AddressesLocationWidget : public QSplitter
+{
+ Q_OBJECT
+public:
+ explicit AddressesLocationWidget(QWidget *parent = nullptr);
+ ~AddressesLocationWidget();
+
+ void loadContact(const KContacts::Addressee &contact);
+ void storeContact(KContacts::Addressee &contact) const;
+
+ void setReadOnly(bool readOnly);
+private:
+ AddressesLocationEngineViewer *mAddressesLocationViewer;
+ AddressLocationWidget *mAddressLocationWidget;
+};
+}
+#endif // ADDRESSESLOCATIONWIDGET_H
diff --git a/src/contact-editor/editor/addresseditor/addressgrantleeobject.cpp b/src/contact-editor/editor/addresseditor/addressgrantleeobject.cpp
new file mode 100644
index 0000000..11a580e
--- /dev/null
+++ b/src/contact-editor/editor/addresseditor/addressgrantleeobject.cpp
@@ -0,0 +1,129 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "addressgrantleeobject.h"
+#include "iconnamecache_p.h"
+#include <KIconLoader>
+#include <KLocalizedString>
+#include <QUrlQuery>
+using namespace Akonadi;
+AddressGrantleeObject::AddressGrantleeObject(const KContacts::Address &address, int addressIndex, QObject *parent)
+ : QObject(parent),
+ mAddress(address),
+ mAddressIndex(addressIndex)
+{
+ mIconSize = KIconLoader::global()->currentSize(KIconLoader::Small);
+}
+
+AddressGrantleeObject::~AddressGrantleeObject()
+{
+
+}
+
+QString AddressGrantleeObject::formattedAddress() const
+{
+ QString str;
+ if (mAddress.label().isEmpty()) {
+ str = mAddress.formattedAddress().trimmed().toHtmlEscaped();
+ } else {
+ str = mAddress.label().toHtmlEscaped();
+ }
+ return str;
+}
+
+QString AddressGrantleeObject::createActionUrl(const QString &actionName) const
+{
+ QUrl url;
+ url.setScheme(QStringLiteral("addresslocationaction"));
+ url.setPath(actionName);
+ QUrlQuery query;
+ query.addQueryItem(QStringLiteral("id"), QString::number(mAddressIndex));
+ url.setQuery(query);
+ return url.toDisplayString();
+}
+
+QString AddressGrantleeObject::preferredAddressAction() const
+{
+ QString text;
+ if (preferredAddress()) {
+ const QString iconPath = QUrl::fromLocalFile(IconNameCache::instance()->iconPath(QStringLiteral("bookmarks"), KIconLoader::Small)).url();
+ text = QStringLiteral("<img class=\"headimage\" height=\"%3\" width=\"%3\" title=\"%1\" src=\"%2\"></a>\n")
+ .arg(i18n("Remove Address"), iconPath, QString::number(mIconSize));
+ }
+ return text;
+}
+
+QString AddressGrantleeObject::postOfficeBox() const
+{
+ return mAddress.postOfficeBox();
+}
+
+QString AddressGrantleeObject::street() const
+{
+ return mAddress.street();
+}
+
+QString AddressGrantleeObject::locality() const
+{
+ return mAddress.locality();
+}
+
+QString AddressGrantleeObject::region() const
+{
+ return mAddress.region();
+}
+
+QString AddressGrantleeObject::postalCode() const
+{
+ return mAddress.postalCode();
+}
+
+QString AddressGrantleeObject::country() const
+{
+ return mAddress.country();
+}
+
+QString AddressGrantleeObject::removeAddressAction() const
+{
+ const QString iconPath = QUrl::fromLocalFile(IconNameCache::instance()->iconPath(QStringLiteral("edit-delete"), KIconLoader::Small)).url();
+ const QString text = QStringLiteral("<a href=\"%1\"><img class=\"headimage\" height=\"%4\" width=\"%4\" title=\"%3\" src=\"%2\"></a>\n")
+ .arg(createActionUrl(QStringLiteral("removeaddress")), iconPath, i18n("Remove Address"), QString::number(mIconSize));
+ return text;
+}
+
+QString AddressGrantleeObject::modifyAddressAction() const
+{
+ const QString iconPath = QUrl::fromLocalFile(IconNameCache::instance()->iconPath(QStringLiteral("document-edit"), KIconLoader::Small)).url();
+ const QString text = QStringLiteral("<a href=\"%1\"><img class=\"headimage\" height=\"%4\" width=\"%4\" title=\"%3\" src=\"%2\"></a>\n")
+ .arg(createActionUrl(QStringLiteral("editaddress")), iconPath, i18n("Edit Address"), QString::number(mIconSize));
+ return text;
+}
+
+QString AddressGrantleeObject::addressType() const
+{
+ return KContacts::Address::typeLabel(mAddress.type());
+}
+
+bool AddressGrantleeObject::preferredAddress() const
+{
+ return (mAddress.type() & KContacts::Address::Pref);
+}
diff --git a/src/contact-editor/editor/addresseditor/addressgrantleeobject.h b/src/contact-editor/editor/addresseditor/addressgrantleeobject.h
new file mode 100644
index 0000000..31c8bb7
--- /dev/null
+++ b/src/contact-editor/editor/addresseditor/addressgrantleeobject.h
@@ -0,0 +1,69 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 ADDRESSGRANTLEEOBJECT_H
+#define ADDRESSGRANTLEEOBJECT_H
+
+#include <QObject>
+#include <KContacts/Address>
+namespace Akonadi
+{
+class AddressGrantleeObject : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString removeAddressAction READ removeAddressAction)
+ Q_PROPERTY(QString modifyAddressAction READ modifyAddressAction)
+ Q_PROPERTY(QString formattedAddress READ formattedAddress)
+ Q_PROPERTY(QString preferredAddressAction READ preferredAddressAction)
+ Q_PROPERTY(QString addressType READ addressType)
+ Q_PROPERTY(QString postOfficeBox READ postOfficeBox)
+ Q_PROPERTY(QString street READ street)
+ Q_PROPERTY(QString locality READ locality)
+ Q_PROPERTY(QString region READ region)
+ Q_PROPERTY(QString postalCode READ postalCode)
+ Q_PROPERTY(QString country READ country)
+ Q_PROPERTY(bool preferredAddress READ preferredAddress)
+public:
+ explicit AddressGrantleeObject(const KContacts::Address &address, int addressIndex, QObject *parent = nullptr);
+ ~AddressGrantleeObject();
+
+ QString removeAddressAction() const;
+ QString modifyAddressAction() const;
+ QString formattedAddress() const;
+ QString addressType() const;
+ bool preferredAddress() const;
+ QString preferredAddressAction() const;
+ QString postOfficeBox() const;
+ QString street() const;
+ QString locality() const;
+ QString region() const;
+ QString postalCode() const;
+ QString country() const;
+
+private:
+ QString createActionUrl(const QString &actionName) const;
+ KContacts::Address mAddress;
+ int mAddressIndex;
+ int mIconSize;
+};
+}
+#endif // ADDRESSGRANTLEEOBJECT_H
diff --git a/src/contact-editor/editor/addresseditor/addresslocationwidget.cpp b/src/contact-editor/editor/addresseditor/addresslocationwidget.cpp
new file mode 100644
index 0000000..4cf60df
--- /dev/null
+++ b/src/contact-editor/editor/addresseditor/addresslocationwidget.cpp
@@ -0,0 +1,295 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "addresslocationwidget.h"
+#include "selectaddresstypecombobox.h"
+
+#include <KComboBox>
+#include <KLineEdit>
+#include <KLocalizedString>
+
+#include <QVBoxLayout>
+#include <QLabel>
+#include <QCheckBox>
+#include <QPushButton>
+#include <QStackedWidget>
+using namespace Akonadi;
+struct LocaleAwareLessThan : std::binary_function<QString, QString, bool> {
+ bool operator()(const QString &s1, const QString &s2) const
+ {
+ return QString::localeAwareCompare(s1, s2) < 0;
+ }
+};
+
+AddressLocationWidget::AddressLocationWidget(QWidget *parent)
+ : QWidget(parent),
+ mCurrentAddress(-1),
+ mCurrentMode(CreateAddress)
+{
+ QVBoxLayout *topLayout = new QVBoxLayout(this);
+
+ QGridLayout *gridLayout = new QGridLayout;
+ topLayout->addLayout(gridLayout);
+
+ mTypeCombo = new SelectAddressTypeComboBox(this);
+ mTypeCombo->setObjectName(QStringLiteral("typeaddress"));
+ gridLayout->addWidget(mTypeCombo, 0, 0, 1, 2);
+
+ QLabel *label = new QLabel(KContacts::Address::streetLabel(), this);
+ label->setObjectName(QStringLiteral("streetlabel"));
+ gridLayout->addWidget(label, 1, 0);
+
+ mStreetEdit = new KLineEdit(this);
+ mStreetEdit->setPlaceholderText(i18n("Add Street"));
+ mStreetEdit->setObjectName(QStringLiteral("streetlineedit"));
+ mStreetEdit->setTrapReturnKey(true);
+ gridLayout->addWidget(mStreetEdit, 2, 0);
+
+ label = new QLabel(KContacts::Address::postOfficeBoxLabel(), this);
+ label->setObjectName(QStringLiteral("postofficeboxlabel"));
+ gridLayout->addWidget(label, 1, 1);
+
+ mPOBoxEdit = new KLineEdit(this);
+ mPOBoxEdit->setPlaceholderText(i18n("Add Post Office Box"));
+ mPOBoxEdit->setObjectName(QStringLiteral("postofficeboxlineedit"));
+ mPOBoxEdit->setTrapReturnKey(true);
+ gridLayout->addWidget(mPOBoxEdit, 2, 1);
+
+ label = new QLabel(KContacts::Address::postalCodeLabel(), this);
+ label->setObjectName(QStringLiteral("postalcodelabel"));
+ gridLayout->addWidget(label, 3, 0);
+ mPostalCodeEdit = new KLineEdit(this);
+ mPostalCodeEdit->setPlaceholderText(i18n("Add Postal Code"));
+ mPostalCodeEdit->setObjectName(QStringLiteral("postalcodelineedit"));
+ mPostalCodeEdit->setTrapReturnKey(true);
+ gridLayout->addWidget(mPostalCodeEdit, 4, 0);
+
+ label = new QLabel(KContacts::Address::localityLabel(), this);
+ label->setObjectName(QStringLiteral("localitylabel"));
+ gridLayout->addWidget(label, 3, 1);
+ mLocalityEdit = new KLineEdit(this);
+ mLocalityEdit->setPlaceholderText(i18n("Add Locality"));
+ mLocalityEdit->setObjectName(QStringLiteral("localitylineedit"));
+ mLocalityEdit->setTrapReturnKey(true);
+ gridLayout->addWidget(mLocalityEdit, 4, 1);
+
+ label = new QLabel(KContacts::Address::regionLabel(), this);
+ label->setObjectName(QStringLiteral("regionlabel"));
+ gridLayout->addWidget(label, 5, 0);
+ mRegionEdit = new KLineEdit(this);
+ mRegionEdit->setPlaceholderText(i18n("Add Region"));
+ mRegionEdit->setObjectName(QStringLiteral("regionlineedit"));
+ mRegionEdit->setTrapReturnKey(true);
+ gridLayout->addWidget(mRegionEdit, 6, 0);
+
+ label = new QLabel(KContacts::Address::countryLabel(), this);
+ label->setObjectName(QStringLiteral("countrylabel"));
+ gridLayout->addWidget(label, 5, 1);
+ mCountryCombo = new KComboBox(this);
+ KLineEdit *edit = new KLineEdit(this);
+ edit->setTrapReturnKey(true);
+ mCountryCombo->setLineEdit(edit);
+ mCountryCombo->setObjectName(QStringLiteral("countrycombobox"));
+ mCountryCombo->setEditable(true);
+ mCountryCombo->lineEdit()->setPlaceholderText(i18n("Add a Country"));
+ mCountryCombo->setDuplicatesEnabled(false);
+ gridLayout->addWidget(mCountryCombo, 6, 1);
+
+ mPreferredCheckBox = new QCheckBox(i18nc("street/postal", "This is the preferred address"), this);
+ mPreferredCheckBox->setObjectName(QStringLiteral("preferredcheckbox"));
+ gridLayout->addWidget(mPreferredCheckBox, 7, 0, 1, 2);
+
+ mButtonStack = new QStackedWidget(this);
+ mButtonStack->setObjectName(QStringLiteral("buttonstacked"));
+ topLayout->addWidget(mButtonStack);
+
+ QWidget *addButtonWidget = new QWidget(this);
+ QHBoxLayout *addButtonWidgetLayout = new QHBoxLayout(addButtonWidget);
+ addButtonWidgetLayout->setMargin(0);
+ mAddAddress = new QPushButton(i18n("Add Address"), this);
+ mAddAddress->setObjectName(QStringLiteral("addbuttonaddress"));
+ connect(mAddAddress, &QPushButton::clicked, this, &AddressLocationWidget::slotAddAddress);
+ addButtonWidgetLayout->addWidget(mAddAddress);
+ addButtonWidgetLayout->addStretch(1);
+ mButtonStack->addWidget(addButtonWidget);
+
+ QWidget *modifyButtonWidget = new QWidget(this);
+ QHBoxLayout *modifyButtonWidgetLayout = new QHBoxLayout(modifyButtonWidget);
+ modifyButtonWidgetLayout->setMargin(0);
+ mButtonStack->addWidget(modifyButtonWidget);
+
+ mModifyAddress = new QPushButton(i18n("Update Address"), this);
+ mModifyAddress->setObjectName(QStringLiteral("modifybuttonaddress"));
+ modifyButtonWidgetLayout->addWidget(mModifyAddress);
+ connect(mModifyAddress, &QPushButton::clicked, this, &AddressLocationWidget::slotUpdateAddress);
+
+ mCancelAddress = new QPushButton(i18n("Cancel"), this);
+ mCancelAddress->setObjectName(QStringLiteral("cancelbuttonaddress"));
+ connect(mCancelAddress, &QPushButton::clicked, this, &AddressLocationWidget::slotCancelModifyAddress);
+ modifyButtonWidgetLayout->addWidget(mCancelAddress);
+ modifyButtonWidgetLayout->addStretch(1);
+ const int buttonWidth = qMax(mCancelAddress->width(), mModifyAddress->width());
+ mModifyAddress->setMinimumWidth(buttonWidth);
+ mCancelAddress->setMinimumWidth(buttonWidth);
+
+ topLayout->addStretch(1);
+ fillCountryCombo();
+ switchMode();
+}
+
+AddressLocationWidget::~AddressLocationWidget()
+{
+
+}
+
+void AddressLocationWidget::setReadOnly(bool readOnly)
+{
+ mPreferredCheckBox->setEnabled(!readOnly);
+ mPOBoxEdit->setReadOnly(readOnly);
+ mLocalityEdit->setReadOnly(readOnly);
+ mRegionEdit->setReadOnly(readOnly);
+ mPostalCodeEdit->setReadOnly(readOnly);
+ mStreetEdit->setReadOnly(readOnly);
+ mCountryCombo->setEnabled(!readOnly);
+ mTypeCombo->setEnabled(!readOnly);
+
+ mAddAddress->setEnabled(!readOnly);
+ mModifyAddress->setEnabled(!readOnly);
+ mCancelAddress->setEnabled(!readOnly);
+}
+
+void AddressLocationWidget::fillCountryCombo()
+{
+ QStringList countries;
+ const QList<QLocale> localeList = QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript, QLocale::AnyCountry);
+ countries.reserve(localeList.count());
+ for (const QLocale &locale : localeList) {
+ const QString localeStr = QLocale::countryToString(locale.country());
+ if (countries.contains(localeStr)) {
+ continue;
+ }
+ countries.append(localeStr);
+ }
+
+ std::sort(countries.begin(), countries.end(), LocaleAwareLessThan());
+
+ mCountryCombo->addItems(countries);
+ mCountryCombo->setAutoCompletion(true);
+ mCountryCombo->completionObject()->setItems(countries);
+ mCountryCombo->completionObject()->setIgnoreCase(true);
+
+ const QString currentCountry = QLocale::countryToString(QLocale().country());
+ mCountryCombo->setCurrentIndex(mCountryCombo->findText(currentCountry));
+}
+
+void AddressLocationWidget::slotAddAddress()
+{
+ KContacts::Address addr = address();
+ if (!addr.isEmpty()) {
+ Q_EMIT addNewAddress(addr);
+ reset();
+ }
+}
+
+void AddressLocationWidget::setAddress(const KContacts::Address &address)
+{
+ mAddress = address;
+ mTypeCombo->setType(mAddress.type());
+ mStreetEdit->setText(mAddress.street());
+ mRegionEdit->setText(address.region());
+ mLocalityEdit->setText(address.locality());
+ mPostalCodeEdit->setText(address.postalCode());
+ mPOBoxEdit->setText(address.postOfficeBox());
+ mPreferredCheckBox->setChecked(address.type() &KContacts::Address::Pref);
+ if (address.isEmpty()) {
+ mCountryCombo->setItemText(mCountryCombo->currentIndex(),
+ QLocale::countryToString(QLocale().country()));
+ } else {
+ mCountryCombo->setItemText(mCountryCombo->currentIndex(), mAddress.country());
+ }
+}
+
+KContacts::Address AddressLocationWidget::address() const
+{
+ KContacts::Address address(mAddress);
+
+ address.setType(mTypeCombo->type());
+ address.setLocality(mLocalityEdit->text());
+ address.setRegion(mRegionEdit->text());
+ address.setPostalCode(mPostalCodeEdit->text());
+ address.setCountry(mCountryCombo->currentText());
+ address.setPostOfficeBox(mPOBoxEdit->text());
+ address.setStreet(mStreetEdit->text());
+ if (mPreferredCheckBox->isChecked()) {
+ address.setType(address.type() | KContacts::Address::Pref);
+ } else {
+ address.setType(address.type() & ~(KContacts::Address::Pref));
+ }
+ return address;
+}
+
+void AddressLocationWidget::switchMode()
+{
+ switch (mCurrentMode) {
+ case CreateAddress:
+ mButtonStack->setCurrentIndex(0);
+ break;
+ case ModifyAddress:
+ mButtonStack->setCurrentIndex(1);
+ break;
+ }
+}
+
+void AddressLocationWidget::slotModifyAddress(const KContacts::Address &address, int currentIndex)
+{
+ setAddress(address);
+ mCurrentMode = ModifyAddress;
+ mCurrentAddress = currentIndex;
+ switchMode();
+}
+
+void AddressLocationWidget::clear()
+{
+ mCurrentMode = CreateAddress;
+ setAddress(KContacts::Address());
+ switchMode();
+}
+
+void AddressLocationWidget::slotUpdateAddress()
+{
+ if (mCurrentMode == ModifyAddress) {
+ Q_EMIT updateAddress(address(), mCurrentAddress);
+ reset();
+ }
+}
+
+void AddressLocationWidget::reset()
+{
+ Q_EMIT updateAddressCanceled();
+ mCurrentAddress = -1;
+ clear();
+}
+
+void AddressLocationWidget::slotCancelModifyAddress()
+{
+ reset();
+}
diff --git a/src/contact-editor/editor/addresseditor/addresslocationwidget.h b/src/contact-editor/editor/addresseditor/addresslocationwidget.h
new file mode 100644
index 0000000..45ebb16
--- /dev/null
+++ b/src/contact-editor/editor/addresseditor/addresslocationwidget.h
@@ -0,0 +1,86 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 ADDRESSLOCATIONWIDGET_H
+#define ADDRESSLOCATIONWIDGET_H
+
+#include <QWidget>
+#include <KContacts/Address>
+class QStackedWidget;
+class QCheckBox;
+class KLineEdit;
+class KComboBox;
+class QPushButton;
+namespace Akonadi
+{
+class SelectAddressTypeComboBox;
+class AddressLocationWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ enum Mode {
+ CreateAddress = 0,
+ ModifyAddress
+ };
+
+ explicit AddressLocationWidget(QWidget *parent = nullptr);
+ ~AddressLocationWidget();
+
+ void setAddress(const KContacts::Address &address);
+ KContacts::Address address() const;
+
+ void slotModifyAddress(const KContacts::Address &address, int currentIndex);
+
+ void clear();
+
+ void setReadOnly(bool readOnly);
+
+Q_SIGNALS:
+ void addNewAddress(const KContacts::Address &address);
+ void updateAddress(const KContacts::Address &address, int index);
+ void updateAddressCanceled();
+
+private:
+ void slotAddAddress();
+ void slotUpdateAddress();
+ void slotCancelModifyAddress();
+ void fillCountryCombo();
+ void switchMode();
+ void reset();
+ KContacts::Address mAddress;
+ QCheckBox *mPreferredCheckBox;
+ KLineEdit *mPOBoxEdit;
+ KLineEdit *mLocalityEdit;
+ KLineEdit *mRegionEdit;
+ KLineEdit *mPostalCodeEdit;
+ KLineEdit *mStreetEdit;
+ KComboBox *mCountryCombo;
+ QPushButton *mAddAddress;
+ QPushButton *mModifyAddress;
+ QPushButton *mCancelAddress;
+ QStackedWidget *mButtonStack;
+ SelectAddressTypeComboBox *mTypeCombo;
+ int mCurrentAddress;
+ Mode mCurrentMode;
+};
+}
+#endif // ADDRESSLOCATIONWIDGET_H
diff --git a/src/contact-editor/editor/addresseditor/addresstypedialog.cpp b/src/contact-editor/editor/addresseditor/addresstypedialog.cpp
new file mode 100644
index 0000000..e47327c
--- /dev/null
+++ b/src/contact-editor/editor/addresseditor/addresstypedialog.cpp
@@ -0,0 +1,92 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (c) 2009 Tobias Koenig <[email protected]>
+
+ 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 "addresstypedialog.h"
+#include <KLocalizedString>
+#include <QVBoxLayout>
+#include <QPushButton>
+#include <QDialogButtonBox>
+#include <QGroupBox>
+#include <QCheckBox>
+#include <QButtonGroup>
+using namespace Akonadi;
+AddressTypeDialog::AddressTypeDialog(KContacts::Address::Type type, QWidget *parent)
+ : QDialog(parent)
+{
+ QVBoxLayout *mainLayout = new QVBoxLayout(this);
+ setWindowTitle(i18nc("street/postal", "Edit Address Type"));
+ QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
+ QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok);
+ okButton->setDefault(true);
+ okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
+ connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
+ connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
+
+ QWidget *page = new QWidget(this);
+ mainLayout->addWidget(page);
+ mainLayout->addWidget(buttonBox);
+ QVBoxLayout *layout = new QVBoxLayout(page);
+ layout->setMargin(0);
+
+ QGroupBox *box = new QGroupBox(i18nc("street/postal", "Address Types"), page);
+ mainLayout->addWidget(box);
+ layout->addWidget(box);
+ mGroup = new QButtonGroup(box);
+ mGroup->setExclusive(false);
+
+ QGridLayout *buttonLayout = new QGridLayout(box);
+
+ mTypeList = KContacts::Address::typeList();
+ mTypeList.removeAll(KContacts::Address::Pref);
+
+ KContacts::Address::TypeList::ConstIterator it;
+ int i = 0;
+ int row = 0;
+ KContacts::Address::TypeList::ConstIterator end(mTypeList.constEnd());
+ for (it = mTypeList.constBegin(); it != end; ++it, ++i) {
+ QCheckBox *cb = new QCheckBox(KContacts::Address::typeLabel(*it), box);
+ cb->setChecked(type & mTypeList[i]);
+ buttonLayout->addWidget(cb, row, i % 3);
+
+ if (i % 3 == 2) {
+ ++row;
+ }
+ mGroup->addButton(cb);
+ }
+}
+
+AddressTypeDialog::~AddressTypeDialog()
+{
+}
+
+KContacts::Address::Type AddressTypeDialog::type() const
+{
+ KContacts::Address::Type type;
+ const int numberOfButtons(mGroup->buttons().count());
+ for (int i = 0; i < numberOfButtons; ++i) {
+ QCheckBox *box = qobject_cast<QCheckBox *>(mGroup->buttons().at(i));
+ if (box && box->isChecked()) {
+ type |= mTypeList[i];
+ }
+ }
+
+ return type;
+}
diff --git a/src/contact-editor/editor/addresseditor/addresstypedialog.h b/src/contact-editor/editor/addresseditor/addresstypedialog.h
new file mode 100644
index 0000000..ad44345
--- /dev/null
+++ b/src/contact-editor/editor/addresseditor/addresstypedialog.h
@@ -0,0 +1,51 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (c) 2009 Tobias Koenig <[email protected]>
+
+ 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 ADDRESSTYPEDIALOG_H
+#define ADDRESSTYPEDIALOG_H
+
+#include <QDialog>
+#include <KContacts/Address>
+class QButtonGroup;
+/**
+ * Dialog for creating a new address types.
+ *
+ * @note This dialog is only used by AddressTypeCombo.
+ */
+namespace Akonadi
+{
+class AddressTypeDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ AddressTypeDialog(KContacts::Address::Type type, QWidget *parent);
+ ~AddressTypeDialog();
+
+ KContacts::Address::Type type() const;
+
+private:
+ QButtonGroup *mGroup;
+
+ KContacts::Address::TypeList mTypeList;
+};
+}
+
+#endif // ADDRESSTYPEDIALOG_H
diff --git a/src/contact-editor/editor/addresseditor/autotests/CMakeLists.txt b/src/contact-editor/editor/addresseditor/autotests/CMakeLists.txt
new file mode 100644
index 0000000..e4eac46
--- /dev/null
+++ b/src/contact-editor/editor/addresseditor/autotests/CMakeLists.txt
@@ -0,0 +1,31 @@
+include(ECMMarkAsTest)
+
+set(akonadicontact_addresslocation_web_editor_SRCS
+ ../webengine/addresseslocationengineviewer.cpp
+ ../webengine/addresseslocationenginepage.cpp
+ )
+set(akonadicontact_webengine_LIB Qt5::WebEngine Qt5::WebEngineWidgets)
+
+ecm_qt_declare_logging_category(akonadicontact_addresslocation_web_editor_SRCS HEADER akonadi_contact_debug.h IDENTIFIER AKONADICONTACT_LOG CATEGORY_NAME org.kde.pim.akonadi_contact)
+
+set(addresseslocationviewer_SRCS addresseslocationviewertest.cpp ${akonadicontact_addresslocation_web_editor_SRCS} ../addresseslocationgrantleeformater.cpp
+ ../addressgrantleeobject.cpp ../iconnamecache.cpp)
+add_executable(addresseslocationviewer ${addresseslocationviewer_SRCS})
+add_test(addresseslocationviewer addresseslocationviewer)
+ecm_mark_as_test(addresseslocationviewer)
+target_link_libraries(addresseslocationviewer Qt5::Test Qt5::Widgets KF5::ContactEditor KF5::Contacts KF5::I18n ${akonadicontact_webengine_LIB} Grantlee5::Templates
+ KF5::IconThemes KF5::WidgetsAddons)
+
+set(addresslocationwidget_SRCS addresslocationwidgettest.cpp ../addresslocationwidget.cpp ../selectaddresstypecombobox.cpp ../addresstypedialog.cpp)
+add_executable(addresslocationwidget ${addresslocationwidget_SRCS})
+add_test(addresslocationwidget addresslocationwidget)
+ecm_mark_as_test(addresslocationwidget)
+target_link_libraries(addresslocationwidget Qt5::Test Qt5::Widgets KF5::ContactEditor KF5::Contacts KF5::I18n KF5::Completion)
+
+set(addresseslocationwidget_SRCS addresseslocationwidgettest.cpp ../addresseslocationwidget.cpp ${akonadicontact_addresslocation_web_editor_SRCS} ../addresseslocationgrantleeformater.cpp
+ ../addressgrantleeobject.cpp ../iconnamecache.cpp ../addresslocationwidget.cpp ../selectaddresstypecombobox.cpp ../addresstypedialog.cpp)
+add_executable(addresseslocationwidget ${addresseslocationwidget_SRCS})
+add_test(addresseslocationwidget addresseslocationwidget)
+ecm_mark_as_test(addresseslocationwidget)
+target_link_libraries(addresseslocationwidget Qt5::Test Qt5::Widgets KF5::ContactEditor KF5::Contacts KF5::I18n KF5::Completion ${akonadicontact_webengine_LIB}
+ Grantlee5::Templates KF5::IconThemes KF5::WidgetsAddons)
diff --git a/src/contact-editor/editor/addresseditor/autotests/addresseslocationviewertest.cpp b/src/contact-editor/editor/addresseditor/autotests/addresseslocationviewertest.cpp
new file mode 100644
index 0000000..530d282
--- /dev/null
+++ b/src/contact-editor/editor/addresseditor/autotests/addresseslocationviewertest.cpp
@@ -0,0 +1,45 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "addresseslocationviewertest.h"
+#include "config-contact-editor.h"
+#include "../webengine/addresseslocationengineviewer.h"
+#include <QTest>
+using namespace Akonadi;
+AddressesLocationViewerTest::AddressesLocationViewerTest(QObject *parent)
+ : QObject(parent)
+{
+
+}
+
+AddressesLocationViewerTest::~AddressesLocationViewerTest()
+{
+
+}
+
+void AddressesLocationViewerTest::shouldHaveDefaultValue()
+{
+ AddressesLocationEngineViewer w;
+ QVERIFY(w.addresses().isEmpty());
+}
+
+QTEST_MAIN(AddressesLocationViewerTest)
diff --git a/src/contact-editor/editor/addresseditor/autotests/addresseslocationviewertest.h b/src/contact-editor/editor/addresseditor/autotests/addresseslocationviewertest.h
new file mode 100644
index 0000000..16615f8
--- /dev/null
+++ b/src/contact-editor/editor/addresseditor/autotests/addresseslocationviewertest.h
@@ -0,0 +1,38 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 ADDRESSESLOCATIONVIEWERTEST_H
+#define ADDRESSESLOCATIONVIEWERTEST_H
+
+#include <QObject>
+
+class AddressesLocationViewerTest : public QObject
+{
+ Q_OBJECT
+public:
+ explicit AddressesLocationViewerTest(QObject *parent = nullptr);
+ ~AddressesLocationViewerTest();
+private Q_SLOTS:
+ void shouldHaveDefaultValue();
+};
+
+#endif // ADDRESSESLOCATIONVIEWERTEST_H
diff --git a/src/contact-editor/editor/addresseditor/autotests/addresseslocationwidgettest.cpp b/src/contact-editor/editor/addresseditor/autotests/addresseslocationwidgettest.cpp
new file mode 100644
index 0000000..5eb4d64
--- /dev/null
+++ b/src/contact-editor/editor/addresseditor/autotests/addresseslocationwidgettest.cpp
@@ -0,0 +1,53 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "addresseslocationwidgettest.h"
+#include "config-contact-editor.h"
+#include "../webengine/addresseslocationengineviewer.h"
+
+#include "../addresseslocationwidget.h"
+#include <QTest>
+
+#include <editor/addresseditor/addresslocationwidget.h>
+using namespace Akonadi;
+AddressesLocationWidgetTest::AddressesLocationWidgetTest(QObject *parent)
+ : QObject(parent)
+{
+
+}
+
+AddressesLocationWidgetTest::~AddressesLocationWidgetTest()
+{
+
+}
+
+void AddressesLocationWidgetTest::shouldHaveDefaultValue()
+{
+ AddressesLocationWidget w;
+ AddressLocationWidget *addressLocationWidget = w.findChild<AddressLocationWidget *>(QStringLiteral("addresslocationwidget"));
+ QVERIFY(addressLocationWidget);
+
+ AddressesLocationEngineViewer *addressesLocationViewer = w.findChild<AddressesLocationEngineViewer *>(QStringLiteral("addresseslocationviewer"));
+ QVERIFY(addressesLocationViewer);
+}
+
+QTEST_MAIN(AddressesLocationWidgetTest)
diff --git a/src/contact-editor/editor/addresseditor/autotests/addresseslocationwidgettest.h b/src/contact-editor/editor/addresseditor/autotests/addresseslocationwidgettest.h
new file mode 100644
index 0000000..3c8eae2
--- /dev/null
+++ b/src/contact-editor/editor/addresseditor/autotests/addresseslocationwidgettest.h
@@ -0,0 +1,39 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 ADDRESSESLOCATIONWIDGETTEST_H
+#define ADDRESSESLOCATIONWIDGETTEST_H
+
+#include <QObject>
+
+class AddressesLocationWidgetTest : public QObject
+{
+ Q_OBJECT
+public:
+ explicit AddressesLocationWidgetTest(QObject *parent = nullptr);
+ ~AddressesLocationWidgetTest();
+
+private Q_SLOTS:
+ void shouldHaveDefaultValue();
+};
+
+#endif // ADDRESSESLOCATIONWIDGETTEST_H
diff --git a/src/contact-editor/editor/addresseditor/autotests/addresslocationwidgettest.cpp b/src/contact-editor/editor/addresseditor/autotests/addresslocationwidgettest.cpp
new file mode 100644
index 0000000..8483dc8
--- /dev/null
+++ b/src/contact-editor/editor/addresseditor/autotests/addresslocationwidgettest.cpp
@@ -0,0 +1,123 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "addresslocationwidgettest.h"
+#include "../addresslocationwidget.h"
+#include <QLabel>
+#include <QPushButton>
+#include <KComboBox>
+#include <KLineEdit>
+#include <QTest>
+#include <QCheckBox>
+#include <editor/addresseditor/selectaddresstypecombobox.h>
+using namespace Akonadi;
+AddressLocationWidgetTest::AddressLocationWidgetTest(QObject *parent)
+ : QObject(parent)
+{
+
+}
+
+AddressLocationWidgetTest::~AddressLocationWidgetTest()
+{
+
+}
+
+void AddressLocationWidgetTest::shouldHaveDefaultValue()
+{
+ AddressLocationWidget w;
+
+ SelectAddressTypeComboBox *typeAddress = w.findChild<SelectAddressTypeComboBox *>(QStringLiteral("typeaddress"));
+ QVERIFY(typeAddress);
+
+ QLabel *streetlabel = w.findChild<QLabel *>(QStringLiteral("streetlabel"));
+ QVERIFY(streetlabel);
+ KLineEdit *mStreetEdit = w.findChild<KLineEdit *>(QStringLiteral("streetlineedit"));
+ QVERIFY(mStreetEdit);
+
+ QLabel *postofficeboxlabel = w.findChild<QLabel *>(QStringLiteral("postofficeboxlabel"));
+ QVERIFY(postofficeboxlabel);
+ KLineEdit *postofficeboxlineedit = w.findChild<KLineEdit *>(QStringLiteral("postofficeboxlineedit"));
+ QVERIFY(postofficeboxlineedit);
+
+ QLabel *localitylabel = w.findChild<QLabel *>(QStringLiteral("localitylabel"));
+ QVERIFY(localitylabel);
+ KLineEdit *localitylineedit = w.findChild<KLineEdit *>(QStringLiteral("localitylineedit"));
+ QVERIFY(localitylineedit);
+
+ QLabel *regionlabel = w.findChild<QLabel *>(QStringLiteral("regionlabel"));
+ QVERIFY(regionlabel);
+ KLineEdit *regionlineedit = w.findChild<KLineEdit *>(QStringLiteral("regionlineedit"));
+ QVERIFY(regionlineedit);
+
+ QLabel *postalcodelabel = w.findChild<QLabel *>(QStringLiteral("postalcodelabel"));
+ QVERIFY(postalcodelabel);
+ KLineEdit *postalcodelineedit = w.findChild<KLineEdit *>(QStringLiteral("postalcodelineedit"));
+ QVERIFY(postalcodelineedit);
+
+ QLabel *countrylabel = w.findChild<QLabel *>(QStringLiteral("countrylabel"));
+ QVERIFY(countrylabel);
+ KComboBox *countrycombobox = w.findChild<KComboBox *>(QStringLiteral("countrycombobox"));
+ QVERIFY(countrycombobox);
+
+ QCheckBox *preferredcheckbox = w.findChild<QCheckBox *>(QStringLiteral("preferredcheckbox"));
+ QVERIFY(preferredcheckbox);
+
+ QPushButton *addbuttonaddress = w.findChild<QPushButton *>(QStringLiteral("addbuttonaddress"));
+ QVERIFY(addbuttonaddress);
+
+ QPushButton *modifybuttonaddress = w.findChild<QPushButton *>(QStringLiteral("modifybuttonaddress"));
+ QVERIFY(modifybuttonaddress);
+
+ QPushButton *cancelbuttonaddress = w.findChild<QPushButton *>(QStringLiteral("cancelbuttonaddress"));
+ QVERIFY(cancelbuttonaddress);
+}
+
+void AddressLocationWidgetTest::shouldChangeReadOnlyStatus()
+{
+ AddressLocationWidget w;
+
+ w.setReadOnly(true);
+ SelectAddressTypeComboBox *typeAddress = w.findChild<SelectAddressTypeComboBox *>(QStringLiteral("typeaddress"));
+ QCOMPARE(typeAddress->isEnabled(), false);
+ KLineEdit *mStreetEdit = w.findChild<KLineEdit *>(QStringLiteral("streetlineedit"));
+ QCOMPARE(mStreetEdit->isReadOnly(), true);
+ KLineEdit *postofficeboxlineedit = w.findChild<KLineEdit *>(QStringLiteral("postofficeboxlineedit"));
+ QCOMPARE(postofficeboxlineedit->isReadOnly(), true);
+ KLineEdit *localitylineedit = w.findChild<KLineEdit *>(QStringLiteral("localitylineedit"));
+ QCOMPARE(localitylineedit->isReadOnly(), true);
+ KLineEdit *regionlineedit = w.findChild<KLineEdit *>(QStringLiteral("regionlineedit"));
+ QCOMPARE(regionlineedit->isReadOnly(), true);
+ KLineEdit *postalcodelineedit = w.findChild<KLineEdit *>(QStringLiteral("postalcodelineedit"));
+ QCOMPARE(postalcodelineedit->isReadOnly(), true);
+ KComboBox *countrycombobox = w.findChild<KComboBox *>(QStringLiteral("countrycombobox"));
+ QCOMPARE(countrycombobox->isEnabled(), false);
+ QCheckBox *preferredcheckbox = w.findChild<QCheckBox *>(QStringLiteral("preferredcheckbox"));
+ QCOMPARE(preferredcheckbox->isEnabled(), false);
+ QPushButton *addbuttonaddress = w.findChild<QPushButton *>(QStringLiteral("addbuttonaddress"));
+ QCOMPARE(addbuttonaddress->isEnabled(), false);
+ QPushButton *modifybuttonaddress = w.findChild<QPushButton *>(QStringLiteral("modifybuttonaddress"));
+ QCOMPARE(modifybuttonaddress->isEnabled(), false);
+ QPushButton *cancelbuttonaddress = w.findChild<QPushButton *>(QStringLiteral("cancelbuttonaddress"));
+ QCOMPARE(cancelbuttonaddress->isEnabled(), false);
+}
+
+QTEST_MAIN(AddressLocationWidgetTest)
diff --git a/src/contact-editor/editor/addresseditor/autotests/addresslocationwidgettest.h b/src/contact-editor/editor/addresseditor/autotests/addresslocationwidgettest.h
new file mode 100644
index 0000000..23be533
--- /dev/null
+++ b/src/contact-editor/editor/addresseditor/autotests/addresslocationwidgettest.h
@@ -0,0 +1,40 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 ADDRESSLOCATIONWIDGETTEST_H
+#define ADDRESSLOCATIONWIDGETTEST_H
+
+#include <QObject>
+
+class AddressLocationWidgetTest : public QObject
+{
+ Q_OBJECT
+public:
+ explicit AddressLocationWidgetTest(QObject *parent = nullptr);
+ ~AddressLocationWidgetTest();
+
+private Q_SLOTS:
+ void shouldHaveDefaultValue();
+ void shouldChangeReadOnlyStatus();
+};
+
+#endif // ADDRESSLOCATIONWIDGETTEST_H
diff --git a/src/contact-editor/editor/addresseditor/html/CMakeLists.txt b/src/contact-editor/editor/addresseditor/html/CMakeLists.txt
new file mode 100644
index 0000000..4ab97e7
--- /dev/null
+++ b/src/contact-editor/editor/addresseditor/html/CMakeLists.txt
@@ -0,0 +1 @@
+install(DIRECTORY default DESTINATION ${KDE_INSTALL_DATADIR}/akonadicontact/grantleetheme/ )
diff --git a/src/contact-editor/editor/addresseditor/html/default/addresseslocation.css b/src/contact-editor/editor/addresseditor/html/default/addresseslocation.css
new file mode 100644
index 0000000..02d83b3
--- /dev/null
+++ b/src/contact-editor/editor/addresseditor/html/default/addresseslocation.css
@@ -0,0 +1,16 @@
+#headeraddress {
+}
+
+#addresstype {
+ float: left;
+ color: #0000FF;
+}
+
+#actiontype {
+ float: right;
+ text-align: right;
+}
+
+#address {
+ float: left;
+}
diff --git a/src/contact-editor/editor/addresseditor/html/default/addresseslocation.html b/src/contact-editor/editor/addresseditor/html/default/addresseslocation.html
new file mode 100644
index 0000000..345015b
--- /dev/null
+++ b/src/contact-editor/editor/addresseditor/html/default/addresseslocation.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">
+<html>
+<head>
+<title>.</title>
+<link href="{{ absoluteThemePath }}/addresseslocation.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+{% if addresses %}
+{% for address in addresses %}
+ <div id="headeraddress">
+ <div id="addresstype">{{ address.addressType }}</div>
+ <div id="actiontype">
+ {% if readOnly %}
+ {% else %}
+ {{ address.modifyAddressAction|safe}} {{ address.removeAddressAction|safe}}
+ {% endif %}
+ </div>
+
+ <br>
+ <div id="address" > {{ address.formattedAddress }} </div>
+
+ <br style="clear: both;"/>
+ <br/>
+ </div>
+{% endfor %}
+{% endif %}
+
+</body>
+
diff --git a/src/contact-editor/editor/addresseditor/iconnamecache.cpp b/src/contact-editor/editor/addresseditor/iconnamecache.cpp
new file mode 100644
index 0000000..b1f0abc
--- /dev/null
+++ b/src/contact-editor/editor/addresseditor/iconnamecache.cpp
@@ -0,0 +1,55 @@
+/* Copyright 2009 Thomas McGuire <[email protected]>
+
+ 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 ) version 3 or, at the discretion of KDE e.V.
+ ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 "iconnamecache_p.h"
+
+#include <KIconLoader>
+using namespace Akonadi;
+Q_GLOBAL_STATIC(IconNameCache, s_iconNameCache)
+
+IconNameCache *IconNameCache::instance()
+{
+ return s_iconNameCache;
+}
+
+bool IconNameCache::Entry::operator < (const Entry &other) const
+{
+ const int fileNameCompare = fileName.compare(other.fileName);
+ if (fileNameCompare != 0) {
+ return fileNameCompare < 0;
+ } else {
+ return size < other.size;
+ }
+}
+
+QString IconNameCache::iconPath(const QString &name, int size) const
+{
+ Entry entry;
+ entry.fileName = name;
+ entry.size = size;
+
+ const QString path = mCachedEntries.value(entry);
+ if (!path.isEmpty()) {
+ return path;
+ }
+
+ const QString fileName = KIconLoader::global()->iconPath(name, size);
+ mCachedEntries.insert(entry, fileName);
+ return fileName;
+}
diff --git a/src/contact-editor/editor/addresseditor/iconnamecache_p.h b/src/contact-editor/editor/addresseditor/iconnamecache_p.h
new file mode 100644
index 0000000..9d320b6
--- /dev/null
+++ b/src/contact-editor/editor/addresseditor/iconnamecache_p.h
@@ -0,0 +1,54 @@
+/* Copyright 2009 Thomas McGuire <[email protected]>
+
+ 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 ) version 3 or, at the discretion of KDE e.V.
+ ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 ICONNAMECACHE_H
+#define ICONNAMECACHE_H
+
+#include <QMap>
+#include <QString>
+/**
+ * This class is a replacement for KIconLoader::iconPath(), because the iconPath()
+ * function can be slow for non-existing icons or icons that fall back to a generic icon.
+ * Reason is that KIconLoader does slow system calls for finding the icons.
+ *
+ * The IconNameCache caches the result of iconPath() in a map and solves the slowness.
+ */
+namespace Akonadi
+{
+class IconNameCache
+{
+public:
+
+ static IconNameCache *instance();
+ QString iconPath(const QString &name, int size) const;
+
+private:
+
+ class Entry
+ {
+ public:
+ QString fileName;
+ int size;
+
+ bool operator < (const Entry &other) const;
+ };
+
+ mutable QMap<Entry, QString> mCachedEntries;
+};
+}
+#endif
diff --git a/src/contact-editor/editor/addresseditor/selectaddresstypecombobox.cpp b/src/contact-editor/editor/addresseditor/selectaddresstypecombobox.cpp
new file mode 100644
index 0000000..3ffb774
--- /dev/null
+++ b/src/contact-editor/editor/addresseditor/selectaddresstypecombobox.cpp
@@ -0,0 +1,112 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "addresstypedialog.h"
+#include "selectaddresstypecombobox.h"
+#include <KLocalizedString>
+#include <autoqpointer_p.h>
+using namespace Akonadi;
+SelectAddressTypeComboBox::SelectAddressTypeComboBox(QWidget *parent)
+ : KComboBox(parent)
+ , mType(KContacts::Address::Home)
+ , mLastSelected(0)
+{
+ const int count = KContacts::Address::typeList().count();
+ mTypeList.reserve(count + 2);
+ mTypeList.append(-2); // Add initial message
+ for (int i = 0; i < count; ++i) {
+ mTypeList.append(KContacts::Address::typeList().at(i));
+ }
+ mTypeList.append(-1); // Others...
+
+ update();
+
+ connect(this, SIGNAL(activated(int)), this, SLOT(selected(int)));
+}
+
+SelectAddressTypeComboBox::~SelectAddressTypeComboBox()
+{
+}
+
+void SelectAddressTypeComboBox::setType(KContacts::Address::Type type)
+{
+ if (!mTypeList.contains(static_cast<int>(type))) {
+ // insert at the end, but before the 'Others...' entry
+ mTypeList.insert(mTypeList.at(mTypeList.count() - 1), static_cast<int>(type));
+ }
+
+ mType = type;
+ update();
+}
+
+KContacts::Address::Type SelectAddressTypeComboBox::type() const
+{
+ return mType;
+}
+
+void SelectAddressTypeComboBox::update()
+{
+ bool blocked = signalsBlocked();
+ blockSignals(true);
+
+ clear();
+ const int numberOfType(mTypeList.count());
+ for (int i = 0; i < numberOfType; ++i) {
+ if (mTypeList.at(i) == -1) { // "Other..." entry
+ addItem(i18nc("@item:inlistbox Category of contact info field", "Other..."));
+ } else if (mTypeList.at(i) == -2) {
+ addItem(i18nc("@item:inlistbox Category of contact info field", "New Address Type"));
+ } else {
+ addItem(KContacts::Address::typeLabel(KContacts::Address::Type(mTypeList.at(i))));
+ }
+ }
+
+ setCurrentIndex(mLastSelected = mTypeList.indexOf(mType));
+
+ blockSignals(blocked);
+}
+
+void SelectAddressTypeComboBox::selected(int pos)
+{
+ if (mTypeList.at(pos) == -1) {
+ otherSelected();
+ } else if (mTypeList.at(pos) == -2) {
+ return;
+ } else {
+ mType = KContacts::Address::Type(mTypeList.at(pos));
+ mLastSelected = pos;
+ }
+}
+
+void SelectAddressTypeComboBox::otherSelected()
+{
+ AutoQPointer<AddressTypeDialog> dlg = new AddressTypeDialog(mType, this);
+ if (dlg->exec()) {
+ mType = dlg->type();
+ if (!mTypeList.contains(mType)) {
+ mTypeList.insert(mTypeList.at(mTypeList.count() - 1), mType);
+ }
+ } else {
+ setType(KContacts::Address::Type(mTypeList.at(mLastSelected)));
+ }
+ update();
+}
diff --git a/src/contact-editor/editor/addresseditor/selectaddresstypecombobox.h b/src/contact-editor/editor/addresseditor/selectaddresstypecombobox.h
new file mode 100644
index 0000000..95fc731
--- /dev/null
+++ b/src/contact-editor/editor/addresseditor/selectaddresstypecombobox.h
@@ -0,0 +1,74 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 SELECTADDRESSTYPECOMBOBOX_H
+#define SELECTADDRESSTYPECOMBOBOX_H
+
+#include <KComboBox>
+#include <KContacts/Address>
+
+/**
+ * @short A widget for selecting the type of an address.
+ */
+namespace Akonadi
+{
+class SelectAddressTypeComboBox : public KComboBox
+{
+ Q_OBJECT
+
+public:
+ /**
+ * Creates a new address type combo.
+ *
+ * @param parent The parent widget.
+ */
+ explicit SelectAddressTypeComboBox(QWidget *parent = nullptr);
+
+ /**
+ * Destroys the address type combo.
+ */
+ ~SelectAddressTypeComboBox();
+
+ /**
+ * Sets the type that shall be selected in the combobox.
+ * @param type KABC address type to set.
+ */
+ void setType(KContacts::Address::Type type);
+
+ /**
+ * Returns the type that is currently selected.
+ */
+ KContacts::Address::Type type() const;
+
+private Q_SLOTS:
+ void selected(int);
+ void otherSelected();
+
+private:
+ void update();
+
+ KContacts::Address::Type mType;
+ int mLastSelected;
+ QList<int> mTypeList;
+};
+}
+#endif
diff --git a/src/contact-editor/editor/addresseditor/tests/CMakeLists.txt b/src/contact-editor/editor/addresseditor/tests/CMakeLists.txt
new file mode 100644
index 0000000..3cdee48
--- /dev/null
+++ b/src/contact-editor/editor/addresseditor/tests/CMakeLists.txt
@@ -0,0 +1,34 @@
+set(akonadicontact_addresslocation_web_editor_SRCS
+ ../webengine/addresseslocationengineviewer.cpp
+ ../webengine/addresseslocationenginepage.cpp
+ )
+set(akonadicontact_webengine_LIB Qt5::WebEngine Qt5::WebEngineWidgets)
+
+ecm_qt_declare_logging_category(akonadicontact_addresslocation_web_editor_SRCS HEADER akonadi_contact_debug.h IDENTIFIER AKONADICONTACT_LOG CATEGORY_NAME org.kde.pim.akonadi_contact)
+
+set(addresseditor_SRCS
+ ${akonadicontact_addresslocation_web_editor_SRCS}
+ main.cpp
+ ../addresseslocationwidget.cpp
+ ../addresseslocationgrantleeformater.cpp
+ ../addressgrantleeobject.cpp
+ ../iconnamecache.cpp
+ ../addresslocationwidget.cpp
+ ../selectaddresstypecombobox.cpp
+ ../addresstypedialog.cpp
+ )
+
+add_executable(addresseditortest ${addresseditor_SRCS})
+
+target_link_libraries(addresseditortest
+ Qt5::Widgets
+ KF5::AkonadiContact
+ KF5::Contacts
+ KF5::I18n
+ KF5::Completion
+ Grantlee5::Templates
+ KF5::IconThemes
+ KF5::WidgetsAddons
+ ${akonadicontact_webengine_LIB}
+ )
+
diff --git a/src/contact-editor/editor/addresseditor/tests/main.cpp b/src/contact-editor/editor/addresseditor/tests/main.cpp
new file mode 100644
index 0000000..ff97a9f
--- /dev/null
+++ b/src/contact-editor/editor/addresseditor/tests/main.cpp
@@ -0,0 +1,35 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 <QApplication>
+
+#include "../addresseslocationwidget.h"
+using namespace Akonadi;
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ AddressesLocationWidget *addresseslocationwidget = new AddressesLocationWidget;
+ addresseslocationwidget->show();
+
+ return app.exec();
+}
diff --git a/src/contact-editor/editor/addresseditor/webengine/addresseslocationenginepage.cpp b/src/contact-editor/editor/addresseditor/webengine/addresseslocationenginepage.cpp
new file mode 100644
index 0000000..637e1e3
--- /dev/null
+++ b/src/contact-editor/editor/addresseditor/webengine/addresseslocationenginepage.cpp
@@ -0,0 +1,66 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "addresseslocationenginepage.h"
+#include <QWebEngineSettings>
+#include <QWebEngineProfile>
+
+using namespace Akonadi;
+
+AddressesLocationEnginePage::AddressesLocationEnginePage(QObject *parent)
+ : QWebEnginePage(parent)
+{
+ settings()->setAttribute(QWebEngineSettings::JavascriptEnabled, false);
+ settings()->setAttribute(QWebEngineSettings::PluginsEnabled, false);
+ settings()->setAttribute(QWebEngineSettings::AutoLoadImages, true);
+ settings()->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, false);
+ settings()->setAttribute(QWebEngineSettings::JavascriptCanAccessClipboard, false);
+ settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, false);
+ settings()->setAttribute(QWebEngineSettings::XSSAuditingEnabled, false);
+ settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
+ settings()->setAttribute(QWebEngineSettings::LocalContentCanAccessRemoteUrls, false);
+ settings()->setAttribute(QWebEngineSettings::LocalContentCanAccessFileUrls, false);
+ settings()->setAttribute(QWebEngineSettings::ScreenCaptureEnabled, false);
+ settings()->setAttribute(QWebEngineSettings::WebGLEnabled, false);
+ settings()->setAttribute(QWebEngineSettings::AutoLoadIconsForPage, false);
+ settings()->setAttribute(QWebEngineSettings::Accelerated2dCanvasEnabled, false);
+ settings()->setAttribute(QWebEngineSettings::WebGLEnabled, false);
+
+#if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)
+ settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, false);
+ settings()->setAttribute(QWebEngineSettings::AllowRunningInsecureContent, false);
+#endif
+ profile()->setPersistentCookiesPolicy(QWebEngineProfile::NoPersistentCookies);
+
+}
+
+AddressesLocationEnginePage::~AddressesLocationEnginePage()
+{
+
+}
+
+bool AddressesLocationEnginePage::acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame)
+{
+ Q_UNUSED(type);
+ Q_UNUSED(isMainFrame);
+ Q_EMIT urlClicked(url);
+ return false;
+}
diff --git a/src/contact-editor/editor/addresseditor/webengine/addresseslocationenginepage.h b/src/contact-editor/editor/addresseditor/webengine/addresseslocationenginepage.h
new file mode 100644
index 0000000..77f3ef8
--- /dev/null
+++ b/src/contact-editor/editor/addresseditor/webengine/addresseslocationenginepage.h
@@ -0,0 +1,44 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 ADDRESSESLOCATIONENGINEPAGE_H
+#define ADDRESSESLOCATIONENGINEPAGE_H
+
+#include <QWebEnginePage>
+
+namespace Akonadi
+{
+class AddressesLocationEnginePage : public QWebEnginePage
+{
+ Q_OBJECT
+public:
+ explicit AddressesLocationEnginePage(QObject *parent = nullptr);
+ ~AddressesLocationEnginePage();
+
+Q_SIGNALS:
+ void urlClicked(const QUrl &url);
+
+protected:
+ bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame) override;
+};
+}
+
+#endif // ADDRESSESLOCATIONENGINEPAGE_H
diff --git a/src/contact-editor/editor/addresseditor/webengine/addresseslocationengineviewer.cpp b/src/contact-editor/editor/addresseditor/webengine/addresseslocationengineviewer.cpp
new file mode 100644
index 0000000..d6fddcc
--- /dev/null
+++ b/src/contact-editor/editor/addresseditor/webengine/addresseslocationengineviewer.cpp
@@ -0,0 +1,145 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "addresseslocationengineviewer.h"
+#include "addresseslocationenginepage.h"
+#include "akonadi_contact_debug.h"
+#include "../addresseslocationgrantleeformater.h"
+#include <KMessageBox>
+#include <KLocalizedString>
+#include <QUrlQuery>
+#include <QWebEngineSettings>
+
+using namespace Akonadi;
+
+AddressesLocationEngineViewer::AddressesLocationEngineViewer(QWidget *parent)
+ : QWebEngineView(parent),
+ mAddressesLocationGrantleeFormatter(new AddressesLocationGrantleeFormater(this)),
+ mEditMode(false)
+{
+
+ AddressesLocationEnginePage *pageEngine = new AddressesLocationEnginePage(this);
+ setPage(pageEngine);
+
+ setFocusPolicy(Qt::WheelFocus);
+ connect(pageEngine, &AddressesLocationEnginePage::urlClicked, this, &AddressesLocationEngineViewer::slotLinkClicked);
+
+ setContextMenuPolicy(Qt::CustomContextMenu);
+}
+
+AddressesLocationEngineViewer::~AddressesLocationEngineViewer()
+{
+
+}
+
+void AddressesLocationEngineViewer::setReadOnly(bool readOnly)
+{
+ mAddressesLocationGrantleeFormatter->setReadOnly(readOnly);
+ updateView();
+}
+
+void AddressesLocationEngineViewer::slotLinkClicked(const QUrl &url)
+{
+ if (url.scheme() == QLatin1String("addresslocationaction")) {
+ const QString urlPath(url.path());
+ if (url.hasQuery()) {
+ const QUrlQuery urlQuery(url);
+ const int addressId = urlQuery.queryItemValue(QStringLiteral("id")).toInt();
+ if (urlPath == QStringLiteral("removeaddress")) {
+ if (!mEditMode) {
+ removeAddress(addressId);
+ }
+ } else if (urlPath == QStringLiteral("editaddress")) {
+ if (!mEditMode) {
+ editAddress(addressId);
+ }
+ } else {
+ qCDebug(AKONADICONTACT_LOG) << "Unknown url" << url;
+ }
+ }
+ }
+}
+
+void AddressesLocationEngineViewer::removeAddress(int index)
+{
+ if (index < 0) {
+ return;
+ } else if (index < mAddresses.count()) {
+ const int result = KMessageBox::questionYesNo(this, i18n("Do you really want to delete this address?"));
+
+ if (result != KMessageBox::Yes) {
+ return;
+ }
+ mAddresses.remove(index);
+ updateView();
+ }
+}
+
+void AddressesLocationEngineViewer::editAddress(int index)
+{
+ if (index < 0) {
+ return;
+ } else if (index < mAddresses.count()) {
+ mEditMode = true;
+ Q_EMIT modifyAddress(mAddresses.at(index), index);
+ }
+}
+
+void AddressesLocationEngineViewer::replaceAddress(const KContacts::Address &address, int index)
+{
+ if (index < 0) {
+ return;
+ } else if (index < mAddresses.count()) {
+ mAddresses[index] = address;
+ updateView();
+ }
+ mEditMode = false;
+}
+
+void AddressesLocationEngineViewer::updateAddressCanceled()
+{
+ mEditMode = false;
+}
+
+void AddressesLocationEngineViewer::updateView()
+{
+ const QString html = mAddressesLocationGrantleeFormatter->formatAddresses(mAddresses);
+ setHtml(html, QUrl(QStringLiteral("file://")));
+}
+
+void AddressesLocationEngineViewer::addAddress(const KContacts::Address &address)
+{
+ if (!address.isEmpty()) {
+ mAddresses.append(address);
+ updateView();
+ }
+}
+
+KContacts::Address::List AddressesLocationEngineViewer::addresses() const
+{
+ return mAddresses;
+}
+
+void AddressesLocationEngineViewer::setAddresses(const KContacts::Address::List &addresses)
+{
+ mAddresses = addresses;
+ updateView();
+}
diff --git a/src/contact-editor/editor/addresseditor/webengine/addresseslocationengineviewer.h b/src/contact-editor/editor/addresseditor/webengine/addresseslocationengineviewer.h
new file mode 100644
index 0000000..f31af6b
--- /dev/null
+++ b/src/contact-editor/editor/addresseditor/webengine/addresseslocationengineviewer.h
@@ -0,0 +1,61 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 AddressesLocationEngineViewer_H
+#define AddressesLocationEngineViewer_H
+
+#include <QWebEngineView>
+#include <KContacts/Address>
+namespace Akonadi
+{
+class AddressesLocationGrantleeFormater;
+class AddressesLocationEngineViewer : public QWebEngineView
+{
+ Q_OBJECT
+public:
+ explicit AddressesLocationEngineViewer(QWidget *parent = nullptr);
+ ~AddressesLocationEngineViewer();
+
+ KContacts::Address::List addresses() const;
+ void setAddresses(const KContacts::Address::List &addresses);
+ void setReadOnly(bool readOnly);
+
+public Q_SLOTS:
+ void addAddress(const KContacts::Address &address);
+ void replaceAddress(const KContacts::Address &address, int index);
+ void updateAddressCanceled();
+
+private Q_SLOTS:
+ void slotLinkClicked(const QUrl &url);
+
+Q_SIGNALS:
+ void modifyAddress(const KContacts::Address &address, int currentIndex);
+
+private:
+ void updateView();
+ void editAddress(int index);
+ void removeAddress(int index);
+ KContacts::Address::List mAddresses;
+ AddressesLocationGrantleeFormater *mAddressesLocationGrantleeFormatter;
+ bool mEditMode;
+};
+}
+#endif
diff --git a/src/contact-editor/editor/businesseditor/businesseditorwidget.cpp b/src/contact-editor/editor/businesseditor/businesseditorwidget.cpp
new file mode 100644
index 0000000..b09afa1
--- /dev/null
+++ b/src/contact-editor/editor/businesseditor/businesseditorwidget.cpp
@@ -0,0 +1,179 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "businesseditorwidget.h"
+#include "../utils/utils.h"
+
+#include <KLineEdit>
+#include <KLocalizedString>
+#include <QGridLayout>
+#include <QLabel>
+
+#include "freebusyeditwidget.h"
+#include "../widgets/imagewidget.h"
+
+#include <KContacts/Addressee>
+
+using namespace Akonadi;
+
+BusinessEditorWidget::BusinessEditorWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ QHBoxLayout *topLayout = new QHBoxLayout(this);
+
+ QVBoxLayout *logoLayout = new QVBoxLayout;
+ topLayout->addLayout(logoLayout);
+
+ // setup general group box
+ mLogoWidget = new ImageWidget(ImageWidget::Logo);
+ logoLayout->addWidget(mLogoWidget, Qt::AlignTop);
+ logoLayout->addStretch(0);
+
+ QGridLayout *generalLayout = new QGridLayout;
+ topLayout->addLayout(generalLayout);
+
+ QLabel *label = new QLabel(i18nc("@label The organization of a contact", "Organization:"));
+ generalLayout->addWidget(label, 0, 0);
+
+ mOrganizationWidget = new KLineEdit;
+ mOrganizationWidget->setTrapReturnKey(true);
+ mOrganizationWidget->setPlaceholderText(i18n("Add organization's name"));
+ label->setBuddy(mOrganizationWidget);
+ generalLayout->addWidget(mOrganizationWidget, 1, 0);
+
+ label = new QLabel(i18nc("@label The profession of a contact", "Profession:"));
+ generalLayout->addWidget(label, 0, 1);
+
+ mProfessionWidget = new KLineEdit;
+ mProfessionWidget->setPlaceholderText(i18n("Add profession"));
+ mProfessionWidget->setTrapReturnKey(true);
+ label->setBuddy(mProfessionWidget);
+ generalLayout->addWidget(mProfessionWidget, 1, 1);
+
+ label = new QLabel(i18nc("@label The title of a contact", "Title:"));
+ generalLayout->addWidget(label, 3, 0);
+
+ mTitleWidget = new KLineEdit;
+ mTitleWidget->setPlaceholderText(i18n("Add the title"));
+ mTitleWidget->setTrapReturnKey(true);
+ label->setBuddy(mTitleWidget);
+ generalLayout->addWidget(mTitleWidget, 4, 0);
+
+ label = new QLabel(i18nc("@label The department of a contact", "Department:"));
+ generalLayout->addWidget(label, 3, 1);
+
+ mDepartmentWidget = new KLineEdit;
+ mDepartmentWidget->setPlaceholderText(i18n("Add the department"));
+ mDepartmentWidget->setTrapReturnKey(true);
+ label->setBuddy(mDepartmentWidget);
+ generalLayout->addWidget(mDepartmentWidget, 4, 1);
+
+ label = new QLabel(i18nc("@label The office of a contact", "Office:"));
+ generalLayout->addWidget(label, 5, 0);
+
+ mOfficeWidget = new KLineEdit;
+ mOfficeWidget->setTrapReturnKey(true);
+ mOfficeWidget->setPlaceholderText(i18n("Add the office"));
+
+ label->setBuddy(mOfficeWidget);
+ generalLayout->addWidget(mOfficeWidget, 6, 0);
+
+ label = new QLabel(i18nc("@label The manager's name of a contact", "Manager's name:"));
+ generalLayout->addWidget(label, 5, 1);
+
+ mManagerWidget = new KLineEdit;
+ mManagerWidget->setPlaceholderText(i18n("Add manager's name"));
+ mManagerWidget->setTrapReturnKey(true);
+ label->setBuddy(mManagerWidget);
+ generalLayout->addWidget(mManagerWidget, 6, 1);
+
+ label = new QLabel(i18nc("@label The assistant's name of a contact", "Assistant's name:"));
+ generalLayout->addWidget(label, 7, 0);
+
+ mAssistantWidget = new KLineEdit;
+ mAssistantWidget->setPlaceholderText(i18n("Add assistant's name"));
+ mAssistantWidget->setTrapReturnKey(true);
+ label->setBuddy(mAssistantWidget);
+ generalLayout->addWidget(mAssistantWidget, 8, 0);
+
+ // setup groupware group box
+ label = new QLabel(i18nc("@label The free/busy information of a contact", "Free/Busy:"));
+ generalLayout->addWidget(label, 7, 1);
+
+ mFreeBusyWidget = new FreeBusyEditWidget;
+ label->setBuddy(mFreeBusyWidget);
+ generalLayout->addWidget(mFreeBusyWidget, 8, 1);
+ generalLayout->setRowStretch(9, 1);
+ connect(mOrganizationWidget, &KLineEdit::textChanged, this, &BusinessEditorWidget::organizationChanged);
+}
+
+BusinessEditorWidget::~BusinessEditorWidget()
+{
+
+}
+
+void BusinessEditorWidget::loadContact(const KContacts::Addressee &contact)
+{
+ mLogoWidget->loadContact(contact);
+ mOrganizationWidget->setText(contact.organization());
+ mProfessionWidget->setText(Akonadi::Utils::loadCustom(contact, QStringLiteral("X-Profession")));
+ mTitleWidget->setText(contact.title());
+ mDepartmentWidget->setText(contact.department());
+ mOfficeWidget->setText(Akonadi::Utils::loadCustom(contact, QStringLiteral("X-Office")));
+ mManagerWidget->setText(Akonadi::Utils::loadCustom(contact, QStringLiteral("X-ManagersName")));
+ mAssistantWidget->setText(Akonadi::Utils::loadCustom(contact, QStringLiteral("X-AssistantsName")));
+
+ // groupware group
+ mFreeBusyWidget->loadContact(contact);
+
+}
+
+void BusinessEditorWidget::storeContact(KContacts::Addressee &contact)
+{
+ // general group
+ mLogoWidget->storeContact(contact);
+ contact.setOrganization(mOrganizationWidget->text());
+ Akonadi::Utils::storeCustom(contact, QStringLiteral("X-Profession"), mProfessionWidget->text().trimmed());
+ contact.setTitle(mTitleWidget->text().trimmed());
+ contact.setDepartment(mDepartmentWidget->text().trimmed());
+ Akonadi::Utils::storeCustom(contact, QStringLiteral("X-Office"), mOfficeWidget->text().trimmed());
+ Akonadi::Utils::storeCustom(contact, QStringLiteral("X-ManagersName"), mManagerWidget->text().trimmed());
+ Akonadi::Utils::storeCustom(contact, QStringLiteral("X-AssistantsName"), mAssistantWidget->text().trimmed());
+
+ // groupware group
+ mFreeBusyWidget->storeContact(contact);
+}
+
+void BusinessEditorWidget::setReadOnly(bool readOnly)
+{
+ mLogoWidget->setReadOnly(readOnly);
+ mOrganizationWidget->setReadOnly(readOnly);
+ mProfessionWidget->setReadOnly(readOnly);
+ mTitleWidget->setReadOnly(readOnly);
+ mDepartmentWidget->setReadOnly(readOnly);
+ mOfficeWidget->setReadOnly(readOnly);
+ mManagerWidget->setReadOnly(readOnly);
+ mAssistantWidget->setReadOnly(readOnly);
+
+ // widgets from groupware group
+ mFreeBusyWidget->setReadOnly(readOnly);
+
+}
diff --git a/src/contact-editor/editor/businesseditor/businesseditorwidget.h b/src/contact-editor/editor/businesseditor/businesseditorwidget.h
new file mode 100644
index 0000000..768b796
--- /dev/null
+++ b/src/contact-editor/editor/businesseditor/businesseditorwidget.h
@@ -0,0 +1,59 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 BUSINESSEDITORWIDGET_H
+#define BUSINESSEDITORWIDGET_H
+
+#include <QWidget>
+class KLineEdit;
+class ImageWidget;
+class FreeBusyEditWidget;
+namespace KContacts
+{
+class Addressee;
+}
+namespace Akonadi
+{
+class BusinessEditorWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit BusinessEditorWidget(QWidget *parent = nullptr);
+ ~BusinessEditorWidget();
+ void loadContact(const KContacts::Addressee &contact);
+ void storeContact(KContacts::Addressee &contact);
+ void setReadOnly(bool readOnly);
+
+Q_SIGNALS:
+ void organizationChanged(const QString &text);
+
+private:
+ KLineEdit *mOrganizationWidget;
+ KLineEdit *mProfessionWidget;
+ KLineEdit *mTitleWidget;
+ KLineEdit *mDepartmentWidget;
+ KLineEdit *mOfficeWidget;
+ KLineEdit *mManagerWidget;
+ KLineEdit *mAssistantWidget;
+ FreeBusyEditWidget *mFreeBusyWidget;
+ ImageWidget *mLogoWidget;
+};
+}
+#endif // BUSINESSEDITORWIDGET_H
diff --git a/src/contact-editor/editor/businesseditor/freebusyeditwidget.cpp b/src/contact-editor/editor/businesseditor/freebusyeditwidget.cpp
new file mode 100644
index 0000000..0c57c9f
--- /dev/null
+++ b/src/contact-editor/editor/businesseditor/freebusyeditwidget.cpp
@@ -0,0 +1,81 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (c) 2009 Tobias Koenig <[email protected]>
+
+ 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 "freebusyeditwidget.h"
+
+#include <kcontacts/addressee.h>
+#include <kurlrequester.h>
+#include <KConfig>
+#include <KConfigGroup>
+#include <KLineEdit>
+#include <KLocalizedString>
+
+#include <QHBoxLayout>
+#include <QStandardPaths>
+
+FreeBusyEditWidget::FreeBusyEditWidget(QWidget *parent)
+ : QWidget(parent)
+ , mReadOnly(false)
+{
+ QHBoxLayout *layout = new QHBoxLayout(this);
+ layout->setMargin(0);
+
+ mURL = new KUrlRequester(this);
+ mURL->lineEdit()->setTrapReturnKey(true);
+ mURL->lineEdit()->setPlaceholderText(i18n("Add FreeBusy"));
+ layout->addWidget(mURL);
+ setFocusProxy(mURL);
+ setFocusPolicy(Qt::StrongFocus);
+}
+
+FreeBusyEditWidget::~FreeBusyEditWidget()
+{
+}
+
+static QString freeBusyUrlStore()
+{
+ return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + QStringLiteral("korganizer/freebusyurls");
+}
+
+void FreeBusyEditWidget::loadContact(const KContacts::Addressee &contact)
+{
+ if (contact.preferredEmail().isEmpty()) {
+ return;
+ }
+
+ KConfig config(freeBusyUrlStore());
+ mURL->setUrl(QUrl(config.group(contact.preferredEmail()).readEntry("url")));
+}
+
+void FreeBusyEditWidget::storeContact(KContacts::Addressee &contact) const
+{
+ if (contact.preferredEmail().isEmpty()) {
+ return;
+ }
+
+ KConfig config(freeBusyUrlStore());
+ config.group(contact.preferredEmail()).writeEntry("url", mURL->url().url());
+}
+
+void FreeBusyEditWidget::setReadOnly(bool readOnly)
+{
+ mURL->setEnabled(!readOnly);
+}
diff --git a/src/contact-editor/editor/businesseditor/freebusyeditwidget.h b/src/contact-editor/editor/businesseditor/freebusyeditwidget.h
new file mode 100644
index 0000000..8527da8
--- /dev/null
+++ b/src/contact-editor/editor/businesseditor/freebusyeditwidget.h
@@ -0,0 +1,52 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (c) 2009 Tobias Koenig <[email protected]>
+
+ 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 FREEBUSYEDITWIDGET_H
+#define FREEBUSYEDITWIDGET_H
+
+#include <QWidget>
+
+namespace KContacts
+{
+class Addressee;
+}
+
+class KUrlRequester;
+
+class FreeBusyEditWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit FreeBusyEditWidget(QWidget *parent = nullptr);
+ ~FreeBusyEditWidget();
+
+ void loadContact(const KContacts::Addressee &contact);
+ void storeContact(KContacts::Addressee &contact) const;
+
+ void setReadOnly(bool readOnly);
+
+private:
+ KUrlRequester *mURL;
+ bool mReadOnly;
+};
+
+#endif
diff --git a/src/contact-editor/editor/contacteditorwidget.cpp b/src/contact-editor/editor/contacteditorwidget.cpp
new file mode 100644
index 0000000..5ed58fb
--- /dev/null
+++ b/src/contact-editor/editor/contacteditorwidget.cpp
@@ -0,0 +1,287 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (c) 2009 Tobias Koenig <[email protected]>
+
+ 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 "contacteditorwidget.h"
+#include "config-contact-editor.h"
+
+#include "personaleditor/personaleditorwidget.h"
+#include "contacteditorpageplugin.h"
+#include "contactmetadatabase_p.h"
+
+
+#include <kconfig.h>
+#include <kconfiggroup.h>
+#include <KLocalizedString>
+#include <qtabwidget.h>
+#include <ktextedit.h>
+
+#include <QDirIterator>
+#include <QPluginLoader>
+#include <QVBoxLayout>
+#include "addresseditor/addresseslocationwidget.h"
+#include "customfieldeditor/customfieldswidget.h"
+#include "businesseditor/businesseditorwidget.h"
+#include "generalinfoeditor/generalinfowidget.h"
+
+class Q_DECL_HIDDEN ContactEditorWidget::Private
+{
+public:
+ Private(ContactEditorWidget::DisplayMode displayMode, ContactEditorWidget *parent)
+ : mDisplayMode(displayMode)
+ , mParent(parent)
+ , mCustomFieldsWidget(nullptr)
+ {
+ }
+
+ void initGui();
+ void initGuiContactTab();
+ void initGuiLocationTab();
+ void initGuiBusinessTab();
+ void initGuiPersonalTab();
+ void initGuiNotesTab();
+ void initGuiCustomFieldsTab();
+
+ void loadCustomPages();
+
+ QString loadCustom(const KContacts::Addressee &contact, const QString &key) const;
+ void storeCustom(KContacts::Addressee &contact, const QString &key, const QString &value) const;
+
+ ContactEditorWidget::DisplayMode mDisplayMode;
+ ContactEditorWidget *mParent;
+ QTabWidget *mTabWidget;
+
+ Akonadi::GeneralInfoWidget *mGeneralInfoWidget;
+
+ // widgets from addresses group
+ Akonadi::AddressesLocationWidget *mAddressesLocationWidget;
+
+ Akonadi::BusinessEditorWidget *mBusinessEditorWidget;
+
+ // widgets from notes group
+ KTextEdit *mNotesWidget;
+
+ Akonadi::PersonalEditorWidget *mPersonalEditorWidget;
+
+ // widgets from custom fields group
+ Akonadi::CustomFieldsWidget *mCustomFieldsWidget;
+
+ // custom editor pages
+ QList<Akonadi::ContactEditorPagePlugin *> mCustomPages;
+};
+
+void ContactEditorWidget::Private::initGui()
+{
+ QVBoxLayout *layout = new QVBoxLayout(mParent);
+ layout->setMargin(0);
+
+ mTabWidget = new QTabWidget(mParent);
+ layout->addWidget(mTabWidget);
+
+ initGuiContactTab();
+ initGuiLocationTab();
+ initGuiBusinessTab();
+ initGuiPersonalTab();
+ initGuiNotesTab();
+ if (mDisplayMode == FullMode) {
+ initGuiCustomFieldsTab();
+ loadCustomPages();
+ }
+}
+
+void ContactEditorWidget::Private::initGuiContactTab()
+{
+ mGeneralInfoWidget = new Akonadi::GeneralInfoWidget;
+ mTabWidget->addTab(mGeneralInfoWidget, i18nc("@title:tab", "Contact"));
+}
+
+void ContactEditorWidget::Private::initGuiLocationTab()
+{
+ mAddressesLocationWidget = new Akonadi::AddressesLocationWidget;
+ mTabWidget->addTab(mAddressesLocationWidget, i18nc("@title:tab", "Location"));
+}
+
+void ContactEditorWidget::Private::initGuiBusinessTab()
+{
+ mBusinessEditorWidget = new Akonadi::BusinessEditorWidget();
+ mTabWidget->addTab(mBusinessEditorWidget, i18nc("@title:tab", "Business"));
+}
+
+void ContactEditorWidget::Private::initGuiPersonalTab()
+{
+ mPersonalEditorWidget = new Akonadi::PersonalEditorWidget;
+ mTabWidget->addTab(mPersonalEditorWidget, i18nc("@title:tab Personal properties of a contact", "Personal"));
+}
+
+void ContactEditorWidget::Private::initGuiNotesTab()
+{
+ QWidget *widget = new QWidget;
+ QVBoxLayout *layout = new QVBoxLayout(widget);
+
+ mTabWidget->addTab(widget, i18nc("@title:tab", "Notes"));
+
+ mNotesWidget = new KTextEdit;
+ mNotesWidget->setAcceptRichText(false);
+ layout->addWidget(mNotesWidget);
+}
+
+void ContactEditorWidget::Private::initGuiCustomFieldsTab()
+{
+ mCustomFieldsWidget = new Akonadi::CustomFieldsWidget;
+ mTabWidget->addTab(mCustomFieldsWidget, i18nc("@title:tab", "Custom Fields"));
+}
+
+void ContactEditorWidget::Private::loadCustomPages()
+{
+ qDeleteAll(mCustomPages);
+ mCustomPages.clear();
+
+ const QString pluginDirectory = QStringLiteral("%1/akonadi/contact/editorpageplugins/").arg(QStringLiteral(AKONADI_CONTACT_LIB));
+ QDirIterator it(pluginDirectory, QDir::Files);
+
+ while (it.hasNext()) {
+ QPluginLoader loader(it.next());
+ if (!loader.load()) {
+ continue;
+ }
+
+ Akonadi::ContactEditorPagePlugin *plugin = qobject_cast<Akonadi::ContactEditorPagePlugin *>(loader.instance());
+ if (!plugin) {
+ continue;
+ }
+
+ mCustomPages.append(plugin);
+ }
+
+ for (Akonadi::ContactEditorPagePlugin *plugin : qAsConst(mCustomPages)) {
+ mTabWidget->addTab(plugin, plugin->title());
+ }
+}
+
+QString ContactEditorWidget::Private::loadCustom(const KContacts::Addressee &contact, const QString &key) const
+{
+ return contact.custom(QStringLiteral("KADDRESSBOOK"), key);
+}
+
+void ContactEditorWidget::Private::storeCustom(KContacts::Addressee &contact, const QString &key, const QString &value) const
+{
+ if (value.isEmpty()) {
+ contact.removeCustom(QStringLiteral("KADDRESSBOOK"), key);
+ } else {
+ contact.insertCustom(QStringLiteral("KADDRESSBOOK"), key, value);
+ }
+}
+
+ContactEditorWidget::ContactEditorWidget(QWidget *parent)
+ : d(new Private(FullMode, this))
+{
+ Q_UNUSED(parent)
+ d->initGui();
+}
+
+ContactEditorWidget::ContactEditorWidget(ContactEditorWidget::DisplayMode displayMode, QWidget *parent)
+ : d(new Private(displayMode, this))
+{
+ Q_UNUSED(parent)
+ d->initGui();
+}
+
+ContactEditorWidget::~ContactEditorWidget()
+{
+ delete d;
+}
+
+void ContactEditorWidget::loadContact(const KContacts::Addressee &contact, const Akonadi::ContactMetaDataBase &metaData)
+{
+ d->mGeneralInfoWidget->loadContact(contact);
+
+ // address group
+ d->mAddressesLocationWidget->loadContact(contact);
+
+ // general group
+ d->mBusinessEditorWidget->loadContact(contact);
+ // notes group
+ d->mNotesWidget->setPlainText(contact.note());
+
+ d->mPersonalEditorWidget->loadContact(contact);
+ d->mGeneralInfoWidget->setDisplayType((DisplayNameEditWidget::DisplayType)metaData.displayNameMode());
+ if (d->mDisplayMode == FullMode) {
+ // custom fields group
+ d->mCustomFieldsWidget->setLocalCustomFieldDescriptions(metaData.customFieldDescriptions());
+ d->mCustomFieldsWidget->loadContact(contact);
+
+ // custom pages
+ for (Akonadi::ContactEditorPagePlugin *plugin : qAsConst(d->mCustomPages)) {
+ plugin->loadContact(contact);
+ }
+ }
+}
+
+void ContactEditorWidget::storeContact(KContacts::Addressee &contact, Akonadi::ContactMetaDataBase &metaData) const
+{
+ d->mGeneralInfoWidget->storeContact(contact);
+
+ // address group
+ d->mAddressesLocationWidget->storeContact(contact);
+
+ // general group
+ d->mBusinessEditorWidget->storeContact(contact);
+
+ // notes group
+ contact.setNote(d->mNotesWidget->toPlainText());
+ d->mPersonalEditorWidget->storeContact(contact);
+
+ if (d->mDisplayMode == FullMode) {
+ // custom fields group
+ d->mCustomFieldsWidget->storeContact(contact);
+ metaData.setCustomFieldDescriptions(d->mCustomFieldsWidget->localCustomFieldDescriptions());
+
+ metaData.setDisplayNameMode(d->mGeneralInfoWidget->displayType());
+
+ // custom pages
+ for (Akonadi::ContactEditorPagePlugin *plugin : qAsConst(d->mCustomPages)) {
+ plugin->storeContact(contact);
+ }
+ }
+}
+
+void ContactEditorWidget::setReadOnly(bool readOnly)
+{
+ d->mGeneralInfoWidget->setReadOnly(readOnly);
+ // widgets from addresses group
+ d->mAddressesLocationWidget->setReadOnly(readOnly);
+
+ // widgets from general group
+ d->mBusinessEditorWidget->setReadOnly(readOnly);
+
+ // widgets from notes group
+ d->mNotesWidget->setReadOnly(readOnly);
+
+ d->mPersonalEditorWidget->setReadOnly(readOnly);
+ if (d->mDisplayMode == FullMode) {
+ // widgets from custom fields group
+ d->mCustomFieldsWidget->setReadOnly(readOnly);
+
+ // custom pages
+ for (Akonadi::ContactEditorPagePlugin *plugin : qAsConst(d->mCustomPages)) {
+ plugin->setReadOnly(readOnly);
+ }
+ }
+}
diff --git a/src/contact-editor/editor/contacteditorwidget.h b/src/contact-editor/editor/contacteditorwidget.h
new file mode 100644
index 0000000..6726732
--- /dev/null
+++ b/src/contact-editor/editor/contacteditorwidget.h
@@ -0,0 +1,82 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (c) 2009 Tobias Koenig <[email protected]>
+
+ 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 CONTACTEDITOR_H
+#define CONTACTEDITOR_H
+
+#include "abstractcontacteditorwidget_p.h"
+#include "contacteditor_export.h"
+namespace KContacts
+{
+class Addressee;
+}
+
+/**
+ * @short A widget for editing a contact.
+ *
+ * @author Tobias Koenig <[email protected]>
+ */
+class CONTACTEDITOR_EXPORT ContactEditorWidget : public Akonadi::AbstractContactEditorWidget
+{
+public:
+ enum DisplayMode {
+ FullMode, ///< Show all pages
+ VCardMode ///< Show just pages with elements stored in vcard.
+ };
+
+ /**
+ * Creates a new contact editor widget.
+ *
+ * @param parent The parent widget.
+ */
+ explicit ContactEditorWidget(QWidget *parent = nullptr);
+
+ ContactEditorWidget(DisplayMode displayMode, QWidget *parent);
+
+ /**
+ * Destroys the contact editor widget.
+ */
+ ~ContactEditorWidget();
+
+ /**
+ * Initializes the fields of the contact editor
+ * with the values from a @p contact.
+ */
+ void loadContact(const KContacts::Addressee &contact, const Akonadi::ContactMetaDataBase &metaData) override;
+
+ /**
+ * Stores back the fields of the contact editor
+ * into the given @p contact.
+ */
+ void storeContact(KContacts::Addressee &contact, Akonadi::ContactMetaDataBase &metaData) const override;
+
+ /**
+ * Sets whether the contact in the editor allows
+ * the user to edit the contact or not.
+ */
+ void setReadOnly(bool readOnly) override;
+
+private:
+ class Private;
+ Private *const d;
+};
+
+#endif
diff --git a/src/contact-editor/editor/customfieldeditor/autotests/CMakeLists.txt b/src/contact-editor/editor/customfieldeditor/autotests/CMakeLists.txt
new file mode 100644
index 0000000..f2826e8
--- /dev/null
+++ b/src/contact-editor/editor/customfieldeditor/autotests/CMakeLists.txt
@@ -0,0 +1,20 @@
+set(customfieldswidgettest_SRCS customfieldswidgettest.cpp ../customfieldswidget.cpp ../customfieldeditorwidget.cpp ../customfieldslistwidget.cpp ../customfieldsmodel.cpp
+ ../../../customfields.cpp ../customfieldslistdelegate.cpp ../../../customfieldmanager.cpp ../../utils/utils.cpp)
+add_executable(customfieldswidgettest ${customfieldswidgettest_SRCS})
+add_test(customfieldswidgettest customfieldswidgettest)
+ecm_mark_as_test(customfieldswidgettest)
+target_link_libraries(customfieldswidgettest Qt5::Test Qt5::Widgets KF5::AkonadiContact KF5::Contacts KF5::I18n KF5::Completion KF5::ConfigCore KF5::WidgetsAddons)
+
+
+set(customfieldeditorwidgettest_SRCS customfieldeditorwidgettest.cpp ../customfieldeditorwidget.cpp ../../../customfields.cpp)
+add_executable(customfieldeditorwidgettest ${customfieldeditorwidgettest_SRCS})
+add_test(customfieldeditorwidgettest customfieldeditorwidgettest)
+ecm_mark_as_test(customfieldeditorwidgettest)
+target_link_libraries(customfieldeditorwidgettest Qt5::Test Qt5::Widgets KF5::AkonadiContact KF5::Contacts KF5::I18n KF5::Completion KF5::WidgetsAddons)
+
+set(customfieldslistwidgettest_SRCS customfieldslistwidgettest.cpp ../customfieldslistwidget.cpp ../../../customfields.cpp ../customfieldsmodel.cpp
+ ../customfieldslistdelegate.cpp ../../../customfieldmanager.cpp ../../utils/utils.cpp)
+add_executable(customfieldslistwidgettest ${customfieldslistwidgettest_SRCS})
+add_test(customfieldslistwidgettest customfieldslistwidgettest)
+ecm_mark_as_test(customfieldslistwidgettest)
+target_link_libraries(customfieldslistwidgettest Qt5::Test Qt5::Widgets KF5::AkonadiContact KF5::Contacts KF5::I18n KF5::Completion KF5::ConfigCore KF5::WidgetsAddons)
diff --git a/src/contact-editor/editor/customfieldeditor/autotests/customfieldeditorwidgettest.cpp b/src/contact-editor/editor/customfieldeditor/autotests/customfieldeditorwidgettest.cpp
new file mode 100644
index 0000000..ba07e4c
--- /dev/null
+++ b/src/contact-editor/editor/customfieldeditor/autotests/customfieldeditorwidgettest.cpp
@@ -0,0 +1,91 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "customfieldeditorwidgettest.h"
+#include "../customfieldeditorwidget.h"
+#include <QTest>
+#include <QLabel>
+#include <QLineEdit>
+#include <QPushButton>
+#include <QComboBox>
+
+CustomFieldEditorWidgetTest::CustomFieldEditorWidgetTest(QObject *parent)
+ : QObject(parent)
+{
+
+}
+
+CustomFieldEditorWidgetTest::~CustomFieldEditorWidgetTest()
+{
+
+}
+
+void CustomFieldEditorWidgetTest::shouldHaveDefaultValue()
+{
+ Akonadi::CustomFieldEditorWidget w;
+ QLineEdit *fieldname = w.findChild<QLineEdit *>(QStringLiteral("fieldname"));
+ QVERIFY(fieldname);
+ QVERIFY(fieldname->text().isEmpty());
+
+ QLabel *label = w.findChild<QLabel *>(QStringLiteral("labeltitle"));
+ QVERIFY(label);
+ QPushButton *addfield = w.findChild<QPushButton *>(QStringLiteral("addfield"));
+ QVERIFY(addfield);
+ QVERIFY(!addfield->isEnabled());
+
+ QComboBox *combobox = w.findChild<QComboBox *>(QStringLiteral("fieldtype"));
+ QVERIFY(combobox);
+ QVERIFY(combobox->count() > 0);
+ QCOMPARE(combobox->currentIndex(), 0);
+
+}
+
+void CustomFieldEditorWidgetTest::shouldEnableAddButtonWhenTextIsNotEmpty()
+{
+ Akonadi::CustomFieldEditorWidget w;
+ QLineEdit *fieldname = w.findChild<QLineEdit *>(QStringLiteral("fieldname"));
+ QVERIFY(fieldname->text().isEmpty());
+ QPushButton *addfield = w.findChild<QPushButton *>(QStringLiteral("addfield"));
+ QVERIFY(!addfield->isEnabled());
+
+ fieldname->setText(QStringLiteral("foo"));
+ QVERIFY(addfield->isEnabled());
+ fieldname->clear();
+ QVERIFY(!addfield->isEnabled());
+}
+
+void CustomFieldEditorWidgetTest::shouldClearEditorWhenPressAdd()
+{
+ Akonadi::CustomFieldEditorWidget w;
+ QLineEdit *fieldname = w.findChild<QLineEdit *>(QStringLiteral("fieldname"));
+ QPushButton *addfield = w.findChild<QPushButton *>(QStringLiteral("addfield"));
+ QComboBox *combobox = w.findChild<QComboBox *>(QStringLiteral("fieldtype"));
+ combobox->setCurrentIndex(1);
+ fieldname->setText(QStringLiteral("foo"));
+ QTest::mouseClick(addfield, Qt::LeftButton);
+ QVERIFY(fieldname->text().isEmpty());
+ QVERIFY(!addfield->isEnabled());
+ QCOMPARE(combobox->currentIndex(), 0);
+
+}
+
+QTEST_MAIN(CustomFieldEditorWidgetTest)
diff --git a/src/contact-editor/editor/customfieldeditor/autotests/customfieldeditorwidgettest.h b/src/contact-editor/editor/customfieldeditor/autotests/customfieldeditorwidgettest.h
new file mode 100644
index 0000000..fb0ebe8
--- /dev/null
+++ b/src/contact-editor/editor/customfieldeditor/autotests/customfieldeditorwidgettest.h
@@ -0,0 +1,41 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 CUSTOMFIELDEDITORWIDGETTEST_H
+#define CUSTOMFIELDEDITORWIDGETTEST_H
+
+#include <QObject>
+
+class CustomFieldEditorWidgetTest : public QObject
+{
+ Q_OBJECT
+public:
+ explicit CustomFieldEditorWidgetTest(QObject *parent = nullptr);
+ ~CustomFieldEditorWidgetTest();
+private Q_SLOTS:
+ void shouldHaveDefaultValue();
+ void shouldEnableAddButtonWhenTextIsNotEmpty();
+ void shouldClearEditorWhenPressAdd();
+
+};
+
+#endif // CUSTOMFIELDEDITORWIDGETTEST_H
diff --git a/src/contact-editor/editor/customfieldeditor/autotests/customfieldslistwidgettest.cpp b/src/contact-editor/editor/customfieldeditor/autotests/customfieldslistwidgettest.cpp
new file mode 100644
index 0000000..ed17f54
--- /dev/null
+++ b/src/contact-editor/editor/customfieldeditor/autotests/customfieldslistwidgettest.cpp
@@ -0,0 +1,35 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "customfieldslistwidgettest.h"
+#include <QTest>
+CustomFielsListWidgetTest::CustomFielsListWidgetTest(QObject *parent)
+ : QObject(parent)
+{
+
+}
+
+CustomFielsListWidgetTest::~CustomFielsListWidgetTest()
+{
+
+}
+
+QTEST_MAIN(CustomFielsListWidgetTest)
diff --git a/src/contact-editor/editor/customfieldeditor/autotests/customfieldslistwidgettest.h b/src/contact-editor/editor/customfieldeditor/autotests/customfieldslistwidgettest.h
new file mode 100644
index 0000000..b9cec4a
--- /dev/null
+++ b/src/contact-editor/editor/customfieldeditor/autotests/customfieldslistwidgettest.h
@@ -0,0 +1,35 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 CUSTOMFIELSLISTWIDGETTEST_H
+#define CUSTOMFIELSLISTWIDGETTEST_H
+
+#include <QObject>
+
+class CustomFielsListWidgetTest : public QObject
+{
+ Q_OBJECT
+public:
+ explicit CustomFielsListWidgetTest(QObject *parent = nullptr);
+ ~CustomFielsListWidgetTest();
+};
+
+#endif // CUSTOMFIELSLISTWIDGETTEST_H
diff --git a/src/contact-editor/editor/customfieldeditor/autotests/customfieldswidgettest.cpp b/src/contact-editor/editor/customfieldeditor/autotests/customfieldswidgettest.cpp
new file mode 100644
index 0000000..08b0596
--- /dev/null
+++ b/src/contact-editor/editor/customfieldeditor/autotests/customfieldswidgettest.cpp
@@ -0,0 +1,50 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "customfieldswidgettest.h"
+#include "../customfieldswidget.h"
+#include <QTest>
+#include <editor/customfieldeditor/customfieldeditorwidget.h>
+#include <editor/customfieldeditor/customfieldslistwidget.h>
+
+CustomFieldsWidgetTest::CustomFieldsWidgetTest(QObject *parent)
+ : QObject(parent)
+{
+
+}
+
+CustomFieldsWidgetTest::~CustomFieldsWidgetTest()
+{
+
+}
+
+void CustomFieldsWidgetTest::shouldHaveDefaultValue()
+{
+ Akonadi::CustomFieldsWidget w;
+ Akonadi::CustomFieldEditorWidget *customFieldEditorWidget = w.findChild<Akonadi::CustomFieldEditorWidget *>(QStringLiteral("customfieldeditorwidget"));
+ QVERIFY(customFieldEditorWidget);
+
+ Akonadi::CustomFieldsListWidget *customFieldsListWidget = w.findChild<Akonadi::CustomFieldsListWidget *>(QStringLiteral("customfieldslistwidget"));
+ QVERIFY(customFieldsListWidget);
+}
+
+QTEST_MAIN(CustomFieldsWidgetTest)
diff --git a/src/contact-editor/editor/customfieldeditor/autotests/customfieldswidgettest.h b/src/contact-editor/editor/customfieldeditor/autotests/customfieldswidgettest.h
new file mode 100644
index 0000000..8c1488e
--- /dev/null
+++ b/src/contact-editor/editor/customfieldeditor/autotests/customfieldswidgettest.h
@@ -0,0 +1,38 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 CUSTOMFIELDSWIDGETTEST_H
+#define CUSTOMFIELDSWIDGETTEST_H
+
+#include <QObject>
+
+class CustomFieldsWidgetTest : public QObject
+{
+ Q_OBJECT
+public:
+ explicit CustomFieldsWidgetTest(QObject *parent = nullptr);
+ ~CustomFieldsWidgetTest();
+private Q_SLOTS:
+ void shouldHaveDefaultValue();
+};
+
+#endif // CUSTOMFIELDSWIDGETTEST_H
diff --git a/src/contact-editor/editor/customfieldeditor/customfieldeditorwidget.cpp b/src/contact-editor/editor/customfieldeditor/customfieldeditorwidget.cpp
new file mode 100644
index 0000000..ba271e8
--- /dev/null
+++ b/src/contact-editor/editor/customfieldeditor/customfieldeditorwidget.cpp
@@ -0,0 +1,125 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "customfieldeditorwidget.h"
+#include "customfieldsmodel.h"
+#include <QGridLayout>
+#include <KLocalizedString>
+#include <QLabel>
+#include <QLineEdit>
+#include <QPushButton>
+#include <QComboBox>
+#include <QCheckBox>
+#include <QUuid>
+#include <KContacts/Addressee>
+
+using namespace Akonadi;
+
+CustomFieldEditorWidget::CustomFieldEditorWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ QVBoxLayout *topLayout = new QVBoxLayout(this);
+ QLabel *label = new QLabel(i18n("Custom Field Title"), this);
+ label->setObjectName(QStringLiteral("labeltitle"));
+
+ topLayout->addWidget(label);
+
+ QHBoxLayout *fieldLayout = new QHBoxLayout;
+ topLayout->addLayout(fieldLayout);
+ mFieldName = new QLineEdit(this);
+ mFieldName->setPlaceholderText(i18n("Add name"));
+ mFieldName->setObjectName(QStringLiteral("fieldname"));
+ fieldLayout->addWidget(mFieldName);
+
+ mFieldType = new QComboBox(this);
+ mFieldType->setObjectName(QStringLiteral("fieldtype"));
+ fieldLayout->addWidget(mFieldType);
+ fillTypes();
+
+ mAddField = new QPushButton(i18n("Add Field"), this);
+ mAddField->setObjectName(QStringLiteral("addfield"));
+ fieldLayout->addWidget(mAddField);
+ mAddField->setEnabled(false); //Disable at the beginning
+ connect(mAddField, &QPushButton::clicked, this, &CustomFieldEditorWidget::slotAddField);
+ connect(mFieldName, &QLineEdit::textChanged, this, &CustomFieldEditorWidget::slotFielNameChanged);
+
+ mUseAllContacts = new QCheckBox(i18n("Use field for all contacts"));
+ mUseAllContacts->setObjectName(QStringLiteral("useallcontact"));
+ topLayout->addWidget(mUseAllContacts);
+}
+
+CustomFieldEditorWidget::~CustomFieldEditorWidget()
+{
+
+}
+
+void CustomFieldEditorWidget::fillTypes()
+{
+ mFieldType->addItem(i18n("Text"), CustomField::TextType);
+ mFieldType->addItem(i18n("Numeric"), CustomField::NumericType);
+ mFieldType->addItem(i18n("Boolean"), CustomField::BooleanType);
+ mFieldType->addItem(i18n("Date"), CustomField::DateType);
+ mFieldType->addItem(i18n("Time"), CustomField::TimeType);
+ mFieldType->addItem(i18n("DateTime"), CustomField::DateTimeType);
+ mFieldType->addItem(i18n("Url"), CustomField::UrlType);
+}
+
+void CustomFieldEditorWidget::setReadOnly(bool readOnly)
+{
+ mFieldName->setReadOnly(readOnly);
+ mAddField->setEnabled(!readOnly && !mFieldName->text().trimmed().isEmpty());
+ mFieldType->setEnabled(!readOnly);
+ mUseAllContacts->setEnabled(!readOnly);
+}
+
+void CustomFieldEditorWidget::slotFielNameChanged(const QString &text)
+{
+ mAddField->setEnabled(!text.trimmed().isEmpty());
+}
+
+void CustomFieldEditorWidget::slotAddField()
+{
+ if (mFieldName->text().trimmed().isEmpty()) {
+ return;
+ }
+ CustomField field;
+ // We use a Uuid as default key, so we won't have any duplicated keys,
+ // the user can still change it to something else in the editor dialog.
+ // Since the key only allows [A-Za-z0-9\-]*, we have to remove the curly
+ // braces as well.
+ QString key = QUuid::createUuid().toString();
+ key.remove(QLatin1Char('{'));
+ key.remove(QLatin1Char('}'));
+
+ field.setKey(key);
+ field.setTitle(mFieldName->text());
+ field.setType(static_cast<CustomField::Type>(mFieldType->itemData(mFieldType->currentIndex()).toInt()));
+
+ //TODO verify it
+ if (field.scope() != CustomField::ExternalScope) {
+ // do not change the scope for externally defined custom fields
+ field.setScope(mUseAllContacts->isChecked() ? CustomField::GlobalScope : CustomField::LocalScope);
+ }
+ Q_EMIT addNewField(field);
+ mFieldName->clear();
+ mFieldType->setCurrentIndex(0);
+}
diff --git a/src/contact-editor/editor/customfieldeditor/customfieldeditorwidget.h b/src/contact-editor/editor/customfieldeditor/customfieldeditorwidget.h
new file mode 100644
index 0000000..9b8c74b
--- /dev/null
+++ b/src/contact-editor/editor/customfieldeditor/customfieldeditorwidget.h
@@ -0,0 +1,55 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 CUSTOMFIELDEDITORWIDGET_H
+#define CUSTOMFIELDEDITORWIDGET_H
+
+#include <QWidget>
+#include "customfields_p.h"
+class QLineEdit;
+class QPushButton;
+class QCheckBox;
+class QComboBox;
+namespace Akonadi
+{
+class CustomFieldEditorWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit CustomFieldEditorWidget(QWidget *parent = nullptr);
+ ~CustomFieldEditorWidget();
+ void setReadOnly(bool readOnly);
+
+Q_SIGNALS:
+ void addNewField(const CustomField &field);
+
+private:
+ void slotAddField();
+ void slotFielNameChanged(const QString &text);
+ void fillTypes();
+ QLineEdit *mFieldName;
+ QPushButton *mAddField;
+ QCheckBox *mUseAllContacts;
+ QComboBox *mFieldType;
+};
+}
+#endif // CUSTOMFIELDEDITORWIDGET_H
diff --git a/src/contact-editor/editor/customfieldeditor/customfieldslistdelegate.cpp b/src/contact-editor/editor/customfieldeditor/customfieldslistdelegate.cpp
new file mode 100644
index 0000000..9f160ee
--- /dev/null
+++ b/src/contact-editor/editor/customfieldeditor/customfieldslistdelegate.cpp
@@ -0,0 +1,242 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (c) 2010 Tobias Koenig <[email protected]>
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "customfieldslistdelegate.h"
+
+#include "customfieldsmodel.h"
+
+#include <KLocalizedString>
+#include <KMessageBox>
+
+#include <QDateEdit>
+#include <QDateTimeEdit>
+#include <QCheckBox>
+#include <QSpinBox>
+#include <QTimeEdit>
+#include <QMouseEvent>
+#include <QAbstractItemView>
+#include <QTimer>
+
+using namespace Akonadi;
+CustomFieldsListDelegate::CustomFieldsListDelegate(QAbstractItemView *view, QObject *parent)
+ : QStyledItemDelegate(parent),
+ mIcon(QIcon::fromTheme(QStringLiteral("list-remove"))),
+ mButtonSize(16, 16),
+ mItemView(view)
+{
+}
+
+CustomFieldsListDelegate::~CustomFieldsListDelegate()
+{
+}
+
+QWidget *CustomFieldsListDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &item, const QModelIndex &index) const
+{
+ if (index.column() == 1) {
+ const CustomField::Type type = static_cast<CustomField::Type>(index.data(CustomFieldsModel::TypeRole).toInt());
+
+ switch (type) {
+ case CustomField::TextType:
+ case CustomField::UrlType:
+ default:
+ return QStyledItemDelegate::createEditor(parent, item, index);
+ break;
+ case CustomField::NumericType: {
+ QSpinBox *editor = new QSpinBox(parent);
+ editor->setFrame(false);
+ editor->setAutoFillBackground(true);
+ return editor;
+ break;
+ }
+ case CustomField::BooleanType: {
+ QCheckBox *editor = new QCheckBox(parent);
+ return editor;
+ break;
+ }
+ case CustomField::DateType: {
+ QDateEdit *editor = new QDateEdit(parent);
+ editor->setFrame(false);
+ editor->setAutoFillBackground(true);
+ return editor;
+ break;
+ }
+ case CustomField::TimeType: {
+ QTimeEdit *editor = new QTimeEdit(parent);
+ editor->setFrame(false);
+ editor->setAutoFillBackground(true);
+ return editor;
+ break;
+ }
+ case CustomField::DateTimeType: {
+ QDateTimeEdit *editor = new QDateTimeEdit(parent);
+ editor->setFrame(false);
+ editor->setAutoFillBackground(true);
+ return editor;
+ break;
+ }
+ }
+ } else {
+ return QStyledItemDelegate::createEditor(parent, item, index);
+ }
+}
+
+void CustomFieldsListDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
+{
+ if (index.column() == 1) {
+ const CustomField::Type type = static_cast<CustomField::Type>(index.data(CustomFieldsModel::TypeRole).toInt());
+
+ switch (type) {
+ case CustomField::TextType:
+ case CustomField::UrlType:
+ QStyledItemDelegate::setEditorData(editor, index);
+ break;
+ case CustomField::NumericType: {
+ QSpinBox *widget = qobject_cast<QSpinBox *>(editor);
+ widget->setValue(index.data(Qt::EditRole).toInt());
+ break;
+ }
+ case CustomField::BooleanType: {
+ QCheckBox *widget = qobject_cast<QCheckBox *>(editor);
+ widget->setChecked(index.data(Qt::EditRole).toString() == QLatin1String("true"));
+ break;
+ }
+ case CustomField::DateType: {
+ QDateEdit *widget = qobject_cast<QDateEdit *>(editor);
+ widget->setDisplayFormat(QStringLiteral("dd.MM.yyyy"));
+ widget->setDate(QDate::fromString(index.data(Qt::EditRole).toString(), Qt::ISODate));
+ break;
+ }
+ case CustomField::TimeType: {
+ QTimeEdit *widget = qobject_cast<QTimeEdit *>(editor);
+ widget->setDisplayFormat(QStringLiteral("hh:mm"));
+ widget->setTime(QTime::fromString(index.data(Qt::EditRole).toString(), Qt::ISODate));
+ break;
+ }
+ case CustomField::DateTimeType: {
+ QDateTimeEdit *widget = qobject_cast<QDateTimeEdit *>(editor);
+ widget->setDisplayFormat(QStringLiteral("dd.MM.yyyy hh:mm"));
+ widget->setDateTime(QDateTime::fromString(index.data(Qt::EditRole).toString(), Qt::ISODate));
+ break;
+ }
+ }
+ } else {
+ QStyledItemDelegate::setEditorData(editor, index);
+ }
+}
+
+void CustomFieldsListDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
+{
+ if (index.column() == 1) {
+ const CustomField::Type type = static_cast<CustomField::Type>(index.data(CustomFieldsModel::TypeRole).toInt());
+
+ switch (type) {
+ case CustomField::TextType:
+ case CustomField::UrlType:
+ QStyledItemDelegate::setModelData(editor, model, index);
+ break;
+ case CustomField::NumericType: {
+ QSpinBox *widget = qobject_cast<QSpinBox *>(editor);
+ model->setData(index, QString::number(widget->value()));
+ break;
+ }
+ case CustomField::BooleanType: {
+ QCheckBox *widget = qobject_cast<QCheckBox *>(editor);
+ model->setData(index, widget->isChecked() ? QStringLiteral("true") : QStringLiteral("false"));
+ break;
+ }
+ case CustomField::DateType: {
+ QDateEdit *widget = qobject_cast<QDateEdit *>(editor);
+ model->setData(index, widget->date().toString(Qt::ISODate));
+ break;
+ }
+ case CustomField::TimeType: {
+ QTimeEdit *widget = qobject_cast<QTimeEdit *>(editor);
+ model->setData(index, widget->time().toString(Qt::ISODate));
+ break;
+ }
+ case CustomField::DateTimeType: {
+ QDateTimeEdit *widget = qobject_cast<QDateTimeEdit *>(editor);
+ model->setData(index, widget->dateTime().toString(Qt::ISODate));
+ break;
+ }
+ }
+ } else {
+ QStyledItemDelegate::setModelData(editor, model, index);
+ }
+}
+
+void CustomFieldsListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+ //TODO: somehow mark local/global/external fields
+ QStyledItemDelegate::paint(painter, option, index);
+ if (index.column() == 1) {
+ mIcon.paint(painter, option.rect, Qt::AlignRight);
+ }
+}
+
+QSize CustomFieldsListDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+ Q_UNUSED(option)
+
+ QSize hint = QStyledItemDelegate::sizeHint(option, index);
+ hint.setHeight(qMax(hint.height(), mButtonSize.height()));
+
+ if (index.column() == 1) {
+ hint.setWidth(hint.width() + mButtonSize.width());
+ }
+
+ return hint;
+}
+
+bool CustomFieldsListDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
+{
+ if (index.column() == 1) {
+ if (event->type() == QEvent::MouseButtonRelease) {
+ const QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
+ QRect buttonRect = mItemView->visualRect(index);
+ buttonRect.setLeft(buttonRect.right() - mButtonSize.width());
+
+ if (buttonRect.contains(mouseEvent->pos())) {
+ removeField(index.row(), model);
+ return true;
+ }
+ }
+ }
+ return QStyledItemDelegate::editorEvent(event, model, option, index);
+}
+
+void CustomFieldsListDelegate::setFirstColumnAsCurrent()
+{
+ mItemView->setCurrentIndex(mItemView->model()->index(mItemView->currentIndex().row(), 0));
+}
+
+void CustomFieldsListDelegate::removeField(int row, QAbstractItemModel *model)
+{
+ if (KMessageBox::warningContinueCancel(mItemView,
+ i18nc("Custom Fields", "Do you really want to delete the selected custom field?"),
+ i18n("Confirm Delete"), KStandardGuiItem::del()) != KMessageBox::Continue) {
+ return;
+ }
+
+ model->removeRow(row);
+ QTimer::singleShot(0, this, &CustomFieldsListDelegate::setFirstColumnAsCurrent);
+}
diff --git a/src/contact-editor/editor/customfieldeditor/customfieldslistdelegate.h b/src/contact-editor/editor/customfieldeditor/customfieldslistdelegate.h
new file mode 100644
index 0000000..812cd79
--- /dev/null
+++ b/src/contact-editor/editor/customfieldeditor/customfieldslistdelegate.h
@@ -0,0 +1,52 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (c) 2010 Tobias Koenig <[email protected]>
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 CUSTOMFIELDSLISTDELEGATE_H
+#define CUSTOMFIELDSLISTDELEGATE_H
+
+#include <QStyledItemDelegate>
+class QAbstractItemView;
+namespace Akonadi
+{
+class CustomFieldsListDelegate : public QStyledItemDelegate
+{
+public:
+ explicit CustomFieldsListDelegate(QAbstractItemView *view, QObject *parent = nullptr);
+ ~CustomFieldsListDelegate();
+
+ QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
+
+ void setEditorData(QWidget *editor, const QModelIndex &index) const override;
+ void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override;
+ void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
+ QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
+ bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) override;
+
+private:
+ void setFirstColumnAsCurrent();
+ void removeField(int row, QAbstractItemModel *model);
+ const QIcon mIcon;
+ QSize mButtonSize;
+ QAbstractItemView *mItemView;
+};
+}
+#endif
diff --git a/src/contact-editor/editor/customfieldeditor/customfieldslistwidget.cpp b/src/contact-editor/editor/customfieldeditor/customfieldslistwidget.cpp
new file mode 100644
index 0000000..c3f052e
--- /dev/null
+++ b/src/contact-editor/editor/customfieldeditor/customfieldslistwidget.cpp
@@ -0,0 +1,236 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "customfieldslistwidget.h"
+#include "../utils/utils.h"
+
+#include "customfieldmanager_p.h"
+#include "customfieldslistdelegate.h"
+#include <QSortFilterProxyModel>
+#include <QTreeView>
+#include <QVBoxLayout>
+#include <KContacts/Addressee>
+#include "customfieldsmodel.h"
+
+using namespace Akonadi;
+
+CustomFieldsListWidget::CustomFieldsListWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ QVBoxLayout *topLayout = new QVBoxLayout(this);
+ mCustomFieldList = new QTreeView(this);
+ mCustomFieldList->setObjectName(QStringLiteral("customfieldlist"));
+ mCustomFieldList->setSortingEnabled(true);
+ mCustomFieldList->setRootIsDecorated(false);
+ Akonadi::CustomFieldsListDelegate *customFieldDelegate = new Akonadi::CustomFieldsListDelegate(mCustomFieldList, this);
+ mCustomFieldList->setItemDelegate(customFieldDelegate);
+ topLayout->addWidget(mCustomFieldList);
+
+ mModel = new CustomFieldsModel(this);
+ QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel;
+ proxyModel->setDynamicSortFilter(true);
+ proxyModel->setSourceModel(mModel);
+ mCustomFieldList->setModel(proxyModel);
+ mCustomFieldList->setColumnHidden(2, true); // hide the 'key' column
+}
+
+CustomFieldsListWidget::~CustomFieldsListWidget()
+{
+
+}
+
+void CustomFieldsListWidget::loadContact(const KContacts::Addressee &contact)
+{
+ CustomField::List externalCustomFields;
+
+ CustomField::List globalCustomFields = CustomFieldManager::globalCustomFieldDescriptions();
+
+ const QStringList customs = contact.customs();
+ for (const QString &custom : customs) {
+
+ QString app, name, value;
+ Akonadi::Utils::splitCustomField(custom, app, name, value);
+
+ // skip all well-known fields that have separated editor widgets
+ if (custom.startsWith(QStringLiteral("messaging/"))) { // IM addresses
+ continue;
+ }
+
+ if (app == QLatin1String("KADDRESSBOOK")) {
+ static QSet<QString> blacklist;
+ if (blacklist.isEmpty()) {
+ blacklist << QStringLiteral("BlogFeed")
+ << QStringLiteral("X-IMAddress")
+ << QStringLiteral("X-Profession")
+ << QStringLiteral("X-Office")
+ << QStringLiteral("X-ManagersName")
+ << QStringLiteral("X-AssistantsName")
+ << QStringLiteral("X-Anniversary")
+ << QStringLiteral("X-SpousesName")
+ << QStringLiteral("MailPreferedFormatting")
+ << QStringLiteral("MailAllowToRemoteContent")
+ << QStringLiteral("CRYPTOPROTOPREF")
+ << QStringLiteral("OPENPGPFP")
+ << QStringLiteral("SMIMEFP")
+ << QStringLiteral("CRYPTOSIGNPREF")
+ << QStringLiteral("CRYPTOENCRYPTPREF");
+ }
+ QSet<QString> upperCaseBlacklist;
+ for (const QString &blacklistEntry : qAsConst(blacklist)) {
+ upperCaseBlacklist << blacklistEntry.toUpper();
+ }
+ blacklist.unite(upperCaseBlacklist);
+ if (blacklist.contains(name)) { // several KAddressBook specific fields
+ continue;
+ }
+ }
+
+ // check whether it correspond to a local custom field
+ bool isLocalCustomField = false;
+ const int localCustomFieldsCount(mLocalCustomFields.count());
+ for (int i = 0; i < localCustomFieldsCount; ++i) {
+ if (mLocalCustomFields[i].key() == name) {
+ mLocalCustomFields[i].setValue(value);
+ isLocalCustomField = true;
+ break;
+ }
+ }
+
+ // check whether it correspond to a global custom field
+ bool isGlobalCustomField = false;
+ const int globalCustomFieldsCount(globalCustomFields.count());
+ for (int i = 0; i < globalCustomFieldsCount; ++i) {
+ if (globalCustomFields[i].key() == name) {
+ globalCustomFields[i].setValue(value);
+ isGlobalCustomField = true;
+ break;
+ }
+ }
+
+ // if not local and not global it must be external
+ if (!isLocalCustomField && !isGlobalCustomField) {
+ if (app == QLatin1String("KADDRESSBOOK")) {
+ // however if it starts with our prefix it might be that this is an outdated
+ // global custom field, in this case treat it as local field of type text
+ CustomField customField(name, name, CustomField::TextType, CustomField::LocalScope);
+ customField.setValue(value);
+
+ mLocalCustomFields << customField;
+ } else {
+ // it is really an external custom field
+ const QString key = app + QLatin1Char('-') + name;
+ CustomField customField(key, key, CustomField::TextType, CustomField::ExternalScope);
+ customField.setValue(value);
+
+ externalCustomFields << customField;
+ }
+ }
+ }
+
+ mModel->setCustomFields(CustomField::List() << mLocalCustomFields << globalCustomFields << externalCustomFields);
+}
+
+void CustomFieldsListWidget::storeContact(KContacts::Addressee &contact) const
+{
+ const CustomField::List customFields = mModel->customFields();
+ for (const CustomField &customField : customFields) {
+ // write back values for local and global scope, leave external untouched
+ if (customField.scope() != CustomField::ExternalScope) {
+ if (!customField.value().isEmpty()) {
+ contact.insertCustom(QStringLiteral("KADDRESSBOOK"), customField.key(), customField.value());
+ } else {
+ contact.removeCustom(QStringLiteral("KADDRESSBOOK"), customField.key());
+ }
+ }
+ }
+
+ // Now remove all fields that were available in loadContact (these are stored in mLocalCustomFields)
+ // but are not part of customFields now, which means they have been removed or renamed by the user
+ // in the editor dialog.
+ for (const CustomField &oldCustomField : qAsConst(mLocalCustomFields)) {
+ if (oldCustomField.scope() != CustomField::ExternalScope) {
+
+ bool fieldStillExists = false;
+ for (const CustomField &newCustomField : qAsConst(customFields)) {
+ if (newCustomField.scope() != CustomField::ExternalScope) {
+ if (newCustomField.key() == oldCustomField.key()) {
+ fieldStillExists = true;
+ break;
+ }
+ }
+ }
+
+ if (!fieldStillExists) {
+ contact.removeCustom(QStringLiteral("KADDRESSBOOK"), oldCustomField.key());
+ }
+ }
+ }
+
+ // And store the global custom fields descriptions as well
+ CustomField::List globalCustomFields;
+ for (const CustomField &customField : qAsConst(customFields)) {
+ if (customField.scope() == CustomField::GlobalScope) {
+ globalCustomFields << customField;
+ }
+ }
+
+ CustomFieldManager::setGlobalCustomFieldDescriptions(globalCustomFields);
+}
+
+void CustomFieldsListWidget::setReadOnly(bool readOnly)
+{
+ mCustomFieldList->setEnabled(!readOnly);
+}
+
+void CustomFieldsListWidget::slotAddNewField(const CustomField &field)
+{
+ const int lastRow = mModel->rowCount();
+ mModel->insertRow(lastRow);
+ mModel->setData(mModel->index(lastRow, 2), field.key(), Qt::EditRole);
+ mModel->setData(mModel->index(lastRow, 0), field.title(), Qt::EditRole);
+ mModel->setData(mModel->index(lastRow, 0), field.type(), CustomFieldsModel::TypeRole);
+ mModel->setData(mModel->index(lastRow, 0), field.scope(), CustomFieldsModel::ScopeRole);
+
+}
+
+void CustomFieldsListWidget::setLocalCustomFieldDescriptions(const QVariantList &descriptions)
+{
+ mLocalCustomFields.clear();
+ mLocalCustomFields.reserve(descriptions.count());
+ for (const QVariant &description : descriptions) {
+ mLocalCustomFields.append(CustomField::fromVariantMap(description.toMap(), CustomField::LocalScope));
+ }
+}
+
+QVariantList CustomFieldsListWidget::localCustomFieldDescriptions() const
+{
+ const CustomField::List customFields = mModel->customFields();
+
+ QVariantList descriptions;
+ for (const CustomField &field : customFields) {
+ if (field.scope() == CustomField::LocalScope) {
+ descriptions.append(field.toVariantMap());
+ }
+ }
+
+ return descriptions;
+}
diff --git a/src/contact-editor/editor/customfieldeditor/customfieldslistwidget.h b/src/contact-editor/editor/customfieldeditor/customfieldslistwidget.h
new file mode 100644
index 0000000..d5e178e
--- /dev/null
+++ b/src/contact-editor/editor/customfieldeditor/customfieldslistwidget.h
@@ -0,0 +1,57 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 CUSTOMFIELDSLISTWIDGET_H
+#define CUSTOMFIELDSLISTWIDGET_H
+
+#include <QWidget>
+#include "customfieldsmodel.h"
+class QTreeView;
+namespace KContacts
+{
+class Addressee;
+}
+class CustomFieldsModel;
+namespace Akonadi
+{
+class CustomFieldsListWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit CustomFieldsListWidget(QWidget *parent = nullptr);
+ ~CustomFieldsListWidget();
+ void storeContact(KContacts::Addressee &contact) const;
+ void loadContact(const KContacts::Addressee &contact);
+ void setReadOnly(bool readOnly);
+
+ void setLocalCustomFieldDescriptions(const QVariantList &descriptions);
+ QVariantList localCustomFieldDescriptions() const;
+public Q_SLOTS:
+ void slotAddNewField(const CustomField &field);
+
+private:
+ CustomField::List mLocalCustomFields;
+ QTreeView *mCustomFieldList;
+ CustomFieldsModel *mModel;
+};
+}
+#endif // CUSTOMFIELDSLISTWIDGET_H
diff --git a/src/contact-editor/editor/customfieldeditor/customfieldsmodel.cpp b/src/contact-editor/editor/customfieldeditor/customfieldsmodel.cpp
new file mode 100644
index 0000000..d9b7463
--- /dev/null
+++ b/src/contact-editor/editor/customfieldeditor/customfieldsmodel.cpp
@@ -0,0 +1,284 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (c) 2010 Tobias Koenig <[email protected]>
+
+ 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 "customfieldsmodel.h"
+
+#include <KLocalizedString>
+
+#include <QDateTime>
+#include <QLocale>
+
+Q_DECLARE_METATYPE(Qt::CheckState)
+
+CustomFieldsModel::CustomFieldsModel(QObject *parent)
+ : QAbstractItemModel(parent)
+{
+}
+
+CustomFieldsModel::~CustomFieldsModel()
+{
+}
+
+void CustomFieldsModel::setCustomFields(const CustomField::List &customFields)
+{
+ Q_EMIT layoutAboutToBeChanged();
+
+ mCustomFields = customFields;
+
+ Q_EMIT layoutChanged();
+}
+
+CustomField::List CustomFieldsModel::customFields() const
+{
+ return mCustomFields;
+}
+
+QModelIndex CustomFieldsModel::index(int row, int column, const QModelIndex &parent) const
+{
+ Q_UNUSED(parent);
+ return createIndex(row, column);
+}
+
+QModelIndex CustomFieldsModel::parent(const QModelIndex &child) const
+{
+ Q_UNUSED(child);
+ return QModelIndex();
+}
+
+QVariant CustomFieldsModel::data(const QModelIndex &index, int role) const
+{
+ if (!index.isValid()) {
+ return QVariant();
+ }
+
+ if (index.row() < 0 || index.row() >= mCustomFields.count()) {
+ return QVariant();
+ }
+
+ if (index.column() < 0 || index.column() > 2) {
+ return QVariant();
+ }
+
+ const CustomField &customField = mCustomFields[index.row()];
+
+ if (role == Qt::DisplayRole) {
+ if (index.column() == 0) {
+ return customField.title();
+ } else if (index.column() == 1) {
+ switch (customField.type()) {
+ case CustomField::TextType:
+ case CustomField::NumericType:
+ case CustomField::UrlType:
+ return customField.value();
+ break;
+ case CustomField::BooleanType:
+ return QString();
+ break;
+ case CustomField::DateType: {
+ const QDate value = QDate::fromString(customField.value(), Qt::ISODate);
+ return QLocale().toString(value, QLocale::ShortFormat);
+ break;
+ }
+ case CustomField::TimeType: {
+ const QTime value = QTime::fromString(customField.value(), Qt::ISODate);
+ return QLocale().toString(value);
+ break;
+ }
+ case CustomField::DateTimeType: {
+ const QDateTime value = QDateTime::fromString(customField.value(), Qt::ISODate);
+ return QLocale().toString(value);
+ break;
+ }
+ }
+ return customField.value();
+ } else {
+ return customField.key();
+ }
+ }
+
+ if (role == Qt::CheckStateRole) {
+ if (index.column() == 1) {
+ if (customField.type() == CustomField::BooleanType) {
+ return (customField.value() == QLatin1String("true") ? Qt::Checked : Qt::Unchecked);
+ }
+ }
+ }
+
+ if (role == Qt::EditRole) {
+ if (index.column() == 0) {
+ return customField.title();
+ } else if (index.column() == 1) {
+ return customField.value();
+ } else {
+ return customField.key();
+ }
+ }
+
+ if (role == TypeRole) {
+ return customField.type();
+ }
+
+ if (role == ScopeRole) {
+ return customField.scope();
+ }
+
+ return QVariant();
+}
+
+bool CustomFieldsModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+ if (!index.isValid()) {
+ return false;
+ }
+
+ if (index.row() < 0 || index.row() >= mCustomFields.count()) {
+ return false;
+ }
+
+ if (index.column() < 0 || index.column() > 2) {
+ return false;
+ }
+
+ CustomField &customField = mCustomFields[index.row()];
+
+ if (role == Qt::EditRole) {
+ if (index.column() == 0) {
+ customField.setTitle(value.toString());
+ } else if (index.column() == 1) {
+ customField.setValue(value.toString());
+ } else {
+ customField.setKey(value.toString());
+ }
+
+ Q_EMIT dataChanged(index, index);
+ return true;
+ }
+
+ if (role == Qt::CheckStateRole) {
+ if (index.column() == 1) {
+ if (customField.type() == CustomField::BooleanType) {
+ customField.setValue(static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked ?
+ QStringLiteral("true") : QStringLiteral("false"));
+ Q_EMIT dataChanged(index, index);
+ return true;
+ }
+ }
+ }
+
+ if (role == TypeRole) {
+ customField.setType((CustomField::Type)value.toInt());
+ Q_EMIT dataChanged(index, index);
+ return true;
+ }
+
+ if (role == ScopeRole) {
+ customField.setScope((CustomField::Scope)value.toInt());
+ Q_EMIT dataChanged(index, index);
+ return true;
+ }
+
+ return false;
+}
+
+QVariant CustomFieldsModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ if (section < 0 || section > 1) {
+ return QVariant();
+ }
+
+ if (orientation != Qt::Horizontal) {
+ return QVariant();
+ }
+
+ if (role != Qt::DisplayRole) {
+ return QVariant();
+ }
+
+ if (section == 0) {
+ return i18nc("custom field title", "Title");
+ } else {
+ return i18nc("custom field value", "Value");
+ }
+}
+
+Qt::ItemFlags CustomFieldsModel::flags(const QModelIndex &index) const
+{
+ if (!index.isValid() || index.row() < 0 || index.row() >= mCustomFields.count()) {
+ return QAbstractItemModel::flags(index);
+ }
+
+ const CustomField &customField = mCustomFields[index.row()];
+
+ const Qt::ItemFlags parentFlags = QAbstractItemModel::flags(index);
+ if ((customField.type() == CustomField::BooleanType) && (index.column() == 1)) {
+ return (parentFlags | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsUserCheckable);
+ } else {
+ return (parentFlags | Qt::ItemIsEnabled | Qt::ItemIsEditable);
+ }
+}
+
+int CustomFieldsModel::columnCount(const QModelIndex &parent) const
+{
+ if (!parent.isValid()) {
+ return 3;
+ } else {
+ return 0;
+ }
+}
+
+int CustomFieldsModel::rowCount(const QModelIndex &parent) const
+{
+ if (!parent.isValid()) {
+ return mCustomFields.count();
+ } else {
+ return 0;
+ }
+}
+
+bool CustomFieldsModel::insertRows(int row, int count, const QModelIndex &parent)
+{
+ if (parent.isValid()) {
+ return false;
+ }
+
+ beginInsertRows(parent, row, row + count - 1);
+ for (int i = 0; i < count; ++i) {
+ mCustomFields.insert(row, CustomField());
+ }
+ endInsertRows();
+
+ return true;
+}
+
+bool CustomFieldsModel::removeRows(int row, int count, const QModelIndex &parent)
+{
+ if (parent.isValid()) {
+ return false;
+ }
+
+ beginRemoveRows(parent, row, row + count - 1);
+ for (int i = 0; i < count; ++i) {
+ mCustomFields.remove(row);
+ }
+ endRemoveRows();
+
+ return true;
+}
diff --git a/src/contact-editor/editor/customfieldeditor/customfieldsmodel.h b/src/contact-editor/editor/customfieldeditor/customfieldsmodel.h
new file mode 100644
index 0000000..19534fb
--- /dev/null
+++ b/src/contact-editor/editor/customfieldeditor/customfieldsmodel.h
@@ -0,0 +1,60 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (c) 2010 Tobias Koenig <[email protected]>
+
+ 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 CUSTOMFIELDSMODEL_H
+#define CUSTOMFIELDSMODEL_H
+
+#include "customfields_p.h"
+
+#include <QAbstractItemModel>
+
+class CustomFieldsModel : public QAbstractItemModel
+{
+ Q_OBJECT
+public:
+ enum Role {
+ TypeRole = Qt::UserRole,
+ ScopeRole
+ };
+
+ explicit CustomFieldsModel(QObject *parent = nullptr);
+ ~CustomFieldsModel();
+
+ void setCustomFields(const CustomField::List &addresses);
+ CustomField::List customFields() const;
+
+ QModelIndex index(int row, int col, const QModelIndex &parent = QModelIndex()) const override;
+ QModelIndex parent(const QModelIndex &child) const override;
+ QVariant data(const QModelIndex &index, int role) const override;
+ bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
+ QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
+ Qt::ItemFlags flags(const QModelIndex &index) const override;
+ int columnCount(const QModelIndex &parent = QModelIndex()) const override;
+ int rowCount(const QModelIndex &parent = QModelIndex()) const override;
+
+ bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
+ bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
+
+private:
+ CustomField::List mCustomFields;
+};
+
+#endif
diff --git a/src/contact-editor/editor/customfieldeditor/customfieldswidget.cpp b/src/contact-editor/editor/customfieldeditor/customfieldswidget.cpp
new file mode 100644
index 0000000..4284bf3
--- /dev/null
+++ b/src/contact-editor/editor/customfieldeditor/customfieldswidget.cpp
@@ -0,0 +1,75 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "customfieldeditorwidget.h"
+#include "customfieldswidget.h"
+#include "customfieldslistwidget.h"
+#include <QVBoxLayout>
+
+using namespace Akonadi;
+
+CustomFieldsWidget::CustomFieldsWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ QVBoxLayout *topLayout = new QVBoxLayout(this);
+ topLayout->setMargin(0);
+ mCustomFieldEditorWidget = new Akonadi::CustomFieldEditorWidget(this);
+ mCustomFieldEditorWidget->setObjectName(QStringLiteral("customfieldeditorwidget"));
+ topLayout->addWidget(mCustomFieldEditorWidget);
+
+ mCustomFieldsListWidget = new Akonadi::CustomFieldsListWidget(this);
+ mCustomFieldsListWidget->setObjectName(QStringLiteral("customfieldslistwidget"));
+ topLayout->addWidget(mCustomFieldsListWidget);
+
+ connect(mCustomFieldEditorWidget, &CustomFieldEditorWidget::addNewField, mCustomFieldsListWidget, &CustomFieldsListWidget::slotAddNewField);
+}
+
+CustomFieldsWidget::~CustomFieldsWidget()
+{
+
+}
+
+void CustomFieldsWidget::loadContact(const KContacts::Addressee &contact)
+{
+ mCustomFieldsListWidget->loadContact(contact);
+}
+
+void CustomFieldsWidget::storeContact(KContacts::Addressee &contact) const
+{
+ mCustomFieldsListWidget->storeContact(contact);
+}
+
+void CustomFieldsWidget::setReadOnly(bool readOnly)
+{
+ mCustomFieldEditorWidget->setReadOnly(readOnly);
+ mCustomFieldsListWidget->setReadOnly(readOnly);
+}
+
+void CustomFieldsWidget::setLocalCustomFieldDescriptions(const QVariantList &descriptions)
+{
+ mCustomFieldsListWidget->setLocalCustomFieldDescriptions(descriptions);
+}
+
+QVariantList CustomFieldsWidget::localCustomFieldDescriptions() const
+{
+ return mCustomFieldsListWidget->localCustomFieldDescriptions();
+}
diff --git a/src/contact-editor/editor/customfieldeditor/customfieldswidget.h b/src/contact-editor/editor/customfieldeditor/customfieldswidget.h
new file mode 100644
index 0000000..b560ff7
--- /dev/null
+++ b/src/contact-editor/editor/customfieldeditor/customfieldswidget.h
@@ -0,0 +1,55 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 CUSTOMFIELDSWIDGET_H
+#define CUSTOMFIELDSWIDGET_H
+
+#include <QWidget>
+#include <QVariantList>
+
+namespace KContacts
+{
+class Addressee;
+}
+
+namespace Akonadi
+{
+class CustomFieldEditorWidget;
+class CustomFieldsListWidget;
+class CustomFieldsWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit CustomFieldsWidget(QWidget *parent = nullptr);
+ ~CustomFieldsWidget();
+ void storeContact(KContacts::Addressee &contact) const;
+ void loadContact(const KContacts::Addressee &contact);
+
+ void setReadOnly(bool readOnly);
+ void setLocalCustomFieldDescriptions(const QVariantList &descriptions);
+ QVariantList localCustomFieldDescriptions() const;
+private:
+ Akonadi::CustomFieldEditorWidget *mCustomFieldEditorWidget;
+ Akonadi::CustomFieldsListWidget *mCustomFieldsListWidget;
+};
+}
+#endif // CUSTOMFIELDSWIDGET_H
diff --git a/src/contact-editor/editor/customfieldeditor/tests/CMakeLists.txt b/src/contact-editor/editor/customfieldeditor/tests/CMakeLists.txt
new file mode 100644
index 0000000..3f0b8bb
--- /dev/null
+++ b/src/contact-editor/editor/customfieldeditor/tests/CMakeLists.txt
@@ -0,0 +1,24 @@
+set(customfieldeditor_SRCS
+ ../customfieldswidget.cpp
+ ../customfieldeditorwidget.cpp
+ ../customfieldslistwidget.cpp
+ ../customfieldsmodel.cpp
+ ../../../customfields.cpp
+ ../customfieldslistdelegate.cpp
+ ../../../customfieldmanager.cpp
+ ../../utils/utils.cpp
+ main.cpp
+ )
+
+add_executable(customfieldeditortest ${customfieldeditor_SRCS})
+
+target_link_libraries(customfieldeditortest
+ Qt5::Widgets
+ KF5::AkonadiContact
+ KF5::Contacts
+ KF5::I18n
+ KF5::Completion
+ KF5::IconThemes
+ KF5::WidgetsAddons
+ KF5::ConfigCore
+ )
diff --git a/src/contact-editor/editor/customfieldeditor/tests/main.cpp b/src/contact-editor/editor/customfieldeditor/tests/main.cpp
new file mode 100644
index 0000000..d85319c
--- /dev/null
+++ b/src/contact-editor/editor/customfieldeditor/tests/main.cpp
@@ -0,0 +1,32 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 <QApplication>
+#include "../customfieldswidget.h"
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ Akonadi::CustomFieldsWidget w;
+ w.show();
+ return app.exec();
+}
diff --git a/src/contact-editor/editor/data/zone.tab b/src/contact-editor/editor/data/zone.tab
new file mode 100644
index 0000000..2bdf923
--- /dev/null
+++ b/src/contact-editor/editor/data/zone.tab
@@ -0,0 +1,434 @@
+# <pre>
+# @(#)zone.tab 8.38
+# This file is in the public domain, so clarified as of
+# 2009-05-17 by Arthur David Olson.
+#
+# TZ zone descriptions
+#
+# From Paul Eggert (1996-08-05):
+#
+# This file contains a table with the following columns:
+# 1. ISO 3166 2-character country code. See the file `iso3166.tab'.
+# 2. Latitude and longitude of the zone's principal location
+# in ISO 6709 sign-degrees-minutes-seconds format,
+# either +-DDMM+-DDDMM or +-DDMMSS+-DDDMMSS,
+# first latitude (+ is north), then longitude (+ is east).
+# 3. Zone name used in value of TZ environment variable.
+# 4. Comments; present if and only if the country has multiple rows.
+#
+# Columns are separated by a single tab.
+# The table is sorted first by country, then an order within the country that
+# (1) makes some geographical sense, and
+# (2) puts the most populous zones first, where that does not contradict (1).
+#
+# Lines beginning with `#' are comments.
+#
+#country-
+#code coordinates TZ comments
+AD +4230+00131 Europe/Andorra
+AE +2518+05518 Asia/Dubai
+AF +3431+06912 Asia/Kabul
+AG +1703-06148 America/Antigua
+AI +1812-06304 America/Anguilla
+AL +4120+01950 Europe/Tirane
+AM +4011+04430 Asia/Yerevan
+AN +1211-06900 America/Curacao
+AO -0848+01314 Africa/Luanda
+AQ -7750+16636 Antarctica/McMurdo McMurdo Station, Ross Island
+AQ -9000+00000 Antarctica/South_Pole Amundsen-Scott Station, South Pole
+AQ -6734-06808 Antarctica/Rothera Rothera Station, Adelaide Island
+AQ -6448-06406 Antarctica/Palmer Palmer Station, Anvers Island
+AQ -6736+06253 Antarctica/Mawson Mawson Station, Holme Bay
+AQ -6835+07758 Antarctica/Davis Davis Station, Vestfold Hills
+AQ -6617+11031 Antarctica/Casey Casey Station, Bailey Peninsula
+AQ -7824+10654 Antarctica/Vostok Vostok Station, Lake Vostok
+AQ -6640+14001 Antarctica/DumontDUrville Dumont-d'Urville Station, Terre Adelie
+AQ -690022+0393524 Antarctica/Syowa Syowa Station, E Ongul I
+AQ -5430+15857 Antarctica/Macquarie Macquarie Island Station, Macquarie Island
+AR -3436-05827 America/Argentina/Buenos_Aires Buenos Aires (BA, CF)
+AR -3124-06411 America/Argentina/Cordoba most locations (CB, CC, CN, ER, FM, MN, SE, SF)
+AR -2447-06525 America/Argentina/Salta (SA, LP, NQ, RN)
+AR -2411-06518 America/Argentina/Jujuy Jujuy (JY)
+AR -2649-06513 America/Argentina/Tucuman Tucuman (TM)
+AR -2828-06547 America/Argentina/Catamarca Catamarca (CT), Chubut (CH)
+AR -2926-06651 America/Argentina/La_Rioja La Rioja (LR)
+AR -3132-06831 America/Argentina/San_Juan San Juan (SJ)
+AR -3253-06849 America/Argentina/Mendoza Mendoza (MZ)
+AR -3319-06621 America/Argentina/San_Luis San Luis (SL)
+AR -5138-06913 America/Argentina/Rio_Gallegos Santa Cruz (SC)
+AR -5448-06818 America/Argentina/Ushuaia Tierra del Fuego (TF)
+AS -1416-17042 Pacific/Pago_Pago
+AT +4813+01620 Europe/Vienna
+AU -3133+15905 Australia/Lord_Howe Lord Howe Island
+AU -4253+14719 Australia/Hobart Tasmania - most locations
+AU -3956+14352 Australia/Currie Tasmania - King Island
+AU -3749+14458 Australia/Melbourne Victoria
+AU -3352+15113 Australia/Sydney New South Wales - most locations
+AU -3157+14127 Australia/Broken_Hill New South Wales - Yancowinna
+AU -2728+15302 Australia/Brisbane Queensland - most locations
+AU -2016+14900 Australia/Lindeman Queensland - Holiday Islands
+AU -3455+13835 Australia/Adelaide South Australia
+AU -1228+13050 Australia/Darwin Northern Territory
+AU -3157+11551 Australia/Perth Western Australia - most locations
+AU -3143+12852 Australia/Eucla Western Australia - Eucla area
+AW +1230-06958 America/Aruba
+AX +6006+01957 Europe/Mariehamn
+AZ +4023+04951 Asia/Baku
+BA +4352+01825 Europe/Sarajevo
+BB +1306-05937 America/Barbados
+BD +2343+09025 Asia/Dhaka
+BE +5050+00420 Europe/Brussels
+BF +1222-00131 Africa/Ouagadougou
+BG +4241+02319 Europe/Sofia
+BH +2623+05035 Asia/Bahrain
+BI -0323+02922 Africa/Bujumbura
+BJ +0629+00237 Africa/Porto-Novo
+BL +1753-06251 America/St_Barthelemy
+BM +3217-06446 Atlantic/Bermuda
+BN +0456+11455 Asia/Brunei
+BO -1630-06809 America/La_Paz
+BR -0351-03225 America/Noronha Atlantic islands
+BR -0127-04829 America/Belem Amapa, E Para
+BR -0343-03830 America/Fortaleza NE Brazil (MA, PI, CE, RN, PB)
+BR -0803-03454 America/Recife Pernambuco
+BR -0712-04812 America/Araguaina Tocantins
+BR -0940-03543 America/Maceio Alagoas, Sergipe
+BR -1259-03831 America/Bahia Bahia
+BR -2332-04637 America/Sao_Paulo S & SE Brazil (GO, DF, MG, ES, RJ, SP, PR, SC, RS)
+BR -2027-05437 America/Campo_Grande Mato Grosso do Sul
+BR -1535-05605 America/Cuiaba Mato Grosso
+BR -0226-05452 America/Santarem W Para
+BR -0846-06354 America/Porto_Velho Rondonia
+BR +0249-06040 America/Boa_Vista Roraima
+BR -0308-06001 America/Manaus E Amazonas
+BR -0640-06952 America/Eirunepe W Amazonas
+BR -0958-06748 America/Rio_Branco Acre
+BS +2505-07721 America/Nassau
+BT +2728+08939 Asia/Thimphu
+BW -2439+02555 Africa/Gaborone
+BY +5354+02734 Europe/Minsk
+BZ +1730-08812 America/Belize
+CA +4734-05243 America/St_Johns Newfoundland Time, including SE Labrador
+CA +4439-06336 America/Halifax Atlantic Time - Nova Scotia (most places), PEI
+CA +4612-05957 America/Glace_Bay Atlantic Time - Nova Scotia - places that did not observe DST 1966-1971
+CA +4606-06447 America/Moncton Atlantic Time - New Brunswick
+CA +5320-06025 America/Goose_Bay Atlantic Time - Labrador - most locations
+CA +5125-05707 America/Blanc-Sablon Atlantic Standard Time - Quebec - Lower North Shore
+CA +4531-07334 America/Montreal Eastern Time - Quebec - most locations
+CA +4339-07923 America/Toronto Eastern Time - Ontario - most locations
+CA +4901-08816 America/Nipigon Eastern Time - Ontario & Quebec - places that did not observe DST 1967-1973
+CA +4823-08915 America/Thunder_Bay Eastern Time - Thunder Bay, Ontario
+CA +6344-06828 America/Iqaluit Eastern Time - east Nunavut - most locations
+CA +6608-06544 America/Pangnirtung Eastern Time - Pangnirtung, Nunavut
+CA +744144-0944945 America/Resolute Eastern Standard Time - Resolute, Nunavut
+CA +484531-0913718 America/Atikokan Eastern Standard Time - Atikokan, Ontario and Southampton I, Nunavut
+CA +624900-0920459 America/Rankin_Inlet Central Time - central Nunavut
+CA +4953-09709 America/Winnipeg Central Time - Manitoba & west Ontario
+CA +4843-09434 America/Rainy_River Central Time - Rainy River & Fort Frances, Ontario
+CA +5024-10439 America/Regina Central Standard Time - Saskatchewan - most locations
+CA +5017-10750 America/Swift_Current Central Standard Time - Saskatchewan - midwest
+CA +5333-11328 America/Edmonton Mountain Time - Alberta, east British Columbia & west Saskatchewan
+CA +690650-1050310 America/Cambridge_Bay Mountain Time - west Nunavut
+CA +6227-11421 America/Yellowknife Mountain Time - central Northwest Territories
+CA +682059-1334300 America/Inuvik Mountain Time - west Northwest Territories
+CA +5946-12014 America/Dawson_Creek Mountain Standard Time - Dawson Creek & Fort Saint John, British Columbia
+CA +4916-12307 America/Vancouver Pacific Time - west British Columbia
+CA +6043-13503 America/Whitehorse Pacific Time - south Yukon
+CA +6404-13925 America/Dawson Pacific Time - north Yukon
+CC -1210+09655 Indian/Cocos
+CD -0418+01518 Africa/Kinshasa west Dem. Rep. of Congo
+CD -1140+02728 Africa/Lubumbashi east Dem. Rep. of Congo
+CF +0422+01835 Africa/Bangui
+CG -0416+01517 Africa/Brazzaville
+CH +4723+00832 Europe/Zurich
+CI +0519-00402 Africa/Abidjan
+CK -2114-15946 Pacific/Rarotonga
+CL -3327-07040 America/Santiago most locations
+CL -2709-10926 Pacific/Easter Easter Island & Sala y Gomez
+CM +0403+00942 Africa/Douala
+CN +3114+12128 Asia/Shanghai east China - Beijing, Guangdong, Shanghai, etc.
+CN +4545+12641 Asia/Harbin Heilongjiang (except Mohe), Jilin
+CN +2934+10635 Asia/Chongqing central China - Sichuan, Yunnan, Guangxi, Shaanxi, Guizhou, etc.
+CN +4348+08735 Asia/Urumqi most of Tibet & Xinjiang
+CN +3929+07559 Asia/Kashgar west Tibet & Xinjiang
+CO +0436-07405 America/Bogota
+CR +0956-08405 America/Costa_Rica
+CU +2308-08222 America/Havana
+CV +1455-02331 Atlantic/Cape_Verde
+CX -1025+10543 Indian/Christmas
+CY +3510+03322 Asia/Nicosia
+CZ +5005+01426 Europe/Prague
+DE +5230+01322 Europe/Berlin
+DJ +1136+04309 Africa/Djibouti
+DK +5540+01235 Europe/Copenhagen
+DM +1518-06124 America/Dominica
+DO +1828-06954 America/Santo_Domingo
+DZ +3647+00303 Africa/Algiers
+EC -0210-07950 America/Guayaquil mainland
+EC -0054-08936 Pacific/Galapagos Galapagos Islands
+EE +5925+02445 Europe/Tallinn
+EG +3003+03115 Africa/Cairo
+EH +2709-01312 Africa/El_Aaiun
+ER +1520+03853 Africa/Asmara
+ES +4024-00341 Europe/Madrid mainland
+ES +3553-00519 Africa/Ceuta Ceuta & Melilla
+ES +2806-01524 Atlantic/Canary Canary Islands
+ET +0902+03842 Africa/Addis_Ababa
+FI +6010+02458 Europe/Helsinki
+FJ -1808+17825 Pacific/Fiji
+FK -5142-05751 Atlantic/Stanley
+FM +0725+15147 Pacific/Chuuk Chuuk (Truk) and Yap
+FM +0658+15813 Pacific/Pohnpei Pohnpei (Ponape)
+FM +0519+16259 Pacific/Kosrae Kosrae
+FO +6201-00646 Atlantic/Faroe
+FR +4852+00220 Europe/Paris
+GA +0023+00927 Africa/Libreville
+GB +513030-0000731 Europe/London
+GD +1203-06145 America/Grenada
+GE +4143+04449 Asia/Tbilisi
+GF +0456-05220 America/Cayenne
+GG +4927-00232 Europe/Guernsey
+GH +0533-00013 Africa/Accra
+GI +3608-00521 Europe/Gibraltar
+GL +6411-05144 America/Godthab most locations
+GL +7646-01840 America/Danmarkshavn east coast, north of Scoresbysund
+GL +7029-02158 America/Scoresbysund Scoresbysund / Ittoqqortoormiit
+GL +7634-06847 America/Thule Thule / Pituffik
+GM +1328-01639 Africa/Banjul
+GN +0931-01343 Africa/Conakry
+GP +1614-06132 America/Guadeloupe
+GQ +0345+00847 Africa/Malabo
+GR +3758+02343 Europe/Athens
+GS -5416-03632 Atlantic/South_Georgia
+GT +1438-09031 America/Guatemala
+GU +1328+14445 Pacific/Guam
+GW +1151-01535 Africa/Bissau
+GY +0648-05810 America/Guyana
+HK +2217+11409 Asia/Hong_Kong
+HN +1406-08713 America/Tegucigalpa
+HR +4548+01558 Europe/Zagreb
+HT +1832-07220 America/Port-au-Prince
+HU +4730+01905 Europe/Budapest
+ID -0610+10648 Asia/Jakarta Java & Sumatra
+ID -0002+10920 Asia/Pontianak west & central Borneo
+ID -0507+11924 Asia/Makassar east & south Borneo, Celebes, Bali, Nusa Tengarra, west Timor
+ID -0232+14042 Asia/Jayapura Irian Jaya & the Moluccas
+IE +5320-00615 Europe/Dublin
+IL +3146+03514 Asia/Jerusalem
+IM +5409-00428 Europe/Isle_of_Man
+IN +2232+08822 Asia/Kolkata
+IO -0720+07225 Indian/Chagos
+IQ +3321+04425 Asia/Baghdad
+IR +3540+05126 Asia/Tehran
+IS +6409-02151 Atlantic/Reykjavik
+IT +4154+01229 Europe/Rome
+JE +4912-00207 Europe/Jersey
+JM +1800-07648 America/Jamaica
+JO +3157+03556 Asia/Amman
+JP +353916+1394441 Asia/Tokyo
+KE -0117+03649 Africa/Nairobi
+KG +4254+07436 Asia/Bishkek
+KH +1133+10455 Asia/Phnom_Penh
+KI +0125+17300 Pacific/Tarawa Gilbert Islands
+KI -0308-17105 Pacific/Enderbury Phoenix Islands
+KI +0152-15720 Pacific/Kiritimati Line Islands
+KM -1141+04316 Indian/Comoro
+KN +1718-06243 America/St_Kitts
+KP +3901+12545 Asia/Pyongyang
+KR +3733+12658 Asia/Seoul
+KW +2920+04759 Asia/Kuwait
+KY +1918-08123 America/Cayman
+KZ +4315+07657 Asia/Almaty most locations
+KZ +4448+06528 Asia/Qyzylorda Qyzylorda (Kyzylorda, Kzyl-Orda)
+KZ +5017+05710 Asia/Aqtobe Aqtobe (Aktobe)
+KZ +4431+05016 Asia/Aqtau Atyrau (Atirau, Gur'yev), Mangghystau (Mankistau)
+KZ +5113+05121 Asia/Oral West Kazakhstan
+LA +1758+10236 Asia/Vientiane
+LB +3353+03530 Asia/Beirut
+LC +1401-06100 America/St_Lucia
+LI +4709+00931 Europe/Vaduz
+LK +0656+07951 Asia/Colombo
+LR +0618-01047 Africa/Monrovia
+LS -2928+02730 Africa/Maseru
+LT +5441+02519 Europe/Vilnius
+LU +4936+00609 Europe/Luxembourg
+LV +5657+02406 Europe/Riga
+LY +3254+01311 Africa/Tripoli
+MA +3339-00735 Africa/Casablanca
+MC +4342+00723 Europe/Monaco
+MD +4700+02850 Europe/Chisinau
+ME +4226+01916 Europe/Podgorica
+MF +1804-06305 America/Marigot
+MG -1855+04731 Indian/Antananarivo
+MH +0709+17112 Pacific/Majuro most locations
+MH +0905+16720 Pacific/Kwajalein Kwajalein
+MK +4159+02126 Europe/Skopje
+ML +1239-00800 Africa/Bamako
+MM +1647+09610 Asia/Rangoon
+MN +4755+10653 Asia/Ulaanbaatar most locations
+MN +4801+09139 Asia/Hovd Bayan-Olgiy, Govi-Altai, Hovd, Uvs, Zavkhan
+MN +4804+11430 Asia/Choibalsan Dornod, Sukhbaatar
+MO +2214+11335 Asia/Macau
+MP +1512+14545 Pacific/Saipan
+MQ +1436-06105 America/Martinique
+MR +1806-01557 Africa/Nouakchott
+MS +1643-06213 America/Montserrat
+MT +3554+01431 Europe/Malta
+MU -2010+05730 Indian/Mauritius
+MV +0410+07330 Indian/Maldives
+MW -1547+03500 Africa/Blantyre
+MX +1924-09909 America/Mexico_City Central Time - most locations
+MX +2105-08646 America/Cancun Central Time - Quintana Roo
+MX +2058-08937 America/Merida Central Time - Campeche, Yucatan
+MX +2540-10019 America/Monterrey Mexican Central Time - Coahuila, Durango, Nuevo Leon, Tamaulipas away from US border
+MX +2550-09730 America/Matamoros US Central Time - Coahuila, Durango, Nuevo Leon, Tamaulipas near US border
+MX +2313-10625 America/Mazatlan Mountain Time - S Baja, Nayarit, Sinaloa
+MX +2838-10605 America/Chihuahua Mexican Mountain Time - Chihuahua away from US border
+MX +2934-10425 America/Ojinaga US Mountain Time - Chihuahua near US border
+MX +2904-11058 America/Hermosillo Mountain Standard Time - Sonora
+MX +3232-11701 America/Tijuana US Pacific Time - Baja California near US border
+MX +3018-11452 America/Santa_Isabel Mexican Pacific Time - Baja California away from US border
+MX +2048-10515 America/Bahia_Banderas Mexican Central Time - Bahia de Banderas
+MY +0310+10142 Asia/Kuala_Lumpur peninsular Malaysia
+MY +0133+11020 Asia/Kuching Sabah & Sarawak
+MZ -2558+03235 Africa/Maputo
+NA -2234+01706 Africa/Windhoek
+NC -2216+16627 Pacific/Noumea
+NE +1331+00207 Africa/Niamey
+NF -2903+16758 Pacific/Norfolk
+NG +0627+00324 Africa/Lagos
+NI +1209-08617 America/Managua
+NL +5222+00454 Europe/Amsterdam
+NO +5955+01045 Europe/Oslo
+NP +2743+08519 Asia/Kathmandu
+NR -0031+16655 Pacific/Nauru
+NU -1901-16955 Pacific/Niue
+NZ -3652+17446 Pacific/Auckland most locations
+NZ -4357-17633 Pacific/Chatham Chatham Islands
+OM +2336+05835 Asia/Muscat
+PA +0858-07932 America/Panama
+PE -1203-07703 America/Lima
+PF -1732-14934 Pacific/Tahiti Society Islands
+PF -0900-13930 Pacific/Marquesas Marquesas Islands
+PF -2308-13457 Pacific/Gambier Gambier Islands
+PG -0930+14710 Pacific/Port_Moresby
+PH +1435+12100 Asia/Manila
+PK +2452+06703 Asia/Karachi
+PL +5215+02100 Europe/Warsaw
+PM +4703-05620 America/Miquelon
+PN -2504-13005 Pacific/Pitcairn
+PR +182806-0660622 America/Puerto_Rico
+PS +3130+03428 Asia/Gaza
+PT +3843-00908 Europe/Lisbon mainland
+PT +3238-01654 Atlantic/Madeira Madeira Islands
+PT +3744-02540 Atlantic/Azores Azores
+PW +0720+13429 Pacific/Palau
+PY -2516-05740 America/Asuncion
+QA +2517+05132 Asia/Qatar
+RE -2052+05528 Indian/Reunion
+RO +4426+02606 Europe/Bucharest
+RS +4450+02030 Europe/Belgrade
+RU +5443+02030 Europe/Kaliningrad Moscow-01 - Kaliningrad
+RU +5545+03735 Europe/Moscow Moscow+00 - west Russia
+RU +4844+04425 Europe/Volgograd Moscow+00 - Caspian Sea
+RU +5312+05009 Europe/Samara Moscow - Samara, Udmurtia
+RU +5651+06036 Asia/Yekaterinburg Moscow+02 - Urals
+RU +5500+07324 Asia/Omsk Moscow+03 - west Siberia
+RU +5502+08255 Asia/Novosibirsk Moscow+03 - Novosibirsk
+RU +5345+08707 Asia/Novokuznetsk Moscow+03 - Novokuznetsk
+RU +5601+09250 Asia/Krasnoyarsk Moscow+04 - Yenisei River
+RU +5216+10420 Asia/Irkutsk Moscow+05 - Lake Baikal
+RU +6200+12940 Asia/Yakutsk Moscow+06 - Lena River
+RU +4310+13156 Asia/Vladivostok Moscow+07 - Amur River
+RU +4658+14242 Asia/Sakhalin Moscow+07 - Sakhalin Island
+RU +5934+15048 Asia/Magadan Moscow+08 - Magadan
+RU +5301+15839 Asia/Kamchatka Moscow+08 - Kamchatka
+RU +6445+17729 Asia/Anadyr Moscow+08 - Bering Sea
+RW -0157+03004 Africa/Kigali
+SA +2438+04643 Asia/Riyadh
+SB -0932+16012 Pacific/Guadalcanal
+SC -0440+05528 Indian/Mahe
+SD +1536+03232 Africa/Khartoum
+SE +5920+01803 Europe/Stockholm
+SG +0117+10351 Asia/Singapore
+SH -1555-00542 Atlantic/St_Helena
+SI +4603+01431 Europe/Ljubljana
+SJ +7800+01600 Arctic/Longyearbyen
+SK +4809+01707 Europe/Bratislava
+SL +0830-01315 Africa/Freetown
+SM +4355+01228 Europe/San_Marino
+SN +1440-01726 Africa/Dakar
+SO +0204+04522 Africa/Mogadishu
+SR +0550-05510 America/Paramaribo
+ST +0020+00644 Africa/Sao_Tome
+SV +1342-08912 America/El_Salvador
+SY +3330+03618 Asia/Damascus
+SZ -2618+03106 Africa/Mbabane
+TC +2128-07108 America/Grand_Turk
+TD +1207+01503 Africa/Ndjamena
+TF -492110+0701303 Indian/Kerguelen
+TG +0608+00113 Africa/Lome
+TH +1345+10031 Asia/Bangkok
+TJ +3835+06848 Asia/Dushanbe
+TK -0922-17114 Pacific/Fakaofo
+TL -0833+12535 Asia/Dili
+TM +3757+05823 Asia/Ashgabat
+TN +3648+01011 Africa/Tunis
+TO -2110-17510 Pacific/Tongatapu
+TR +4101+02858 Europe/Istanbul
+TT +1039-06131 America/Port_of_Spain
+TV -0831+17913 Pacific/Funafuti
+TW +2503+12130 Asia/Taipei
+TZ -0648+03917 Africa/Dar_es_Salaam
+UA +5026+03031 Europe/Kiev most locations
+UA +4837+02218 Europe/Uzhgorod Ruthenia
+UA +4750+03510 Europe/Zaporozhye Zaporozh'ye, E Lugansk / Zaporizhia, E Luhansk
+UA +4457+03406 Europe/Simferopol central Crimea
+UG +0019+03225 Africa/Kampala
+UM +1645-16931 Pacific/Johnston Johnston Atoll
+UM +2813-17722 Pacific/Midway Midway Islands
+UM +1917+16637 Pacific/Wake Wake Island
+US +404251-0740023 America/New_York Eastern Time
+US +421953-0830245 America/Detroit Eastern Time - Michigan - most locations
+US +381515-0854534 America/Kentucky/Louisville Eastern Time - Kentucky - Louisville area
+US +364947-0845057 America/Kentucky/Monticello Eastern Time - Kentucky - Wayne County
+US +394606-0860929 America/Indiana/Indianapolis Eastern Time - Indiana - most locations
+US +384038-0873143 America/Indiana/Vincennes Eastern Time - Indiana - Daviess, Dubois, Knox & Martin Counties
+US +410305-0863611 America/Indiana/Winamac Eastern Time - Indiana - Pulaski County
+US +382232-0862041 America/Indiana/Marengo Eastern Time - Indiana - Crawford County
+US +382931-0871643 America/Indiana/Petersburg Eastern Time - Indiana - Pike County
+US +384452-0850402 America/Indiana/Vevay Eastern Time - Indiana - Switzerland County
+US +415100-0873900 America/Chicago Central Time
+US +375711-0864541 America/Indiana/Tell_City Central Time - Indiana - Perry County
+US +411745-0863730 America/Indiana/Knox Central Time - Indiana - Starke County
+US +450628-0873651 America/Menominee Central Time - Michigan - Dickinson, Gogebic, Iron & Menominee Counties
+US +470659-1011757 America/North_Dakota/Center Central Time - North Dakota - Oliver County
+US +465042-1012439 America/North_Dakota/New_Salem Central Time - North Dakota - Morton County (except Mandan area)
+US +394421-1045903 America/Denver Mountain Time
+US +433649-1161209 America/Boise Mountain Time - south Idaho & east Oregon
+US +364708-1084111 America/Shiprock Mountain Time - Navajo
+US +332654-1120424 America/Phoenix Mountain Standard Time - Arizona
+US +340308-1181434 America/Los_Angeles Pacific Time
+US +611305-1495401 America/Anchorage Alaska Time
+US +581807-1342511 America/Juneau Alaska Time - Alaska panhandle
+US +593249-1394338 America/Yakutat Alaska Time - Alaska panhandle neck
+US +643004-1652423 America/Nome Alaska Time - west Alaska
+US +515248-1763929 America/Adak Aleutian Islands
+US +211825-1575130 Pacific/Honolulu Hawaii
+UY -3453-05611 America/Montevideo
+UZ +3940+06648 Asia/Samarkand west Uzbekistan
+UZ +4120+06918 Asia/Tashkent east Uzbekistan
+VA +415408+0122711 Europe/Vatican
+VC +1309-06114 America/St_Vincent
+VE +1030-06656 America/Caracas
+VG +1827-06437 America/Tortola
+VI +1821-06456 America/St_Thomas
+VN +1045+10640 Asia/Ho_Chi_Minh
+VU -1740+16825 Pacific/Efate
+WF -1318-17610 Pacific/Wallis
+WS -1350-17144 Pacific/Apia
+YE +1245+04512 Asia/Aden
+YT -1247+04514 Indian/Mayotte
+ZA -2615+02800 Africa/Johannesburg
+ZM -1525+02817 Africa/Lusaka
+ZW -1750+03103 Africa/Harare
diff --git a/src/contact-editor/editor/generalinfoeditor/akonadicontactselecttypecombobox.cpp b/src/contact-editor/editor/generalinfoeditor/akonadicontactselecttypecombobox.cpp
new file mode 100644
index 0000000..cc3b26c
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/akonadicontactselecttypecombobox.cpp
@@ -0,0 +1,55 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "akonadicontactselecttypecombobox.h"
+#include <KLocalizedString>
+
+using namespace Akonadi;
+
+AkonadiContactSelectTypeCombobox::AkonadiContactSelectTypeCombobox(QWidget *parent)
+ : Akonadi::AkonadiContactComboBox(parent)
+{
+ initialize();
+}
+
+AkonadiContactSelectTypeCombobox::~AkonadiContactSelectTypeCombobox()
+{
+
+}
+
+void AkonadiContactSelectTypeCombobox::initialize()
+{
+ addItem(i18n("Select..."), QString());
+ QString type = QStringLiteral("HOME");
+ mSelectType.append(type);
+ addItem(i18n("Home"), type);
+ type = QStringLiteral("WORK");
+ mSelectType.append(type);
+ addItem(i18n("Work"), type);
+ type = QStringLiteral("OTHER");
+ mSelectType.append(type);
+ addItem(i18n("Other"), type);
+}
+
+QStringList AkonadiContactSelectTypeCombobox::selectTypeList() const
+{
+ return mSelectType;
+}
diff --git a/src/contact-editor/editor/generalinfoeditor/akonadicontactselecttypecombobox.h b/src/contact-editor/editor/generalinfoeditor/akonadicontactselecttypecombobox.h
new file mode 100644
index 0000000..8c79389
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/akonadicontactselecttypecombobox.h
@@ -0,0 +1,45 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 AKONADICONTACTSELECTTYPECOMBOBOX_H
+#define AKONADICONTACTSELECTTYPECOMBOBOX_H
+
+#include "../widgets/akonadicontactcombobox.h"
+#include "contacteditor_private_export.h"
+
+namespace Akonadi
+{
+class AKONADI_CONTACTS_TESTS_EXPORT AkonadiContactSelectTypeCombobox : public Akonadi::AkonadiContactComboBox
+{
+ Q_OBJECT
+public:
+ explicit AkonadiContactSelectTypeCombobox(QWidget *parent = nullptr);
+ ~AkonadiContactSelectTypeCombobox();
+
+ QStringList selectTypeList() const;
+
+private:
+ void initialize();
+ QStringList mSelectType;
+};
+}
+
+#endif // AKONADICONTACTSELECTTYPECOMBOBOX_H
diff --git a/src/contact-editor/editor/generalinfoeditor/autotests/CMakeLists.txt b/src/contact-editor/editor/generalinfoeditor/autotests/CMakeLists.txt
new file mode 100644
index 0000000..98c883a
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/autotests/CMakeLists.txt
@@ -0,0 +1,40 @@
+set(phonewidgettest_SRCS phonewidgettest.cpp)
+add_executable(phonewidgettest ${phonewidgettest_SRCS})
+add_test(phonewidgettest phonewidgettest)
+ecm_mark_as_test(phonewidgettest)
+target_link_libraries(phonewidgettest Qt5::Test Qt5::Widgets KF5::ContactEditor KF5::Contacts KF5::I18n KF5::Completion KF5::IconThemes)
+
+
+set(mailwidgettest_SRCS mailwidgettest.cpp)
+add_executable(mailwidgettest ${mailwidgettest_SRCS})
+add_test(mailwidgettest mailwidgettest)
+ecm_mark_as_test(mailwidgettest)
+target_link_libraries(mailwidgettest Qt5::Test Qt5::Widgets KF5::ContactEditor KF5::Contacts KF5::I18n KF5::Completion KF5::IconThemes)
+
+set(messagingwidgettest_SRCS messagingwidgettest.cpp ../../widgets/preferredlineeditwidget.cpp)
+add_executable(messagingwidgettest ${messagingwidgettest_SRCS})
+add_test(messagingwidgettest messagingwidgettest)
+ecm_mark_as_test(messagingwidgettest)
+target_link_libraries(messagingwidgettest Qt5::Test Qt5::Widgets KF5::ContactEditor KF5::Contacts KF5::I18n KF5::Completion KF5::Service KF5::IconThemes)
+
+
+
+set(akonadicontactselecttypecomboboxtest_SRCS akonadicontactselecttypecomboboxtest.cpp)
+add_executable(akonadicontactselecttypecomboboxtest ${akonadicontactselecttypecomboboxtest_SRCS})
+add_test(akonadicontactselecttypecomboboxtest akonadicontactselecttypecomboboxtest)
+ecm_mark_as_test(akonadicontactselecttypecomboboxtest)
+target_link_libraries(akonadicontactselecttypecomboboxtest Qt5::Test Qt5::Widgets KF5::ContactEditor KF5::I18n )
+
+
+set(nicknamewidgettest_SRCS nicknamewidgettest.cpp)
+add_executable(nicknamewidgettest ${nicknamewidgettest_SRCS})
+add_test(nicknamewidgettest nicknamewidgettest)
+ecm_mark_as_test(nicknamewidgettest)
+target_link_libraries(nicknamewidgettest Qt5::Test Qt5::Widgets KF5::ContactEditor KF5::I18n )
+
+
+set(messageformattingwidgettest_SRCS messageformattingwidgettest.cpp)
+add_executable(messageformattingwidgettest ${messageformattingwidgettest_SRCS})
+add_test(messageformattingwidgettest messageformattingwidgettest)
+ecm_mark_as_test(messageformattingwidgettest)
+target_link_libraries(messageformattingwidgettest Qt5::Test Qt5::Widgets KF5::ContactEditor KF5::I18n )
diff --git a/src/contact-editor/editor/generalinfoeditor/autotests/akonadicontactselecttypecomboboxtest.cpp b/src/contact-editor/editor/generalinfoeditor/autotests/akonadicontactselecttypecomboboxtest.cpp
new file mode 100644
index 0000000..8652faf
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/autotests/akonadicontactselecttypecomboboxtest.cpp
@@ -0,0 +1,44 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "akonadicontactselecttypecomboboxtest.h"
+#include "../akonadicontactselecttypecombobox.h"
+#include <QTest>
+
+AkonadiContactSelectTypeComboboxTest::AkonadiContactSelectTypeComboboxTest(QObject *parent)
+ : QObject(parent)
+{
+
+}
+
+AkonadiContactSelectTypeComboboxTest::~AkonadiContactSelectTypeComboboxTest()
+{
+
+}
+
+void AkonadiContactSelectTypeComboboxTest::shouldHaveDefaultValue()
+{
+ Akonadi::AkonadiContactSelectTypeCombobox w;
+ QVERIFY(!w.selectTypeList().isEmpty());
+ QCOMPARE(w.count(), w.selectTypeList().count() + 1);
+}
+
+QTEST_MAIN(AkonadiContactSelectTypeComboboxTest)
diff --git a/src/contact-editor/editor/generalinfoeditor/autotests/akonadicontactselecttypecomboboxtest.h b/src/contact-editor/editor/generalinfoeditor/autotests/akonadicontactselecttypecomboboxtest.h
new file mode 100644
index 0000000..488f9e7
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/autotests/akonadicontactselecttypecomboboxtest.h
@@ -0,0 +1,37 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 AKONADICONTACTSELECTTYPECOMBOBOXTEST_H
+#define AKONADICONTACTSELECTTYPECOMBOBOXTEST_H
+
+#include <QObject>
+
+class AkonadiContactSelectTypeComboboxTest : public QObject
+{
+ Q_OBJECT
+public:
+ explicit AkonadiContactSelectTypeComboboxTest(QObject *parent = nullptr);
+ ~AkonadiContactSelectTypeComboboxTest();
+private Q_SLOTS:
+ void shouldHaveDefaultValue();
+};
+
+#endif // AKONADICONTACTSELECTTYPECOMBOBOXTEST_H
diff --git a/src/contact-editor/editor/generalinfoeditor/autotests/mailwidgettest.cpp b/src/contact-editor/editor/generalinfoeditor/autotests/mailwidgettest.cpp
new file mode 100644
index 0000000..0216370
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/autotests/mailwidgettest.cpp
@@ -0,0 +1,57 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "mailwidgettest.h"
+#include "../mail/mailwidget.h"
+#include <QTest>
+#include <QLineEdit>
+#include <QToolButton>
+#include <QComboBox>
+
+MailWidgetTest::MailWidgetTest(QObject *parent)
+ : QObject(parent)
+{
+
+}
+
+MailWidgetTest::~MailWidgetTest()
+{
+
+}
+
+void MailWidgetTest::shouldHaveDefaultValue()
+{
+ Akonadi::MailWidget w;
+ QLineEdit *line = w.findChild<QLineEdit *>(QStringLiteral("mailedit"));
+ QVERIFY(line);
+ QVERIFY(line->text().isEmpty());
+ QToolButton *addButton = w.findChild<QToolButton *>(QStringLiteral("addbutton"));
+ QVERIFY(addButton);
+
+ QToolButton *removeButton = w.findChild<QToolButton *>(QStringLiteral("removebutton"));
+ QVERIFY(removeButton);
+
+ QComboBox *mailtype = w.findChild<QComboBox *>(QStringLiteral("mailtype"));
+ QVERIFY(mailtype);
+}
+
+QTEST_MAIN(MailWidgetTest)
diff --git a/src/contact-editor/editor/generalinfoeditor/autotests/mailwidgettest.h b/src/contact-editor/editor/generalinfoeditor/autotests/mailwidgettest.h
new file mode 100644
index 0000000..9869aba
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/autotests/mailwidgettest.h
@@ -0,0 +1,37 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 PHONEWIDGETTEST_H
+#define PHONEWIDGETTEST_H
+
+#include <QObject>
+class MailWidgetTest : public QObject
+{
+ Q_OBJECT
+public:
+ explicit MailWidgetTest(QObject *parent = nullptr);
+ ~MailWidgetTest();
+private Q_SLOTS:
+ void shouldHaveDefaultValue();
+};
+
+#endif // PHONEWIDGETTEST_H
diff --git a/src/contact-editor/editor/generalinfoeditor/autotests/messageformattingwidgettest.cpp b/src/contact-editor/editor/generalinfoeditor/autotests/messageformattingwidgettest.cpp
new file mode 100644
index 0000000..d24bc60
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/autotests/messageformattingwidgettest.cpp
@@ -0,0 +1,54 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2017 Laurent Montel <[email protected]>
+
+ 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 "messageformattingwidgettest.h"
+#include "../messageformattingwidget.h"
+#include <QCheckBox>
+#include <QComboBox>
+#include <QLabel>
+#include <QTest>
+
+MessageFormattingWidgetTest::MessageFormattingWidgetTest(QObject *parent)
+ : QObject(parent)
+{
+
+}
+
+void MessageFormattingWidgetTest::shouldHaveDefaultValue()
+{
+ Akonadi::MessageFormattingWidget w;
+
+ QLabel *label = w.findChild<QLabel *>(QStringLiteral("label"));
+ QVERIFY(label);
+ QVERIFY(!label->text().isEmpty());
+
+ QComboBox *mMailPreferFormatting = w.findChild<QComboBox *>(QStringLiteral("mMailPreferFormatting"));
+ QVERIFY(mMailPreferFormatting);
+ QVERIFY(mMailPreferFormatting->count() > 0);
+
+ QCheckBox *mAllowRemoteContent = w.findChild<QCheckBox *>(QStringLiteral("mAllowRemoteContent"));
+ QVERIFY(mAllowRemoteContent);
+ QVERIFY(!mAllowRemoteContent->text().isEmpty());
+ QVERIFY(!mAllowRemoteContent->isChecked());
+}
+
+QTEST_MAIN(MessageFormattingWidgetTest)
diff --git a/src/contact-editor/editor/generalinfoeditor/autotests/messageformattingwidgettest.h b/src/contact-editor/editor/generalinfoeditor/autotests/messageformattingwidgettest.h
new file mode 100644
index 0000000..bfc95c5
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/autotests/messageformattingwidgettest.h
@@ -0,0 +1,37 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2017 Laurent Montel <[email protected]>
+
+ 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 MESSAGEFORMATTINGWIDGETTEST_H
+#define MESSAGEFORMATTINGWIDGETTEST_H
+
+#include <QObject>
+
+class MessageFormattingWidgetTest : public QObject
+{
+ Q_OBJECT
+public:
+ explicit MessageFormattingWidgetTest(QObject *parent = nullptr);
+ ~MessageFormattingWidgetTest() = default;
+private Q_SLOTS:
+ void shouldHaveDefaultValue();
+};
+
+#endif // MESSAGEFORMATTINGWIDGETTEST_H
diff --git a/src/contact-editor/editor/generalinfoeditor/autotests/messagingwidgettest.cpp b/src/contact-editor/editor/generalinfoeditor/autotests/messagingwidgettest.cpp
new file mode 100644
index 0000000..c7f4ecf
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/autotests/messagingwidgettest.cpp
@@ -0,0 +1,56 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "messagingwidgettest.h"
+#include "../messaging/messagingwidget.h"
+#include <KLineEdit>
+#include <QComboBox>
+#include <QTest>
+#include <QToolButton>
+
+MessagingWidgetTest::MessagingWidgetTest(QObject *parent)
+ : QObject(parent)
+{
+
+}
+
+MessagingWidgetTest::~MessagingWidgetTest()
+{
+
+}
+
+void MessagingWidgetTest::shouldHaveDefaultValues()
+{
+ Akonadi::MessagingWidget w;
+ KLineEdit *line = w.findChild<KLineEdit *>(QStringLiteral("messaginglineedit"));
+ QVERIFY(line);
+
+ QComboBox *protocolCombo = w.findChild<QComboBox *>(QStringLiteral("protocol"));
+ QVERIFY(protocolCombo);
+ QVERIFY(protocolCombo->count() > 0);
+
+ QToolButton *add = w.findChild<QToolButton *>(QStringLiteral("addbutton"));
+ QVERIFY(add);
+ QToolButton *remove = w.findChild<QToolButton *>(QStringLiteral("removebutton"));
+ QVERIFY(remove);
+}
+
+QTEST_MAIN(MessagingWidgetTest)
diff --git a/src/contact-editor/editor/generalinfoeditor/autotests/messagingwidgettest.h b/src/contact-editor/editor/generalinfoeditor/autotests/messagingwidgettest.h
new file mode 100644
index 0000000..63b7884
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/autotests/messagingwidgettest.h
@@ -0,0 +1,37 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 MESSAGINGWIDGETTEST_H
+#define MESSAGINGWIDGETTEST_H
+
+#include <QObject>
+
+class MessagingWidgetTest : public QObject
+{
+ Q_OBJECT
+public:
+ explicit MessagingWidgetTest(QObject *parent = nullptr);
+ ~MessagingWidgetTest();
+private Q_SLOTS:
+ void shouldHaveDefaultValues();
+};
+
+#endif // MESSAGINGWIDGETTEST_H
diff --git a/src/contact-editor/editor/generalinfoeditor/autotests/nicknamewidgettest.cpp b/src/contact-editor/editor/generalinfoeditor/autotests/nicknamewidgettest.cpp
new file mode 100644
index 0000000..3534958
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/autotests/nicknamewidgettest.cpp
@@ -0,0 +1,33 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2017 Laurent Montel <[email protected]>
+
+ 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 "nicknamewidgettest.h"
+
+#include <QTest>
+
+NicknameWidgetTest::NicknameWidgetTest(QObject *parent)
+ : QObject(parent)
+{
+
+}
+
+QTEST_MAIN(NicknameWidgetTest)
diff --git a/src/contact-editor/editor/generalinfoeditor/autotests/nicknamewidgettest.h b/src/contact-editor/editor/generalinfoeditor/autotests/nicknamewidgettest.h
new file mode 100644
index 0000000..13af5bf
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/autotests/nicknamewidgettest.h
@@ -0,0 +1,36 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2017 Laurent Montel <[email protected]>
+
+ 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 NICKNAMEWIDGETTEST_H
+#define NICKNAMEWIDGETTEST_H
+
+#include <QObject>
+
+class NicknameWidgetTest : public QObject
+{
+ Q_OBJECT
+public:
+ explicit NicknameWidgetTest(QObject *parent = nullptr);
+ ~NicknameWidgetTest() = default;
+};
+
+#endif // NICKNAMEWIDGETTEST_H
diff --git a/src/contact-editor/editor/generalinfoeditor/autotests/phonewidgettest.cpp b/src/contact-editor/editor/generalinfoeditor/autotests/phonewidgettest.cpp
new file mode 100644
index 0000000..eeac9f6
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/autotests/phonewidgettest.cpp
@@ -0,0 +1,56 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "phonewidgettest.h"
+#include "../phone/phonewidget.h"
+#include "../phone/phonecomboboxtype.h"
+#include <QTest>
+#include <QLineEdit>
+#include <QToolButton>
+
+PhoneWidgetTest::PhoneWidgetTest(QObject *parent)
+ : QObject(parent)
+{
+
+}
+
+PhoneWidgetTest::~PhoneWidgetTest()
+{
+
+}
+
+void PhoneWidgetTest::shouldHaveDefaultValue()
+{
+ Akonadi::PhoneWidget w;
+ QLineEdit *line = w.findChild<QLineEdit *>(QStringLiteral("phonenumber"));
+ QVERIFY(line);
+ QToolButton *addButton = w.findChild<QToolButton *>(QStringLiteral("addbutton"));
+ QVERIFY(addButton);
+
+ Akonadi::PhoneComboBoxType *combotype = w.findChild<Akonadi::PhoneComboBoxType *>(QStringLiteral("phonetype"));
+ QVERIFY(combotype);
+
+ QToolButton *removeButton = w.findChild<QToolButton *>(QStringLiteral("removebutton"));
+ QVERIFY(removeButton);
+}
+
+QTEST_MAIN(PhoneWidgetTest)
diff --git a/src/contact-editor/editor/generalinfoeditor/autotests/phonewidgettest.h b/src/contact-editor/editor/generalinfoeditor/autotests/phonewidgettest.h
new file mode 100644
index 0000000..2142177
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/autotests/phonewidgettest.h
@@ -0,0 +1,37 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 PHONEWIDGETTEST_H
+#define PHONEWIDGETTEST_H
+
+#include <QObject>
+class PhoneWidgetTest : public QObject
+{
+ Q_OBJECT
+public:
+ explicit PhoneWidgetTest(QObject *parent = nullptr);
+ ~PhoneWidgetTest();
+private Q_SLOTS:
+ void shouldHaveDefaultValue();
+};
+
+#endif // PHONEWIDGETTEST_H
diff --git a/src/contact-editor/editor/generalinfoeditor/categorieseditwidget.cpp b/src/contact-editor/editor/generalinfoeditor/categorieseditwidget.cpp
new file mode 100644
index 0000000..3f5fdc1
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/categorieseditwidget.cpp
@@ -0,0 +1,73 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (c) 2009 Tobias Koenig <[email protected]>
+
+ 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 "categorieseditwidget.h"
+
+#include <item.h>
+#include <tag.h>
+#include <tagwidget.h>
+#include <kcontacts/addressee.h>
+
+#include <QHBoxLayout>
+
+CategoriesEditWidget::CategoriesEditWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ QHBoxLayout *layout = new QHBoxLayout(this);
+ layout->setMargin(0);
+ mTagWidget = new Akonadi::TagWidget(this);
+ layout->addWidget(mTagWidget);
+}
+
+CategoriesEditWidget::~CategoriesEditWidget()
+{
+}
+
+void CategoriesEditWidget::setReadOnly(bool readOnly)
+{
+ mTagWidget->setEnabled(!readOnly);
+}
+
+void CategoriesEditWidget::loadContact(const KContacts::Addressee &contact)
+{
+ Akonadi::Tag::List tags;
+
+ const QStringList categories = contact.categories();
+ tags.reserve(categories.count());
+ for (const QString &category : categories) {
+ tags.append(Akonadi::Tag::fromUrl(QUrl(category)));
+ }
+
+ mTagWidget->setSelection(tags);
+}
+
+void CategoriesEditWidget::storeContact(KContacts::Addressee &contact) const
+{
+ QStringList categories;
+
+ const Akonadi::Tag::List tags = mTagWidget->selection();
+ categories.reserve(tags.count());
+ for (const Akonadi::Tag &tag : tags) {
+ categories.append(tag.url().url());
+ }
+
+ contact.setCategories(categories);
+}
diff --git a/src/contact-editor/editor/generalinfoeditor/categorieseditwidget.h b/src/contact-editor/editor/generalinfoeditor/categorieseditwidget.h
new file mode 100644
index 0000000..6dd5490
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/categorieseditwidget.h
@@ -0,0 +1,54 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (c) 2010 Tobias Koenig <[email protected]>
+
+ 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 CATEGORIESEDITWIDGET_H
+#define CATEGORIESEDITWIDGET_H
+
+#include <QWidget>
+
+#include <kcontacts/addressee.h>
+
+namespace Akonadi
+{
+class TagWidget;
+}
+
+/**
+ * @short A widget for editing the categories of a contact.
+ */
+class CategoriesEditWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit CategoriesEditWidget(QWidget *parent = nullptr);
+ ~CategoriesEditWidget();
+
+ void loadContact(const KContacts::Addressee &contact);
+ void storeContact(KContacts::Addressee &contact) const;
+
+ void setReadOnly(bool readOnly);
+
+private:
+ Akonadi::TagWidget *mTagWidget;
+};
+
+#endif
diff --git a/src/contact-editor/editor/generalinfoeditor/displaynameeditwidget.cpp b/src/contact-editor/editor/generalinfoeditor/displaynameeditwidget.cpp
new file mode 100644
index 0000000..66de6d5
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/displaynameeditwidget.cpp
@@ -0,0 +1,258 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (c) 2009 Tobias Koenig <[email protected]>
+
+ 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 "displaynameeditwidget.h"
+
+
+#include <QEvent>
+#include <QAbstractItemView>
+#include <QHBoxLayout>
+#include <QPainter>
+#include <QStyledItemDelegate>
+
+#include <kcontacts/addressee.h>
+#include <KComboBox>
+#include <KLocalizedString>
+
+// Tries to guess the display type that is used for the passed contact
+static DisplayNameEditWidget::DisplayType guessedDisplayType(const KContacts::Addressee &contact)
+{
+ if (contact.formattedName() == (contact.givenName() + QLatin1Char(' ') + contact.familyName())) {
+ return DisplayNameEditWidget::SimpleName;
+ } else if (contact.formattedName() == contact.assembledName()) {
+ return DisplayNameEditWidget::FullName;
+ } else if (contact.formattedName() == (contact.familyName() + QStringLiteral(", ") + contact.givenName())) {
+ return DisplayNameEditWidget::ReverseNameWithComma;
+ } else if (contact.formattedName() == (contact.familyName() + QLatin1Char(' ') + contact.givenName())) {
+ return DisplayNameEditWidget::ReverseName;
+ } else if (contact.formattedName() == contact.organization()) {
+ return DisplayNameEditWidget::Organization;
+ } else {
+ return DisplayNameEditWidget::CustomName;
+ }
+}
+
+class DisplayNameDelegate : public QStyledItemDelegate
+{
+ Q_OBJECT
+public:
+ DisplayNameDelegate(QAbstractItemView *view, QObject *parent = nullptr)
+ : QStyledItemDelegate(parent)
+ , mMaxDescriptionWidth(0)
+ {
+ mDescriptions.append(i18n("Short Name"));
+ mDescriptions.append(i18n("Full Name"));
+ mDescriptions.append(i18n("Reverse Name with Comma"));
+ mDescriptions.append(i18n("Reverse Name"));
+ mDescriptions.append(i18n("Organization"));
+ mDescriptions.append(i18nc("@item:inlistbox A custom name format", "Custom"));
+
+ QFont font = view->font();
+ font.setStyle(QFont::StyleItalic);
+ QFontMetrics metrics(font);
+ for (const QString &description : qAsConst(mDescriptions)) {
+ mMaxDescriptionWidth = qMax(mMaxDescriptionWidth, metrics.width(description));
+ }
+
+ mMaxDescriptionWidth += 3;
+ }
+
+ int maximumDescriptionWidth() const
+ {
+ return mMaxDescriptionWidth;
+ }
+
+ void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override
+ {
+ QStyledItemDelegate::paint(painter, option, index);
+ const QRect rect(option.rect.width() - mMaxDescriptionWidth, option.rect.y(), mMaxDescriptionWidth, option.rect.height());
+ painter->save();
+ QFont font(painter->font());
+ font.setStyle(QFont::StyleItalic);
+ painter->setFont(font);
+ if (option.state & QStyle::State_Selected) {
+ painter->setPen(option.palette.color(QPalette::Normal, QPalette::BrightText));
+ } else {
+ painter->setPen(option.palette.color(QPalette::Disabled, QPalette::Text));
+ }
+ painter->drawText(rect, Qt::AlignLeft, mDescriptions.at(index.row()));
+ painter->restore();
+ }
+
+ QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override
+ {
+ QSize size = QStyledItemDelegate::sizeHint(option, index);
+ size.setWidth(size.width() + mMaxDescriptionWidth);
+
+ return size;
+ }
+
+private:
+ QStringList mDescriptions;
+ int mMaxDescriptionWidth;
+};
+
+DisplayNameEditWidget::DisplayNameEditWidget(QWidget *parent)
+ : QWidget(parent)
+ , mDisplayType(FullName)
+{
+ QHBoxLayout *layout = new QHBoxLayout(this);
+ layout->setMargin(0);
+
+ mView = new KComboBox(this);
+ mView->addItems(QStringList() << QString() << QString() << QString()
+ << QString() << QString() << QString());
+
+ layout->addWidget(mView);
+ setFocusProxy(mView);
+ setFocusPolicy(Qt::StrongFocus);
+ connect(mView, static_cast<void (KComboBox::*)(int)>(&KComboBox::activated), this, &DisplayNameEditWidget::displayTypeChanged);
+
+ DisplayNameDelegate *delegate = new DisplayNameDelegate(mView->view());
+ mView->view()->setItemDelegate(delegate);
+
+ mAdditionalPopupWidth = delegate->maximumDescriptionWidth();
+
+ mViewport = mView->view()->viewport();
+ mViewport->installEventFilter(this);
+}
+
+DisplayNameEditWidget::~DisplayNameEditWidget()
+{
+}
+
+void DisplayNameEditWidget::setReadOnly(bool readOnly)
+{
+ mView->setEnabled(!readOnly);
+}
+
+void DisplayNameEditWidget::setDisplayType(DisplayType type)
+{
+ if ((int)type == -1) {
+ // guess the used display type
+ mDisplayType = guessedDisplayType(mContact);
+ } else {
+ mDisplayType = type;
+ }
+
+ updateView();
+}
+
+DisplayNameEditWidget::DisplayType DisplayNameEditWidget::displayType() const
+{
+ return mDisplayType;
+}
+
+void DisplayNameEditWidget::loadContact(const KContacts::Addressee &contact)
+{
+ mContact = contact;
+
+ mDisplayType = guessedDisplayType(mContact);
+
+ updateView();
+}
+
+void DisplayNameEditWidget::storeContact(KContacts::Addressee &contact) const
+{
+ contact.setFormattedName(mView->currentText());
+}
+
+void DisplayNameEditWidget::changeName(const KContacts::Addressee &contact)
+{
+ const QString organization = mContact.organization();
+ mContact = contact;
+ mContact.setOrganization(organization);
+ if (mDisplayType == CustomName) {
+ mContact.setFormattedName(mView->currentText());
+ }
+
+ updateView();
+}
+
+void DisplayNameEditWidget::changeOrganization(const QString &organization)
+{
+ mContact.setOrganization(organization);
+
+ updateView();
+}
+
+void DisplayNameEditWidget::displayTypeChanged(int type)
+{
+ mDisplayType = (DisplayType)type;
+
+ updateView();
+}
+
+bool DisplayNameEditWidget::eventFilter(QObject *object, QEvent *event)
+{
+ if (object == mViewport) {
+ if (event->type() == QEvent::Show) {
+ // retrieve the widget that contains the popup view
+ QWidget *parentWidget = mViewport->parentWidget()->parentWidget();
+
+ int maxWidth = 0;
+ QFontMetrics metrics(mView->font());
+ const int viewCount(mView->count());
+ for (int i = 0; i < viewCount; ++i) {
+ maxWidth = qMax(maxWidth, metrics.width(mView->itemText(i)));
+ }
+
+ // resize it to show the complete content
+ parentWidget->resize(maxWidth + mAdditionalPopupWidth + 20, parentWidget->height());
+ }
+ return false;
+ }
+
+ return QWidget::eventFilter(object, event);
+}
+
+void DisplayNameEditWidget::updateView()
+{
+ // SimpleName:
+ mView->setItemText(0, mContact.givenName() + QLatin1Char(' ') + mContact.familyName());
+
+ // FullName:
+ mView->setItemText(1, mContact.assembledName());
+
+ // ReverseNameWithComma:
+ mView->setItemText(2, mContact.familyName() + QStringLiteral(", ") + mContact.givenName());
+
+ // ReverseName:
+ mView->setItemText(3, mContact.familyName() + QLatin1Char(' ') + mContact.givenName());
+
+ // Organization:
+ mView->setItemText(4, mContact.organization());
+
+ // CustomName:
+ mView->setItemText(5, mContact.formattedName());
+
+ // delay the state change here, since we might have been called from mView via a signal
+ QMetaObject::invokeMethod(this, "setComboBoxEditable", Qt::QueuedConnection, Q_ARG(bool, mDisplayType == CustomName));
+
+ mView->setCurrentIndex((int)mDisplayType);
+}
+
+void DisplayNameEditWidget::setComboBoxEditable(bool value)
+{
+ mView->setEditable(value);
+}
+
+#include "displaynameeditwidget.moc"
diff --git a/src/contact-editor/editor/generalinfoeditor/displaynameeditwidget.h b/src/contact-editor/editor/generalinfoeditor/displaynameeditwidget.h
new file mode 100644
index 0000000..af9955e
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/displaynameeditwidget.h
@@ -0,0 +1,84 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (c) 2009 Tobias Koenig <[email protected]>
+
+ 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 DISPLAYNAMEEDITWIDGET_H
+#define DISPLAYNAMEEDITWIDGET_H
+
+#include <QWidget>
+
+#include <kcontacts/addressee.h>
+
+class KComboBox;
+
+/**
+ * @short A widget for editing the display name of a contact.
+ *
+ * The widget will either use a predefined schema for formatting
+ * the name or a custom one.
+ */
+class DisplayNameEditWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ /**
+ * Describes what the display name should look like.
+ */
+ enum DisplayType {
+ SimpleName, ///< A name of the form: givenName familyName
+ FullName, ///< A name of the form: prefix givenName additionalName familyName suffix
+ ReverseNameWithComma, ///< A name of the form: familyName, givenName
+ ReverseName, ///< A name of the form: familyName givenName
+ Organization, ///< The organization name
+ CustomName ///< Let the user input a display name
+ };
+
+ explicit DisplayNameEditWidget(QWidget *parent = nullptr);
+ ~DisplayNameEditWidget();
+
+ void loadContact(const KContacts::Addressee &contact);
+ void storeContact(KContacts::Addressee &contact) const;
+
+ void setReadOnly(bool readOnly);
+
+ void setDisplayType(DisplayType type);
+ DisplayType displayType() const;
+
+public Q_SLOTS:
+ void changeName(const KContacts::Addressee &contact);
+ void changeOrganization(const QString &organization);
+
+protected:
+ bool eventFilter(QObject *object, QEvent *event) override;
+
+private:
+ void displayTypeChanged(int);
+ void setComboBoxEditable(bool);
+ void updateView();
+
+ KComboBox *mView;
+ KContacts::Addressee mContact;
+ QWidget *mViewport;
+ DisplayType mDisplayType;
+ int mAdditionalPopupWidth;
+};
+
+#endif
diff --git a/src/contact-editor/editor/generalinfoeditor/generalinfowidget.cpp b/src/contact-editor/editor/generalinfoeditor/generalinfowidget.cpp
new file mode 100644
index 0000000..0af896f
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/generalinfowidget.cpp
@@ -0,0 +1,154 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "generalinfowidget.h"
+#include "namewidget.h"
+#include "nicknamewidget.h"
+#include <QGridLayout>
+#include <QLabel>
+#include <KLocalizedString>
+#include <QLineEdit>
+#include "phone/phonelistwidget.h"
+#include "messaging/messaginglistwidget.h"
+#include "mail/maillistwidget.h"
+#include "web/weblistwidget.h"
+#include "categorieseditwidget.h"
+#include "../widgets/imagewidget.h"
+#include "messageformattingwidget.h"
+
+using namespace Akonadi;
+
+GeneralInfoWidget::GeneralInfoWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ QHBoxLayout *topLayout = new QHBoxLayout(this);
+
+ QVBoxLayout *photoLayout = new QVBoxLayout;
+ topLayout->addLayout(photoLayout);
+ mPhotoWidget = new ImageWidget(ImageWidget::Photo);
+ mPhotoWidget->setObjectName(QStringLiteral("photowidget"));
+ photoLayout->addWidget(mPhotoWidget);
+ photoLayout->addStretch(1);
+
+ QVBoxLayout *leftLayout = new QVBoxLayout;
+ topLayout->addLayout(leftLayout);
+
+ QVBoxLayout *rightLayout = new QVBoxLayout;
+ topLayout->addLayout(rightLayout);
+
+ mNameWidget = new NameWidget(this);
+ mNameWidget->setObjectName(QStringLiteral("namewidget"));
+ leftLayout->addWidget(mNameWidget);
+
+ mNickNameWidget = new NicknameWidget(this);
+ mNickNameWidget->setObjectName(QStringLiteral("nicknamewidget"));
+ rightLayout->addWidget(mNickNameWidget);
+
+ mPhoneListWidget = new PhoneListWidget(this);
+ mPhoneListWidget->setObjectName(QStringLiteral("phonelistwidget"));
+ leftLayout->addWidget(mPhoneListWidget);
+
+ mWebListWidget = new WebListWidget(this);
+ mWebListWidget->setObjectName(QStringLiteral("weblistwidget"));
+ leftLayout->addWidget(mWebListWidget);
+
+ mMessagingListWidget = new MessagingListWidget(this);
+ mMessagingListWidget->setObjectName(QStringLiteral("messaginglistwidget"));
+ rightLayout->addWidget(mMessagingListWidget);
+
+ mMailListWidget = new MailListWidget(this);
+ mMailListWidget->setObjectName(QStringLiteral("maillistwidget"));
+ rightLayout->addWidget(mMailListWidget);
+
+ QWidget *categoryWidget = new QWidget(this);
+ QVBoxLayout *categoryWidgetLayout = new QVBoxLayout(categoryWidget);
+ categoryWidgetLayout->setMargin(0);
+ QLabel *label = new QLabel(i18n("Tags"), this);
+ label->setObjectName(QStringLiteral("categorylabel"));
+ categoryWidgetLayout->addWidget(label);
+
+ mCategoriesWidget = new CategoriesEditWidget(this);
+ mCategoriesWidget->setObjectName(QStringLiteral("categories"));
+ categoryWidgetLayout->addWidget(mCategoriesWidget);
+ leftLayout->addWidget(categoryWidget);
+
+ mMessageFormattingWidget = new MessageFormattingWidget(this);
+ mMessageFormattingWidget->setObjectName(QStringLiteral("mMessageFormattingWidget"));
+ leftLayout->addWidget(mMessageFormattingWidget);
+
+ leftLayout->addStretch(1);
+ rightLayout->addStretch(1);
+}
+
+GeneralInfoWidget::~GeneralInfoWidget()
+{
+
+}
+
+void GeneralInfoWidget::setDisplayType(DisplayNameEditWidget::DisplayType type)
+{
+ mNameWidget->setDisplayType(type);
+}
+
+DisplayNameEditWidget::DisplayType GeneralInfoWidget::displayType() const
+{
+ return mNameWidget->displayType();
+}
+
+void GeneralInfoWidget::loadContact(const KContacts::Addressee &contact)
+{
+ mPhoneListWidget->loadContact(contact);
+ mWebListWidget->loadContact(contact);
+ mMessagingListWidget->loadContact(contact);
+ mMailListWidget->loadContact(contact);
+ mNameWidget->loadContact(contact);
+ mNickNameWidget->loadContact(contact);
+ mPhotoWidget->loadContact(contact);
+ mCategoriesWidget->loadContact(contact);
+ mMessageFormattingWidget->loadContact(contact);
+}
+
+void GeneralInfoWidget::storeContact(KContacts::Addressee &contact) const
+{
+ mPhoneListWidget->storeContact(contact);
+ mWebListWidget->storeContact(contact);
+ mMessagingListWidget->storeContact(contact);
+ mMailListWidget->storeContact(contact);
+ mNameWidget->storeContact(contact);
+ mNickNameWidget->storeContact(contact);
+ mPhotoWidget->storeContact(contact);
+ mCategoriesWidget->storeContact(contact);
+ mMessageFormattingWidget->storeContact(contact);
+}
+
+void GeneralInfoWidget::setReadOnly(bool readOnly)
+{
+ mPhoneListWidget->setReadOnly(readOnly);
+ mWebListWidget->setReadOnly(readOnly);
+ mMessagingListWidget->setReadOnly(readOnly);
+ mMailListWidget->setReadOnly(readOnly);
+ mNameWidget->setReadOnly(readOnly);
+ mNickNameWidget->setReadOnly(readOnly);
+ mPhotoWidget->setReadOnly(readOnly);
+ mCategoriesWidget->setReadOnly(readOnly);
+ mMessageFormattingWidget->setReadOnly(readOnly);
+}
diff --git a/src/contact-editor/editor/generalinfoeditor/generalinfowidget.h b/src/contact-editor/editor/generalinfoeditor/generalinfowidget.h
new file mode 100644
index 0000000..498b34a
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/generalinfowidget.h
@@ -0,0 +1,70 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 GENERALINFOWIDGET_H
+#define GENERALINFOWIDGET_H
+
+#include <QWidget>
+#include "displaynameeditwidget.h"
+class ImageWidget;
+class CategoriesEditWidget;
+namespace KContacts
+{
+class Addressee;
+}
+
+namespace Akonadi
+{
+class PhoneListWidget;
+class WebListWidget;
+class MessagingListWidget;
+class MailListWidget;
+class NameWidget;
+class NicknameWidget;
+class MessageFormattingWidget;
+class GeneralInfoWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit GeneralInfoWidget(QWidget *parent = nullptr);
+ ~GeneralInfoWidget();
+
+ void loadContact(const KContacts::Addressee &contact);
+
+ void storeContact(KContacts::Addressee &contact) const;
+
+ void setReadOnly(bool readOnly);
+ void setDisplayType(DisplayNameEditWidget::DisplayType type);
+ DisplayNameEditWidget::DisplayType displayType() const;
+private:
+ PhoneListWidget *mPhoneListWidget;
+ WebListWidget *mWebListWidget;
+ MessagingListWidget *mMessagingListWidget;
+ MailListWidget *mMailListWidget;
+ ImageWidget *mPhotoWidget;
+ NameWidget *mNameWidget;
+ NicknameWidget *mNickNameWidget;
+ CategoriesEditWidget *mCategoriesWidget;
+ MessageFormattingWidget *mMessageFormattingWidget;
+};
+}
+#endif // GENERALINFOWIDGET_H
diff --git a/src/contact-editor/editor/generalinfoeditor/mail/maillistwidget.cpp b/src/contact-editor/editor/generalinfoeditor/mail/maillistwidget.cpp
new file mode 100644
index 0000000..a945a44
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/mail/maillistwidget.cpp
@@ -0,0 +1,65 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "maillistwidget.h"
+#include "mailwidgetlister.h"
+#include <QLabel>
+#include <QVBoxLayout>
+#include <KLocalizedString>
+#include <KContacts/Addressee>
+using namespace Akonadi;
+
+MailListWidget::MailListWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ QVBoxLayout *topLayout = new QVBoxLayout(this);
+ topLayout->setMargin(0);
+ topLayout->setSpacing(0);
+
+ QLabel *label = new QLabel(i18n("Email"), this);
+ label->setObjectName(QStringLiteral("emaillistlabel"));
+ topLayout->addWidget(label);
+
+ mMailWidgetLister = new Akonadi::MailWidgetLister(this);
+ mMailWidgetLister->setObjectName(QStringLiteral("emailwidgetlister"));
+ topLayout->addWidget(mMailWidgetLister);
+}
+
+MailListWidget::~MailListWidget()
+{
+
+}
+
+void MailListWidget::loadContact(const KContacts::Addressee &contact)
+{
+ mMailWidgetLister->loadContact(contact);
+}
+
+void MailListWidget::storeContact(KContacts::Addressee &contact) const
+{
+ mMailWidgetLister->storeContact(contact);
+}
+
+void MailListWidget::setReadOnly(bool readOnly)
+{
+ mMailWidgetLister->setEnabled(!readOnly);
+}
diff --git a/src/contact-editor/editor/generalinfoeditor/mail/maillistwidget.h b/src/contact-editor/editor/generalinfoeditor/mail/maillistwidget.h
new file mode 100644
index 0000000..5796ddc
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/mail/maillistwidget.h
@@ -0,0 +1,47 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 MAILISTWIDGET_H
+#define MAILISTWIDGET_H
+
+#include <QWidget>
+namespace KContacts
+{
+class Addressee;
+}
+namespace Akonadi
+{
+class MailWidgetLister;
+class MailListWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit MailListWidget(QWidget *parent = nullptr);
+ ~MailListWidget();
+ void loadContact(const KContacts::Addressee &contact);
+ void storeContact(KContacts::Addressee &contact) const;
+ void setReadOnly(bool readOnly);
+private:
+ Akonadi::MailWidgetLister *mMailWidgetLister;
+};
+}
+#endif // MAILISTWIDGET_H
diff --git a/src/contact-editor/editor/generalinfoeditor/mail/mailwidget.cpp b/src/contact-editor/editor/generalinfoeditor/mail/mailwidget.cpp
new file mode 100644
index 0000000..ade39a7
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/mail/mailwidget.cpp
@@ -0,0 +1,150 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "mailwidget.h"
+#include <KLocalizedString>
+#include <QHBoxLayout>
+#include <KLineEdit>
+#include <QToolButton>
+#include <QComboBox>
+#include <editor/generalinfoeditor/akonadicontactselecttypecombobox.h>
+#include <editor/widgets/preferredlineeditwidget.h>
+
+using namespace Akonadi;
+MailWidget::MailWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ QHBoxLayout *layout = new QHBoxLayout(this);
+ layout->setSpacing(0);
+ layout->setMargin(0);
+
+ mMailEdit = new PreferredLineEditWidget(this);
+ mMailEdit->setTrapReturnKey(true);
+ mMailEdit->setPlaceholderText(i18n("Add an Email Account"));
+ mMailEdit->setObjectName(QStringLiteral("mailedit"));
+ layout->addWidget(mMailEdit);
+ connect(mMailEdit, &PreferredLineEditWidget::preferredChanged, this, &MailWidget::slotPreferredChanged);
+
+ mMailType = new Akonadi::AkonadiContactSelectTypeCombobox(this);
+ mMailType->setObjectName(QStringLiteral("mailtype"));
+ layout->addWidget(mMailType);
+
+ mAddButton = new QToolButton(this);
+ mAddButton->setIcon(QIcon::fromTheme(QStringLiteral("list-add")));
+ mAddButton->setObjectName(QStringLiteral("addbutton"));
+ mAddButton->setToolTip(i18n("Add an Email"));
+ connect(mAddButton, &QToolButton::clicked, this, &MailWidget::slotAddMail);
+ layout->addWidget(mAddButton);
+
+ mRemoveButton = new QToolButton(this);
+ mRemoveButton->setIcon(QIcon::fromTheme(QStringLiteral("list-remove")));
+ mRemoveButton->setObjectName(QStringLiteral("removebutton"));
+ mRemoveButton->setToolTip(i18n("Remove Email"));
+ connect(mRemoveButton, &QToolButton::clicked, this, &MailWidget::slotRemoveMail);
+ layout->addWidget(mRemoveButton);
+}
+
+MailWidget::~MailWidget()
+{
+
+}
+
+void MailWidget::slotPreferredChanged()
+{
+ Q_EMIT preferredChanged(this);
+}
+
+void MailWidget::clearWidget()
+{
+ mMailEdit->clear();
+ mEmail = KContacts::Email();
+ mMailType->setCurrentIndex(0);
+}
+
+void MailWidget::updateAddRemoveButton(bool addButtonEnabled)
+{
+ mAddButton->setEnabled(addButtonEnabled);
+}
+
+void MailWidget::setMail(const KContacts::Email &email)
+{
+ mEmail = email;
+ mMailEdit->setText(email.mail());
+ const QMap<QString, QStringList> parameters = mEmail.parameters();
+ const QStringList value = parameters.value(QStringLiteral("type"));
+ if (value.contains(QStringLiteral("PREF"))) {
+ setPreferred(true);
+ }
+ const QStringList lst = mMailType->selectTypeList();
+ for (const QString &type : lst) {
+ if (value.contains(type)) {
+ mOldType = type;
+ mMailType->setCurrentIndex(mMailType->findData(type));
+ break;
+ }
+ }
+}
+
+KContacts::Email MailWidget::email()
+{
+ mEmail.setEmail(mMailEdit->text());
+ QMap<QString, QStringList> parameters = mEmail.parameters();
+ QStringList value = parameters.value(QStringLiteral("type"));
+ const QString newType = mMailType->currentData().toString();
+ if (!newType.isEmpty()) {
+ if (mOldType != newType) {
+ if (!value.contains(newType)) {
+ value.append(newType);
+ }
+ if (!mOldType.isEmpty()) {
+ value.removeAll(mOldType);
+ }
+ }
+ }
+ if (mMailEdit->preferred()) {
+ if (!value.contains(QStringLiteral("PREF"))) {
+ value.append(QStringLiteral("PREF"));
+ }
+ } else {
+ value.removeAll(QStringLiteral("PREF"));
+ }
+ if (!value.isEmpty()) {
+ parameters.insert(QStringLiteral("type"), value);
+ }
+ mEmail.setParameters(parameters);
+ return mEmail;
+}
+
+void MailWidget::setPreferred(bool b)
+{
+ mMailEdit->setPreferred(b);
+}
+
+void MailWidget::slotAddMail()
+{
+ Q_EMIT addWidget(this);
+}
+
+void MailWidget::slotRemoveMail()
+{
+ Q_EMIT removeWidget(this);
+}
diff --git a/src/contact-editor/editor/generalinfoeditor/mail/mailwidget.h b/src/contact-editor/editor/generalinfoeditor/mail/mailwidget.h
new file mode 100644
index 0000000..694a90a
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/mail/mailwidget.h
@@ -0,0 +1,63 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 MAILWIDGET_H
+#define MAILWIDGET_H
+
+#include <QWidget>
+#include <KContacts/Email>
+#include "contacteditor_private_export.h"
+class QToolButton;
+namespace Akonadi
+{
+class PreferredLineEditWidget;
+class AkonadiContactSelectTypeCombobox;
+class AKONADI_CONTACTS_TESTS_EXPORT MailWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit MailWidget(QWidget *parent = nullptr);
+ ~MailWidget();
+
+ void clearWidget();
+ void updateAddRemoveButton(bool addButtonEnabled);
+ void setMail(const KContacts::Email &email);
+ KContacts::Email email();
+ void setPreferred(bool b);
+Q_SIGNALS:
+ void addWidget(MailWidget *);
+ void removeWidget(MailWidget *);
+ void preferredChanged(MailWidget *);
+
+private:
+ void slotAddMail();
+ void slotRemoveMail();
+ void slotPreferredChanged();
+ KContacts::Email mEmail;
+ QString mOldType;
+ PreferredLineEditWidget *mMailEdit;
+ Akonadi::AkonadiContactSelectTypeCombobox *mMailType;
+ QToolButton *mAddButton;
+ QToolButton *mRemoveButton;
+};
+}
+#endif // MAILWIDGET_H
diff --git a/src/contact-editor/editor/generalinfoeditor/mail/mailwidgetlister.cpp b/src/contact-editor/editor/generalinfoeditor/mail/mailwidgetlister.cpp
new file mode 100644
index 0000000..6d7436d
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/mail/mailwidgetlister.cpp
@@ -0,0 +1,129 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "mailwidgetlister.h"
+#include "mailwidget.h"
+
+#include <KContacts/Addressee>
+using namespace Akonadi;
+
+MailWidgetLister::MailWidgetLister(QWidget *parent)
+ : KWidgetLister(1, 8, parent)
+{
+ setNumberOfShownWidgetsTo(widgetsMinimum());
+ updateAddRemoveButton();
+}
+
+MailWidgetLister::~MailWidgetLister()
+{
+
+}
+
+void MailWidgetLister::loadContact(const KContacts::Addressee &contact)
+{
+ KContacts::Email::List mailList = contact.emailList();
+ if (mailList.isEmpty()) {
+ setNumberOfShownWidgetsTo(1);
+ } else {
+ setNumberOfShownWidgetsTo(mailList.count());
+ const QList<QWidget *> widgetList = widgets();
+ auto wIt = widgetList.constBegin();
+ auto wEnd = widgetList.constEnd();
+ for (int i = 0; wIt != wEnd; ++wIt, ++i) {
+ MailWidget *w = qobject_cast<MailWidget *>(*wIt);
+ w->setMail(mailList.at(i));
+ }
+ }
+}
+
+void MailWidgetLister::storeContact(KContacts::Addressee &contact) const
+{
+ const QList<QWidget *> widgetList = widgets();
+ KContacts::Email::List emailList;
+ for (QWidget *widget : widgetList) {
+ MailWidget *w = qobject_cast<MailWidget *>(widget);
+ KContacts::Email newEmail = w->email();
+ if (newEmail.isValid()) {
+ emailList << newEmail;
+ }
+ }
+ contact.setEmailList(emailList);
+}
+
+QWidget *MailWidgetLister::createWidget(QWidget *parent)
+{
+ MailWidget *w = new MailWidget(parent);
+ reconnectWidget(w);
+ return w;
+}
+
+void MailWidgetLister::reconnectWidget(MailWidget *w)
+{
+ connect(w, &MailWidget::addWidget, this, &MailWidgetLister::slotAddWidget, Qt::UniqueConnection);
+ connect(w, &MailWidget::removeWidget, this, &MailWidgetLister::slotRemoveWidget, Qt::UniqueConnection);
+ connect(w, &MailWidget::preferredChanged, this, &MailWidgetLister::slotPreferredChanged, Qt::UniqueConnection);
+}
+
+void MailWidgetLister::slotAddWidget(MailWidget *w)
+{
+ addWidgetAfterThisWidget(w);
+ updateAddRemoveButton();
+}
+
+void MailWidgetLister::slotRemoveWidget(MailWidget *w)
+{
+ if (widgets().count() == 1) {
+ w->clearWidget();
+ } else {
+ removeWidget(w);
+ updateAddRemoveButton();
+ }
+}
+
+void MailWidgetLister::slotPreferredChanged(MailWidget *w)
+{
+ const QList<QWidget *> widgetList = widgets();
+ for (QWidget *widget : widgetList) {
+ if (widget != w) {
+ (static_cast<MailWidget *>(widget))->setPreferred(false);
+ }
+ }
+}
+
+void MailWidgetLister::updateAddRemoveButton()
+{
+ const QList<QWidget *> widgetList = widgets();
+ const int numberOfWidget(widgetList.count());
+ bool addButtonEnabled = false;
+ if (numberOfWidget <= widgetsMinimum()) {
+ addButtonEnabled = true;
+ } else if (numberOfWidget >= widgetsMaximum()) {
+ addButtonEnabled = false;
+ } else {
+ addButtonEnabled = true;
+ }
+
+ for (QWidget *widget : widgetList) {
+ MailWidget *w = qobject_cast<MailWidget *>(widget);
+ w->updateAddRemoveButton(addButtonEnabled);
+ }
+}
diff --git a/src/contact-editor/editor/generalinfoeditor/mail/mailwidgetlister.h b/src/contact-editor/editor/generalinfoeditor/mail/mailwidgetlister.h
new file mode 100644
index 0000000..c12877c
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/mail/mailwidgetlister.h
@@ -0,0 +1,57 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 MAILWIDGETLISTER_H
+#define MAILWIDGETLISTER_H
+
+#include "../../widgets/kwidgetlister_p.h"
+namespace KContacts
+{
+class Addressee;
+}
+namespace Akonadi
+{
+class MailWidget;
+class MailWidgetLister : public KWidgetLister
+{
+ Q_OBJECT
+public:
+ explicit MailWidgetLister(QWidget *parent = nullptr);
+ ~MailWidgetLister();
+
+ void loadContact(const KContacts::Addressee &contact);
+ void storeContact(KContacts::Addressee &contact) const;
+
+protected:
+ QWidget *createWidget(QWidget *) override;
+
+private Q_SLOTS:
+ void slotAddWidget(MailWidget *w);
+ void slotRemoveWidget(MailWidget *w);
+ void slotPreferredChanged(MailWidget *w);
+
+private:
+ void reconnectWidget(MailWidget *w);
+ void updateAddRemoveButton();
+};
+}
+#endif // MAILWIDGETLISTER_H
diff --git a/src/contact-editor/editor/generalinfoeditor/messageformattingwidget.cpp b/src/contact-editor/editor/generalinfoeditor/messageformattingwidget.cpp
new file mode 100644
index 0000000..d52453f
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/messageformattingwidget.cpp
@@ -0,0 +1,100 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2017 Laurent Montel <[email protected]>
+
+ 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 "messageformattingwidget.h"
+#include "editor/utils/utils.h"
+#include <KLocalizedString>
+
+#include <QCheckBox>
+#include <QComboBox>
+#include <QHBoxLayout>
+#include <QLabel>
+
+using namespace Akonadi;
+
+MessageFormattingWidget::MessageFormattingWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ QVBoxLayout *topLayout = new QVBoxLayout(this);
+ topLayout->setMargin(0);
+ QLabel *label = new QLabel(i18n("Show messages received from this contact as:"), this);
+ label->setObjectName(QStringLiteral("label"));
+ topLayout->addWidget(label);
+
+ mMailPreferFormatting = new QComboBox(this);
+ mMailPreferFormatting->setObjectName(QStringLiteral("mMailPreferFormatting"));
+ topLayout->addWidget(mMailPreferFormatting);
+ label->setBuddy(mMailPreferFormatting);
+ const QStringList listFormat {i18n("Default"), i18n("Plain Text"), i18n("HTML")};
+ mMailPreferFormatting->addItems(listFormat);
+
+ mAllowRemoteContent = new QCheckBox(i18n("Allow remote content in received HTML messages"), this);
+ mAllowRemoteContent->setObjectName(QStringLiteral("mAllowRemoteContent"));
+ topLayout->addWidget(mAllowRemoteContent);
+}
+
+MessageFormattingWidget::~MessageFormattingWidget()
+{
+
+}
+
+void MessageFormattingWidget::loadContact(const KContacts::Addressee &contact)
+{
+ const QString mailAllowToRemoteContent = Akonadi::Utils::loadCustom(contact, QLatin1String("MailAllowToRemoteContent"));
+ mAllowRemoteContent->setChecked(mailAllowToRemoteContent == QLatin1String("TRUE"));
+
+ const QString mailPreferedFormatting = Akonadi::Utils::loadCustom(contact, QLatin1String("MailPreferedFormatting"));
+ if (mailPreferedFormatting.isEmpty()) {
+ mMailPreferFormatting->setCurrentIndex(0);
+ } else if (mailPreferedFormatting == QLatin1String("TEXT")) {
+ mMailPreferFormatting->setCurrentIndex(1);
+ } else if (mailPreferedFormatting == QLatin1String("HTML")) {
+ mMailPreferFormatting->setCurrentIndex(2);
+ } else {
+ mMailPreferFormatting->setCurrentIndex(0);
+ }
+}
+
+void MessageFormattingWidget::storeContact(KContacts::Addressee &contact) const
+{
+ QString mailPreferedFormatting;
+ const int index = mMailPreferFormatting->currentIndex();
+ if (index == 0) {
+ //Nothing => remove custom variable
+ } else if (index == 1) {
+ mailPreferedFormatting = QLatin1String("TEXT");
+ } else if (index == 2) {
+ mailPreferedFormatting = QLatin1String("HTML");
+ }
+ Akonadi::Utils::storeCustom(contact, QLatin1String("MailPreferedFormatting"), mailPreferedFormatting);
+
+ QString mailAllowToRemoteContent;
+ if (mAllowRemoteContent->isChecked()) {
+ mailAllowToRemoteContent = QLatin1String("TRUE");
+ }
+ Akonadi::Utils::storeCustom(contact, QLatin1String("MailAllowToRemoteContent"), mailAllowToRemoteContent);
+}
+
+void MessageFormattingWidget::setReadOnly(bool readOnly)
+{
+ mMailPreferFormatting->setEnabled(!readOnly);
+ mAllowRemoteContent->setEnabled(!readOnly);
+}
diff --git a/src/contact-editor/editor/generalinfoeditor/messageformattingwidget.h b/src/contact-editor/editor/generalinfoeditor/messageformattingwidget.h
new file mode 100644
index 0000000..b8b0740
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/messageformattingwidget.h
@@ -0,0 +1,48 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2017 Laurent Montel <[email protected]>
+
+ 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 MESSAGEFORMATTINGWIDGET_H
+#define MESSAGEFORMATTINGWIDGET_H
+
+#include <QWidget>
+#include <KContacts/Addressee>
+#include "contacteditor_private_export.h"
+class QComboBox;
+class QCheckBox;
+namespace Akonadi
+{
+class AKONADI_CONTACTS_TESTS_EXPORT MessageFormattingWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit MessageFormattingWidget(QWidget *parent = nullptr);
+ ~MessageFormattingWidget();
+
+ void loadContact(const KContacts::Addressee &contact);
+ void storeContact(KContacts::Addressee &contact) const;
+ void setReadOnly(bool readOnly);
+
+private:
+ QComboBox *mMailPreferFormatting;
+ QCheckBox *mAllowRemoteContent;
+};
+}
+#endif // MESSAGEFORMATTINGWIDGET_H
diff --git a/src/contact-editor/editor/generalinfoeditor/messaging/messaginglistwidget.cpp b/src/contact-editor/editor/generalinfoeditor/messaging/messaginglistwidget.cpp
new file mode 100644
index 0000000..c66286a
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/messaging/messaginglistwidget.cpp
@@ -0,0 +1,65 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "messaginglistwidget.h"
+#include "messagingwidgetlister.h"
+#include <QLabel>
+#include <QVBoxLayout>
+#include <KLocalizedString>
+#include <KContacts/Addressee>
+using namespace Akonadi;
+
+MessagingListWidget::MessagingListWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ QVBoxLayout *topLayout = new QVBoxLayout(this);
+ topLayout->setMargin(0);
+ topLayout->setSpacing(0);
+
+ QLabel *label = new QLabel(i18n("Messaging"), this);
+ label->setObjectName(QStringLiteral("messaginglistlabel"));
+ topLayout->addWidget(label);
+
+ mMessagingWidgetLister = new Akonadi::MessagingWidgetLister(this);
+ mMessagingWidgetLister->setObjectName(QStringLiteral("messagingwidgetlister"));
+ topLayout->addWidget(mMessagingWidgetLister);
+}
+
+MessagingListWidget::~MessagingListWidget()
+{
+
+}
+
+void MessagingListWidget::loadContact(const KContacts::Addressee &contact)
+{
+ mMessagingWidgetLister->loadContact(contact);
+}
+
+void MessagingListWidget::storeContact(KContacts::Addressee &contact) const
+{
+ mMessagingWidgetLister->storeContact(contact);
+}
+
+void MessagingListWidget::setReadOnly(bool readOnly)
+{
+ mMessagingWidgetLister->setEnabled(!readOnly);
+}
diff --git a/src/contact-editor/editor/generalinfoeditor/messaging/messaginglistwidget.h b/src/contact-editor/editor/generalinfoeditor/messaging/messaginglistwidget.h
new file mode 100644
index 0000000..bd8f482
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/messaging/messaginglistwidget.h
@@ -0,0 +1,49 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 MESSAGINGLISTWIDGET_H
+#define MESSAGINGLISTWIDGET_H
+
+#include <QWidget>
+namespace KContacts
+{
+class Addressee;
+}
+namespace Akonadi
+{
+class MessagingWidgetLister;
+class MessagingListWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit MessagingListWidget(QWidget *parent = nullptr);
+ ~MessagingListWidget();
+
+ void loadContact(const KContacts::Addressee &contact);
+ void storeContact(KContacts::Addressee &contact) const;
+ void setReadOnly(bool readOnly);
+
+private:
+ Akonadi::MessagingWidgetLister *mMessagingWidgetLister;
+};
+}
+#endif // MAILISTWIDGET_H
diff --git a/src/contact-editor/editor/generalinfoeditor/messaging/messagingwidget.cpp b/src/contact-editor/editor/generalinfoeditor/messaging/messagingwidget.cpp
new file mode 100644
index 0000000..970db6b
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/messaging/messagingwidget.cpp
@@ -0,0 +1,123 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "messagingwidget.h"
+#include "../../im/improtocols.h"
+#include "../../widgets/akonadicontactcombobox.h"
+#include <QComboBox>
+#include <KLocalizedString>
+#include <QHBoxLayout>
+#include <KLineEdit>
+#include <QToolButton>
+#include <editor/widgets/preferredlineeditwidget.h>
+
+using namespace Akonadi;
+MessagingWidget::MessagingWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ QHBoxLayout *layout = new QHBoxLayout(this);
+ layout->setSpacing(0);
+ layout->setMargin(0);
+
+ mMessagingEdit = new PreferredLineEditWidget(this);
+ mMessagingEdit->setTrapReturnKey(true);
+ mMessagingEdit->setPlaceholderText(i18n("Add an identifier"));
+ mMessagingEdit->setObjectName(QStringLiteral("messaginglineedit"));
+ connect(mMessagingEdit, &PreferredLineEditWidget::preferredChanged, this, &MessagingWidget::slotPreferredChanged);
+ layout->addWidget(mMessagingEdit);
+
+ mProtocolCombo = new Akonadi::AkonadiContactComboBox(this);
+ mProtocolCombo->setObjectName(QStringLiteral("protocol"));
+ mProtocolCombo->addItem(i18nc("@item:inlistbox select from a list of IM protocols",
+ "Select..."));
+ layout->addWidget(mProtocolCombo);
+
+ const QStringList protocols = IMProtocols::self()->protocols();
+ for (const QString &protocol : protocols) {
+ mProtocolCombo->addItem(QIcon::fromTheme(IMProtocols::self()->icon(protocol)),
+ IMProtocols::self()->name(protocol),
+ protocol);
+ }
+
+ mAddButton = new QToolButton(this);
+ mAddButton->setIcon(QIcon::fromTheme(QStringLiteral("list-add")));
+ mAddButton->setObjectName(QStringLiteral("addbutton"));
+ mAddButton->setToolTip(i18n("Add an IM"));
+ connect(mAddButton, &QToolButton::clicked, this, &MessagingWidget::slotAddMessaging);
+ layout->addWidget(mAddButton);
+
+ mRemoveButton = new QToolButton(this);
+ mRemoveButton->setIcon(QIcon::fromTheme(QStringLiteral("list-remove")));
+ mRemoveButton->setObjectName(QStringLiteral("removebutton"));
+ mRemoveButton->setToolTip(i18n("Add IM"));
+ connect(mRemoveButton, &QToolButton::clicked, this, &MessagingWidget::slotRemoveMessaging);
+ layout->addWidget(mRemoveButton);
+}
+
+MessagingWidget::~MessagingWidget()
+{
+
+}
+
+void MessagingWidget::slotPreferredChanged()
+{
+ Q_EMIT preferredChanged(this);
+}
+
+void MessagingWidget::setIMAddress(const IMAddress &address)
+{
+ mProtocolCombo->setCurrentIndex(
+ IMProtocols::self()->protocols().indexOf(address.protocol()) + 1);
+ mMessagingEdit->setText(address.name());
+}
+
+void MessagingWidget::setPreferred(bool b)
+{
+ mMessagingEdit->setPreferred(b);
+}
+
+IMAddress MessagingWidget::imAddress() const
+{
+ return IMAddress(mProtocolCombo->itemData(mProtocolCombo->currentIndex()).toString(),
+ mMessagingEdit->text().trimmed(), false);
+}
+
+void MessagingWidget::updateAddRemoveButton(bool addButtonEnabled)
+{
+ mAddButton->setEnabled(addButtonEnabled);
+}
+
+void MessagingWidget::slotAddMessaging()
+{
+ Q_EMIT addWidget(this);
+}
+
+void MessagingWidget::slotRemoveMessaging()
+{
+ Q_EMIT removeWidget(this);
+}
+
+void MessagingWidget::clearWidget()
+{
+ mProtocolCombo->setCurrentIndex(0);
+ mMessagingEdit->clear();
+}
diff --git a/src/contact-editor/editor/generalinfoeditor/messaging/messagingwidget.h b/src/contact-editor/editor/generalinfoeditor/messaging/messagingwidget.h
new file mode 100644
index 0000000..90271dd
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/messaging/messagingwidget.h
@@ -0,0 +1,63 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 MESSAGINGWIDGET_H
+#define MESSAGINGWIDGET_H
+
+#include <QWidget>
+
+#include <editor/im/imaddress.h>
+#include "contacteditor_private_export.h"
+class QToolButton;
+namespace Akonadi
+{
+class PreferredLineEditWidget;
+class AkonadiContactComboBox;
+class AKONADI_CONTACTS_TESTS_EXPORT MessagingWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit MessagingWidget(QWidget *parent = nullptr);
+ ~MessagingWidget();
+
+ void updateAddRemoveButton(bool addButtonEnabled);
+ IMAddress imAddress() const;
+ void setIMAddress(const IMAddress &address);
+ void setPreferred(bool b);
+ void clearWidget();
+Q_SIGNALS:
+ void addWidget(MessagingWidget *);
+ void removeWidget(MessagingWidget *);
+ void preferredChanged(MessagingWidget *);
+
+private Q_SLOTS:
+ void slotAddMessaging();
+ void slotRemoveMessaging();
+ void slotPreferredChanged();
+private:
+ PreferredLineEditWidget *mMessagingEdit;
+ QToolButton *mAddButton;
+ QToolButton *mRemoveButton;
+ Akonadi::AkonadiContactComboBox *mProtocolCombo;
+};
+}
+#endif // MESSAGINGWIDGET_H
diff --git a/src/contact-editor/editor/generalinfoeditor/messaging/messagingwidgetlister.cpp b/src/contact-editor/editor/generalinfoeditor/messaging/messagingwidgetlister.cpp
new file mode 100644
index 0000000..f4f4e07
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/messaging/messagingwidgetlister.cpp
@@ -0,0 +1,173 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "messagingwidgetlister.h"
+#include "messagingwidget.h"
+#include "../../im/imaddress.h"
+#include "../../im/improtocols.h"
+#include "../../utils/utils.h"
+
+
+#include <KContacts/Addressee>
+using namespace Akonadi;
+
+MessagingWidgetLister::MessagingWidgetLister(QWidget *parent)
+ : KWidgetLister(1, 8, parent)
+{
+ setNumberOfShownWidgetsTo(widgetsMinimum());
+ updateAddRemoveButton();
+}
+
+MessagingWidgetLister::~MessagingWidgetLister()
+{
+
+}
+
+void MessagingWidgetLister::loadContact(const KContacts::Addressee &contact)
+{
+ IMAddress::List imaddresses;
+ const QStringList customs = contact.customs();
+
+ for (const QString &custom : customs) {
+ QString app, name, value;
+ Akonadi::Utils::splitCustomField(custom, app, name, value);
+
+ if (app.startsWith(QStringLiteral("messaging/"))) {
+ if (name == QLatin1String("All")) {
+ const QString protocol = app;
+ const QStringList names = value.split(QChar(0xE000), QString::SkipEmptyParts);
+
+ for (const QString &name : names) {
+ //TODO preferred support ?
+ imaddresses << IMAddress(protocol, name, false);
+ }
+ }
+ }
+ }
+ if (imaddresses.isEmpty()) {
+ setNumberOfShownWidgetsTo(1);
+ } else {
+ setNumberOfShownWidgetsTo(imaddresses.count());
+ const QList<QWidget *> widgetList = widgets();
+ auto wIt = widgetList.constBegin();
+ auto wEnd = widgetList.constEnd();
+ for (int i = 0; wIt != wEnd; ++wIt, ++i) {
+ MessagingWidget *w = qobject_cast<MessagingWidget *>(*wIt);
+ w->setIMAddress(imaddresses.at(i));
+ }
+ }
+ //TODO add real support for IM vcard4
+}
+
+void MessagingWidgetLister::storeContact(KContacts::Addressee &contact) const
+{
+ IMAddress::List imaddresses;
+ const QList<QWidget *> widgetList = widgets();
+ for (QWidget *widget : widgetList) {
+ MessagingWidget *w = qobject_cast<MessagingWidget *>(widget);
+ imaddresses << w->imAddress();
+ }
+ // create a map with protocol as key and list of names for that protocol as value
+ QMap<QString, QStringList> protocolMap;
+
+ // fill map with all known protocols
+ const QStringList lstProtocols = IMProtocols::self()->protocols();
+ for (const QString &protocol : lstProtocols) {
+ protocolMap.insert(protocol, QStringList());
+ }
+
+ // add the configured addresses
+ for (const IMAddress &address : qAsConst(imaddresses)) {
+ protocolMap[address.protocol()].append(address.name());
+ }
+
+ // iterate over this list and modify the contact according
+ QMap<QString, QStringList>::const_iterator it = protocolMap.cbegin();
+ const QMap<QString, QStringList>::const_iterator itEnd = protocolMap.cend();
+ for (; it != itEnd; ++it) {
+ if (!it.value().isEmpty()) {
+ contact.insertCustom(it.key(), QStringLiteral("All"), it.value().join(QString(0xE000)));
+ } else {
+ contact.removeCustom(it.key(), QStringLiteral("All"));
+ }
+ }
+}
+
+QWidget *MessagingWidgetLister::createWidget(QWidget *parent)
+{
+ MessagingWidget *w = new MessagingWidget(parent);
+ reconnectWidget(w);
+ return w;
+}
+
+void MessagingWidgetLister::reconnectWidget(MessagingWidget *w)
+{
+ connect(w, &MessagingWidget::addWidget, this, &MessagingWidgetLister::slotAddWidget, Qt::UniqueConnection);
+ connect(w, &MessagingWidget::removeWidget, this, &MessagingWidgetLister::slotRemoveWidget, Qt::UniqueConnection);
+ connect(w, &MessagingWidget::preferredChanged, this, &MessagingWidgetLister::slotPreferredChanged, Qt::UniqueConnection);
+}
+
+void MessagingWidgetLister::slotPreferredChanged(MessagingWidget *w)
+{
+ const QList<QWidget *> widgetList = widgets();
+ for (QWidget *widget : widgetList) {
+ if (widget != w) {
+ (static_cast<MessagingWidget *>(widget))->setPreferred(false);
+ }
+ }
+}
+
+void MessagingWidgetLister::slotAddWidget(MessagingWidget *w)
+{
+ addWidgetAfterThisWidget(w);
+ updateAddRemoveButton();
+}
+
+void MessagingWidgetLister::slotRemoveWidget(MessagingWidget *w)
+{
+ if (widgets().count() == 1) {
+ w->clearWidget();
+ } else {
+ removeWidget(w);
+ updateAddRemoveButton();
+ }
+}
+
+void MessagingWidgetLister::updateAddRemoveButton()
+{
+ QList<QWidget *> widgetList = widgets();
+ const int numberOfWidget(widgetList.count());
+ bool addButtonEnabled = false;
+ if (numberOfWidget <= widgetsMinimum()) {
+ addButtonEnabled = true;
+ } else if (numberOfWidget >= widgetsMaximum()) {
+ addButtonEnabled = false;
+ } else {
+ addButtonEnabled = true;
+ }
+ QList<QWidget *>::ConstIterator wIt = widgetList.constBegin();
+ QList<QWidget *>::ConstIterator wEnd = widgetList.constEnd();
+ for (; wIt != wEnd; ++wIt) {
+ MessagingWidget *w = qobject_cast<MessagingWidget *>(*wIt);
+ w->updateAddRemoveButton(addButtonEnabled);
+ }
+}
diff --git a/src/contact-editor/editor/generalinfoeditor/messaging/messagingwidgetlister.h b/src/contact-editor/editor/generalinfoeditor/messaging/messagingwidgetlister.h
new file mode 100644
index 0000000..57060f7
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/messaging/messagingwidgetlister.h
@@ -0,0 +1,56 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 MESSAGINGWIDGETLISTER_H
+#define MESSAGINGWIDGETLISTER_H
+
+#include "../../widgets/kwidgetlister_p.h"
+namespace KContacts
+{
+class Addressee;
+}
+namespace Akonadi
+{
+class MessagingWidget;
+class MessagingWidgetLister : public KWidgetLister
+{
+ Q_OBJECT
+public:
+ explicit MessagingWidgetLister(QWidget *parent = nullptr);
+ ~MessagingWidgetLister();
+
+ void loadContact(const KContacts::Addressee &contact);
+ void storeContact(KContacts::Addressee &contact) const;
+
+protected:
+ QWidget *createWidget(QWidget *) override;
+
+private Q_SLOTS:
+ void slotAddWidget(MessagingWidget *w);
+ void slotRemoveWidget(MessagingWidget *w);
+ void slotPreferredChanged(MessagingWidget *w);
+private:
+ void reconnectWidget(MessagingWidget *w);
+ void updateAddRemoveButton();
+};
+}
+#endif // MESSAGINGWIDGETLISTER_H
diff --git a/src/contact-editor/editor/generalinfoeditor/nameeditdialog.cpp b/src/contact-editor/editor/generalinfoeditor/nameeditdialog.cpp
new file mode 100644
index 0000000..774b955
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/nameeditdialog.cpp
@@ -0,0 +1,180 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (c) 2010 Tobias Koenig <[email protected]>
+
+ 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 "displaynameeditwidget.h"
+#include "nameeditdialog.h"
+
+#include <QFormLayout>
+
+#include <KComboBox>
+#include <KLineEdit>
+#include <KLocalizedString>
+
+#include <QDialogButtonBox>
+#include <QPushButton>
+
+NameEditDialog::NameEditDialog(QWidget *parent)
+ : QDialog(parent)
+{
+ setWindowTitle(i18n("Edit Contact Name"));
+
+ QVBoxLayout *mainLayout = new QVBoxLayout(this);
+
+ QFormLayout *layout = new QFormLayout;
+ mainLayout->addLayout(layout);
+
+ mPrefixCombo = new KComboBox(this);
+ mPrefixCombo->setDuplicatesEnabled(false);
+ mPrefixCombo->setEditable(true);
+
+ mGivenNameEdit = new KLineEdit(this);
+ mGivenNameEdit->setTrapReturnKey(true);
+
+ mAdditionalNameEdit = new KLineEdit(this);
+ mAdditionalNameEdit->setTrapReturnKey(true);
+
+ mFamilyNameEdit = new KLineEdit(this);
+ mFamilyNameEdit->setTrapReturnKey(true);
+
+ mSuffixCombo = new KComboBox(this);
+ mSuffixCombo->setDuplicatesEnabled(false);
+ mSuffixCombo->setEditable(true);
+
+ mDisplayNameEdit = new DisplayNameEditWidget(this);
+
+ layout->addRow(i18n("Honorific prefixes:"), mPrefixCombo);
+ layout->addRow(i18n("Given name:"), mGivenNameEdit);
+ layout->addRow(i18n("Additional names:"), mAdditionalNameEdit);
+ layout->addRow(i18n("Family names:"), mFamilyNameEdit);
+ layout->addRow(i18n("Honorific suffixes:"), mSuffixCombo);
+ layout->addRow(i18n("Display:"), mDisplayNameEdit);
+
+ QStringList prefixList;
+ prefixList += QString();
+ prefixList += i18n("Dr.");
+ prefixList += i18n("Miss");
+ prefixList += i18n("Mr.");
+ prefixList += i18n("Mrs.");
+ prefixList += i18n("Ms.");
+ prefixList += i18n("Prof.");
+ prefixList.sort();
+
+ QStringList suffixList;
+ suffixList += QString();
+ suffixList += i18n("I");
+ suffixList += i18n("II");
+ suffixList += i18n("III");
+ suffixList += i18n("Jr.");
+ suffixList += i18n("Sr.");
+ suffixList.sort();
+
+ mPrefixCombo->addItems(prefixList);
+ mSuffixCombo->addItems(suffixList);
+
+ mPrefixCombo->lineEdit()->setFocus();
+ QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
+ QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok);
+ okButton->setDefault(true);
+ okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
+ connect(buttonBox, &QDialogButtonBox::accepted, this, &NameEditDialog::accept);
+ connect(buttonBox, &QDialogButtonBox::rejected, this, &NameEditDialog::reject);
+ mainLayout->addWidget(buttonBox);
+}
+
+void NameEditDialog::setFamilyName(const QString &name)
+{
+ mFamilyNameEdit->setText(name);
+}
+
+QString NameEditDialog::familyName() const
+{
+ return mFamilyNameEdit->text();
+}
+
+void NameEditDialog::setGivenName(const QString &name)
+{
+ mGivenNameEdit->setText(name);
+}
+
+QString NameEditDialog::givenName() const
+{
+ return mGivenNameEdit->text();
+}
+
+void NameEditDialog::setPrefix(const QString &prefix)
+{
+ mPrefixCombo->setItemText(mPrefixCombo->currentIndex(), prefix);
+}
+
+QString NameEditDialog::prefix() const
+{
+ return mPrefixCombo->currentText();
+}
+
+void NameEditDialog::setSuffix(const QString &suffix)
+{
+ mSuffixCombo->setItemText(mSuffixCombo->currentIndex(), suffix);
+}
+
+QString NameEditDialog::suffix() const
+{
+ return mSuffixCombo->currentText();
+}
+
+void NameEditDialog::setAdditionalName(const QString &name)
+{
+ mAdditionalNameEdit->setText(name);
+}
+
+QString NameEditDialog::additionalName() const
+{
+ return mAdditionalNameEdit->text();
+}
+
+void NameEditDialog::loadContact(const KContacts::Addressee &contact)
+{
+ setPrefix(contact.prefix());
+ setGivenName(contact.givenName());
+ setAdditionalName(contact.additionalName());
+ setFamilyName(contact.familyName());
+ setSuffix(contact.suffix());
+ mDisplayNameEdit->loadContact(contact);
+}
+
+void NameEditDialog::storeContact(KContacts::Addressee &contact) const
+{
+ mDisplayNameEdit->storeContact(contact);
+ contact.setPrefix(prefix());
+ contact.setGivenName(givenName());
+ contact.setAdditionalName(additionalName());
+ contact.setFamilyName(familyName());
+ contact.setSuffix(suffix());
+}
+
+void NameEditDialog::setDisplayType(DisplayNameEditWidget::DisplayType type)
+{
+ mDisplayNameEdit->setDisplayType(type);
+}
+
+DisplayNameEditWidget::DisplayType NameEditDialog::displayType() const
+{
+ return mDisplayNameEdit->displayType();
+}
diff --git a/src/contact-editor/editor/generalinfoeditor/nameeditdialog.h b/src/contact-editor/editor/generalinfoeditor/nameeditdialog.h
new file mode 100644
index 0000000..341b330
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/nameeditdialog.h
@@ -0,0 +1,68 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (c) 2010 Tobias Koenig <[email protected]>
+
+ 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 NAMEEDITDIALOG_H
+#define NAMEEDITDIALOG_H
+
+#include "displaynameeditwidget.h"
+#include <QDialog>
+
+#include <KContacts/Addressee>
+
+class KLineEdit;
+class KComboBox;
+class DisplayNameEditWidget;
+class NameEditDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ explicit NameEditDialog(QWidget *parent = nullptr);
+
+ void setFamilyName(const QString &name);
+ QString familyName() const;
+
+ void setGivenName(const QString &name);
+ QString givenName() const;
+
+ void setPrefix(const QString &prefix);
+ QString prefix() const;
+
+ void setSuffix(const QString &suffix);
+ QString suffix() const;
+
+ void setAdditionalName(const QString &name);
+ QString additionalName() const;
+
+ void loadContact(const KContacts::Addressee &contact);
+ void storeContact(KContacts::Addressee &contact) const;
+
+ void setDisplayType(DisplayNameEditWidget::DisplayType type);
+ DisplayNameEditWidget::DisplayType displayType() const;
+private:
+ KComboBox *mSuffixCombo;
+ KComboBox *mPrefixCombo;
+ KLineEdit *mFamilyNameEdit;
+ KLineEdit *mGivenNameEdit;
+ KLineEdit *mAdditionalNameEdit;
+ DisplayNameEditWidget *mDisplayNameEdit;
+};
+
+#endif
diff --git a/src/contact-editor/editor/generalinfoeditor/namewidget.cpp b/src/contact-editor/editor/generalinfoeditor/namewidget.cpp
new file mode 100644
index 0000000..f1031e9
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/namewidget.cpp
@@ -0,0 +1,127 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "namewidget.h"
+#include <KLocalizedString>
+#include <QVBoxLayout>
+#include <QLabel>
+#include <QLineEdit>
+#include <KLineEdit>
+#include <QToolButton>
+#include "nameeditdialog.h"
+
+using namespace Akonadi;
+
+NameWidget::NameWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ QVBoxLayout *topLayout = new QVBoxLayout(this);
+ topLayout->setMargin(0);
+ QLabel *label = new QLabel(i18n("Name"));
+ label->setObjectName(QStringLiteral("namelabel"));
+ topLayout->addWidget(label);
+
+ QHBoxLayout *lineLayout = new QHBoxLayout;
+ lineLayout->setMargin(0);
+ topLayout->addLayout(lineLayout);
+
+ mNameEdit = new KLineEdit;
+ mNameEdit->setTrapReturnKey(true);
+ lineLayout->addWidget(mNameEdit);
+ setFocusProxy(mNameEdit);
+ setFocusPolicy(Qt::StrongFocus);
+
+ mButtonEdit = new QToolButton;
+ mButtonEdit->setText(i18n("..."));
+ mButtonEdit->setToolTip(i18n("Edit Contact Name"));
+ lineLayout->addWidget(mButtonEdit);
+
+ connect(mNameEdit, &QLineEdit::textChanged, this, &NameWidget::slotTextChanged);
+ connect(mButtonEdit, &QToolButton::clicked, this, &NameWidget::slotOpenNameEditDialog);
+}
+
+NameWidget::~NameWidget()
+{
+
+}
+
+void NameWidget::setReadOnly(bool readOnly)
+{
+ mNameEdit->setReadOnly(readOnly);
+ mButtonEdit->setEnabled(!readOnly);
+}
+
+void NameWidget::setDisplayType(DisplayNameEditWidget::DisplayType type)
+{
+ mDisplayType = type;
+}
+
+DisplayNameEditWidget::DisplayType NameWidget::displayType() const
+{
+ return mDisplayType;
+}
+
+void NameWidget::loadContact(const KContacts::Addressee &contact)
+{
+ mContact = contact;
+
+ disconnect(mNameEdit, &QLineEdit::textChanged, this, &NameWidget::slotTextChanged);
+ mNameEdit->setText(contact.assembledName());
+ connect(mNameEdit, &QLineEdit::textChanged, this, &NameWidget::slotTextChanged);
+}
+
+void NameWidget::storeContact(KContacts::Addressee &contact) const
+{
+ contact.setPrefix(mContact.prefix());
+ contact.setGivenName(mContact.givenName());
+ contact.setAdditionalName(mContact.additionalName());
+ contact.setFamilyName(mContact.familyName());
+ contact.setSuffix(mContact.suffix());
+ contact.setFormattedName(mContact.formattedName());
+}
+
+void NameWidget::slotTextChanged(const QString &text)
+{
+ mContact.setNameFromString(text);
+
+ Q_EMIT nameChanged(mContact);
+}
+
+void NameWidget::slotOpenNameEditDialog()
+{
+ QPointer<NameEditDialog> dlg = new NameEditDialog(this);
+ dlg->loadContact(mContact);
+ dlg->setDisplayType(mDisplayType);
+
+ if (dlg->exec() == QDialog::Accepted) {
+ dlg->storeContact(mContact);
+ mDisplayType = dlg->displayType();
+ disconnect(mNameEdit, &QLineEdit::textChanged, this, &NameWidget::slotTextChanged);
+ mNameEdit->setText(mContact.assembledName());
+ connect(mNameEdit, &QLineEdit::textChanged, this, &NameWidget::slotTextChanged);
+
+ Q_EMIT nameChanged(mContact);
+ }
+
+ delete dlg;
+}
+
diff --git a/src/contact-editor/editor/generalinfoeditor/namewidget.h b/src/contact-editor/editor/generalinfoeditor/namewidget.h
new file mode 100644
index 0000000..cb41b3e
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/namewidget.h
@@ -0,0 +1,60 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 NAMEWIDGET_H
+#define NAMEWIDGET_H
+
+#include "displaynameeditwidget.h"
+#include <QWidget>
+
+#include <KContacts/Addressee>
+class KLineEdit;
+class QToolButton;
+namespace Akonadi
+{
+class NameWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit NameWidget(QWidget *parent = nullptr);
+ ~NameWidget();
+
+ void loadContact(const KContacts::Addressee &contact);
+ void storeContact(KContacts::Addressee &contact) const;
+ void setReadOnly(bool readOnly);
+
+ void setDisplayType(DisplayNameEditWidget::DisplayType type);
+ DisplayNameEditWidget::DisplayType displayType() const;
+
+Q_SIGNALS:
+ void nameChanged(const KContacts::Addressee &contact);
+
+private:
+ void slotTextChanged(const QString &text);
+ void slotOpenNameEditDialog();
+ DisplayNameEditWidget::DisplayType mDisplayType;
+ KContacts::Addressee mContact;
+ KLineEdit *mNameEdit;
+ QToolButton *mButtonEdit;
+};
+}
+#endif // NAMEWIDGET_H
diff --git a/src/contact-editor/editor/generalinfoeditor/nicknamewidget.cpp b/src/contact-editor/editor/generalinfoeditor/nicknamewidget.cpp
new file mode 100644
index 0000000..e0ef94c
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/nicknamewidget.cpp
@@ -0,0 +1,65 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "nicknamewidget.h"
+#include <KLocalizedString>
+#include <QLabel>
+#include <QVBoxLayout>
+#include <KLineEdit>
+#include <KContacts/Addressee>
+using namespace Akonadi;
+
+NicknameWidget::NicknameWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ QVBoxLayout *topLayout = new QVBoxLayout(this);
+ topLayout->setMargin(0);
+ QLabel *nickNameLabel = new QLabel(i18n("Nickname"), this);
+ nickNameLabel->setObjectName(QStringLiteral("nicknamelabel"));
+ topLayout->addWidget(nickNameLabel);
+
+ mNickName = new KLineEdit(this);
+ mNickName->setTrapReturnKey(true);
+ mNickName->setPlaceholderText(i18n("Add a Nickname"));
+ mNickName->setObjectName(QStringLiteral("nickname"));
+ topLayout->addWidget(mNickName);
+}
+
+NicknameWidget::~NicknameWidget()
+{
+
+}
+
+void NicknameWidget::loadContact(const KContacts::Addressee &contact)
+{
+ mNickName->setText(contact.nickName());
+}
+
+void NicknameWidget::storeContact(KContacts::Addressee &contact) const
+{
+ contact.setNickName(mNickName->text().trimmed());
+}
+
+void NicknameWidget::setReadOnly(bool readOnly)
+{
+ mNickName->setReadOnly(readOnly);
+}
diff --git a/src/contact-editor/editor/generalinfoeditor/nicknamewidget.h b/src/contact-editor/editor/generalinfoeditor/nicknamewidget.h
new file mode 100644
index 0000000..9b14812
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/nicknamewidget.h
@@ -0,0 +1,47 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 NICKNAMEWIDGET_H
+#define NICKNAMEWIDGET_H
+
+#include <QWidget>
+class KLineEdit;
+namespace KContacts
+{
+class Addressee;
+}
+namespace Akonadi
+{
+class NicknameWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit NicknameWidget(QWidget *parent = nullptr);
+ ~NicknameWidget();
+ void loadContact(const KContacts::Addressee &contact);
+ void storeContact(KContacts::Addressee &contact) const;
+ void setReadOnly(bool readOnly);
+private:
+ KLineEdit *mNickName;
+};
+}
+#endif // NICKNAMEWIDGET_H
diff --git a/src/contact-editor/editor/generalinfoeditor/phone/phonecomboboxtype.cpp b/src/contact-editor/editor/generalinfoeditor/phone/phonecomboboxtype.cpp
new file mode 100644
index 0000000..136e0c7
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/phone/phonecomboboxtype.cpp
@@ -0,0 +1,118 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "phonecomboboxtype.h"
+#include "phonetypedialog.h"
+#include <KLocalizedString>
+#include <autoqpointer_p.h>
+
+using namespace Akonadi;
+
+PhoneComboBoxType::PhoneComboBoxType(QWidget *parent)
+ : Akonadi::AkonadiContactComboBox(parent)
+ , mType(KContacts::PhoneNumber::Home)
+ , mLastSelected(0)
+{
+ const int nbMax = KContacts::PhoneNumber::typeList().count();
+ mTypeList.reserve(nbMax + 1);
+ for (int i = 0; i < nbMax; ++i) {
+ const KContacts::PhoneNumber::TypeFlag typeflag = KContacts::PhoneNumber::typeList().at(i);
+ if (typeflag != KContacts::PhoneNumber::Pref) {
+ mTypeList.append(typeflag);
+ }
+ }
+
+ mTypeList.append(-1); // Others...
+
+ update();
+
+ connect(this, static_cast<void (PhoneComboBoxType::*)(int)>(&PhoneComboBoxType::activated), this, &PhoneComboBoxType::selected);
+}
+
+PhoneComboBoxType::~PhoneComboBoxType()
+{
+}
+
+void PhoneComboBoxType::setType(KContacts::PhoneNumber::Type type)
+{
+ if (static_cast<int>(type) != 0) {
+
+ if (!mTypeList.contains(type)) {
+ mTypeList.insert(mTypeList.at(mTypeList.count() - 1), type);
+ }
+ }
+ mType = type;
+ update();
+}
+
+KContacts::PhoneNumber::Type PhoneComboBoxType::type() const
+{
+ return mType;
+}
+
+void PhoneComboBoxType::resetToDefault()
+{
+ setCurrentIndex(0);
+}
+
+void PhoneComboBoxType::update()
+{
+ clear();
+
+ const int typeListCount(mTypeList.count());
+ for (int i = 0; i < typeListCount; ++i) {
+ if (mTypeList.at(i) == -1) { // "Other..." entry
+ addItem(i18nc("@item:inlistbox Category of contact info field", "Other..."));
+ } else {
+ addItem(KContacts::PhoneNumber::typeLabel(KContacts::PhoneNumber::Type(mTypeList.at(i))));
+ }
+ }
+
+ setCurrentIndex(mLastSelected = mTypeList.indexOf(mType));
+}
+
+void PhoneComboBoxType::selected(int pos)
+{
+ if (mTypeList.at(pos) == -1) {
+ otherSelected();
+ } else {
+ mType = KContacts::PhoneNumber::Type(mTypeList.at(pos));
+ mLastSelected = pos;
+ }
+}
+
+void PhoneComboBoxType::otherSelected()
+{
+ AutoQPointer<Akonadi::PhoneTypeDialog> dlg = new Akonadi::PhoneTypeDialog(mType, this);
+ if (dlg->exec()) {
+ mType = dlg->type();
+ if (!mTypeList.contains(mType)) {
+ if (static_cast<int>(mType) != 0) {
+ mTypeList.insert(mTypeList.at(mTypeList.count() - 1), mType);
+ }
+ }
+ } else {
+ setType(KContacts::PhoneNumber::Type(mTypeList.at(mLastSelected)));
+ }
+
+ update();
+}
diff --git a/src/contact-editor/editor/generalinfoeditor/phone/phonecomboboxtype.h b/src/contact-editor/editor/generalinfoeditor/phone/phonecomboboxtype.h
new file mode 100644
index 0000000..57a087e
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/phone/phonecomboboxtype.h
@@ -0,0 +1,73 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 PHONECOMBOBOXTYPE_H
+#define PHONECOMBOBOXTYPE_H
+
+#include <editor/widgets/akonadicontactcombobox.h>
+#include <kcontacts/addressee.h>
+#include "contacteditor_private_export.h"
+namespace Akonadi
+{
+/**
+ * @short A combobox to select a phone number type.
+ */
+class AKONADI_CONTACTS_TESTS_EXPORT PhoneComboBoxType : public Akonadi::AkonadiContactComboBox
+{
+ Q_OBJECT
+
+public:
+ /**
+ * Creates a phone type combo.
+ *
+ * @param parent The parent widget.
+ */
+ explicit PhoneComboBoxType(QWidget *parent = nullptr);
+
+ /**
+ * Destroys the phone type combo.
+ */
+ ~PhoneComboBoxType();
+
+ /**
+ * Sets the phone number @p type that shall be selected.
+ */
+ void setType(KContacts::PhoneNumber::Type type);
+
+ /**
+ * Returns the selected phone number type.
+ */
+ KContacts::PhoneNumber::Type type() const;
+
+ void resetToDefault();
+private Q_SLOTS:
+ void selected(int);
+ void otherSelected();
+
+private:
+ void update();
+ KContacts::PhoneNumber::Type mType;
+ int mLastSelected;
+ QList<int> mTypeList;
+};
+}
+#endif
diff --git a/src/contact-editor/editor/generalinfoeditor/phone/phonelistwidget.cpp b/src/contact-editor/editor/generalinfoeditor/phone/phonelistwidget.cpp
new file mode 100644
index 0000000..ad66b39
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/phone/phonelistwidget.cpp
@@ -0,0 +1,65 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "phonelistwidget.h"
+#include "phonewidgetlister.h"
+#include <QLabel>
+#include <QVBoxLayout>
+#include <KLocalizedString>
+#include <KContacts/Addressee>
+using namespace Akonadi;
+
+PhoneListWidget::PhoneListWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ QVBoxLayout *topLayout = new QVBoxLayout(this);
+ topLayout->setMargin(0);
+ topLayout->setSpacing(0);
+
+ QLabel *label = new QLabel(i18n("Phone"), this);
+ label->setObjectName(QStringLiteral("phonelistlabel"));
+ topLayout->addWidget(label);
+
+ mPhoneWidgetLister = new Akonadi::PhoneWidgetLister(this);
+ mPhoneWidgetLister->setObjectName(QStringLiteral("phonewidgetlister"));
+ topLayout->addWidget(mPhoneWidgetLister);
+}
+
+PhoneListWidget::~PhoneListWidget()
+{
+
+}
+
+void PhoneListWidget::loadContact(const KContacts::Addressee &contact)
+{
+ mPhoneWidgetLister->loadContact(contact);
+}
+
+void PhoneListWidget::storeContact(KContacts::Addressee &contact) const
+{
+ mPhoneWidgetLister->storeContact(contact);
+}
+
+void PhoneListWidget::setReadOnly(bool readOnly)
+{
+ mPhoneWidgetLister->setEnabled(!readOnly);
+}
diff --git a/src/contact-editor/editor/generalinfoeditor/phone/phonelistwidget.h b/src/contact-editor/editor/generalinfoeditor/phone/phonelistwidget.h
new file mode 100644
index 0000000..731afc4
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/phone/phonelistwidget.h
@@ -0,0 +1,48 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 PHONELISTWIDGET_H
+#define PHONELISTWIDGET_H
+
+#include <QWidget>
+#include "contacteditor_private_export.h"
+namespace KContacts
+{
+class Addressee;
+}
+namespace Akonadi
+{
+class PhoneWidgetLister;
+class AKONADI_CONTACTS_TESTS_EXPORT PhoneListWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit PhoneListWidget(QWidget *parent = nullptr);
+ ~PhoneListWidget();
+ void loadContact(const KContacts::Addressee &contact);
+ void storeContact(KContacts::Addressee &contact) const;
+ void setReadOnly(bool readOnly);
+private:
+ Akonadi::PhoneWidgetLister *mPhoneWidgetLister;
+};
+}
+#endif // PHONELISTWIDGET_H
diff --git a/src/contact-editor/editor/generalinfoeditor/phone/phonetypedialog.cpp b/src/contact-editor/editor/generalinfoeditor/phone/phonetypedialog.cpp
new file mode 100644
index 0000000..6e56799
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/phone/phonetypedialog.cpp
@@ -0,0 +1,86 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "phonetypedialog.h"
+#include <KLocalizedString>
+
+#include <QButtonGroup>
+#include <QCheckBox>
+#include <QDialogButtonBox>
+#include <QGroupBox>
+#include <QPushButton>
+#include <QVBoxLayout>
+
+using namespace Akonadi;
+
+PhoneTypeDialog::PhoneTypeDialog(KContacts::PhoneNumber::Type type, QWidget *parent)
+ : QDialog(parent)
+ , mType(type)
+{
+ setWindowTitle(i18n("Edit Phone Number"));
+
+ QVBoxLayout *layout = new QVBoxLayout(this);
+
+ QGridLayout *buttonLayout = new QGridLayout;
+ layout->addLayout(buttonLayout);
+
+ // fill widgets
+ mTypeList = KContacts::PhoneNumber::typeList();
+ mTypeList.removeAll(KContacts::PhoneNumber::Pref);
+ KContacts::PhoneNumber::TypeList::ConstIterator it;
+ int row, column, counter;
+ row = column = counter = 0;
+ mGroup = new QButtonGroup(this);
+ mGroup->setExclusive(false);
+ for (it = mTypeList.constBegin(); it != mTypeList.constEnd(); ++it, ++counter) {
+ QCheckBox *cb = new QCheckBox(KContacts::PhoneNumber::typeLabel(*it), this);
+ cb->setChecked(type & mTypeList[counter]);
+ buttonLayout->addWidget(cb, row, column);
+ mGroup->addButton(cb);
+
+ column++;
+ if (column == 5) {
+ column = 0;
+ ++row;
+ }
+ }
+
+ QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
+ QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok);
+ okButton->setDefault(true);
+ okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
+ layout->addWidget(buttonBox);
+ connect(buttonBox, &QDialogButtonBox::accepted, this, &PhoneTypeDialog::accept);
+ connect(buttonBox, &QDialogButtonBox::rejected, this, &PhoneTypeDialog::reject);
+}
+
+KContacts::PhoneNumber::Type PhoneTypeDialog::type() const
+{
+ KContacts::PhoneNumber::Type type = 0;
+
+ for (int i = 0; i < mGroup->buttons().count(); ++i) {
+ QCheckBox *box = qobject_cast<QCheckBox *>(mGroup->buttons().at(i));
+ if (box && box->isChecked()) {
+ type |= mTypeList[i];
+ }
+ }
+ return type;
+}
diff --git a/src/contact-editor/editor/generalinfoeditor/phone/phonetypedialog.h b/src/contact-editor/editor/generalinfoeditor/phone/phonetypedialog.h
new file mode 100644
index 0000000..1c4d7f0
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/phone/phonetypedialog.h
@@ -0,0 +1,58 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 PHONETYPEDIALOG_H
+#define PHONETYPEDIALOG_H
+
+#include <QDialog>
+#include <KContacts/PhoneNumber>
+#include "contacteditor_private_export.h"
+class QButtonGroup;
+
+namespace Akonadi
+{
+/**
+ * A dialog for editing phone number types.
+ */
+class AKONADI_CONTACTS_TESTS_EXPORT PhoneTypeDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ /**
+ * Creates a new phone type dialog.
+ *
+ * @param type The initial type of the phone number.
+ * @param parent The parent widget.
+ */
+ explicit PhoneTypeDialog(KContacts::PhoneNumber::Type type, QWidget *parent = nullptr);
+
+ /**
+ * Returns the selected type.
+ */
+ KContacts::PhoneNumber::Type type() const;
+
+private:
+ KContacts::PhoneNumber::Type mType;
+ KContacts::PhoneNumber::TypeList mTypeList;
+
+ QButtonGroup *mGroup;
+};
+}
+#endif // PHONETYPEDIALOG_H
diff --git a/src/contact-editor/editor/generalinfoeditor/phone/phonewidget.cpp b/src/contact-editor/editor/generalinfoeditor/phone/phonewidget.cpp
new file mode 100644
index 0000000..2501fb9
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/phone/phonewidget.cpp
@@ -0,0 +1,119 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "phonecomboboxtype.h"
+#include "phonewidget.h"
+#include <KLocalizedString>
+#include <QHBoxLayout>
+#include <KLineEdit>
+#include <QToolButton>
+#include <editor/widgets/preferredlineeditwidget.h>
+
+using namespace Akonadi;
+PhoneWidget::PhoneWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ QHBoxLayout *layout = new QHBoxLayout(this);
+ layout->setSpacing(0);
+ layout->setMargin(0);
+
+ mPhoneNumberEdit = new PreferredLineEditWidget(this);
+ mPhoneNumberEdit->setTrapReturnKey(true);
+ mPhoneNumberEdit->setPlaceholderText(i18n("Add a Phone Number"));
+ mPhoneNumberEdit->setObjectName(QStringLiteral("phonenumber"));
+ layout->addWidget(mPhoneNumberEdit);
+ connect(mPhoneNumberEdit, &PreferredLineEditWidget::preferredChanged, this, &PhoneWidget::slotPreferredChanged);
+
+ mPhoneType = new PhoneComboBoxType(this);
+ mPhoneType->setObjectName(QStringLiteral("phonetype"));
+ layout->addWidget(mPhoneType);
+
+ mAddButton = new QToolButton(this);
+ mAddButton->setIcon(QIcon::fromTheme(QStringLiteral("list-add")));
+ mAddButton->setToolTip(i18n("Add a Phone Number"));
+ mAddButton->setObjectName(QStringLiteral("addbutton"));
+ connect(mAddButton, &QToolButton::clicked, this, &PhoneWidget::slotAddPhone);
+ layout->addWidget(mAddButton);
+
+ mRemoveButton = new QToolButton(this);
+ mRemoveButton->setObjectName(QStringLiteral("removebutton"));
+ mRemoveButton->setToolTip(i18n("Remove Phone Number"));
+ mRemoveButton->setIcon(QIcon::fromTheme(QStringLiteral("list-remove")));
+ connect(mRemoveButton, &QToolButton::clicked, this, &PhoneWidget::slotRemovePhone);
+ layout->addWidget(mRemoveButton);
+}
+
+PhoneWidget::~PhoneWidget()
+{
+
+}
+
+void PhoneWidget::updateAddRemoveButton(bool addButtonEnabled)
+{
+ mAddButton->setEnabled(addButtonEnabled);
+}
+
+KContacts::PhoneNumber PhoneWidget::storePhone()
+{
+ KContacts::PhoneNumber number;
+ number.setNumber(mPhoneNumberEdit->text());
+ KContacts::PhoneNumber::Type currentType = mPhoneType->type();
+ if (mPhoneNumberEdit->preferred()) {
+ currentType |= KContacts::PhoneNumber::Pref;
+ }
+ number.setType(currentType);
+ return number;
+}
+
+void PhoneWidget::loadPhone(const KContacts::PhoneNumber &number)
+{
+ mPhoneNumberEdit->setText(number.number());
+ KContacts::PhoneNumber::Type currentType = number.type();
+ mPhoneType->setType(number.type() & ~ KContacts::PhoneNumber::Pref);
+ mPhoneNumberEdit->setPreferred(currentType & KContacts::PhoneNumber::Pref);
+}
+
+void PhoneWidget::slotAddPhone()
+{
+ Q_EMIT addWidget(this);
+}
+
+void PhoneWidget::slotRemovePhone()
+{
+ Q_EMIT removeWidget(this);
+}
+
+void PhoneWidget::clearWidget()
+{
+ mPhoneNumberEdit->clear();
+ mPhoneType->resetToDefault();
+}
+
+void PhoneWidget::slotPreferredChanged()
+{
+ Q_EMIT preferredChanged(this);
+}
+
+void PhoneWidget::setPreferred(bool b)
+{
+ mPhoneNumberEdit->setPreferred(b);
+}
diff --git a/src/contact-editor/editor/generalinfoeditor/phone/phonewidget.h b/src/contact-editor/editor/generalinfoeditor/phone/phonewidget.h
new file mode 100644
index 0000000..5c8fc82
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/phone/phonewidget.h
@@ -0,0 +1,66 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 PHONEWIDGET_H
+#define PHONEWIDGET_H
+
+#include <QWidget>
+#include "contacteditor_private_export.h"
+class QToolButton;
+namespace KContacts
+{
+class PhoneNumber;
+}
+namespace Akonadi
+{
+class PreferredLineEditWidget;
+class PhoneComboBoxType;
+class AKONADI_CONTACTS_TESTS_EXPORT PhoneWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit PhoneWidget(QWidget *parent = nullptr);
+ ~PhoneWidget();
+
+ void updateAddRemoveButton(bool addButtonEnabled);
+ void loadPhone(const KContacts::PhoneNumber &number);
+ KContacts::PhoneNumber storePhone();
+ void clearWidget();
+ void setPreferred(bool b);
+Q_SIGNALS:
+ void addWidget(PhoneWidget *);
+ void removeWidget(PhoneWidget *);
+ void preferredChanged(PhoneWidget *);
+
+private Q_SLOTS:
+ void slotAddPhone();
+ void slotRemovePhone();
+ void slotPreferredChanged();
+
+private:
+ PreferredLineEditWidget *mPhoneNumberEdit;
+ QToolButton *mAddButton;
+ QToolButton *mRemoveButton;
+ PhoneComboBoxType *mPhoneType;
+};
+}
+#endif // PHONEWIDGET_H
diff --git a/src/contact-editor/editor/generalinfoeditor/phone/phonewidgetlister.cpp b/src/contact-editor/editor/generalinfoeditor/phone/phonewidgetlister.cpp
new file mode 100644
index 0000000..02afd45
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/phone/phonewidgetlister.cpp
@@ -0,0 +1,129 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "phonewidgetlister.h"
+#include "phonewidget.h"
+
+#include <KContacts/Addressee>
+using namespace Akonadi;
+
+PhoneWidgetLister::PhoneWidgetLister(QWidget *parent)
+ : KWidgetLister(1, 8, parent)
+{
+ setNumberOfShownWidgetsTo(widgetsMinimum());
+ updateAddRemoveButton();
+}
+
+PhoneWidgetLister::~PhoneWidgetLister()
+{
+
+}
+
+void PhoneWidgetLister::loadContact(const KContacts::Addressee &contact)
+{
+ const KContacts::PhoneNumber::List phoneNumbers = contact.phoneNumbers();
+ if (phoneNumbers.isEmpty()) {
+ setNumberOfShownWidgetsTo(1);
+ } else {
+ setNumberOfShownWidgetsTo(phoneNumbers.count());
+ const QList<QWidget *> widgetList = widgets();
+ auto wIt = widgetList.constBegin();
+ auto wEnd = widgetList.constEnd();
+ for (int i = 0; wIt != wEnd; ++wIt, ++i) {
+ PhoneWidget *w = qobject_cast<PhoneWidget *>(*wIt);
+ w->loadPhone(phoneNumbers.at(i));
+ }
+ }
+}
+
+void PhoneWidgetLister::storeContact(KContacts::Addressee &contact) const
+{
+ KContacts::PhoneNumber::List phoneNumbers;
+ const QList<QWidget *> widgetList = widgets();
+ for (QWidget *widget : widgetList) {
+ PhoneWidget *w = qobject_cast<PhoneWidget *>(widget);
+ KContacts::PhoneNumber number = w->storePhone();
+ if (!number.isEmpty()) {
+ phoneNumbers << number;
+ }
+ }
+ contact.setPhoneNumbers(phoneNumbers);
+}
+
+QWidget *PhoneWidgetLister::createWidget(QWidget *parent)
+{
+ PhoneWidget *w = new PhoneWidget(parent);
+ reconnectWidget(w);
+ return w;
+}
+
+void PhoneWidgetLister::reconnectWidget(PhoneWidget *w)
+{
+ connect(w, &PhoneWidget::addWidget, this, &PhoneWidgetLister::slotAddWidget, Qt::UniqueConnection);
+ connect(w, &PhoneWidget::removeWidget, this, &PhoneWidgetLister::slotRemoveWidget, Qt::UniqueConnection);
+ connect(w, &PhoneWidget::preferredChanged, this, &PhoneWidgetLister::slotPreferredChanged, Qt::UniqueConnection);
+}
+
+void PhoneWidgetLister::slotAddWidget(PhoneWidget *w)
+{
+ addWidgetAfterThisWidget(w);
+ updateAddRemoveButton();
+}
+
+void PhoneWidgetLister::slotRemoveWidget(PhoneWidget *w)
+{
+ if (widgets().count() == 1) {
+ w->clearWidget();
+ } else {
+ removeWidget(w);
+ updateAddRemoveButton();
+ }
+}
+
+void PhoneWidgetLister::slotPreferredChanged(PhoneWidget *w)
+{
+ const QList<QWidget *> widgetList = widgets();
+ for (QWidget *widget : widgetList) {
+ if (widget != w) {
+ (static_cast<PhoneWidget *>(widget))->setPreferred(false);
+ }
+ }
+}
+
+void PhoneWidgetLister::updateAddRemoveButton()
+{
+ const QList<QWidget *> widgetList = widgets();
+ const int numberOfWidget(widgetList.count());
+ bool addButtonEnabled = false;
+ if (numberOfWidget <= widgetsMinimum()) {
+ addButtonEnabled = true;
+ } else if (numberOfWidget >= widgetsMaximum()) {
+ addButtonEnabled = false;
+ } else {
+ addButtonEnabled = true;
+ }
+
+ for (QWidget *widget : widgetList) {
+ PhoneWidget *w = qobject_cast<PhoneWidget *>(widget);
+ w->updateAddRemoveButton(addButtonEnabled);
+ }
+}
diff --git a/src/contact-editor/editor/generalinfoeditor/phone/phonewidgetlister.h b/src/contact-editor/editor/generalinfoeditor/phone/phonewidgetlister.h
new file mode 100644
index 0000000..df2af58
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/phone/phonewidgetlister.h
@@ -0,0 +1,58 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 PHONEWIDGETLISTER_H
+#define PHONEWIDGETLISTER_H
+
+#include "../../widgets/kwidgetlister_p.h"
+#include "contacteditor_private_export.h"
+namespace KContacts
+{
+class Addressee;
+}
+namespace Akonadi
+{
+class PhoneWidget;
+class AKONADI_CONTACTS_TESTS_EXPORT PhoneWidgetLister : public KWidgetLister
+{
+ Q_OBJECT
+public:
+ explicit PhoneWidgetLister(QWidget *parent = nullptr);
+ ~PhoneWidgetLister();
+
+ void loadContact(const KContacts::Addressee &contact);
+ void storeContact(KContacts::Addressee &contact) const;
+
+protected:
+ QWidget *createWidget(QWidget *) override;
+
+private Q_SLOTS:
+ void slotAddWidget(PhoneWidget *w);
+ void slotRemoveWidget(PhoneWidget *w);
+ void slotPreferredChanged(PhoneWidget *w);
+
+private:
+ void reconnectWidget(PhoneWidget *w);
+ void updateAddRemoveButton();
+};
+}
+#endif // PHONEWIDGETLISTER_H
diff --git a/src/contact-editor/editor/generalinfoeditor/tests/CMakeLists.txt b/src/contact-editor/editor/generalinfoeditor/tests/CMakeLists.txt
new file mode 100644
index 0000000..cb52d17
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/tests/CMakeLists.txt
@@ -0,0 +1,44 @@
+set(generalinfoeditor_SRCS
+ main.cpp
+ ../generalinfowidget.cpp
+ ../phone/phonewidget.cpp
+ ../phone/phonelistwidget.cpp
+ ../phone/phonewidgetlister.cpp
+ ../../widgets/kwidgetlister.cpp
+ ../web/webwidgetlister.cpp
+ ../web/weblistwidget.cpp
+ ../web/webwidget.cpp
+ ../mail/maillistwidget.cpp
+ ../mail/mailwidget.cpp
+ ../mail/mailwidgetlister.cpp
+ ../messaging/messaginglistwidget.cpp
+ ../messaging/messagingwidget.cpp
+ ../messaging/messagingwidgetlister.cpp
+ ../../widgets/imagewidget.cpp
+ ../namewidget.cpp
+ ../nicknamewidget.cpp
+ ../phone/phonecomboboxtype.cpp
+ ../../im/imaddress.cpp
+ ../../utils/utils.cpp
+ ../categorieseditwidget.cpp
+ ../nameeditdialog.cpp
+ ../../widgets/akonadicontactcombobox.cpp
+ ../../widgets/preferredlineeditwidget.cpp
+ ../phone/phonetypedialog.cpp
+ ../displaynameeditwidget.cpp
+ ../akonadicontactselecttypecombobox.cpp
+ )
+
+add_executable(generalinfoeditortest ${generalinfoeditor_SRCS})
+
+target_link_libraries(generalinfoeditortest
+ Qt5::Widgets
+ KF5::ContactEditor
+ KF5::Contacts
+ KF5::I18n
+ KF5::Completion
+ KF5::IconThemes
+ KF5::WidgetsAddons
+ KF5::KIOCore
+ )
+
diff --git a/src/contact-editor/editor/generalinfoeditor/tests/main.cpp b/src/contact-editor/editor/generalinfoeditor/tests/main.cpp
new file mode 100644
index 0000000..d8e9eed
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/tests/main.cpp
@@ -0,0 +1,33 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 <QApplication>
+#include "../generalinfowidget.h"
+using namespace Akonadi;
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ Akonadi::GeneralInfoWidget w;
+ w.show();
+ return app.exec();
+}
diff --git a/src/contact-editor/editor/generalinfoeditor/web/weblistwidget.cpp b/src/contact-editor/editor/generalinfoeditor/web/weblistwidget.cpp
new file mode 100644
index 0000000..d1be79f
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/web/weblistwidget.cpp
@@ -0,0 +1,66 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, sa[email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "weblistwidget.h"
+#include "webwidgetlister.h"
+#include <QLabel>
+#include <KLocalizedString>
+#include <QVBoxLayout>
+#include <KContacts/Addressee>
+
+using namespace Akonadi;
+
+WebListWidget::WebListWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ QVBoxLayout *topLayout = new QVBoxLayout(this);
+ topLayout->setMargin(0);
+ topLayout->setSpacing(0);
+
+ QLabel *label = new QLabel(i18n("Web"), this);
+ label->setObjectName(QStringLiteral("weblistlabel"));
+ topLayout->addWidget(label);
+
+ mWebWidgetLister = new Akonadi::WebWidgetLister(this);
+ mWebWidgetLister->setObjectName(QStringLiteral("webwidgetlister"));
+ topLayout->addWidget(mWebWidgetLister);
+}
+
+WebListWidget::~WebListWidget()
+{
+
+}
+
+void WebListWidget::loadContact(const KContacts::Addressee &contact)
+{
+ mWebWidgetLister->loadContact(contact);
+}
+
+void WebListWidget::storeContact(KContacts::Addressee &contact) const
+{
+ mWebWidgetLister->storeContact(contact);
+}
+
+void WebListWidget::setReadOnly(bool readOnly)
+{
+ mWebWidgetLister->setEnabled(!readOnly);
+}
diff --git a/src/contact-editor/editor/generalinfoeditor/web/weblistwidget.h b/src/contact-editor/editor/generalinfoeditor/web/weblistwidget.h
new file mode 100644
index 0000000..dc89be5
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/web/weblistwidget.h
@@ -0,0 +1,48 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 WEBLISTWIDGET_H
+#define WEBLISTWIDGET_H
+
+#include <QWidget>
+
+namespace KContacts
+{
+class Addressee;
+}
+namespace Akonadi
+{
+class WebWidgetLister;
+class WebListWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit WebListWidget(QWidget *parent = nullptr);
+ ~WebListWidget();
+ void loadContact(const KContacts::Addressee &contact);
+ void storeContact(KContacts::Addressee &contact) const;
+ void setReadOnly(bool readOnly);
+private:
+ WebWidgetLister *mWebWidgetLister;
+};
+}
+#endif // WEBLISTWIDGET_H
diff --git a/src/contact-editor/editor/generalinfoeditor/web/webwidget.cpp b/src/contact-editor/editor/generalinfoeditor/web/webwidget.cpp
new file mode 100644
index 0000000..e8c6baa
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/web/webwidget.cpp
@@ -0,0 +1,162 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "webwidget.h"
+#include <QHBoxLayout>
+#include <KLineEdit>
+#include <QToolButton>
+#include <QUrl>
+#include <KLocalizedString>
+#include <editor/widgets/preferredlineeditwidget.h>
+#include <editor/generalinfoeditor/akonadicontactselecttypecombobox.h>
+using namespace Akonadi;
+
+WebWidget::WebWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ QHBoxLayout *layout = new QHBoxLayout(this);
+ layout->setSpacing(0);
+ layout->setMargin(0);
+
+ mWebSiteEdit = new PreferredLineEditWidget(this);
+ mWebSiteEdit->setTrapReturnKey(true);
+ mWebSiteEdit->setPlaceholderText(i18n("Add a Web Site"));
+ mWebSiteEdit->setObjectName(QStringLiteral("website"));
+ layout->addWidget(mWebSiteEdit);
+ connect(mWebSiteEdit, &PreferredLineEditWidget::preferredChanged, this, &WebWidget::slotPreferredChanged);
+
+ mWebType = new Akonadi::AkonadiContactSelectTypeCombobox(this);
+ mWebType->setObjectName(QStringLiteral("webtype"));
+ mWebType->addItem(i18n("Select..."), QString());
+
+ QString type = QStringLiteral("HOME");
+ mWebSiteType.append(type);
+
+ mWebType->addItem(i18n("Home"), type);
+ type = QStringLiteral("WORK");
+ mWebSiteType.append(type);
+ mWebType->addItem(i18n("Work"), type);
+ type = QStringLiteral("OTHER");
+ mWebSiteType.append(type);
+ mWebType->addItem(i18n("Other"), type);
+ layout->addWidget(mWebType);
+
+ mAddButton = new QToolButton(this);
+ mAddButton->setIcon(QIcon::fromTheme(QStringLiteral("list-add")));
+ mAddButton->setObjectName(QStringLiteral("addbutton"));
+ mAddButton->setToolTip(i18n("Add a Web Site"));
+ connect(mAddButton, &QToolButton::clicked, this, &WebWidget::slotAddWeb);
+ layout->addWidget(mAddButton);
+
+ mRemoveButton = new QToolButton(this);
+ mRemoveButton->setObjectName(QStringLiteral("removebutton"));
+ mRemoveButton->setIcon(QIcon::fromTheme(QStringLiteral("list-remove")));
+ mRemoveButton->setToolTip(i18n("Remove Web Site"));
+ connect(mRemoveButton, &QToolButton::clicked, this, &WebWidget::slotRemoveWeb);
+ layout->addWidget(mRemoveButton);
+}
+
+WebWidget::~WebWidget()
+{
+
+}
+
+void WebWidget::clearWidget()
+{
+ mWebSiteEdit->clear();
+ mWebType->setCurrentIndex(0);
+}
+
+void WebWidget::updateAddRemoveButton(bool addButtonEnabled)
+{
+ mAddButton->setEnabled(addButtonEnabled);
+}
+
+void WebWidget::slotAddWeb()
+{
+ Q_EMIT addWidget(this);
+}
+
+void WebWidget::slotRemoveWeb()
+{
+ Q_EMIT removeWidget(this);
+}
+
+void WebWidget::setPreferred(bool b)
+{
+ mWebSiteEdit->setPreferred(b);
+}
+
+KContacts::ResourceLocatorUrl WebWidget::url()
+{
+ mUrl.setUrl(QUrl(mWebSiteEdit->text()));
+ QMap<QString, QStringList> parameters = mUrl.parameters();
+ QStringList value = parameters.value(QStringLiteral("type"));
+
+ const QString newType = mWebType->currentData().toString();
+ if (!newType.isEmpty()) {
+ if (mOldType != newType) {
+ if (!value.contains(newType)) {
+ value.append(newType);
+ }
+ if (!mOldType.isEmpty()) {
+ value.removeAll(mOldType);
+ }
+ }
+ }
+ if (mWebSiteEdit->preferred()) {
+ if (!value.contains(QStringLiteral("PREF"))) {
+ value.append(QStringLiteral("PREF"));
+ }
+ } else {
+ value.removeAll(QStringLiteral("PREF"));
+ }
+ if (!value.isEmpty()) {
+ parameters.insert(QStringLiteral("type"), value);
+ }
+ mUrl.setParameters(parameters);
+ return mUrl;
+}
+
+void WebWidget::loadWebSite(const KContacts::ResourceLocatorUrl &url)
+{
+ mUrl = url;
+ const QMap<QString, QStringList> parameters = mUrl.parameters();
+ const QStringList value = parameters.value(QStringLiteral("type"));
+ if (value.contains(QStringLiteral("PREF"))) {
+ setPreferred(true);
+ }
+ const QStringList lst = mWebType->selectTypeList();
+ for (const QString &type : lst) {
+ if (value.contains(type)) {
+ mOldType = type;
+ mWebType->setCurrentIndex(mWebType->findData(type));
+ break;
+ }
+ }
+ mWebSiteEdit->setText(mUrl.url().toDisplayString());
+}
+
+void WebWidget::slotPreferredChanged()
+{
+ Q_EMIT preferredChanged(this);
+}
diff --git a/src/contact-editor/editor/generalinfoeditor/web/webwidget.h b/src/contact-editor/editor/generalinfoeditor/web/webwidget.h
new file mode 100644
index 0000000..a5ed46a
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/web/webwidget.h
@@ -0,0 +1,66 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 WEBWIDGET_H
+#define WEBWIDGET_H
+
+#include <QWidget>
+
+#include <kcontacts/resourcelocatorurl.h>
+class QToolButton;
+namespace Akonadi
+{
+class AkonadiContactSelectTypeCombobox;
+class PreferredLineEditWidget;
+class WebWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit WebWidget(QWidget *parent = nullptr);
+ ~WebWidget();
+ void updateAddRemoveButton(bool addButtonEnabled);
+
+ void clearWidget();
+ void setPreferred(bool b);
+
+ KContacts::ResourceLocatorUrl url();
+ void loadWebSite(const KContacts::ResourceLocatorUrl &url);
+
+Q_SIGNALS:
+ void addWidget(WebWidget *);
+ void removeWidget(WebWidget *);
+ void preferredChanged(WebWidget *);
+
+private:
+ void slotRemoveWeb();
+ void slotAddWeb();
+ void slotPreferredChanged();
+ KContacts::ResourceLocatorUrl mUrl;
+ QStringList mWebSiteType;
+ QString mOldType;
+ PreferredLineEditWidget *mWebSiteEdit;
+ QToolButton *mAddButton;
+ QToolButton *mRemoveButton;
+ Akonadi::AkonadiContactSelectTypeCombobox *mWebType;
+};
+}
+#endif // WEBWIDGET_H
diff --git a/src/contact-editor/editor/generalinfoeditor/web/webwidgetlister.cpp b/src/contact-editor/editor/generalinfoeditor/web/webwidgetlister.cpp
new file mode 100644
index 0000000..d1cdc1b
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/web/webwidgetlister.cpp
@@ -0,0 +1,131 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "webwidgetlister.h"
+#include "webwidget.h"
+
+#include <KContacts/Addressee>
+using namespace Akonadi;
+
+WebWidgetLister::WebWidgetLister(QWidget *parent)
+ : KWidgetLister(1, 8, parent)
+{
+ setNumberOfShownWidgetsTo(widgetsMinimum());
+ updateAddRemoveButton();
+}
+
+WebWidgetLister::~WebWidgetLister()
+{
+
+}
+
+void WebWidgetLister::loadContact(const KContacts::Addressee &contact)
+{
+ KContacts::ResourceLocatorUrl::List resourceLocatorList = contact.extraUrlList();
+ if (resourceLocatorList.isEmpty()) {
+ setNumberOfShownWidgetsTo(1);
+ } else {
+ setNumberOfShownWidgetsTo(resourceLocatorList.count());
+ const QList<QWidget *> widgetList = widgets();
+ auto wIt = widgetList.constBegin();
+ auto wEnd = widgetList.constEnd();
+ for (int i = 0; wIt != wEnd; ++wIt, ++i) {
+ WebWidget *w = qobject_cast<WebWidget *>(*wIt);
+ w->loadWebSite(resourceLocatorList.at(i));
+ }
+ }
+}
+
+void WebWidgetLister::storeContact(KContacts::Addressee &contact) const
+{
+ const QList<QWidget *> widgetList = widgets();
+ KContacts::ResourceLocatorUrl::List resourceLocatorList;
+ for (QWidget *widget : widgetList) {
+ WebWidget *w = qobject_cast<WebWidget *>(widget);
+ KContacts::ResourceLocatorUrl newUrl = w->url();
+ if (newUrl.isValid()) {
+ resourceLocatorList << newUrl;
+ }
+ }
+ contact.setExtraUrlList(resourceLocatorList);
+}
+
+QWidget *WebWidgetLister::createWidget(QWidget *parent)
+{
+ WebWidget *w = new WebWidget(parent);
+ reconnectWidget(w);
+ return w;
+}
+
+void WebWidgetLister::reconnectWidget(WebWidget *w)
+{
+ connect(w, &WebWidget::addWidget, this, &WebWidgetLister::slotAddWidget, Qt::UniqueConnection);
+ connect(w, &WebWidget::removeWidget, this, &WebWidgetLister::slotRemoveWidget, Qt::UniqueConnection);
+ connect(w, &WebWidget::preferredChanged, this, &WebWidgetLister::slotPreferredChanged, Qt::UniqueConnection);
+}
+
+void WebWidgetLister::slotAddWidget(WebWidget *w)
+{
+ addWidgetAfterThisWidget(w);
+ updateAddRemoveButton();
+}
+
+void WebWidgetLister::slotRemoveWidget(WebWidget *w)
+{
+ if (widgets().count() == 1) {
+ w->clearWidget();
+ } else {
+ removeWidget(w);
+ updateAddRemoveButton();
+ }
+}
+
+void WebWidgetLister::updateAddRemoveButton()
+{
+ QList<QWidget *> widgetList = widgets();
+ const int numberOfWidget(widgetList.count());
+ bool addButtonEnabled = false;
+ if (numberOfWidget <= widgetsMinimum()) {
+ addButtonEnabled = true;
+ } else if (numberOfWidget >= widgetsMaximum()) {
+ addButtonEnabled = false;
+ } else {
+ addButtonEnabled = true;
+ }
+ QList<QWidget *>::ConstIterator wIt = widgetList.constBegin();
+ QList<QWidget *>::ConstIterator wEnd = widgetList.constEnd();
+ for (; wIt != wEnd; ++wIt) {
+ WebWidget *w = qobject_cast<WebWidget *>(*wIt);
+ w->updateAddRemoveButton(addButtonEnabled);
+ }
+}
+
+void WebWidgetLister::slotPreferredChanged(WebWidget *w)
+{
+ const QList<QWidget *> widgetList = widgets();
+ for (QWidget *widget : widgetList) {
+ if (widget != w) {
+ (static_cast<WebWidget *>(widget))->setPreferred(false);
+ }
+ }
+}
+
diff --git a/src/contact-editor/editor/generalinfoeditor/web/webwidgetlister.h b/src/contact-editor/editor/generalinfoeditor/web/webwidgetlister.h
new file mode 100644
index 0000000..b7fcd6b
--- /dev/null
+++ b/src/contact-editor/editor/generalinfoeditor/web/webwidgetlister.h
@@ -0,0 +1,56 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016 eyeOS S.L.U., a Telefonica company, [email protected]
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 WEBWIDGETLISTER_H
+#define WEBWIDGETLISTER_H
+
+#include "../../widgets/kwidgetlister_p.h"
+namespace KContacts
+{
+class Addressee;
+}
+namespace Akonadi
+{
+class WebWidget;
+class WebWidgetLister : public KWidgetLister
+{
+ Q_OBJECT
+public:
+ explicit WebWidgetLister(QWidget *parent = nullptr);
+ ~WebWidgetLister();
+
+ void loadContact(const KContacts::Addressee &contact);
+ void storeContact(KContacts::Addressee &contact) const;
+protected:
+ QWidget *createWidget(QWidget *) override;
+
+private Q_SLOTS:
+ void slotAddWidget(WebWidget *w);
+ void slotRemoveWidget(WebWidget *w);
+
+ void slotPreferredChanged(WebWidget *w);
+private:
+ void reconnectWidget(WebWidget *w);
+ void updateAddRemoveButton();
+};
+}
+#endif // WEBWIDGETLISTER_H
diff --git a/src/contact-editor/editor/im/CMakeLists.txt b/src/contact-editor/editor/im/CMakeLists.txt
new file mode 100644
index 0000000..6506502
--- /dev/null
+++ b/src/contact-editor/editor/im/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_subdirectory( protocols )
+
+install( FILES kaddressbookimprotocol.desktop DESTINATION ${KDE_INSTALL_KSERVICETYPES5DIR})
diff --git a/src/contact-editor/editor/im/imaddress.cpp b/src/contact-editor/editor/im/imaddress.cpp
new file mode 100644
index 0000000..c7eafc7
--- /dev/null
+++ b/src/contact-editor/editor/im/imaddress.cpp
@@ -0,0 +1,64 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (c) 2010 Tobias Koenig <[email protected]>
+
+ 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 "imaddress.h"
+
+IMAddress::IMAddress()
+ : mProtocol(QStringLiteral("messaging/aim"))
+ , mPreferred(false)
+{
+}
+
+IMAddress::IMAddress(const QString &protocol, const QString &name, bool preferred)
+ : mProtocol(protocol)
+ , mName(name)
+ , mPreferred(preferred)
+{
+}
+
+void IMAddress::setProtocol(const QString &protocol)
+{
+ mProtocol = protocol;
+}
+
+QString IMAddress::protocol() const
+{
+ return mProtocol;
+}
+
+void IMAddress::setName(const QString &name)
+{
+ mName = name;
+}
+
+QString IMAddress::name() const
+{
+ return mName;
+}
+
+void IMAddress::setPreferred(bool preferred)
+{
+ mPreferred = preferred;
+}
+
+bool IMAddress::preferred() const
+{
+ return mPreferred;
+}
diff --git a/src/contact-editor/editor/im/imaddress.h b/src/contact-editor/editor/im/imaddress.h
new file mode 100644
index 0000000..6f24eb2
--- /dev/null
+++ b/src/contact-editor/editor/im/imaddress.h
@@ -0,0 +1,52 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (c) 2010 Tobias Koenig <[email protected]>
+
+ 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 IMADDRESS_H
+#define IMADDRESS_H
+
+#include <QVector>
+#include <QString>
+#include "contacteditor_private_export.h"
+
+class AKONADI_CONTACTS_TESTS_EXPORT IMAddress
+{
+public:
+ typedef QVector<IMAddress> List;
+
+ IMAddress();
+ IMAddress(const QString &protocol, const QString &name, bool preferred);
+
+ void setProtocol(const QString &protocol);
+ QString protocol() const;
+
+ void setName(const QString &name);
+ QString name() const;
+
+ void setPreferred(bool preferred);
+ bool preferred() const;
+
+private:
+ QString mProtocol;
+ QString mName;
+ bool mPreferred;
+};
+
+#endif // IMADDRESS_H
diff --git a/src/contact-editor/editor/im/improtocols.cpp b/src/contact-editor/editor/im/improtocols.cpp
new file mode 100644
index 0000000..73c8cc1
--- /dev/null
+++ b/src/contact-editor/editor/im/improtocols.cpp
@@ -0,0 +1,115 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (c) 2010 Tobias Koenig <[email protected]>
+
+ 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 "improtocols.h"
+
+#include <kiconloader.h>
+#include <kservicetypetrader.h>
+#include <KService>
+IMProtocols *IMProtocols::mSelf = nullptr;
+
+IMProtocols::IMProtocols()
+{
+ const KService::List list = KServiceTypeTrader::self()->query(QStringLiteral("KContacts/IMProtocol"));
+ KService::List::ConstIterator it = list.constBegin();
+ KService::List::ConstIterator lastItem = list.constEnd();
+ QMap<QString, QString> sortingMap;
+ for (; it != lastItem; ++it) {
+ IMProtocolInfo info((*it)->name(), (*it)->icon());
+ const QString propertyName = (*it)->property(QStringLiteral("X-KDE-InstantMessagingKABCField")).toString();
+ mPluginInfos.insert(propertyName, info);
+ sortingMap.insert((*it)->name(), propertyName);
+ }
+
+ QMap<QString, QString>::const_iterator sortedIt = sortingMap.cbegin();
+ const QMap<QString, QString>::const_iterator sortedItEnd = sortingMap.cend();
+ for (; sortedIt != sortedItEnd; ++sortedIt) {
+ mSortedProtocols.append(sortedIt.value());
+ }
+}
+
+IMProtocols::~IMProtocols()
+{
+}
+
+IMProtocols *IMProtocols::self()
+{
+ if (!mSelf) {
+ mSelf = new IMProtocols;
+ }
+
+ return mSelf;
+}
+
+QStringList IMProtocols::protocols() const
+{
+ return mSortedProtocols;
+}
+
+QString IMProtocols::name(const QString &protocol) const
+{
+ if (!mPluginInfos.contains(protocol)) {
+ return QString();
+ }
+
+ return mPluginInfos.value(protocol).name();
+}
+
+QString IMProtocols::icon(const QString &protocol) const
+{
+ if (!mPluginInfos.contains(protocol)) {
+ return QString();
+ }
+
+ return mPluginInfos.value(protocol).icon();
+}
+
+IMProtocolInfo::IMProtocolInfo()
+{
+
+}
+
+IMProtocolInfo::IMProtocolInfo(const QString &name, const QString &icon)
+ : mName(name),
+ mIcon(icon)
+{
+
+}
+
+QString IMProtocolInfo::name() const
+{
+ return mName;
+}
+
+void IMProtocolInfo::setName(const QString &name)
+{
+ mName = name;
+}
+
+QString IMProtocolInfo::icon() const
+{
+ return mIcon;
+}
+
+void IMProtocolInfo::setIcon(const QString &icon)
+{
+ mIcon = icon;
+}
diff --git a/src/contact-editor/editor/im/improtocols.h b/src/contact-editor/editor/im/improtocols.h
new file mode 100644
index 0000000..924d0a6
--- /dev/null
+++ b/src/contact-editor/editor/im/improtocols.h
@@ -0,0 +1,70 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (c) 2010 Tobias Koenig <[email protected]>
+
+ 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 AKONADI_CONTACT_IMPROTOCOLS_H
+#define AKONADI_CONTACT_IMPROTOCOLS_H
+
+#include <kplugininfo.h>
+
+#include "akonadi-contact_export.h"
+
+class IMProtocolInfo
+{
+public:
+ IMProtocolInfo();
+
+ IMProtocolInfo(const QString &name, const QString &icon);
+
+ QString icon() const;
+ void setIcon(const QString &icon);
+ QString name() const;
+ void setName(const QString &name);
+private:
+ QString mName;
+ QString mIcon;
+};
+
+class AKONADI_CONTACT_EXPORT IMProtocols
+{
+public:
+ ~IMProtocols();
+
+ static IMProtocols *self();
+
+ /**
+ * Returns the protocol identifiers in a sorted order.
+ */
+ QStringList protocols() const;
+
+ QString name(const QString &protocol) const;
+ QString icon(const QString &protocol) const;
+
+private:
+ Q_DISABLE_COPY(IMProtocols)
+ IMProtocols();
+
+ static IMProtocols *mSelf;
+
+ QMap<QString, IMProtocolInfo> mPluginInfos;
+ QStringList mSortedProtocols;
+};
+
+#endif
diff --git a/src/contact-editor/editor/im/kaddressbookimprotocol.desktop b/src/contact-editor/editor/im/kaddressbookimprotocol.desktop
new file mode 100644
index 0000000..14723a3
--- /dev/null
+++ b/src/contact-editor/editor/im/kaddressbookimprotocol.desktop
@@ -0,0 +1,55 @@
+[Desktop Entry]
+Type=ServiceType
+X-KDE-ServiceType=KContacts/IMProtocol
+X-KDE-KAddressBook-CEWVersion=1
+Name=KAddressbook Instant Messaging Protocol
+Name[bs]=Protokol brzih poruka K adresara
+Name[ca]=Protocol de missatgeria instantània del KAddressbook
+Name[[email protected]]=Protocol de missatgeria instantània del KAddressbook
+Name[cs]=KAddressbook pro IM protokol
+Name[da]=KAddressbook instant messaging-protokol
+Name[de]=Instant-Messaging-Protokoll im KDE-Adressbuch
+Name[el]=Πρωτόκολλο στιγμιαίων μηνυμάτων KAddressbook
+Name[en_GB]=KAddressbook Instant Messaging Protocol
+Name[eo]=KAddressbook Rapidmesaĝila Protokolo
+Name[es]=Protocolo de mensajería instantánea de KAddressbook
+Name[et]=KDE aadressiraamatu kiirsuhtlusprotokoll
+Name[fi]=KAddressbookin pikaviestinyhteyskäytäntö
+Name[fr]=Protocole de messagerie instantanée KAddressBook
+Name[ga]=Prótacal Teachtaireachtaí Meandaracha KAddressbook
+Name[gl]=Protocolo de mensaxería instantánea do KAddressbook
+Name[he]=פרוטוקול מסרים מידיים של פנקס הכתובות
+Name[hu]=KAddressbook azonnali üzenetküldő protokoll
+Name[ia]=Protocollo de messageria instantanee de KAddressbook
+Name[it]=Protocollo di messaggistica istantanea di KAddressbook
+Name[kk]=KAddressbook-тың лезде хабарласу протоколы
+Name[km]=ពិធីការ​ផ្ញើ​សារ​បន្ទាន់​របស់ KAddressbook
+Name[ko]=KAddressbook 인스턴트 메시징 프로토콜
+Name[lt]=KAdresų knygelės momentinių pranešimų protokolas
+Name[mr]=के-एड्रेस-बूक त्वरित संदेश शिष्टाचार
+Name[nb]=KAdressbook lynmeldingsprotokoll
+Name[nds]=KAddressbook-Kortnarichten-Protokoll
+Name[nl]=KAddressbook Instant Messaging-protocol
+Name[nn]=Lynmeldingsprotokoll for KDE-adresseboka
+Name[pl]=Protokół komunikatora internetowego KAddressbook
+Name[pt]=Protocolo de Mensagens Instantâneas do KAddressbook
+Name[pt_BR]=Protocolo de Mensagens Instantâneas do KAddressbook
+Name[ro]=Protocol de mesagerie instantanee a cărții de adrese
+Name[ru]=Протокол обмена мгновенными сообщениями KAddressBook
+Name[sk]=Protokol KAddressbook Instant Messaging
+Name[sl]=Protokol hipnega sporočanja za KAddressBook
+Name[sr]=Брзогласнички протокол К‑адресара
+Name[[email protected]]=Брзогласнички протокол К‑адресара
+Name[[email protected]]=Brzoglasnički protokol K‑adresara
+Name[[email protected]]=Brzoglasnički protokol K‑adresara
+Name[sv]=Addressbokens direktmeddelandeprotokoll
+Name[th]=โพรโทคอลข้อความด่วนทันใจของสมุดที่อยู่-K
+Name[tr]=KAddressbook Anlık Mesajlaşma Protokolü
+Name[uk]=Протокол миттєвого обміну повідомленнями KAddressbook
+Name[wa]=Protocole di messaedjreye sol moumint di KAddressbook
+Name[x-test]=xxKAddressbook Instant Messaging Protocolxx
+Name[zh_CN]=KAddressbook 即时通讯协议
+Name[zh_TW]=KAddressbook 即時通訊協定
+[PropertyDef::X-KDE-InstantMessagingKABCField]
+Type=QString
+
diff --git a/src/contact-editor/editor/im/protocols/CMakeLists.txt b/src/contact-editor/editor/im/protocols/CMakeLists.txt
new file mode 100644
index 0000000..b6f11b4
--- /dev/null
+++ b/src/contact-editor/editor/im/protocols/CMakeLists.txt
@@ -0,0 +1,16 @@
+
+install( FILES icqprotocol.desktop
+ aimprotocol.desktop
+ ircprotocol.desktop
+ smsprotocol.desktop
+ gaduprotocol.desktop
+ jabberprotocol.desktop
+ yahooprotocol.desktop
+ msnprotocol.desktop
+ groupwiseprotocol.desktop
+ meanwhileprotocol.desktop
+ skypeprotocol.desktop
+ googletalkprotocol.desktop
+ facebookprotocol.desktop
+ twitterprotocol.desktop
+ DESTINATION ${KDE_INSTALL_KSERVICES5DIR}/akonadi/contact )
diff --git a/src/contact-editor/editor/im/protocols/aimprotocol.desktop b/src/contact-editor/editor/im/protocols/aimprotocol.desktop
new file mode 100644
index 0000000..48d80e5
--- /dev/null
+++ b/src/contact-editor/editor/im/protocols/aimprotocol.desktop
@@ -0,0 +1,109 @@
+[Desktop Entry]
+Type=Service
+Icon=im-aim
+X-KDE-ServiceTypes=KContacts/IMProtocol,KPluginInfo
+X-KDE-InstantMessagingKABCField=messaging/aim
+X-KDE-InstantMessagingKContactField=aim
+Comment=AIM Protocol
+Comment[ar]=ميفاق AIM
+Comment[bs]=AIM Protokol
+Comment[ca]=Protocol AIM
+Comment[[email protected]]=Protocol AIM
+Comment[cs]=Protokol AIM
+Comment[da]=AIM-protokollen
+Comment[de]=AIM-Protokoll
+Comment[el]=Πρωτόκολλο AIM
+Comment[en_GB]=AIM Protocol
+Comment[eo]=AIM-Protokolo
+Comment[es]=Protocolo AIM
+Comment[et]=AIM protokoll
+Comment[fi]=AIM-yhteyskäytäntö
+Comment[fr]=Protocole AIM
+Comment[ga]=Prótacal AIM
+Comment[gl]=Protocolo de AIM
+Comment[he]=פרוקוטול AIM
+Comment[hu]=AIM protokoll
+Comment[ia]=Protocollo AIM
+Comment[it]=Protocollo AIM
+Comment[ja]=AIM プロトコル
+Comment[kk]=AIM протоколы
+Comment[km]=ពិធីការ​ AIM ​​
+Comment[ko]=AIM 프로토콜
+Comment[lt]=AIM protokolas
+Comment[mr]=AIM शिष्टाचार
+Comment[nb]=AIM-protokoll
+Comment[nds]=AIM-Protokoll
+Comment[nl]=AIM-protocol
+Comment[nn]=AIM-protokoll
+Comment[pl]=Protokół AIM
+Comment[pt]=Protocolo AIM
+Comment[pt_BR]=Protocolo do AIM
+Comment[ro]=Protocol AIM
+Comment[ru]=Протокол обмена сообщениями AIM
+Comment[sk]=Protokol AIM
+Comment[sl]=Protokol AIM
+Comment[sr]=Протокол АИМ
+Comment[[email protected]]=Протокол АИМ
+Comment[[email protected]]=Protokol AIM
+Comment[[email protected]]=Protokol AIM
+Comment[sv]=AIM-protokoll
+Comment[th]=โพรโทคอล AIM
+Comment[tr]=AIM Protokolü
+Comment[uk]=Протокол AIM
+Comment[wa]=Protocole AIM
+Comment[x-test]=xxAIM Protocolxx
+Comment[zh_CN]=AIM 协议
+Comment[zh_TW]=AIM 協定
+Name=AIM
+Name[ar]=AIM
+Name[ast]=AIM
+Name[bs]=AIM
+Name[ca]=AIM
+Name[cs]=AIM
+Name[da]=AIM
+Name[de]=AIM
+Name[el]=AIM
+Name[en_GB]=AIM
+Name[eo]=AIM
+Name[es]=AIM
+Name[et]=AIM
+Name[fi]=AIM
+Name[fr]=AIM
+Name[ga]=AIM
+Name[gl]=AIM
+Name[he]=AIM
+Name[hu]=AIM
+Name[ia]=AIM
+Name[it]=AIM
+Name[ja]=AIM
+Name[kk]=AIM
+Name[km]=AIM​
+Name[ko]=AIM
+Name[lt]=AIM
+Name[mr]=AIM
+Name[nb]=AIM
+Name[nds]=AIM
+Name[nl]=AIM
+Name[nn]=AIM
+Name[pl]=AIM
+Name[pt]=AIM
+Name[pt_BR]=AIM
+Name[ro]=AIM
+Name[ru]=AIM
+Name[sk]=AIM
+Name[sl]=AIM
+Name[sr]=АИМ
+Name[[email protected]]=АИМ
+Name[sv]=AIM
+Name[th]=AIM
+Name[tr]=AIM
+Name[ug]=AIM
+Name[uk]=AIM
+Name[wa]=AIM
+Name[x-test]=xxAIMxx
+Name[zh_CN]=AIM
+Name[zh_TW]=AIM
+
diff --git a/src/contact-editor/editor/im/protocols/facebookprotocol.desktop b/src/contact-editor/editor/im/protocols/facebookprotocol.desktop
new file mode 100644
index 0000000..0329331
--- /dev/null
+++ b/src/contact-editor/editor/im/protocols/facebookprotocol.desktop
@@ -0,0 +1,68 @@
+[Desktop Entry]
+Type=Service
+Icon=im-facebook
+X-KDE-ServiceTypes=KContacts/IMProtocol,KPluginInfo
+X-KDE-InstantMessagingKContactField=facebook
+X-KDE-InstantMessagingKABCField=messaging/facebook
+Comment=Facebook Protocol
+Comment[ca]=Protocol Facebook
+Comment[[email protected]]=Protocol Facebook
+Comment[cs]=Protokol Facebook
+Comment[da]=Facebook-protokol
+Comment[de]=Facebook-Protokoll
+Comment[en_GB]=Facebook Protocol
+Comment[es]=Protocolo Facebook
+Comment[et]=Facebooki protokoll
+Comment[fi]=Facebook-yhteyskäytäntö
+Comment[fr]=Protocole Facebook
+Comment[gl]=Protocolo de Facebook
+Comment[it]=Protocollo di Facebook
+Comment[ko]=Facebook 프로토콜
+Comment[nl]=Facebook-protocol
+Comment[pl]=Protokół Facebooka
+Comment[pt]=Protocolo do Facebook
+Comment[pt_BR]=Protocolo do Facebook
+Comment[ru]=Протокол Facebook
+Comment[sk]=Protokol Facebook
+Comment[sl]=Protokol Facebook
+Comment[sr]=Протокол Фејсбука
+Comment[[email protected]]=Протокол Фејсбука
+Comment[[email protected]]=Protokol Facebooka
+Comment[[email protected]]=Protokol Facebooka
+Comment[sv]=Facebook-protokoll
+Comment[tr]=Facebook Protokolü
+Comment[uk]=Протокол Facebook
+Comment[x-test]=xxFacebook Protocolxx
+Comment[zh_CN]=Facebook 协议
+Name=Facebook
+Name[ca]=Facebook
+Name[[email protected]]=Facebook
+Name[cs]=Facebook
+Name[da]=Facebook
+Name[de]=Facebook
+Name[en_GB]=Facebook
+Name[es]=Facebook
+Name[et]=Facebook
+Name[fi]=Facebook
+Name[fr]=Facebook
+Name[gl]=Facebook
+Name[it]=Facebook
+Name[ko]=Facebook
+Name[nl]=Facebook
+Name[nn]=Facebook
+Name[pl]=Facebook
+Name[pt]=Facebook
+Name[pt_BR]=Facebook
+Name[ru]=Facebook
+Name[sk]=Facebook
+Name[sl]=Facebook
+Name[sr]=Фејсбук
+Name[[email protected]]=Фејсбук
+Name[[email protected]]=Facebook
+Name[[email protected]]=Facebook
+Name[sv]=Facebook
+Name[tr]=Facebook
+Name[uk]=Facebook
+Name[x-test]=xxFacebookxx
+Name[zh_CN]=Facebook
+
diff --git a/src/contact-editor/editor/im/protocols/gaduprotocol.desktop b/src/contact-editor/editor/im/protocols/gaduprotocol.desktop
new file mode 100644
index 0000000..de310c4
--- /dev/null
+++ b/src/contact-editor/editor/im/protocols/gaduprotocol.desktop
@@ -0,0 +1,108 @@
+[Desktop Entry]
+Type=Service
+Icon=im-gadugadu
+X-KDE-ServiceTypes=KContacts/IMProtocol,KPluginInfo
+X-KDE-InstantMessagingKABCField=messaging/gadu
+X-KDE-InstantMessagingKContactField=gadugadu
+Comment=Gadu-Gadu Protocol
+Comment[ar]=ميفاق غادو-غادو
+Comment[bs]=Gadu-Gadu Protokol
+Comment[ca]=Protocol Gadu-Gadu
+Comment[[email protected]]=Protocol Gadu-Gadu
+Comment[cs]=Protokol Gadu-Gadu
+Comment[da]=Gadu-Gadu-protokollen
+Comment[de]=Gadu-Gadu-Protokoll
+Comment[el]=Πρωτόκολλο Gadu-Gadu
+Comment[en_GB]=Gadu-Gadu Protocol
+Comment[eo]=Gadu-Gadu Protokolo
+Comment[es]=Protocolo Gadu-Gadu
+Comment[et]=Gadu-Gadu protokoll
+Comment[fi]=Gadu-Gadu-yhteyskäytäntö
+Comment[fr]=Protocole Gadu-Gadu
+Comment[ga]=Prótacal Gadu-Gadu
+Comment[gl]=Protocolo de Gadu-Gadu
+Comment[he]=פרוטוקול Gadu-Gadu
+Comment[hu]=Gadu-Gadu protokoll
+Comment[ia]=Protocollo Gadu-Gadu
+Comment[it]=Protocollo Gadu-Gadu
+Comment[ja]=Gadu-Gadu プロトコル
+Comment[kk]=Gadu-Gadu протоколы
+Comment[km]=ពិធីការ​ Gadu-Gadu
+Comment[ko]=Gadu-Gadu 프로토콜
+Comment[lt]=Gadu-Gadu protokolas
+Comment[mr]=गडु-गडु शिष्टाचार
+Comment[nb]=Gadu-Gadu-protokoll
+Comment[nds]=Gadu-Gadu-Protokoll
+Comment[nl]=Gadu-Gadu-protocol
+Comment[nn]=Gadu-Gadu-protokoll
+Comment[pl]=Protokół Gadu-Gadu
+Comment[pt]=Protocolo Gadu-Gadu
+Comment[pt_BR]=Protocolo do Gadu-Gadu
+Comment[ro]=Protocol Gadu-Gadu
+Comment[ru]=Протокол обмена сообщениями Gadu-Gadu
+Comment[sk]=Protokol Gadu-Gadu
+Comment[sl]=Protokol Gadu-Gadu
+Comment[sr]=Протокол гаду‑гаду
+Comment[[email protected]]=Протокол гаду‑гаду
+Comment[[email protected]]=Protokol Gadu‑Gadu
+Comment[[email protected]]=Protokol Gadu‑Gadu
+Comment[sv]=Gadu-Gadu protokoll
+Comment[th]=โพรโทคอล Gadu-Gadu
+Comment[tr]=Gadu-Gadu Protokolü
+Comment[uk]=Протокол Gadu-Gadu
+Comment[wa]=Protocole Gadu-gadu
+Comment[x-test]=xxGadu-Gadu Protocolxx
+Comment[zh_CN]=Gadu-Gadu 协议
+Comment[zh_TW]=Gadu-Gadu 協定
+Name=Gadu-Gadu
+Name[ar]=غادو-غادو
+Name[bs]=Gadu-Gadu
+Name[ca]=Gadu-Gadu
+Name[[email protected]]=Gadu-Gadu
+Name[cs]=Gadu-Gadu
+Name[da]=Gadu-Gadu
+Name[de]=Gadu-Gadu
+Name[el]=Gadu-Gadu
+Name[en_GB]=Gadu-Gadu
+Name[eo]=Gadu-Gadu
+Name[es]=Gadu-Gadu
+Name[et]=Gadu-Gadu
+Name[fi]=Gadu-Gadu
+Name[fr]=Gadu-Gadu
+Name[ga]=Gadu-Gadu
+Name[gl]=Gadu-Gadu
+Name[he]=Gadu-Gadu
+Name[hu]=Gadu-Gadu
+Name[ia]=Gadu-Gadu
+Name[it]=Gadu-Gadu
+Name[ja]=Gadu-Gadu
+Name[kk]=Gadu-Gadu
+Name[km]=Gadu-Gadu
+Name[ko]=Gadu-Gadu
+Name[lt]=Gadu-Gadu
+Name[mr]=गडु-गडु
+Name[nb]=Gadu-Gadu
+Name[nds]=Gadu-Gadu
+Name[nl]=Gadu-Gadu
+Name[nn]=Gadu-Gadu
+Name[pl]=Gadu-Gadu
+Name[pt]=Gadu-Gadu
+Name[pt_BR]=Gadu-Gadu
+Name[ro]=Gadu-Gadu
+Name[ru]=Gadu-Gadu
+Name[sk]=Gadu-Gadu
+Name[sl]=Gadu-Gadu
+Name[sr]=Гаду‑гаду
+Name[[email protected]]=Гаду‑гаду
+Name[[email protected]]=Gadu‑Gadu
+Name[[email protected]]=Gadu‑Gadu
+Name[sv]=Gadu-Gadu
+Name[th]=Gadu-Gadu
+Name[tr]=Gadu-Gadu
+Name[ug]=گادۇ-گادۇ(Gadu-Gadu)
+Name[uk]=Gadu-Gadu
+Name[wa]=Gadu-Gadu
+Name[x-test]=xxGadu-Gaduxx
+Name[zh_CN]=Gadu-Gadu
+Name[zh_TW]=Gadu-Gadu
+
diff --git a/src/contact-editor/editor/im/protocols/googletalkprotocol.desktop b/src/contact-editor/editor/im/protocols/googletalkprotocol.desktop
new file mode 100644
index 0000000..ebedac3
--- /dev/null
+++ b/src/contact-editor/editor/im/protocols/googletalkprotocol.desktop
@@ -0,0 +1,90 @@
+[Desktop Entry]
+Type=Service
+Icon=im-google
+X-KDE-ServiceTypes=KContacts/IMProtocol,KPluginInfo
+X-KDE-InstantMessagingKABCField=messaging/googletalk
+X-KDE-InstantMessagingKContactField=googletalk
+Comment=Google Talk
+Comment[ar]=غوغل توك
+Comment[bs]=Google Talk
+Comment[ca]=Google Talk
+Comment[[email protected]]=Google Talk
+Comment[cs]=Google Talk
+Comment[da]=Google Talk
+Comment[de]=Google Talk
+Comment[el]=Google Talk
+Comment[en_GB]=Google Talk
+Comment[es]=Google Talk
+Comment[et]=Google Talk
+Comment[fi]=Google Talk
+Comment[fr]=Google Talk
+Comment[gl]=Google Talk
+Comment[hu]=Google Talk
+Comment[ia]=Google Talk
+Comment[it]=Google Talk
+Comment[kk]=Google Talk
+Comment[ko]=Google 토크
+Comment[lt]=Google Talk
+Comment[nb]=Google Talk
+Comment[nds]=GoogleTalk
+Comment[nl]=Google Talk
+Comment[pl]=Google Talk
+Comment[pt]=Google Talk
+Comment[pt_BR]=Google Talk
+Comment[ro]=Google Talk
+Comment[ru]=Google Talk
+Comment[sk]=Google Talk
+Comment[sl]=Google Talk
+Comment[sr]=Гугл‑разговор
+Comment[[email protected]]=Гугл‑разговор
+Comment[[email protected]]=Google-razgovor
+Comment[[email protected]]=Google-razgovor
+Comment[sv]=Google Talk
+Comment[tr]=Google Talk
+Comment[ug]=گۇگىل سۆھبەت(Google Talk)
+Comment[uk]=Google Talk
+Comment[x-test]=xxGoogle Talkxx
+Comment[zh_CN]=Google Talk
+Comment[zh_TW]=Google Talk
+Name=Google Talk
+Name[ar]=غوغل توك
+Name[bs]=Google Talk
+Name[ca]=Google Talk
+Name[[email protected]]=Google Talk
+Name[cs]=Google Talk
+Name[da]=Google Talk
+Name[de]=Google Talk
+Name[el]=Google Talk
+Name[en_GB]=Google Talk
+Name[es]=Google Talk
+Name[et]=Google Talk
+Name[fi]=Google Talk
+Name[fr]=Google Talk
+Name[gl]=Google Talk
+Name[hu]=Google Talk
+Name[ia]=Google Talk
+Name[it]=Google Talk
+Name[kk]=Google Talk
+Name[ko]=Google 토크
+Name[lt]=Google Talk
+Name[nb]=Google Talk
+Name[nds]=GoogleTalk
+Name[nl]=Google Talk
+Name[pl]=Google Talk
+Name[pt]=Google Talk
+Name[pt_BR]=Google Talk
+Name[ro]=Google Talk
+Name[ru]=Google Talk
+Name[sk]=Google Talk
+Name[sl]=Google Talk
+Name[sr]=Гугл‑разговор
+Name[[email protected]]=Гугл‑разговор
+Name[[email protected]]=Google-razgovor
+Name[[email protected]]=Google-razgovor
+Name[sv]=Google Talk
+Name[tr]=Google Talk
+Name[ug]=گۇگىل سۆھبەت(Google Talk)
+Name[uk]=Google Talk
+Name[x-test]=xxGoogle Talkxx
+Name[zh_CN]=Google Talk
+Name[zh_TW]=Google Talk
diff --git a/src/contact-editor/editor/im/protocols/groupwiseprotocol.desktop b/src/contact-editor/editor/im/protocols/groupwiseprotocol.desktop
new file mode 100644
index 0000000..0448882
--- /dev/null
+++ b/src/contact-editor/editor/im/protocols/groupwiseprotocol.desktop
@@ -0,0 +1,107 @@
+[Desktop Entry]
+Type=Service
+Icon=im-groupwise
+X-KDE-ServiceTypes=KContacts/IMProtocol,KPluginInfo
+X-KDE-InstantMessagingKABCField=messaging/groupwise
+
+Comment=Novell GroupWise Messenger
+Comment[ar]=مرسالة نوفل GroupWise
+Comment[bs]=Novell GroupWise mesendžer
+Comment[ca]=Novell GroupWise Messenger
+Comment[[email protected]]=Novell GroupWise Messenger
+Comment[cs]=Novell GroupWise komunikátor
+Comment[da]=Novell GroupWise Messenger
+Comment[de]=Novell-GroupWise-Nachrichtendienst
+Comment[el]=Αποστολέας μηνυμάτων Novell GroupWise
+Comment[en_GB]=Novell GroupWise Messenger
+Comment[eo]=Novell GroupWise mesaĝilo
+Comment[es]=Mensajería de Novell GroupWise
+Comment[et]=Novell GroupWise Messenger
+Comment[fi]=Novell Groupwise -pikaviestin
+Comment[fr]=Messagerie « GroupWise Novell »
+Comment[ga]=Teachtaire Novell GroupWise
+Comment[gl]=Mensaxeiro GroupWise da Novell
+Comment[he]=פרוטוקול GroupWise של נובל
+Comment[hu]=Novell GroupWise üzenetküldő
+Comment[ia]=Messagero de GroupWise de Novell
+Comment[it]=Novell GroupWise Messenger
+Comment[kk]=Novell GroupWise хабарласуы
+Comment[km]=កម្មវិធី​ផ្ញើសារ​របស់ Novell GroupWise
+Comment[ko]=Novell GroupWise 메신저
+Comment[lt]=Novell GroupWise žinučių klientas
+Comment[mr]=नोव्हेल ग्रुपवाइज संदेशवाहक
+Comment[nb]=Novell GroupWise meldingsprogram
+Comment[nds]=Novell-GroupWise-Kortnarichtenmaker
+Comment[nl]=Protocol voor Novell GroupWise Messenger
+Comment[nn]=Lynmeldingstenesta Novell GroupWise
+Comment[pl]=Komunikator Novell GroupWise
+Comment[pt]=Novell GroupWise Messenger
+Comment[pt_BR]=Mensageiro do GroupWise da Novell
+Comment[ro]=Mesagerul Novell GroupWise
+Comment[ru]=Протокол обмена сообщениями Novell GroupWise
+Comment[sk]=Novell GroupWise Messenger
+Comment[sl]=Novell GroupWise Messenger
+Comment[sr]=Новелов Групвајз месенџер
+Comment[[email protected]]=Новелов Групвајз месенџер
+Comment[[email protected]]=Novellov GroupWise Messenger
+Comment[[email protected]]=Novellov GroupWise Messenger
+Comment[sv]=Novell GroupWise-meddelandeklient
+Comment[th]=ข้อความด่วนทันใจ GroupWise ของโนเวลล์
+Comment[tr]=Novell GroupWise Messenger
+Comment[ug]=Novell GroupWise مۇڭداشقۇسى
+Comment[uk]=Програма обміну повідомленнями Novell GroupWise
+Comment[wa]=Messaedjî Novell GroupWise
+Comment[x-test]=xxNovell GroupWise Messengerxx
+Comment[zh_CN]=Novell GroupWise Messenger
+Comment[zh_TW]=Novell GroupWise 即時訊息
+Name=GroupWise
+Name[bs]=GroupWise
+Name[ca]=GroupWise
+Name[[email protected]]=GroupWise
+Name[cs]=GroupWise
+Name[da]=GroupWise
+Name[de]=GroupWise
+Name[el]=GroupWise
+Name[en_GB]=GroupWise
+Name[eo]=GroupWise
+Name[es]=GroupWise
+Name[et]=GroupWise
+Name[fi]=GroupWise
+Name[fr]=GroupWise
+Name[ga]=GroupWise
+Name[gl]=GroupWise
+Name[he]=GroupWise
+Name[hu]=GroupWise
+Name[ia]=GroupWise
+Name[it]=GroupWise
+Name[ja]=GroupWise
+Name[kk]=GroupWise
+Name[km]=GroupWise​
+Name[ko]=GroupWise
+Name[lt]=GroupWise
+Name[mr]=नोव्हेल ग्रुपवाइज
+Name[nb]=GroupWise
+Name[nds]=GroupWise
+Name[nl]=GroupWise
+Name[nn]=GroupWise
+Name[pl]=GroupWise
+Name[pt]=GroupWise
+Name[pt_BR]=GroupWise
+Name[ro]=GroupWise
+Name[ru]=GroupWise
+Name[sk]=GroupWise
+Name[sl]=GroupWise
+Name[sr]=Групвајз
+Name[[email protected]]=Групвајз
+Name[[email protected]]=GroupWise
+Name[[email protected]]=GroupWise
+Name[sv]=GroupWise
+Name[th]=GroupWise
+Name[tr]=GroupWise
+Name[ug]=GroupWise
+Name[uk]=GroupWise
+Name[wa]=GroupWise
+Name[x-test]=xxGroupWisexx
+Name[zh_CN]=GroupWise
+Name[zh_TW]=GroupWise
+
diff --git a/src/contact-editor/editor/im/protocols/icqprotocol.desktop b/src/contact-editor/editor/im/protocols/icqprotocol.desktop
new file mode 100644
index 0000000..d7f42e1
--- /dev/null
+++ b/src/contact-editor/editor/im/protocols/icqprotocol.desktop
@@ -0,0 +1,107 @@
+[Desktop Entry]
+Type=Service
+Icon=im-icq
+X-KDE-ServiceTypes=KContacts/IMProtocol,KPluginInfo
+X-KDE-InstantMessagingKABCField=messaging/icq
+X-KDE-InstantMessagingKContactField=icq
+Comment=ICQ Protocol
+Comment[ar]=ميفاق ICQ
+Comment[bs]=ICQ Protokol
+Comment[ca]=Protocol ICQ
+Comment[[email protected]]=Protocol ICQ
+Comment[cs]=Protokol ICQ
+Comment[da]=ICQ-protokollen
+Comment[de]=ICQ-Protokoll
+Comment[el]=Πρωτόκολλο ICQ
+Comment[en_GB]=ICQ Protocol
+Comment[eo]=ICQ Protokolo
+Comment[es]=Protocolo ICQ
+Comment[et]=ICQ protokoll
+Comment[fi]=ICQ-yhteyskäytäntö
+Comment[fr]=Protocole ICQ
+Comment[ga]=Prótacal ICQ
+Comment[gl]=Protocolo de ICQ
+Comment[he]=פרוטוקול ICQ
+Comment[hu]=ICQ protokoll
+Comment[ia]=Protocollo ICQ
+Comment[it]=Protocollo ICQ
+Comment[ja]=ICQ プロトコル
+Comment[kk]=ICQ протоколыl
+Comment[km]=ពិធីការ​ ICQ
+Comment[ko]=ICQ 프로토콜
+Comment[lt]=ICQ protokolas
+Comment[mr]=ICQ शिष्टाचार
+Comment[nb]=ICQ-protokoll
+Comment[nds]=ICQ-Protokoll
+Comment[nl]=ICQ-protocol
+Comment[nn]=ICQ-protokoll
+Comment[pl]=Protokół ICQ
+Comment[pt]=Protocolo ICQ
+Comment[pt_BR]=Protocolo do ICQ
+Comment[ro]=Protocol ICQ
+Comment[ru]=Протокол обмена сообщениями ICQ
+Comment[sk]=Protokol ICQ
+Comment[sl]=Protokol ICQ
+Comment[sr]=Протокол ајсикју
+Comment[[email protected]]=Протокол ајсикју
+Comment[[email protected]]=Protokol ICQ
+Comment[[email protected]]=Protokol ICQ
+Comment[sv]=ICQ-protokoll
+Comment[th]=โพรโทคอล ICQ
+Comment[tr]=ICQ Protokolü
+Comment[uk]=Протокол ICQ
+Comment[wa]=Protocole ICQ
+Comment[x-test]=xxICQ Protocolxx
+Comment[zh_CN]=ICQ 协议
+Comment[zh_TW]=ICQ 協定
+Name=ICQ
+Name[bs]=ICQ
+Name[ca]=ICQ
+Name[cs]=ICQ
+Name[da]=ICQ
+Name[de]=ICQ
+Name[el]=ICQ
+Name[en_GB]=ICQ
+Name[eo]=ICQ
+Name[es]=ICQ
+Name[et]=ICQ
+Name[fi]=ICQ
+Name[fr]=ICQ
+Name[ga]=ICQ
+Name[gl]=ICQ
+Name[he]=ICQ
+Name[hu]=ICQ
+Name[ia]=ICQ
+Name[it]=ICQ
+Name[ja]=ICQ
+Name[kk]=ICQ
+Name[km]=ICQ
+Name[ko]=ICQ
+Name[lt]=ICQ
+Name[mr]=ICQ
+Name[nb]=ICQ
+Name[nds]=ICQ
+Name[nl]=ICQ
+Name[nn]=ICQ
+Name[pl]=ICQ
+Name[pt]=ICQ
+Name[pt_BR]=ICQ
+Name[ro]=ICQ
+Name[ru]=ICQ
+Name[sk]=ICQ
+Name[sl]=ICQ
+Name[sr]=ајсикју
+Name[[email protected]]=ајсикју
+Name[sv]=ICQ
+Name[th]=ICQ
+Name[tr]=ICQ
+Name[ug]=ICQ
+Name[uk]=ICQ
+Name[wa]=ICQ
+Name[x-test]=xxICQxx
+Name[zh_CN]=ICQ
+Name[zh_TW]=ICQ
+
diff --git a/src/contact-editor/editor/im/protocols/ircprotocol.desktop b/src/contact-editor/editor/im/protocols/ircprotocol.desktop
new file mode 100644
index 0000000..3f8f684
--- /dev/null
+++ b/src/contact-editor/editor/im/protocols/ircprotocol.desktop
@@ -0,0 +1,106 @@
+[Desktop Entry]
+Type=Service
+Icon=im-irc
+X-KDE-ServiceTypes=KContacts/IMProtocol,KPluginInfo
+X-KDE-InstantMessagingKABCField=messaging/irc
+Comment=Internet Relay Chat
+Comment[ar]=المحادثة المنقولة بالشّابكة
+Comment[bs]=Ćaskanje putem Interneta
+Comment[ca]=Internet Relay Chat
+Comment[[email protected]]=Internet Relay Chat
+Comment[cs]=Internet Relay Chat
+Comment[da]=Internet Relay Chat
+Comment[de]=Internet Relay Chat
+Comment[el]=Διαδικτυακή συνομιλία
+Comment[en_GB]=Internet Relay Chat
+Comment[eo]=Interreta plusenda babilado
+Comment[es]=Internet Relay Chat
+Comment[et]=Rühmadiskussioon internetis
+Comment[fi]=Internet Relay Chat
+Comment[fr]=Internet Relay Chat
+Comment[ga]=Internet Relay Chat
+Comment[gl]=Conversas por Internet
+Comment[he]=Internet Relay Chat
+Comment[hu]=Internet Relay Chat
+Comment[ia]=Internet Relay Chat (IRC)
+Comment[it]=Internet Relay Chat
+Comment[ja]=インターネットリレーチャット
+Comment[kk]=Internet Relay Chat
+Comment[km]=ជជែកកំសាន្ត​បញ្ជូន​តាម​អ៊ីនធឺណិត​
+Comment[ko]=인터넷 릴레이 채팅
+Comment[lt]=Internetu vykstantys pokalbiai (IRC)
+Comment[nb]=Internet Relay Chat
+Comment[nds]=Klöönsnack (Internet Relay Chat)
+Comment[nl]=Internet Relay Chat
+Comment[nn]=Internet Relay Chat
+Comment[pl]=Internet Relay Chat
+Comment[pt]=Internet Relay Chat
+Comment[pt_BR]=Bate-papo via Internet (IRC)
+Comment[ro]=Internet Relay Chat
+Comment[ru]=Internet Relay Chat
+Comment[sk]=Internet Relay Chat
+Comment[sl]=Internet Relay Chat
+Comment[sr]=Ћаскање путем Интернета
+Comment[[email protected]]=Ћаскање путем Интернета
+Comment[[email protected]]=Ćaskanje putem Interneta
+Comment[[email protected]]=Ćaskanje putem Interneta
+Comment[sv]=Internet Relay Chat
+Comment[tr]=Internet Relay Chat
+Comment[ug]=ئىنتېرنېت ئۇلاپ تارقىتىش سۆھبىتى(IRC)
+Comment[uk]=Internet Relay Chat
+Comment[wa]=Internet Relay Chat
+Comment[x-test]=xxInternet Relay Chatxx
+Comment[zh_CN]=IRC
+Comment[zh_TW]=IRC
+Name=IRC
+Name[ar]=آي​آر​سي
+Name[bs]=IRC
+Name[ca]=IRC
+Name[cs]=IRC
+Name[da]=IRC
+Name[de]=IRC
+Name[el]=IRC
+Name[en_GB]=IRC
+Name[eo]=IRC
+Name[es]=IRC
+Name[et]=IRC
+Name[fi]=IRC
+Name[fr]=IRC
+Name[ga]=IRC
+Name[gl]=IRC
+Name[he]=IRC
+Name[hu]=IRC
+Name[ia]=IRC
+Name[it]=IRC
+Name[ja]=IRC
+Name[kk]=IRC
+Name[km]=IRC​
+Name[ko]=IRC
+Name[lt]=IRC
+Name[mr]=IRC
+Name[nb]=IRC
+Name[nds]=IRC
+Name[nl]=IRC
+Name[nn]=IRC
+Name[pl]=IRC
+Name[pt]=IRC
+Name[pt_BR]=IRC
+Name[ro]=IRC
+Name[ru]=IRC
+Name[sk]=IRC
+Name[sl]=IRC
+Name[sr]=ИРЦ
+Name[[email protected]]=ИРЦ
+Name[sv]=IRC
+Name[th]=IRC
+Name[tr]=IRC
+Name[ug]=IRC
+Name[uk]=IRC
+Name[wa]=IRC
+Name[x-test]=xxIRCxx
+Name[zh_CN]=IRC
+Name[zh_TW]=IRC
+
diff --git a/src/contact-editor/editor/im/protocols/jabberprotocol.desktop b/src/contact-editor/editor/im/protocols/jabberprotocol.desktop
new file mode 100644
index 0000000..24f9399
--- /dev/null
+++ b/src/contact-editor/editor/im/protocols/jabberprotocol.desktop
@@ -0,0 +1,108 @@
+[Desktop Entry]
+Type=Service
+Icon=im-jabber
+X-KDE-ServiceTypes=KContacts/IMProtocol,KPluginInfo
+X-KDE-InstantMessagingKABCField=messaging/xmpp
+X-KDE-InstantMessagingKContactField=jabber
+Comment=Jabber Protocol
+Comment[ar]=ميفاق جابر
+Comment[bs]=Jabber Protokol
+Comment[ca]=Protocol Jabber
+Comment[[email protected]]=Protocol Jabber
+Comment[cs]=Protokol Jabber
+Comment[da]=Jabber-protokollen
+Comment[de]=Jabber-Protokoll
+Comment[el]=Πρωτόκολλο Jabber
+Comment[en_GB]=Jabber Protocol
+Comment[eo]=Jabber Protokolo
+Comment[es]=Protocolo Jabber
+Comment[et]=Jabberi protokoll
+Comment[fi]=Jabber-yhteyskäytäntö
+Comment[fr]=Protocole Jabber
+Comment[ga]=Prótacal Jabber
+Comment[gl]=Protocolo de Jabber
+Comment[he]=פרוטוקול Jabber
+Comment[hu]=Jabber protokoll
+Comment[ia]=Protocollo Jabber
+Comment[it]=Protocollo Jabber
+Comment[ja]=Jabber プロトコル
+Comment[kk]=Jabber протоколы
+Comment[km]=ពិធី​​ការ​ Jabber
+Comment[ko]=Jabber 프로토콜
+Comment[lt]=Jabber protokolas
+Comment[mr]=जेबर शिष्टाचार
+Comment[nb]=Jabber-protokoll
+Comment[nds]=Jabber-Protokoll
+Comment[nl]=Jabber-protocol
+Comment[nn]=Jabber-protokoll
+Comment[pl]=Protokół Jabber
+Comment[pt]=Protocolo Jabber
+Comment[pt_BR]=Protocolo do Jabber
+Comment[ro]=Protocol Jabber
+Comment[ru]=Протокол обмена сообщениями Jabber
+Comment[sk]=Protokol Jabber
+Comment[sl]=Protokol Jabber
+Comment[sr]=Протокол џабер
+Comment[[email protected]]=Протокол џабер
+Comment[[email protected]]=Protokol Jabber
+Comment[[email protected]]=Protokol Jabber
+Comment[sv]=Jabber-protokoll
+Comment[th]=โพรโทคอล Jabber
+Comment[tr]=Jabber Protocolü
+Comment[uk]=Протокол Jabber
+Comment[wa]=Protocole Jabber
+Comment[x-test]=xxJabber Protocolxx
+Comment[zh_CN]=Jabber 协议
+Comment[zh_TW]=Jabber 協定
+Name=Jabber
+Name[ar]=جابر
+Name[bs]=Jabber
+Name[ca]=Jabber
+Name[[email protected]]=Jabber
+Name[cs]=Jabber
+Name[da]=Jabber
+Name[de]=Jabber
+Name[el]=Jabber
+Name[en_GB]=Jabber
+Name[eo]=Jabber
+Name[es]=Jabber
+Name[et]=Jabber
+Name[fi]=Jabber
+Name[fr]=Jabber
+Name[ga]=Jabber
+Name[gl]=Jabber
+Name[he]=Jabber
+Name[hu]=Jabber
+Name[ia]=Jabber
+Name[it]=Jabber
+Name[ja]=Jabber
+Name[kk]=Jabber
+Name[km]=Jabber
+Name[ko]=Jabber
+Name[lt]=Jabber
+Name[mr]=जेबर
+Name[nb]=Jabber
+Name[nds]=Jabber
+Name[nl]=Jabber
+Name[nn]=Jabber
+Name[pl]=Jabber
+Name[pt]=Jabber
+Name[pt_BR]=Jabber
+Name[ro]=Jabber
+Name[ru]=Jabber
+Name[sk]=Jabber
+Name[sl]=Jabber
+Name[sr]=Џабер
+Name[[email protected]]=Џабер
+Name[[email protected]]=Jabber
+Name[[email protected]]=Jabber
+Name[sv]=Jabber
+Name[th]=Jabber
+Name[tr]=Jabber
+Name[ug]=Jabber
+Name[uk]=Jabber
+Name[wa]=Jabber
+Name[x-test]=xxJabberxx
+Name[zh_CN]=Jabber
+Name[zh_TW]=Jabber
+
diff --git a/src/contact-editor/editor/im/protocols/meanwhileprotocol.desktop b/src/contact-editor/editor/im/protocols/meanwhileprotocol.desktop
new file mode 100644
index 0000000..4afc877
--- /dev/null
+++ b/src/contact-editor/editor/im/protocols/meanwhileprotocol.desktop
@@ -0,0 +1,105 @@
+[Desktop Entry]
+Type=Service
+Icon=im-meanwhile
+X-KDE-ServiceTypes=KContacts/IMProtocol,KPluginInfo
+X-KDE-InstantMessagingKABCField=messaging/meanwhile
+Comment=Meanwhile Protocol
+Comment[bs]=Meanwhile Protokol
+Comment[ca]=Protocol Meanwhile
+Comment[[email protected]]=Protocol Meanwhile
+Comment[cs]=Protokol Meanwhile
+Comment[da]=Meanwhile-protokollen
+Comment[de]=Meanwhile-Protokoll
+Comment[el]=Πρωτόκολλο Meanwhile
+Comment[en_GB]=Meanwhile Protocol
+Comment[eo]=Meanwhile Protokolo
+Comment[es]=Protocolo Meanwhile
+Comment[et]=Meanwhile'i protokoll
+Comment[fi]=Meanwhile-yhteyskäytäntö
+Comment[fr]=Protocole Meanwhile
+Comment[ga]=Prótacal Meanwhile
+Comment[gl]=Protocolo de Meanwhile
+Comment[he]=פרוטוקול Meanwhile
+Comment[hu]=Meanwhile protokoll
+Comment[ia]=Protocollo Meanwhile
+Comment[it]=Protocollo Meanwhile
+Comment[ja]=Meanwhile プロトコル
+Comment[kk]=Meanwhile протоколы
+Comment[km]=ពិធីការ​ Meanwhile
+Comment[ko]=Meanwhile 프로토콜
+Comment[lt]=Meanwhile protokolas
+Comment[mr]=मीनव्हाइल शिष्टाचार
+Comment[nb]=Meanwhile-protokoll
+Comment[nds]=Meanwhile-Protokoll
+Comment[nl]=Meanwhile-protocol
+Comment[nn]=Meanwhile-protokoll
+Comment[pl]=Protokół Meanwhile
+Comment[pt]=Protocolo Meanwhile
+Comment[pt_BR]=Protocolo do Meanwhile
+Comment[ro]=Protocol Meanwhile
+Comment[ru]=Протокол обмена сообщениями Meanwhile
+Comment[sk]=Protokol Meanwhile
+Comment[sl]=Protokol Meanwhile
+Comment[sr]=Протокол минвајл
+Comment[[email protected]]=Протокол минвајл
+Comment[[email protected]]=Protokol Meanwhile
+Comment[[email protected]]=Protokol Meanwhile
+Comment[sv]=Meanwhile-protokoll
+Comment[th]=โพรโทคอล Meanwhile
+Comment[tr]=Meanwhile Protokolü
+Comment[uk]=Протокол Meanwhile
+Comment[wa]=Protocole Meanwhile
+Comment[x-test]=xxMeanwhile Protocolxx
+Comment[zh_CN]=Meanwhile 协议
+Comment[zh_TW]=Meanwhile 協定
+Name=Meanwhile
+Name[bs]=Meanwhile
+Name[ca]=Meanwhile
+Name[[email protected]]=Meanwhile
+Name[cs]=Meanwhile
+Name[da]=Meanwhile
+Name[de]=Meanwhile
+Name[el]=Meanwhile
+Name[en_GB]=Meanwhile
+Name[eo]=Meanwhile
+Name[es]=Meanwhile
+Name[et]=Meanwhile
+Name[fi]=Meanwhile
+Name[fr]=Meanwhile
+Name[ga]=Meanwhile
+Name[gl]=Meanwhile
+Name[he]=Meanwhile
+Name[hu]=Meanwhile
+Name[ia]=Meanwhile
+Name[it]=Meanwhile
+Name[ja]=Meanwhile
+Name[kk]=Meanwhile
+Name[km]=Meanwhile
+Name[ko]=Meanwhile
+Name[lt]=Meanwhile
+Name[mr]=मीनव्हाइल
+Name[nb]=Meanwhile
+Name[nds]=Meanwhile
+Name[nl]=Meanwhile
+Name[nn]=Meanwhile
+Name[pl]=Meanwhile
+Name[pt]=Meanwhile
+Name[pt_BR]=Meanwhile
+Name[ro]=Meanwhile
+Name[ru]=Meanwhile
+Name[sk]=Meanwhile
+Name[sl]=Meanwhile
+Name[sr]=Минвајл
+Name[[email protected]]=Минвајл
+Name[[email protected]]=Meanwhile
+Name[[email protected]]=Meanwhile
+Name[sv]=Meanwhile
+Name[th]=Meanwhile
+Name[tr]=Meanwhile
+Name[ug]=Meanwhile
+Name[uk]=Meanwhile
+Name[wa]=Meanwhile
+Name[x-test]=xxMeanwhilexx
+Name[zh_CN]=Meanwhile
+Name[zh_TW]=Meanwhile
+
diff --git a/src/contact-editor/editor/im/protocols/msnprotocol.desktop b/src/contact-editor/editor/im/protocols/msnprotocol.desktop
new file mode 100644
index 0000000..16e7797
--- /dev/null
+++ b/src/contact-editor/editor/im/protocols/msnprotocol.desktop
@@ -0,0 +1,107 @@
+[Desktop Entry]
+Type=Service
+Icon=im-msn
+X-KDE-ServiceTypes=KContacts/IMProtocol,KPluginInfo
+X-KDE-InstantMessagingKABCField=messaging/msn
+X-KDE-InstantMessagingKContactField=msn
+Comment=MSN Messenger
+Comment[ar]=مرسال MSN
+Comment[bs]=MSN Mesendžer
+Comment[ca]=MSN Messenger
+Comment[[email protected]]=MSN Messenger
+Comment[cs]=MSN Messenger
+Comment[da]=MSN Messenger
+Comment[de]=MSN-Nachrichtendienst
+Comment[el]=Αποστολέας μηνυμάτων MSN
+Comment[en_GB]=MSN Messenger
+Comment[eo]=MSN Mesaĝilo
+Comment[es]=MSN Messenger
+Comment[et]=MSN Messenger
+Comment[fi]=MSN Messenger
+Comment[fr]=Messagerie MSN
+Comment[ga]=MSN Messenger
+Comment[gl]=Mensaxeiro MSN
+Comment[he]=פרוטוקול MSN
+Comment[hu]=MSN Messenger
+Comment[ia]=Messaggero MSN
+Comment[it]=MSN Messenger
+Comment[ja]=MSN メッセンジャー
+Comment[kk]=MSN хабарласуы
+Comment[km]=កម្មវិធី​ផ្ញើសារ MSN
+Comment[ko]=MSN 메신저
+Comment[lt]=MSN žinučių klientas
+Comment[mr]=एमएसएन संदेशवाहक
+Comment[nb]=MSN Messenger
+Comment[nds]=MSN-Kortnarichtenmaker
+Comment[nl]=MSN Messenger
+Comment[nn]=MSN Messenger
+Comment[pl]=MSN Messenger
+Comment[pt]=MSN Messenger
+Comment[pt_BR]=MSN Messenger
+Comment[ro]=Mesagerul MSN
+Comment[ru]=Протокол обмена сообщениями MSN
+Comment[sk]=MSN Messenger
+Comment[sl]=MSN Messenger
+Comment[sr]=МСН месенџер
+Comment[[email protected]]=МСН месенџер
+Comment[[email protected]]=MSN Messenger
+Comment[[email protected]]=MSN Messenger
+Comment[sv]=MSN Messenger
+Comment[tr]=MSN Messenger
+Comment[ug]=MSN Messenger
+Comment[uk]=MSN Messenger
+Comment[wa]=MSN Messenger
+Comment[x-test]=xxMSN Messengerxx
+Comment[zh_CN]=MSN Messenger
+Comment[zh_TW]=MSN
+Name=MSN Messenger
+Name[ar]=مرسال MSN
+Name[bs]=MSN Mesendžer
+Name[ca]=MSN Messenger
+Name[[email protected]]=MSN Messenger
+Name[cs]=MSN Messenger
+Name[da]=MSN Messenger
+Name[de]=MSN Messenger
+Name[el]=Αποστολέας μηνυμάτων MSN
+Name[en_GB]=MSN Messenger
+Name[eo]=MSN mesaĝilo
+Name[es]=MSN Messenger
+Name[et]=MSN Messenger
+Name[fi]=MSN Messenger
+Name[fr]=Messagerie MSN
+Name[ga]=MSN Messenger
+Name[gl]=MSN Messenger
+Name[he]=MSN Messenger
+Name[hu]=MSN Messenger
+Name[ia]=Messaggero MSN
+Name[it]=MSN Messenger
+Name[ja]=MSN メッセンジャー
+Name[kk]=MSN Messenger
+Name[km]=កម្មវិធី​ផ្ញើសារ MSN
+Name[ko]=MSN 메신저
+Name[lt]=MSN žinučių klientas
+Name[mr]=एमएसएन संदेशवाहक
+Name[nb]=MSN Messenger
+Name[nds]=MSN-Kortnarichtenmaker
+Name[nl]=MSN Messenger
+Name[nn]=MSN Messenger
+Name[pl]=MSN Messenger
+Name[pt]=MSN Messenger
+Name[pt_BR]=MSN Messenger
+Name[ro]=Mesagerul MSN
+Name[ru]=MSN
+Name[sk]=MSN Messenger
+Name[sl]=MSN Messenger
+Name[sr]=МСН месенџер
+Name[[email protected]]=МСН месенџер
+Name[[email protected]]=MSN Messenger
+Name[[email protected]]=MSN Messenger
+Name[sv]=MSN Messenger
+Name[tr]=MSN Messenger
+Name[ug]=MSN Messenger
+Name[uk]=MSN Messenger
+Name[wa]=MSN Messenger
+Name[x-test]=xxMSN Messengerxx
+Name[zh_CN]=MSN Messenger
+Name[zh_TW]=MSN
+
diff --git a/src/contact-editor/editor/im/protocols/skypeprotocol.desktop b/src/contact-editor/editor/im/protocols/skypeprotocol.desktop
new file mode 100644
index 0000000..99e82b9
--- /dev/null
+++ b/src/contact-editor/editor/im/protocols/skypeprotocol.desktop
@@ -0,0 +1,105 @@
+[Desktop Entry]
+Type=Service
+Icon=im-skype
+X-KDE-ServiceTypes=KContacts/IMProtocol,KPluginInfo
+X-KDE-InstantMessagingKABCField=messaging/skype
+X-KDE-InstantMessagingKContactField=skype
+Comment=Skype Internet Telephony
+Comment[bs]=Skype (Skajp) internet tehnologija
+Comment[ca]=Telefonia d'Internet Skype
+Comment[[email protected]]=Telefonia d'Internet Skype
+Comment[cs]=Internetová telefonie Skype
+Comment[da]=Internettelefoni med Skype
+Comment[de]=Skype-Internettelefonie
+Comment[el]=Διαδικτυακή τηλεφωνία Skype
+Comment[en_GB]=Skype Internet Telephony
+Comment[eo]=Skype Interreta Telefonado
+Comment[es]=Telefonía por Internet de Skype
+Comment[et]=Internetitelefon Skype
+Comment[fi]=Skype-internetpuhelin
+Comment[fr]=Téléphonie Internet Skype
+Comment[ga]=Teileafónaíocht Idirlín Skype
+Comment[gl]=Telefonía por Internet de Skype
+Comment[he]=טלפוניית אינטרנט של Skype
+Comment[hu]=Skype internetes telefon
+Comment[ia]=Telephonia Internet de Skype
+Comment[it]=Telefonia su Internet di Skype
+Comment[ja]=Skype インターネット電話
+Comment[kk]=Skype Интернет телефоны
+Comment[km]=ទូរស័ព្ទ​តាម​អ៊ីនធឺណិត​ ​Skype​
+Comment[ko]=Skype 인터넷 전화
+Comment[lt]=Skype interneto telefonija
+Comment[mr]=स्काइप इंटरनेट टेलिफोनी
+Comment[nb]=Skype IP-telefoni
+Comment[nds]=Internet-Telefoneren mit Skype
+Comment[nl]=Skype internet-telefonie
+Comment[nn]=Skype Internett-telefoni
+Comment[pl]=Internetowa telefonia Skype
+Comment[pt]=Telefonia Internet Skype
+Comment[pt_BR]=Telefonia Internet Skype
+Comment[ro]=Telefonie prin internet Skype
+Comment[ru]=Интернет-телефония Skype
+Comment[sk]=Skype Internet Telephony
+Comment[sl]=Internetna telefonija Skype
+Comment[sr]=Скајп, интернет телефонија
+Comment[[email protected]]=Скајп, интернет телефонија
+Comment[[email protected]]=Skype, internet telefonija
+Comment[[email protected]]=Skype, internet telefonija
+Comment[sv]=Skype Internettelefoni
+Comment[tr]=Skype Internet Telefonu
+Comment[uk]=Інтернет-телефонія Skype
+Comment[wa]=Telefoneye sol Daegntoele Skype
+Comment[x-test]=xxSkype Internet Telephonyxx
+Comment[zh_CN]=Skype 互联网电话
+Comment[zh_TW]=Skype 網路電話
+Name=Skype
+Name[ar]=سكايب
+Name[bs]=Skype (Skajp)
+Name[ca]=Skype
+Name[[email protected]]=Skype
+Name[cs]=Skype
+Name[da]=Skype
+Name[de]=Skype
+Name[el]=Skype
+Name[en_GB]=Skype
+Name[eo]=kype
+Name[es]=Skype
+Name[et]=Skype
+Name[fi]=Skype
+Name[fr]=Skype
+Name[ga]=Skype
+Name[gl]=Skype
+Name[he]=Skype
+Name[hu]=Skype
+Name[ia]=Skype
+Name[it]=Skype
+Name[ja]=Skype
+Name[kk]=Skype
+Name[km]=Skype
+Name[ko]=Skype
+Name[lt]=Skype
+Name[mr]=स्काइप
+Name[nb]=Skype
+Name[nds]=Skype
+Name[nl]=Skype
+Name[nn]=Skype
+Name[pl]=Skype
+Name[pt]=Skype
+Name[pt_BR]=Skype
+Name[ro]=Skype
+Name[ru]=Skype
+Name[sk]=Skype
+Name[sl]=Skype
+Name[sr]=Скајп
+Name[[email protected]]=Скајп
+Name[[email protected]]=Skype
+Name[[email protected]]=Skype
+Name[sv]=Skype
+Name[th]=Skype
+Name[tr]=Skype
+Name[ug]=Skype
+Name[uk]=Skype
+Name[wa]=Skype
+Name[x-test]=xxSkypexx
+Name[zh_CN]=Skype
+Name[zh_TW]=Skype
diff --git a/src/contact-editor/editor/im/protocols/smsprotocol.desktop b/src/contact-editor/editor/im/protocols/smsprotocol.desktop
new file mode 100644
index 0000000..c5b4e96
--- /dev/null
+++ b/src/contact-editor/editor/im/protocols/smsprotocol.desktop
@@ -0,0 +1,106 @@
+[Desktop Entry]
+Type=Service
+Icon=im-sms
+X-KDE-ServiceTypes=KContacts/IMProtocol,KPluginInfo
+X-KDE-InstantMessagingKABCField=messaging/sms
+Comment=SMS Protocol
+Comment[ar]=ميفاق SMS
+Comment[bs]=SMS Protokol
+Comment[ca]=Protocol SMS
+Comment[[email protected]]=Protocol SMS
+Comment[cs]=SMS protokol
+Comment[da]=SMS-protokol
+Comment[de]=SMS-Protokoll
+Comment[el]=Πρωτόκολλο SMS
+Comment[en_GB]=SMS Protocol
+Comment[eo]=SMS Protokolo
+Comment[es]=Protocolo SMS
+Comment[et]=SMS protokoll
+Comment[fi]=Tekstiviestiyhteyskäytäntö
+Comment[fr]=Protocole SMS
+Comment[ga]=Prótacal SMS
+Comment[gl]=Protocolo de SMS
+Comment[he]=פרוטוקול מסרונים
+Comment[hu]=SMS protokoll
+Comment[ia]=Protocollo SMS
+Comment[it]=Protocollo SMS
+Comment[ja]=SMS プロトコル
+Comment[kk]=SMS протоколы
+Comment[km]=ពិធីការ​ SMS ​​
+Comment[ko]=SMS 프로토콜
+Comment[lt]=SMS protokolas
+Comment[mr]=एसएमएस शिष्टाचार
+Comment[nb]=SMS Protokoll
+Comment[nds]=SMS-Protokoll
+Comment[nl]=SMS-protocol
+Comment[nn]=SMS-protokoll
+Comment[pl]=Protokół SMS
+Comment[pt]=Protocolo SMS
+Comment[pt_BR]=Protocolo SMS
+Comment[ro]=Protocol SMS
+Comment[ru]=Протокол SMS
+Comment[sk]=Protokol SMS
+Comment[sl]=Protokol SMS
+Comment[sr]=Протокол СМС
+Comment[[email protected]]=Протокол СМС
+Comment[[email protected]]=Protokol SMS
+Comment[[email protected]]=Protokol SMS
+Comment[sv]=SMS-protokoll
+Comment[th]=โพรโทคอล SMS
+Comment[tr]=SMS Protokolü
+Comment[uk]=Протокол SMS
+Comment[wa]=Protocole SMS
+Comment[x-test]=xxSMS Protocolxx
+Comment[zh_CN]=短消息协议
+Comment[zh_TW]=SMS 協定
+Name=SMS
+Name[bs]=SMS
+Name[ca]=SMS
+Name[cs]=SMS
+Name[da]=SMS
+Name[de]=SMS
+Name[el]=SMS
+Name[en_GB]=SMS
+Name[eo]=SMS
+Name[es]=SMS
+Name[et]=SMS
+Name[fi]=Tekstiviesti
+Name[fr]=SMS
+Name[ga]=SMS
+Name[gl]=SMS
+Name[he]=מסרון
+Name[hu]=SMS
+Name[ia]=SMS
+Name[it]=SMS
+Name[ja]=SMS
+Name[kk]=SMS
+Name[km]=SMS
+Name[ko]=SMS
+Name[lt]=SMS
+Name[mr]=एसएमएस
+Name[nb]=SMS
+Name[nds]=SMS
+Name[nl]=SMS
+Name[nn]=SMS
+Name[pl]=SMS
+Name[pt]=SMS
+Name[pt_BR]=SMS
+Name[ro]=SMS
+Name[ru]=SMS
+Name[sk]=SMS
+Name[sl]=SMS
+Name[sr]=СМС
+Name[[email protected]]=СМС
+Name[sv]=SMS
+Name[th]=SMS
+Name[tr]=SMS
+Name[ug]=SMS
+Name[uk]=SMS
+Name[wa]=SMS
+Name[x-test]=xxSMSxx
+Name[zh_CN]=SMS
+Name[zh_TW]=SMS
+
diff --git a/src/contact-editor/editor/im/protocols/twitterprotocol.desktop b/src/contact-editor/editor/im/protocols/twitterprotocol.desktop
new file mode 100644
index 0000000..7e5b512
--- /dev/null
+++ b/src/contact-editor/editor/im/protocols/twitterprotocol.desktop
@@ -0,0 +1,69 @@
+[Desktop Entry]
+Type=Service
+Icon=im-twitter
+X-KDE-ServiceTypes=KContacts/IMProtocol,KPluginInfo
+X-KDE-InstantMessagingKContactField=twitter
+X-KDE-InstantMessagingKABCField=messaging/twitter
+Comment=Twitter Protocol
+Comment[ca]=Protocol Twitter
+Comment[[email protected]]=Protocol Twitter
+Comment[cs]=Protokol Twitter
+Comment[da]=Twitter-protokollen
+Comment[de]=Twitter-Protokoll
+Comment[en_GB]=Twitter Protocol
+Comment[es]=Protocolo Twitter
+Comment[et]=Twitteri protokoll
+Comment[fi]=Twitter-yhteyskäytäntö
+Comment[fr]=Protocole Twitter
+Comment[gl]=Protocolo de Twitter
+Comment[it]=Protocollo di Twitter
+Comment[ko]=트위터 프로토콜
+Comment[nl]=Twitter-protocol
+Comment[pl]=Protokół Twittera
+Comment[pt]=Protocolo do Twitter
+Comment[pt_BR]=Protocolo do Twitter
+Comment[ru]=Протокол Twitter
+Comment[sk]=Protokol Twitter
+Comment[sl]=Protokol Twitter
+Comment[sr]=Протокол Твитера
+Comment[[email protected]]=Протокол Твитера
+Comment[[email protected]]=Protokol Twittera
+Comment[[email protected]]=Protokol Twittera
+Comment[sv]=Twitter-protokoll
+Comment[tr]=Twitter Protokolü
+Comment[uk]=Протокол Twitter
+Comment[x-test]=xxTwitter Protocolxx
+Comment[zh_CN]=Twitter 协议
+Name=Twitter
+Name[ca]=Twitter
+Name[[email protected]]=Twitter
+Name[cs]=Twitter
+Name[da]=Twitter
+Name[de]=Twitter
+Name[en_GB]=Twitter
+Name[es]=Twitter
+Name[et]=Twitter
+Name[fi]=Twitter
+Name[fr]=Twitter
+Name[gl]=Twitter
+Name[it]=Twitter
+Name[ko]=트위터
+Name[nb]=Twitter
+Name[nl]=Twitter
+Name[nn]=Twitter
+Name[pl]=Twitter
+Name[pt]=Twitter
+Name[pt_BR]=Twitter
+Name[ru]=Twitter
+Name[sk]=Twitter
+Name[sl]=Twitter
+Name[sr]=Твитер
+Name[[email protected]]=Твитер
+Name[[email protected]]=Twitter
+Name[[email protected]]=Twitter
+Name[sv]=Twitter
+Name[tr]=Twitter
+Name[uk]=Twitter
+Name[x-test]=xxTwitterxx
+Name[zh_CN]=Twitter
+
diff --git a/src/contact-editor/editor/im/protocols/yahooprotocol.desktop b/src/contact-editor/editor/im/protocols/yahooprotocol.desktop
new file mode 100644
index 0000000..7cbffe9
--- /dev/null
+++ b/src/contact-editor/editor/im/protocols/yahooprotocol.desktop
@@ -0,0 +1,108 @@
+[Desktop Entry]
+Type=Service
+Icon=im-yahoo
+X-KDE-ServiceTypes=KContacts/IMProtocol,KPluginInfo
+X-KDE-InstantMessagingKABCField=messaging/yahoo
+X-KDE-InstantMessagingKContactField=yahoo
+Comment=Yahoo Protocol
+Comment[ar]=ميفاق ياهو
+Comment[bs]=Yahoo Protokol
+Comment[ca]=Protocol Yahoo
+Comment[[email protected]]=Protocol Yahoo
+Comment[cs]=Protokol Yahoo
+Comment[da]=Yahoo-protokollen
+Comment[de]=Yahoo-Protokoll
+Comment[el]=Πρωτόκολλο Yahoo
+Comment[en_GB]=Yahoo Protocol
+Comment[eo]=Yahoo Protokolo
+Comment[es]=Protocolo Yahoo
+Comment[et]=Yahoo protokoll
+Comment[fi]=Yahoo-yhteyskäytäntö
+Comment[fr]=Protocole Yahoo
+Comment[ga]=Prótacal Yahoo
+Comment[gl]=Protocolo de Yahoo
+Comment[he]=פרוטוקול Yahoo
+Comment[hu]=Yahoo protokoll
+Comment[ia]=Protocollo Yahoo
+Comment[it]=Protocollo di Yahoo
+Comment[ja]=Yahoo プロトコル
+Comment[kk]=Yahoo протоколы
+Comment[km]=ពិធីការ​យ៉ាហ៊ូ​
+Comment[ko]=Yahoo 프로토콜
+Comment[lt]=Yahoo protokolas
+Comment[mr]=याहू शिष्टाचार
+Comment[nb]=Yahoo-protokoll
+Comment[nds]=Yahoo-Protokoll
+Comment[nl]=Yahoo-protocol
+Comment[nn]=Yahoo!-protokoll
+Comment[pl]=Protokół Yahoo
+Comment[pt]=Protocolo Yahoo
+Comment[pt_BR]=Protocolo do Yahoo
+Comment[ro]=Protocol Yahoo
+Comment[ru]=Протокол Yahoo
+Comment[sk]=Protokol Yahoo
+Comment[sl]=Protokol Yahoo
+Comment[sr]=Протокол Јахуа
+Comment[[email protected]]=Протокол Јахуа
+Comment[[email protected]]=Protokol Yahooa
+Comment[[email protected]]=Protokol Yahooa
+Comment[sv]=Yahoo-protokoll
+Comment[th]=โพรโทคอล Yahoo
+Comment[tr]=Yahoo Protokolü
+Comment[uk]=Протокол Yahoo
+Comment[wa]=Protocole Yahoo
+Comment[x-test]=xxYahoo Protocolxx
+Comment[zh_CN]=Yahoo 协议
+Comment[zh_TW]=Yahoo 協定
+Name=Yahoo
+Name[ar]=ياهو
+Name[bs]=Yahoo
+Name[ca]=Yahoo
+Name[[email protected]]=Yahoo
+Name[cs]=Yahoo
+Name[da]=Yahoo
+Name[de]=Yahoo
+Name[el]=Yahoo
+Name[en_GB]=Yahoo
+Name[eo]=Yahoo
+Name[es]=Yahoo
+Name[et]=Yahoo
+Name[fi]=Yahoo
+Name[fr]=Yahoo
+Name[ga]=Yahoo
+Name[gl]=Yahoo
+Name[he]=Yahoo
+Name[hu]=Yahoo
+Name[ia]=Yahoo
+Name[it]=Yahoo
+Name[ja]=Yahoo
+Name[kk]=Yahoo
+Name[km]=យ៉ាហ៊ូ​
+Name[ko]=Yahoo
+Name[lt]=Yahoo
+Name[mr]=याहू
+Name[nb]=Yahoo
+Name[nds]=Yahoo
+Name[nl]=Yahoo
+Name[nn]=Yahoo
+Name[pl]=Yahoo
+Name[pt]=Yahoo
+Name[pt_BR]=Yahoo
+Name[ro]=Yahoo
+Name[ru]=Yahoo
+Name[sk]=Yahoo
+Name[sl]=Yahoo
+Name[sr]=Јаху
+Name[[email protected]]=Јаху
+Name[[email protected]]=Yahoo
+Name[[email protected]]=Yahoo
+Name[sv]=Yahoo
+Name[th]=Yahoo
+Name[tr]=Yahoo
+Name[ug]=ياخۇ
+Name[uk]=Yahoo
+Name[wa]=Yahoo
+Name[x-test]=xxYahooxx
+Name[zh_CN]=Yahoo
+Name[zh_TW]=Yahoo
+
diff --git a/src/contact-editor/editor/personaleditor/dateeditwidget.cpp b/src/contact-editor/editor/personaleditor/dateeditwidget.cpp
new file mode 100644
index 0000000..209eb9a
--- /dev/null
+++ b/src/contact-editor/editor/personaleditor/dateeditwidget.cpp
@@ -0,0 +1,149 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (c) 2009 Tobias Koenig <[email protected]>
+
+ 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 "dateeditwidget.h"
+
+#include "kdatepickerpopup_p.h"
+
+#include <kdatepicker.h>
+
+#include <QContextMenuEvent>
+#include <QHBoxLayout>
+#include <QToolButton>
+#include <KLocalizedString>
+#include <QLocale>
+
+DateView::DateView(QWidget *parent)
+ : QLineEdit(parent)
+{
+ setPlaceholderText(i18n("Click to Add Date"));
+ setReadOnly(true);
+}
+
+void DateView::contextMenuEvent(QContextMenuEvent *event)
+{
+ if (text().isEmpty()) {
+ return;
+ }
+
+ QMenu menu;
+ menu.addAction(i18n("Remove"), this, SLOT(emitSignal()));
+
+ menu.exec(event->globalPos());
+}
+
+void DateView::emitSignal()
+{
+ Q_EMIT resetDate();
+}
+
+DateEditWidget::DateEditWidget(Type type, QWidget *parent)
+ : QWidget(parent)
+ , mReadOnly(false)
+{
+ QHBoxLayout *layout = new QHBoxLayout(this);
+ layout->setMargin(0);
+
+ mView = new DateView;
+ layout->addWidget(mView);
+
+ mClearButton = new QToolButton;
+ if (layoutDirection() == Qt::LeftToRight) {
+ mClearButton->setIcon(QIcon::fromTheme(QStringLiteral("edit-clear-locationbar-rtl")));
+ } else {
+ mClearButton->setIcon(QIcon::fromTheme(QStringLiteral("edit-clear-locationbar-ltr")));
+ }
+ layout->addWidget(mClearButton);
+
+ mSelectButton = new QToolButton;
+ mSelectButton->setPopupMode(QToolButton::InstantPopup);
+ switch (type) {
+ case General:
+ mSelectButton->setIcon(QIcon::fromTheme(QStringLiteral("view-calendar-day")));
+ break;
+ case Birthday:
+ mSelectButton->setIcon(QIcon::fromTheme(QStringLiteral("view-calendar-birthday")));
+ break;
+ case Anniversary:
+ mSelectButton->setIcon(QIcon::fromTheme(QStringLiteral("view-calendar-wedding-anniversary")));
+ break;
+ }
+
+ layout->addWidget(mSelectButton);
+ setFocusProxy(mSelectButton);
+ setFocusPolicy(Qt::StrongFocus);
+
+ mMenu = new KDatePickerPopup(KDatePickerPopup::DatePicker, QDate(), this);
+ mSelectButton->setMenu(mMenu);
+
+ connect(mClearButton, &QToolButton::clicked, this, &DateEditWidget::resetDate);
+ connect(mMenu, &KDatePickerPopup::dateChanged, this, &DateEditWidget::dateSelected);
+ connect(mView, &DateView::resetDate, this, &DateEditWidget::resetDate);
+
+ updateView();
+}
+
+DateEditWidget::~DateEditWidget()
+{
+}
+
+void DateEditWidget::setDate(const QDate &date)
+{
+ mDate = date;
+ mMenu->setDate(mDate);
+ updateView();
+}
+
+QDate DateEditWidget::date() const
+{
+ return mDate;
+}
+
+void DateEditWidget::setReadOnly(bool readOnly)
+{
+ mReadOnly = readOnly;
+
+ mSelectButton->setEnabled(!readOnly);
+ mClearButton->setEnabled(!readOnly);
+}
+
+void DateEditWidget::dateSelected(const QDate &date)
+{
+ mDate = date;
+ updateView();
+}
+
+void DateEditWidget::resetDate()
+{
+ mDate = QDate();
+ updateView();
+}
+
+void DateEditWidget::updateView()
+{
+ if (mDate.isValid()) {
+ mView->setText(QLocale().toString(mDate));
+ mClearButton->show();
+ } else {
+ mView->setText(QString());
+ mClearButton->hide();
+ }
+}
diff --git a/src/contact-editor/editor/personaleditor/dateeditwidget.h b/src/contact-editor/editor/personaleditor/dateeditwidget.h
new file mode 100644
index 0000000..292a66f
--- /dev/null
+++ b/src/contact-editor/editor/personaleditor/dateeditwidget.h
@@ -0,0 +1,84 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (c) 2009 Tobias Koenig <[email protected]>
+
+ 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 DATEEDITWIDGET_H
+#define DATEEDITWIDGET_H
+
+#include <QDate>
+#include <QLineEdit>
+#include <QWidget>
+
+class KDatePickerPopup;
+
+class QContextMenuEvent;
+class QToolButton;
+
+class DateView : public QLineEdit
+{
+ Q_OBJECT
+
+public:
+ explicit DateView(QWidget *parent = nullptr);
+
+Q_SIGNALS:
+ void resetDate();
+
+protected:
+ void contextMenuEvent(QContextMenuEvent *event) override;
+
+private Q_SLOTS:
+ void emitSignal();
+};
+
+class DateEditWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ enum Type {
+ General,
+ Birthday,
+ Anniversary
+ };
+
+ explicit DateEditWidget(Type type = General, QWidget *parent = nullptr);
+ ~DateEditWidget();
+
+ void setDate(const QDate &date);
+ QDate date() const;
+
+ void setReadOnly(bool readOnly);
+
+private Q_SLOTS:
+ void dateSelected(const QDate &date);
+ void resetDate();
+ void updateView();
+
+private:
+ DateView *mView;
+ QToolButton *mSelectButton;
+ QToolButton *mClearButton;
+ KDatePickerPopup *mMenu;
+ QDate mDate;
+ bool mReadOnly;
+};
+
+#endif
diff --git a/src/contact-editor/editor/personaleditor/kdatepickerpopup.cpp b/src/contact-editor/editor/personaleditor/kdatepickerpopup.cpp
new file mode 100644
index 0000000..191e24f
--- /dev/null
+++ b/src/contact-editor/editor/personaleditor/kdatepickerpopup.cpp
@@ -0,0 +1,150 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (c) 2004 Bram Schoenmakers <[email protected]>
+
+ 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 "kdatepickerpopup_p.h"
+
+#include <KDatePicker>
+#include <KLocalizedString>
+
+#include <QDateTime>
+#include <QWidgetAction>
+
+class KDatePickerAction : public QWidgetAction
+{
+public:
+ KDatePickerAction(KDatePicker *widget, QObject *parent)
+ : QWidgetAction(parent)
+ , mDatePicker(widget)
+ , mOriginalParent(widget->parentWidget())
+ {
+ }
+
+protected:
+ QWidget *createWidget(QWidget *parent) override {
+ mDatePicker->setParent(parent);
+ return mDatePicker;
+ }
+
+ void deleteWidget(QWidget *widget) override {
+ if (widget != mDatePicker)
+ {
+ return;
+ }
+
+ mDatePicker->setParent(mOriginalParent);
+ }
+
+private:
+ KDatePicker *mDatePicker;
+ QWidget *mOriginalParent;
+};
+
+KDatePickerPopup::KDatePickerPopup(Items items, const QDate &date, QWidget *parent)
+ : QMenu(parent)
+{
+ mItems = items;
+ mDate = date;
+ mDatePicker = new KDatePicker(this);
+ mDatePicker->setCloseButton(false);
+
+ connect(mDatePicker, &KDatePicker::dateEntered, this, &KDatePickerPopup::slotDateChanged);
+ connect(mDatePicker, &KDatePicker::dateSelected, this, &KDatePickerPopup::slotDateChanged);
+
+ mDatePicker->setDate(date);
+
+ buildMenu();
+}
+
+void KDatePickerPopup::buildMenu()
+{
+ if (isVisible()) {
+ return;
+ }
+ clear();
+
+ if (mItems & DatePicker) {
+ addAction(new KDatePickerAction(mDatePicker, this));
+
+ if ((mItems & NoDate) || (mItems & Words)) {
+ addSeparator();
+ }
+ }
+
+ if (mItems & Words) {
+ addAction(i18nc("@option today", "&Today"), this, SLOT(slotToday()));
+ addAction(i18nc("@option tomorrow", "To&morrow"), this, SLOT(slotTomorrow()));
+ addAction(i18nc("@option next week", "Next &Week"), this, SLOT(slotNextWeek()));
+ addAction(i18nc("@option next month", "Next M&onth"), this, SLOT(slotNextMonth()));
+
+ if (mItems & NoDate) {
+ addSeparator();
+ }
+ }
+
+ if (mItems & NoDate) {
+ addAction(i18nc("@option do not specify a date", "No Date"), this, SLOT(slotNoDate()));
+ }
+}
+
+KDatePicker *KDatePickerPopup::datePicker() const
+{
+ return mDatePicker;
+}
+
+void KDatePickerPopup::setDate(const QDate &date)
+{
+ mDatePicker->setDate(date);
+}
+
+void KDatePickerPopup::slotDateChanged(const QDate &date)
+{
+ if (date != mDate) {
+ Q_EMIT dateChanged(date);
+ }
+ hide();
+}
+
+void KDatePickerPopup::slotToday()
+{
+ Q_EMIT dateChanged(QDate::currentDate());
+}
+
+void KDatePickerPopup::slotTomorrow()
+{
+ Q_EMIT dateChanged(QDate::currentDate().addDays(1));
+}
+
+void KDatePickerPopup::slotNoDate()
+{
+ Q_EMIT dateChanged(QDate());
+}
+
+void KDatePickerPopup::slotNextWeek()
+{
+ Q_EMIT dateChanged(QDate::currentDate().addDays(7));
+}
+
+void KDatePickerPopup::slotNextMonth()
+{
+ Q_EMIT dateChanged(QDate::currentDate().addMonths(1));
+}
+
+#include "moc_kdatepickerpopup_p.cpp"
diff --git a/src/contact-editor/editor/personaleditor/kdatepickerpopup_p.h b/src/contact-editor/editor/personaleditor/kdatepickerpopup_p.h
new file mode 100644
index 0000000..fc3fbac
--- /dev/null
+++ b/src/contact-editor/editor/personaleditor/kdatepickerpopup_p.h
@@ -0,0 +1,113 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (c) 2004 Bram Schoenmakers <[email protected]>
+
+ 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 KDATEPICKERPOPUP_P_H
+#define KDATEPICKERPOPUP_P_H
+
+#include <QDateTime>
+#include <QMenu>
+
+class KDatePicker;
+
+/**
+ @short This menu helps the user to select a date quickly.
+
+ This menu helps the user to select a date quicly. It offers various
+ ways of selecting, e.g. with a KDatePicker or with words like "Tomorrow".
+
+ The available items are:
+
+ @li NoDate: A menu-item with "No Date". If chosen, the datepicker will emit
+ a null QDate.
+ @li DatePicker: Show a KDatePicker-widget.
+ @li Words: Show items like "Today", "Tomorrow" or "Next Week".
+
+ When supplying multiple items, separate each item with a bitwise OR.
+
+ @author Bram Schoenmakers <[email protected]>
+*/
+class KDatePickerPopup : public QMenu
+{
+ Q_OBJECT
+
+public:
+ enum ItemFlag {
+ NoDate = 1,
+ DatePicker = 2,
+ Words = 4
+ };
+
+ Q_DECLARE_FLAGS(Items, ItemFlag)
+
+ /**
+ A constructor for the KDatePickerPopup.
+
+ @param items List of all desirable items, separated with a bitwise OR.
+ @param date Initial date of datepicker-widget.
+ @param parent The object's parent.
+ */
+ explicit KDatePickerPopup(Items items = DatePicker,
+ const QDate &date = QDate::currentDate(),
+ QWidget *parent = nullptr);
+
+ /**
+ @return A pointer to the private variable mDatePicker, an instance of
+ KDatePicker.
+ */
+ KDatePicker *datePicker() const;
+
+ void setDate(const QDate &date);
+
+ /** @return Returns the bitwise result of the active items in the popup. */
+ int items() const
+ {
+ return mItems;
+ }
+
+Q_SIGNALS:
+
+ /**
+ This signal emits the new date (selected with datepicker or other
+ menu-items).
+ @param date changed date
+ */
+ void dateChanged(const QDate &date);
+
+protected Q_SLOTS:
+ void slotDateChanged(const QDate &date);
+
+ void slotToday();
+ void slotTomorrow();
+ void slotNextWeek();
+ void slotNextMonth();
+ void slotNoDate();
+
+private:
+ void buildMenu();
+
+ KDatePicker *mDatePicker;
+ Items mItems;
+ QDate mDate;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(KDatePickerPopup::Items)
+
+#endif
diff --git a/src/contact-editor/editor/personaleditor/personaleditorwidget.cpp b/src/contact-editor/editor/personaleditor/personaleditorwidget.cpp
new file mode 100644
index 0000000..924e34d
--- /dev/null
+++ b/src/contact-editor/editor/personaleditor/personaleditorwidget.cpp
@@ -0,0 +1,100 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "personaleditorwidget.h"
+#include "../utils/utils.h"
+
+#include <KLocalizedString>
+#include <KLineEdit>
+#include <QGridLayout>
+#include <QLabel>
+
+#include "dateeditwidget.h"
+
+#include <KContacts/Addressee>
+
+using namespace Akonadi;
+
+PersonalEditorWidget::PersonalEditorWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ QGridLayout *mainLayout = new QGridLayout(this);
+ QLabel *label = new QLabel(i18nc("@label The birthdate of a contact", "Birthdate:"));
+ mainLayout->addWidget(label, 0, 0);
+
+ mBirthdateWidget = new DateEditWidget(DateEditWidget::Birthday);
+ label->setBuddy(mBirthdateWidget);
+ mainLayout->addWidget(mBirthdateWidget, 1, 0);
+
+ label = new QLabel(i18nc("@label The wedding anniversary of a contact", "Anniversary:"));
+ mainLayout->addWidget(label, 0, 1);
+
+ mAnniversaryWidget = new DateEditWidget(DateEditWidget::Anniversary);
+ label->setBuddy(mAnniversaryWidget);
+ mainLayout->addWidget(mAnniversaryWidget, 1, 1);
+
+ label = new QLabel(i18nc("@label The partner's name of a contact", "Partner's name:"));
+ mainLayout->addWidget(label, 0, 2);
+
+ mPartnerWidget = new KLineEdit;
+ mPartnerWidget->setPlaceholderText(i18n("Add name"));
+ mPartnerWidget->setTrapReturnKey(true);
+ label->setBuddy(mPartnerWidget);
+ mainLayout->addWidget(mPartnerWidget, 1, 2);
+ mainLayout->setColumnStretch(1, 1);
+ mainLayout->setColumnStretch(0, 1);
+ mainLayout->setColumnStretch(2, 1);
+
+ mainLayout->setRowStretch(2, 1);
+}
+
+PersonalEditorWidget::~PersonalEditorWidget()
+{
+
+}
+
+void PersonalEditorWidget::loadContact(const KContacts::Addressee &contact)
+{
+ mBirthdateWidget->setDate(contact.birthday().date());
+ mAnniversaryWidget->setDate(QDate::fromString(Akonadi::Utils::loadCustom(contact, QStringLiteral("X-Anniversary")),
+ Qt::ISODate));
+ // family group
+ mPartnerWidget->setText(Akonadi::Utils::loadCustom(contact, QStringLiteral("X-SpousesName")));
+}
+
+void PersonalEditorWidget::storeContact(KContacts::Addressee &contact)
+{
+ contact.setBirthday(mBirthdateWidget->date());
+ Akonadi::Utils::storeCustom(contact, QStringLiteral("X-Anniversary"), mAnniversaryWidget->date().toString(Qt::ISODate));
+
+ // family group
+ Akonadi::Utils::storeCustom(contact, QStringLiteral("X-SpousesName"), mPartnerWidget->text().trimmed());
+}
+
+void PersonalEditorWidget::setReadOnly(bool readOnly)
+{
+ // widgets from dates group
+ mBirthdateWidget->setReadOnly(readOnly);
+ mAnniversaryWidget->setReadOnly(readOnly);
+
+ // widgets from family group
+ mPartnerWidget->setReadOnly(readOnly);
+}
diff --git a/src/contact-editor/editor/personaleditor/personaleditorwidget.h b/src/contact-editor/editor/personaleditor/personaleditorwidget.h
new file mode 100644
index 0000000..ea1ac8a
--- /dev/null
+++ b/src/contact-editor/editor/personaleditor/personaleditorwidget.h
@@ -0,0 +1,50 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 PERSONALEDITORWIDGET_H
+#define PERSONALEDITORWIDGET_H
+
+#include <QWidget>
+class DateEditWidget;
+class KLineEdit;
+namespace KContacts
+{
+class Addressee;
+}
+
+namespace Akonadi
+{
+class PersonalEditorWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit PersonalEditorWidget(QWidget *parent = nullptr);
+ ~PersonalEditorWidget();
+ void loadContact(const KContacts::Addressee &contact);
+ void storeContact(KContacts::Addressee &contact);
+ void setReadOnly(bool readOnly);
+private:
+ DateEditWidget *mBirthdateWidget;
+ DateEditWidget *mAnniversaryWidget;
+ KLineEdit *mPartnerWidget;
+};
+}
+#endif // PERSONALEDITORWIDGET_H
diff --git a/src/contact-editor/editor/pics/world.jpg b/src/contact-editor/editor/pics/world.jpg
new file mode 100644
index 0000000..1447b3d
--- /dev/null
+++ b/src/contact-editor/editor/pics/world.jpg
Binary files differ
diff --git a/src/contact-editor/editor/utils/utils.cpp b/src/contact-editor/editor/utils/utils.cpp
new file mode 100644
index 0000000..6973750
--- /dev/null
+++ b/src/contact-editor/editor/utils/utils.cpp
@@ -0,0 +1,53 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "utils.h"
+
+#include <KContacts/Addressee>
+
+void Akonadi::Utils::splitCustomField(const QString &str, QString &app, QString &name, QString &value)
+{
+ const int colon = str.indexOf(QLatin1Char(':'));
+ if (colon != -1) {
+ const QString tmp = str.left(colon);
+ value = str.mid(colon + 1);
+
+ const int dash = tmp.indexOf(QLatin1Char('-'));
+ if (dash != -1) {
+ app = tmp.left(dash);
+ name = tmp.mid(dash + 1);
+ }
+ }
+}
+
+QString Akonadi::Utils::loadCustom(const KContacts::Addressee &contact, const QString &key)
+{
+ return contact.custom(QStringLiteral("KADDRESSBOOK"), key);
+}
+
+void Akonadi::Utils::storeCustom(KContacts::Addressee &contact, const QString &key, const QString &value)
+{
+ if (value.isEmpty()) {
+ contact.removeCustom(QStringLiteral("KADDRESSBOOK"), key);
+ } else {
+ contact.insertCustom(QStringLiteral("KADDRESSBOOK"), key, value);
+ }
+}
diff --git a/src/contact-editor/editor/utils/utils.h b/src/contact-editor/editor/utils/utils.h
new file mode 100644
index 0000000..4bbbecd
--- /dev/null
+++ b/src/contact-editor/editor/utils/utils.h
@@ -0,0 +1,40 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016-2017 Laurent Montel <mon[email protected]>
+
+ 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 UTILS_H
+#define UTILS_H
+
+#include <QString>
+namespace KContacts
+{
+class Addressee;
+}
+
+namespace Akonadi
+{
+namespace Utils
+{
+void splitCustomField(const QString &str, QString &app, QString &name, QString &value);
+QString loadCustom(const KContacts::Addressee &contact, const QString &key);
+void storeCustom(KContacts::Addressee &contact, const QString &key, const QString &value);
+}
+}
+#endif // UTILS_H
diff --git a/src/contact-editor/editor/widgets/akonadicontactcombobox.cpp b/src/contact-editor/editor/widgets/akonadicontactcombobox.cpp
new file mode 100644
index 0000000..ca64876
--- /dev/null
+++ b/src/contact-editor/editor/widgets/akonadicontactcombobox.cpp
@@ -0,0 +1,40 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "akonadicontactcombobox.h"
+
+using namespace Akonadi;
+
+AkonadiContactComboBox::AkonadiContactComboBox(QWidget *parent)
+ : QComboBox(parent)
+{
+ setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLength);
+}
+
+AkonadiContactComboBox::~AkonadiContactComboBox()
+{
+
+}
+
+QSize AkonadiContactComboBox::minimumSizeHint() const
+{
+ return QSize(150, QComboBox::minimumSizeHint().height());
+}
diff --git a/src/contact-editor/editor/widgets/akonadicontactcombobox.h b/src/contact-editor/editor/widgets/akonadicontactcombobox.h
new file mode 100644
index 0000000..6b36488
--- /dev/null
+++ b/src/contact-editor/editor/widgets/akonadicontactcombobox.h
@@ -0,0 +1,40 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 AKONADICONTACTCOMBOBOX_H
+#define AKONADICONTACTCOMBOBOX_H
+
+#include <QComboBox>
+#include "contacteditor_private_export.h"
+namespace Akonadi
+{
+class AKONADI_CONTACTS_TESTS_EXPORT AkonadiContactComboBox : public QComboBox
+{
+ Q_OBJECT
+public:
+ explicit AkonadiContactComboBox(QWidget *parent = nullptr);
+ ~AkonadiContactComboBox();
+
+protected:
+ QSize minimumSizeHint() const override;
+};
+}
+#endif // AKONADICONTACTCOMBOBOX_H
diff --git a/src/contact-editor/editor/widgets/autotests/CMakeLists.txt b/src/contact-editor/editor/widgets/autotests/CMakeLists.txt
new file mode 100644
index 0000000..043d676
--- /dev/null
+++ b/src/contact-editor/editor/widgets/autotests/CMakeLists.txt
@@ -0,0 +1,5 @@
+set( preferredlineeditwidgettest_SRCS preferredlineeditwidgettest.cpp ../preferredlineeditwidget.cpp)
+add_executable( preferredlineeditwidgettest ${preferredlineeditwidgettest_SRCS})
+add_test(preferredlineeditwidgettest preferredlineeditwidgettest)
+ecm_mark_as_test(preferredlineeditwidgettest)
+target_link_libraries( preferredlineeditwidgettest Qt5::Test Qt5::Widgets KF5::Completion KF5::IconThemes KF5::I18n)
diff --git a/src/contact-editor/editor/widgets/autotests/preferredlineeditwidgettest.cpp b/src/contact-editor/editor/widgets/autotests/preferredlineeditwidgettest.cpp
new file mode 100644
index 0000000..f105520
--- /dev/null
+++ b/src/contact-editor/editor/widgets/autotests/preferredlineeditwidgettest.cpp
@@ -0,0 +1,64 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "preferredlineeditwidgettest.h"
+#include "../preferredlineeditwidget.h"
+#include <QAction>
+#include <QIcon>
+#include <QTest>
+
+PreferredLineEditWidget::PreferredLineEditWidget(QObject *parent)
+ : QObject(parent)
+{
+
+}
+
+PreferredLineEditWidget::~PreferredLineEditWidget()
+{
+
+}
+
+void PreferredLineEditWidget::shouldHaveDefaultValue()
+{
+ Akonadi::PreferredLineEditWidget w;
+ QAction *act = w.findChild<QAction *>(QStringLiteral("preferredaction"));
+ QVERIFY(act);
+ QVERIFY(!w.preferred());
+}
+
+void PreferredLineEditWidget::shouldChangePreferredValue()
+{
+ Akonadi::PreferredLineEditWidget w;
+ QAction *act = w.findChild<QAction *>(QStringLiteral("preferredaction"));
+ QIcon disabled = act->icon();
+ w.setPreferred(true);
+ QVERIFY(w.preferred());
+ QIcon enabled = act->icon();
+ w.setPreferred(false);
+ QVERIFY(!w.preferred());
+ QCOMPARE(act->icon(), disabled);
+
+ w.setPreferred(true);
+ QCOMPARE(act->icon(), enabled);
+
+}
+
+QTEST_MAIN(PreferredLineEditWidget)
diff --git a/src/contact-editor/editor/widgets/autotests/preferredlineeditwidgettest.h b/src/contact-editor/editor/widgets/autotests/preferredlineeditwidgettest.h
new file mode 100644
index 0000000..e854952
--- /dev/null
+++ b/src/contact-editor/editor/widgets/autotests/preferredlineeditwidgettest.h
@@ -0,0 +1,39 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 PreferredLineEditWidget_H
+#define PreferredLineEditWidget_H
+
+#include <QObject>
+
+class PreferredLineEditWidget : public QObject
+{
+ Q_OBJECT
+public:
+ explicit PreferredLineEditWidget(QObject *parent = nullptr);
+ ~PreferredLineEditWidget();
+
+private Q_SLOTS:
+ void shouldHaveDefaultValue();
+ void shouldChangePreferredValue();
+};
+
+#endif // PreferredLineEditWidget_H
diff --git a/src/contact-editor/editor/widgets/imagewidget.cpp b/src/contact-editor/editor/widgets/imagewidget.cpp
new file mode 100644
index 0000000..8a5514d
--- /dev/null
+++ b/src/contact-editor/editor/widgets/imagewidget.cpp
@@ -0,0 +1,356 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (c) 2009 Tobias Koenig <[email protected]>
+
+ 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 "imagewidget.h"
+
+#include <kcontacts/addressee.h>
+
+#include <KLocalizedString>
+#include <KMessageBox>
+#include <kpixmapregionselectordialog.h>
+#include <KUrlMimeData>
+#include <KIO/TransferJob>
+#include <QImageReader>
+#include <QFileDialog>
+#include <QMimeData>
+#include <QDrag>
+#include <QImageWriter>
+#include <QDragEnterEvent>
+#include <QDropEvent>
+#include <QMenu>
+#include <QApplication>
+#include <QUrl>
+#include <QInputDialog>
+/**
+ * @short Small helper class to load image from network
+ */
+class ImageLoader
+{
+public:
+ ImageLoader(QWidget *parent = nullptr);
+
+ QImage loadImage(const QUrl &url, bool *ok, bool selectPictureSize = true);
+
+private:
+ QWidget *mParent;
+};
+
+ImageLoader::ImageLoader(QWidget *parent)
+ : mParent(parent)
+{
+}
+
+QImage ImageLoader::loadImage(const QUrl &url, bool *ok, bool selectPictureSize)
+{
+ QImage image;
+
+ if (url.isEmpty()) {
+ return image;
+ }
+
+ (*ok) = false;
+
+ if (url.isLocalFile()) {
+ if (image.load(url.toLocalFile())) {
+ (*ok) = true;
+ }
+ } else {
+ QByteArray imageData;
+ KIO::TransferJob *job = KIO::get(url, KIO::NoReload);
+ QObject::connect(job, &KIO::TransferJob::data,
+ [&imageData](KIO::Job *, const QByteArray & data) {
+ imageData.append(data);
+ });
+ if (job->exec()) {
+ if (image.loadFromData(imageData)) {
+ (*ok) = true;
+ }
+ }
+ }
+
+ if (!(*ok)) {
+ // image does not exist (any more)
+ KMessageBox::sorry(mParent, i18n("This contact's image cannot be found."));
+ return image;
+ }
+
+ if (selectPictureSize) {
+ QPixmap pixmap = QPixmap::fromImage(image);
+ image = KPixmapRegionSelectorDialog::getSelectedImage(pixmap, 1, 1, mParent);
+ if (image.isNull()) {
+ (*ok) = false;
+ return image;
+ }
+ }
+
+ if (image.height() > 720 || image.width() > 720) {
+ if (image.height() > image.width()) {
+ image = image.scaledToHeight(720);
+ } else {
+ image = image.scaledToWidth(720);
+ }
+ }
+
+ (*ok) = true;
+
+ return image;
+}
+
+ImageWidget::ImageWidget(Type type, QWidget *parent)
+ : QPushButton(parent)
+ , mImageLoader(nullptr)
+ , mType(type)
+ , mHasImage(false)
+ , mReadOnly(false)
+{
+ setAcceptDrops(true);
+
+ setIconSize(QSize(100, 100));
+ setFixedSize(QSize(120, 120));
+
+ connect(this, &ImageWidget::clicked, this, &ImageWidget::changeImage);
+
+ if (mType == Photo) {
+ setToolTip(i18n("The photo of the contact (click to change)"));
+ } else {
+ setToolTip(i18n("The logo of the company (click to change)"));
+ }
+
+ updateView();
+}
+
+ImageWidget::~ImageWidget()
+{
+ delete mImageLoader;
+}
+
+void ImageWidget::loadContact(const KContacts::Addressee &contact)
+{
+ mPicture = (mType == Photo ? contact.photo() : contact.logo());
+ if (mPicture.isIntern() && !mPicture.data().isNull()) {
+ mHasImage = true;
+ } else if (!mPicture.isIntern() && !mPicture.url().isEmpty()) {
+ mHasImage = true;
+ }
+
+ updateView();
+}
+
+void ImageWidget::storeContact(KContacts::Addressee &contact) const
+{
+ if (mType == Photo) {
+ contact.setPhoto(mPicture);
+ } else {
+ contact.setLogo(mPicture);
+ }
+}
+
+void ImageWidget::setReadOnly(bool readOnly)
+{
+ mReadOnly = readOnly;
+}
+
+void ImageWidget::updateView()
+{
+ if (mHasImage) {
+ if (mPicture.isIntern()) {
+ setIcon(QPixmap::fromImage(mPicture.data()));
+ } else {
+ bool ok = false;
+ const QPixmap pix = QPixmap::fromImage(imageLoader()->loadImage(QUrl(mPicture.url()), &ok, false));
+ if (ok) {
+ setIcon(pix);
+ }
+ }
+ } else {
+ if (mType == Photo) {
+ setIcon(QIcon::fromTheme(QStringLiteral("user-identity")));
+ } else {
+ setIcon(QIcon::fromTheme(QStringLiteral("image-x-generic")));
+ }
+ }
+}
+
+void ImageWidget::dragEnterEvent(QDragEnterEvent *event)
+{
+ const QMimeData *mimeData = event->mimeData();
+ event->setAccepted(mimeData->hasImage() || mimeData->hasUrls());
+}
+
+void ImageWidget::dropEvent(QDropEvent *event)
+{
+ if (mReadOnly) {
+ return;
+ }
+
+ const QMimeData *mimeData = event->mimeData();
+ if (mimeData->hasImage()) {
+ mPicture.setData(qvariant_cast<QImage>(mimeData->imageData()));
+ mHasImage = true;
+ updateView();
+ }
+
+ const QList<QUrl> urls = KUrlMimeData::urlsFromMimeData(mimeData);
+ if (urls.isEmpty()) { // oops, no data
+ event->setAccepted(false);
+ } else {
+ bool ok = false;
+ const QImage image = imageLoader()->loadImage(urls.first(), &ok);
+ if (ok) {
+ mPicture.setData(image);
+ mHasImage = true;
+ updateView();
+ }
+ }
+}
+
+void ImageWidget::mousePressEvent(QMouseEvent *event)
+{
+ mDragStartPos = event->pos();
+ QPushButton::mousePressEvent(event);
+}
+
+void ImageWidget::mouseMoveEvent(QMouseEvent *event)
+{
+ if ((event->buttons() & Qt::LeftButton) &&
+ (event->pos() - mDragStartPos).manhattanLength() > QApplication::startDragDistance()) {
+
+ if (mHasImage) {
+ QDrag *drag = new QDrag(this);
+ drag->setMimeData(new QMimeData());
+ drag->mimeData()->setImageData(mPicture.data());
+ drag->start();
+ }
+ }
+}
+
+void ImageWidget::contextMenuEvent(QContextMenuEvent *event)
+{
+ QMenu menu;
+
+ if (mType == Photo) {
+ if (!mReadOnly) {
+ menu.addAction(i18n("Change photo..."), this, &ImageWidget::changeImage);
+ menu.addAction(i18n("Change URL..."), this, &ImageWidget::changeUrl);
+ }
+
+ if (mHasImage) {
+ menu.addAction(i18n("Save photo..."), this, &ImageWidget::saveImage);
+
+ if (!mReadOnly) {
+ menu.addAction(i18n("Remove photo"), this, &ImageWidget::deleteImage);
+ }
+ }
+ } else {
+ if (!mReadOnly) {
+ menu.addAction(i18n("Change logo..."), this, &ImageWidget::changeImage);
+ menu.addAction(i18n("Change URL..."), this, &ImageWidget::changeUrl);
+ }
+
+ if (mHasImage) {
+ menu.addAction(i18n("Save logo..."), this, &ImageWidget::saveImage);
+
+ if (!mReadOnly) {
+ menu.addAction(i18n("Remove logo"), this, &ImageWidget::deleteImage);
+ }
+ }
+ }
+
+ menu.exec(event->globalPos());
+}
+
+void ImageWidget::changeUrl()
+{
+ if (mReadOnly) {
+ return;
+ }
+ const QString path = QInputDialog::getText(this, i18n("Change image URL"), i18n("Image URL:"), QLineEdit::Normal, mPicture.url());
+ if (!path.isEmpty()) {
+ bool ok;
+ const QImage image = imageLoader()->loadImage(QUrl(path), &ok, false);
+ if (ok && !image.isNull()) {
+ mPicture.setUrl(path);
+ mHasImage = true;
+ updateView();
+ }
+ }
+}
+
+void ImageWidget::changeImage()
+{
+ if (mReadOnly) {
+ return;
+ }
+
+ const QList<QByteArray> supportedImage = QImageReader::supportedImageFormats();
+ QString filter;
+ for (const QByteArray &ba : supportedImage) {
+ if (!filter.isEmpty()) {
+ filter += QLatin1Char(' ');
+ }
+ filter += QLatin1String("*.") + QString::fromLatin1(ba);
+ }
+
+ const QUrl url = QFileDialog::getOpenFileUrl(this, QString(), QUrl(), i18n("Images (%1)", filter));
+ if (url.isValid()) {
+ bool ok = false;
+ const QImage image = imageLoader()->loadImage(url, &ok);
+ if (ok) {
+ mPicture.setData(image);
+ mHasImage = true;
+ updateView();
+ }
+ }
+}
+
+void ImageWidget::saveImage()
+{
+ const QList<QByteArray> supportedImage = QImageWriter::supportedImageFormats();
+ QString filter;
+ for (const QByteArray &ba : supportedImage) {
+ if (!filter.isEmpty()) {
+ filter += QLatin1Char(' ');
+ }
+ filter += QLatin1String("*.") + QString::fromLatin1(ba);
+ }
+
+ const QString fileName = QFileDialog::getSaveFileName(this, QString(), QString(), i18n("Images (%1)", filter));
+ if (!fileName.isEmpty()) {
+ mPicture.data().save(fileName);
+ }
+}
+
+void ImageWidget::deleteImage()
+{
+ mHasImage = false;
+ mPicture.setData(QImage());
+ mPicture.setUrl(QString());
+ updateView();
+}
+
+ImageLoader *ImageWidget::imageLoader()
+{
+ if (!mImageLoader) {
+ mImageLoader = new ImageLoader;
+ }
+
+ return mImageLoader;
+}
diff --git a/src/contact-editor/editor/widgets/imagewidget.h b/src/contact-editor/editor/widgets/imagewidget.h
new file mode 100644
index 0000000..8f9b142
--- /dev/null
+++ b/src/contact-editor/editor/widgets/imagewidget.h
@@ -0,0 +1,84 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (c) 2009 Tobias Koenig <[email protected]>
+
+ 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 IMAGEWIDGET_H
+#define IMAGEWIDGET_H
+
+#include <kcontacts/picture.h>
+
+#include <QPoint>
+#include <QPushButton>
+
+namespace KContacts
+{
+class Addressee;
+}
+
+class ImageLoader;
+
+class ImageWidget : public QPushButton
+{
+ Q_OBJECT
+
+public:
+ enum Type {
+ Photo,
+ Logo
+ };
+
+ explicit ImageWidget(Type type, QWidget *parent = nullptr);
+ ~ImageWidget();
+
+ void loadContact(const KContacts::Addressee &contact);
+ void storeContact(KContacts::Addressee &contact) const;
+
+ void setReadOnly(bool readOnly);
+
+protected:
+ // image drop handling
+ void dragEnterEvent(QDragEnterEvent *event) override;
+ void dropEvent(QDropEvent *event) override;
+
+ // image drag handling
+ void mousePressEvent(QMouseEvent *event) override;
+ void mouseMoveEvent(QMouseEvent *event) override;
+
+ // context menu handling
+ void contextMenuEvent(QContextMenuEvent *event) override;
+
+private:
+ void updateView();
+
+ void changeImage();
+ void changeUrl();
+ void saveImage();
+ void deleteImage();
+ ImageLoader *imageLoader();
+
+ KContacts::Picture mPicture;
+ QPoint mDragStartPos;
+ ImageLoader *mImageLoader;
+ Type mType;
+ bool mHasImage;
+ bool mReadOnly;
+};
+
+#endif
diff --git a/src/contact-editor/editor/widgets/kwidgetlister.cpp b/src/contact-editor/editor/widgets/kwidgetlister.cpp
new file mode 100644
index 0000000..21921e7
--- /dev/null
+++ b/src/contact-editor/editor/widgets/kwidgetlister.cpp
@@ -0,0 +1,225 @@
+/* -*- c++ -*-
+
+ kwidgetlister.cpp
+
+ This file is part of libkdepim.
+ Copyright (c) 2001 Marc Mutz <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this library with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "kwidgetlister_p.h"
+
+#include <QHBoxLayout>
+
+#include <QPushButton>
+#include <QVBoxLayout>
+
+#include <assert.h>
+
+class Q_DECL_HIDDEN KWidgetLister::Private
+{
+public:
+ Private(KWidgetLister *qq)
+ : q(qq),
+ mLayout(nullptr),
+ mButtonBox(nullptr),
+ mMinWidgets(0),
+ mMaxWidgets(0)
+
+ {
+ }
+
+ ~Private()
+ {
+ qDeleteAll(mWidgetList);
+ mWidgetList.clear();
+ }
+
+ KWidgetLister *q;
+ QVBoxLayout *mLayout;
+ QWidget *mButtonBox;
+ QList<QWidget *> mWidgetList;
+ int mMinWidgets;
+ int mMaxWidgets;
+};
+
+KWidgetLister::KWidgetLister(int minWidgets, int maxWidgets, QWidget *parent)
+ : QWidget(parent), d(new Private(this))
+{
+ d->mMinWidgets = qMax(minWidgets, 1);
+ d->mMaxWidgets = qMax(maxWidgets, d->mMinWidgets + 1);
+ init();
+}
+
+KWidgetLister::~KWidgetLister()
+{
+ delete d;
+}
+
+void KWidgetLister::init()
+{
+ //--------- the button box
+ d->mLayout = new QVBoxLayout(this);
+ d->mLayout->setMargin(0);
+ d->mLayout->setSpacing(4);
+
+ d->mButtonBox = new QWidget(this);
+ QHBoxLayout *mButtonBoxHBoxLayout = new QHBoxLayout(d->mButtonBox);
+ mButtonBoxHBoxLayout->setMargin(0);
+ d->mLayout->addWidget(d->mButtonBox);
+ d->mLayout->addStretch(1);
+}
+
+void KWidgetLister::slotMore()
+{
+ // the class should make certain that slotMore can't
+ // be called when mMaxWidgets are on screen.
+ assert((int)d->mWidgetList.count() < d->mMaxWidgets);
+
+ addWidgetAtEnd();
+}
+
+void KWidgetLister::slotFewer()
+{
+ // the class should make certain that slotFewer can't
+ // be called when mMinWidgets are on screen.
+ assert((int)d->mWidgetList.count() > d->mMinWidgets);
+
+ removeLastWidget();
+}
+
+void KWidgetLister::slotClear()
+{
+ setNumberOfShownWidgetsTo(d->mMinWidgets);
+
+ // clear remaining widgets
+ for (QWidget *widget : qAsConst(d->mWidgetList)) {
+ clearWidget(widget);
+ }
+
+ Q_EMIT clearWidgets();
+}
+
+void KWidgetLister::addWidgetAtEnd(QWidget *widget)
+{
+ if (!widget) {
+ widget = this->createWidget(this);
+ }
+
+ d->mLayout->insertWidget(d->mLayout->indexOf(d->mButtonBox), widget);
+ d->mWidgetList.append(widget);
+ widget->show();
+ Q_EMIT widgetAdded();
+ Q_EMIT widgetAdded(widget);
+}
+
+void KWidgetLister::removeLastWidget()
+{
+ // The layout will take care that the
+ // widget is removed from screen, too.
+ delete d->mWidgetList.takeLast();
+ Q_EMIT widgetRemoved();
+}
+
+void KWidgetLister::clearWidget(QWidget *widget)
+{
+ Q_UNUSED(widget);
+}
+
+QWidget *KWidgetLister::createWidget(QWidget *parent)
+{
+ return new QWidget(parent);
+}
+
+void KWidgetLister::setNumberOfShownWidgetsTo(int aNum)
+{
+ int superfluousWidgets = qMax((int)d->mWidgetList.count() - aNum, 0);
+ int missingWidgets = qMax(aNum - (int)d->mWidgetList.count(), 0);
+
+ // remove superfluous widgets
+ for (; superfluousWidgets; superfluousWidgets--) {
+ removeLastWidget();
+ }
+
+ // add missing widgets
+ for (; missingWidgets; missingWidgets--) {
+ addWidgetAtEnd();
+ }
+}
+
+QList<QWidget *> KWidgetLister::widgets() const
+{
+ return d->mWidgetList;
+}
+
+int KWidgetLister::widgetsMinimum() const
+{
+ return d->mMinWidgets;
+}
+
+int KWidgetLister::widgetsMaximum() const
+{
+ return d->mMaxWidgets;
+}
+
+void KWidgetLister::removeWidget(QWidget *widget)
+{
+ // The layout will take care that the
+ // widget is removed from screen, too.
+
+ if (d->mWidgetList.count() <= widgetsMinimum()) {
+ return;
+ }
+
+ const int index = d->mWidgetList.indexOf(widget);
+ QWidget *w = d->mWidgetList.takeAt(index);
+ w->deleteLater();
+ w = nullptr;
+ Q_EMIT widgetRemoved(widget);
+ Q_EMIT widgetRemoved();
+
+}
+
+void KWidgetLister::addWidgetAfterThisWidget(QWidget *currentWidget, QWidget *widget)
+{
+ if (!widget) {
+ widget = this->createWidget(this);
+ }
+
+ int index = d->mLayout->indexOf(currentWidget ? currentWidget : d->mButtonBox) + 1;
+ d->mLayout->insertWidget(index, widget);
+ if (currentWidget) {
+ index = d->mWidgetList.indexOf(currentWidget);
+ d->mWidgetList.insert(index + 1, widget);
+ } else {
+ d->mWidgetList.append(widget);
+ }
+ widget->show();
+
+ Q_EMIT widgetAdded();
+ Q_EMIT widgetAdded(widget);
+}
+
diff --git a/src/contact-editor/editor/widgets/kwidgetlister_p.h b/src/contact-editor/editor/widgets/kwidgetlister_p.h
new file mode 100644
index 0000000..91290bb
--- /dev/null
+++ b/src/contact-editor/editor/widgets/kwidgetlister_p.h
@@ -0,0 +1,212 @@
+/* -*- c++ -*-
+
+ kwidgetlister.h
+
+ This file is part of libkdepim
+ Copyright (c) 2001 Marc Mutz <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this library with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef AKONADICONTACT_KWIDGETLISTER_H
+#define AKONADICONTACT_KWIDGETLISTER_H
+
+#include <QWidget>
+
+/**
+ @short Widget that manages a list of other widgets (incl. 'more', 'fewer' and 'clear' buttons).
+
+ Simple widget that nonetheless does a lot of the dirty work for
+ the filter edit widgets (KMSearchPatternEdit and
+ KMFilterActionEdit). It provides a growable and shrinkable area
+ where widget may be displayed in rows. Widgets can be added by
+ hitting the provided 'More' button, removed by the 'Fewer' button
+ and cleared (e.g. reset, if an derived class implements that and
+ removed for all but @ref mMinWidgets).
+
+ To use this widget, derive from it with the template changed to
+ the type of widgets this class should list. Then reimplement @ref
+ addWidgetAtEnd, @ref removeLastWidget, calling the original
+ implementation as necessary. Instantiate an object of the class and
+ put it in your dialog.
+
+ @author Marc Mutz <[email protected]>
+ @see KMSearchPatternEdit::WidgetLister KMFilterActionEdit::WidgetLister
+
+*/
+
+class KWidgetLister : public QWidget
+{
+ Q_OBJECT
+
+public:
+ /**
+ * Creates a new widget lister.
+ * @param fewerMoreButton Add or Not fewerMoreButton
+ * @param minWidgets The minimum number of widgets to stay on the screen.
+ * @param maxWidgets The maximum number of widgets to stay on the screen.
+ * @param parent The parent widget.
+ */
+ explicit KWidgetLister(int minWidgets = 1, int maxWidgets = 8, QWidget *parent = nullptr);
+
+ /**
+ * Destroys the widget lister.
+ */
+ virtual ~KWidgetLister();
+
+protected Q_SLOTS:
+ /**
+ * Called whenever the user clicks on the 'more' button.
+ * Reimplementations should call this method, because this
+ * implementation does all the dirty work with adding the widgets
+ * to the layout (through @ref addWidgetAtEnd) and enabling/disabling
+ * the control buttons.
+ */
+ virtual void slotMore();
+
+ /**
+ * Called whenever the user clicks on the 'fewer' button.
+ * Reimplementations should call this method, because this
+ * implementation does all the dirty work with removing the widgets
+ * from the layout (through @ref removeLastWidget) and
+ * enabling/disabling the control buttons.
+ */
+ virtual void slotFewer();
+
+ /**
+ * Called whenever the user clicks on the 'clear' button.
+ * Reimplementations should call this method, because this
+ * implementation does all the dirty work with removing all but
+ * @ref mMinWidgets widgets from the layout and enabling/disabling
+ * the control buttons.
+ */
+ virtual void slotClear();
+
+protected:
+ /**
+ * Adds a single widget. Doesn't care if there are already @ref
+ * mMaxWidgets on screen and whether it should enable/disable any
+ * controls. It simply does what it is asked to do. You want to
+ * reimplement this method if you want to initialize the widget
+ * when showing it on screen. Make sure you call this
+ * implementaion, though, since you cannot put the widget on screen
+ * from derived classes (@p mLayout is private).
+ * Make sure the parent of the QWidget to add is this KWidgetLister.
+ */
+ virtual void addWidgetAtEnd(QWidget *widget = nullptr);
+
+ /**
+ * Removes a single (always the last) widget. Doesn't care if there
+ * are still only @ref mMinWidgets left on screen and whether it
+ * should enable/disable any controls. It simply does what it is
+ * asked to do. You want to reimplement this method if you want to
+ * save the widget's state before removing it from screen. Make
+ * sure you call this implementaion, though, since you should not
+ * remove the widget from screen from derived classes.
+ */
+ virtual void removeLastWidget();
+
+ /**
+ * Called to clear a given widget. The default implementation does
+ * nothing.
+ */
+ virtual void clearWidget(QWidget *w);
+
+ /**
+ * Returns a new widget that shall be added to the lister.
+ *
+ * @param parent The parent widget of the new widget.
+ */
+ virtual QWidget *createWidget(QWidget *parent);
+
+ /**
+ * Sets the number of widgets on scrren to exactly @p count. Doesn't
+ * check if @p count is inside the range @p [mMinWidgets,mMaxWidgets].
+ */
+ virtual void setNumberOfShownWidgetsTo(int count);
+
+ /**
+ * Returns the list of widgets.
+ */
+ QList<QWidget *> widgets() const;
+
+ /**
+ * The minimum number of widgets that are to stay on screen.
+ */
+ int widgetsMinimum() const;
+
+ /**
+ * The maximum number of widgets that are to be shown on screen.
+ */
+ int widgetsMaximum() const;
+
+ /**
+ * Remove specific widget
+ */
+ virtual void removeWidget(QWidget *widget);
+ /**
+ * Add widget after specific widget
+ */
+ virtual void addWidgetAfterThisWidget(QWidget *currentWidget, QWidget *widget = nullptr);
+
+private:
+ void init();
+
+Q_SIGNALS:
+ /**
+ * This signal is emitted whenever a widget was added.
+ */
+ void widgetAdded();
+
+ /**
+ * This signal is emitted whenever a widget was added.
+ *
+ * @param widget The added widget.
+ */
+ void widgetAdded(QWidget *widget);
+
+ /**
+ * This signal is emitted whenever a widget was removed.
+ */
+ void widgetRemoved();
+
+ /**
+ * This signal is emitted whenever a widget was removed.
+ */
+ void widgetRemoved(QWidget *widget);
+
+ /**
+ * This signal is emitted whenever the clear button is clicked.
+ */
+ void clearWidgets();
+
+private:
+ //@cond PRIVATE
+ class Private;
+ Private *const d;
+ //@endcond
+};
+
+#endif /* _KWIDGETLISTER_H_ */
diff --git a/src/contact-editor/editor/widgets/preferredlineeditwidget.cpp b/src/contact-editor/editor/widgets/preferredlineeditwidget.cpp
new file mode 100644
index 0000000..247cdbc
--- /dev/null
+++ b/src/contact-editor/editor/widgets/preferredlineeditwidget.cpp
@@ -0,0 +1,74 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 "preferredlineeditwidget.h"
+#include <KIconLoader>
+#include <KIconEffect>
+#include <KLocalizedString>
+#include <QAction>
+
+using namespace Akonadi;
+
+PreferredLineEditWidget::PreferredLineEditWidget(QWidget *parent)
+ : KLineEdit(parent),
+ mPreferred(false)
+{
+ mIconEnabled = QIcon(QIcon::fromTheme(QStringLiteral("rating")));
+ KIconLoader loader;
+ QImage iconDisabled =
+ mIconEnabled.pixmap(loader.currentSize(KIconLoader::Panel)).toImage();
+ KIconEffect::toGray(iconDisabled, 1.0);
+ mIconDisabled = QIcon(QPixmap::fromImage(iconDisabled));
+ mPreferredAction = addAction(mIconDisabled, QLineEdit::TrailingPosition);
+ mPreferredAction->setObjectName(QStringLiteral("preferredaction"));
+ mPreferredAction->setToolTip(i18n("Set as Preferred"));
+ connect(mPreferredAction, &QAction::triggered, this, &PreferredLineEditWidget::slotPreferredStatusChanged);
+}
+
+PreferredLineEditWidget::~PreferredLineEditWidget()
+{
+
+}
+
+void PreferredLineEditWidget::slotPreferredStatusChanged()
+{
+ mPreferred = !mPreferred;
+ updatePreferredIcon();
+ Q_EMIT preferredChanged(this);
+}
+
+void PreferredLineEditWidget::updatePreferredIcon()
+{
+ mPreferredAction->setIcon(mPreferred ? mIconEnabled : mIconDisabled);
+}
+
+void PreferredLineEditWidget::setPreferred(bool preferred)
+{
+ if (mPreferred != preferred) {
+ mPreferred = preferred;
+ updatePreferredIcon();
+ }
+}
+
+bool PreferredLineEditWidget::preferred() const
+{
+ return mPreferred;
+}
diff --git a/src/contact-editor/editor/widgets/preferredlineeditwidget.h b/src/contact-editor/editor/widgets/preferredlineeditwidget.h
new file mode 100644
index 0000000..5e053d6
--- /dev/null
+++ b/src/contact-editor/editor/widgets/preferredlineeditwidget.h
@@ -0,0 +1,55 @@
+/*
+ This file is part of Akonadi Contact.
+
+ Copyright (C) 2016-2017 Laurent Montel <[email protected]>
+
+ 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 PREFEREDLINEEDITWIDGET_H
+#define PREFEREDLINEEDITWIDGET_H
+
+#include <KLineEdit>
+#include <QIcon>
+class QAction;
+namespace Akonadi
+{
+class PreferredLineEditWidget : public KLineEdit
+{
+ Q_OBJECT
+public:
+ explicit PreferredLineEditWidget(QWidget *parent = nullptr);
+ ~PreferredLineEditWidget();
+
+ bool preferred() const;
+
+ void setPreferred(bool preferred);
+
+Q_SIGNALS:
+ void preferredChanged(QWidget *w);
+
+private Q_SLOTS:
+ void slotPreferredStatusChanged();
+
+private:
+ void updatePreferredIcon();
+ bool mPreferred;
+ QIcon mIconEnabled;
+ QIcon mIconDisabled;
+ QAction *mPreferredAction;
+};
+}
+#endif // PREFEREDLINEEDITWIDGET_H