diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b9818a01..bfc86be8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,132 +1,131 @@ set(vcardparser_SRCS vcardparser/vcard.cpp vcardparser/vcardline.cpp vcardparser/vcardparser.cpp ) set(kcontacts_SRCS address.cpp addressee.cpp addresseehelper.cpp - addresseelist.cpp calendarurl.cpp contactgroup.cpp contactgrouptool.cpp email.cpp field.cpp geo.cpp gender.cpp impp.cpp key.cpp lang.cpp ldapdn.cpp ldif.cpp phonenumber.cpp picture.cpp related.cpp resourcelocatorurl.cpp secrecy.cpp sortmode.cpp sound.cpp timezone.cpp vcarddrag.cpp vcardtool.cpp fieldgroup.cpp title.cpp nickname.cpp role.cpp note.cpp org.cpp clientpidmap.cpp ${vcardparser_SRCS} kcontacts.qrc ) set(kcontacts_converter_SRCS converter/vcardconverter.cpp converter/ldifconverter.cpp ) ecm_qt_declare_logging_category(kcontacts_converter_SRCS HEADER kcontacts_debug.h IDENTIFIER KCONTACTS_LOG CATEGORY_NAME org.kde.pim.kcontacts) add_library(KF5Contacts ${kcontacts_SRCS} ${kcontacts_converter_SRCS}) generate_export_header(KF5Contacts BASE_NAME kcontacts) add_library(KF5::Contacts ALIAS KF5Contacts) target_include_directories(KF5Contacts INTERFACE "$") target_include_directories(KF5Contacts PUBLIC "$") target_include_directories(KF5Contacts PUBLIC "$") target_link_libraries(KF5Contacts PUBLIC KF5::CoreAddons PRIVATE Qt5::Gui KF5::ConfigCore KF5::I18n KF5::Codecs # for the vcard parser ) set_target_properties(KF5Contacts PROPERTIES VERSION ${KContacts_VERSION_STRING} SOVERSION ${KContacts_SOVERSION} EXPORT_NAME Contacts ) install(TARGETS KF5Contacts EXPORT KF5ContactsTargets ${KF5_INSTALL_TARGETS_DEFAULT_ARGS}) ecm_generate_headers(KContacts_CamelCase_HEADERS HEADER_NAMES Address Addressee AddresseeList CalendarUrl ContactGroup ContactGroupTool Email Field Geo Gender Key Lang Impp PhoneNumber Picture Related ResourceLocatorUrl Secrecy SortMode Sound TimeZone Title Role Note Org NickName VCardDrag FieldGroup ClientPidMap PREFIX KContacts REQUIRED_HEADERS KContacts_HEADERS ) add_subdirectory(converter) add_subdirectory(generator) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/kcontacts_export.h ${KContacts_HEADERS} DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5}/KContacts/kcontacts COMPONENT Devel ) install(FILES ${KContacts_CamelCase_HEADERS} DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5}/KContacts/KContacts COMPONENT Devel ) ecm_generate_pri_file(BASE_NAME KContacts LIB_NAME KF5Contacts DEPS "CoreAddons" FILENAME_VAR PRI_FILENAME INCLUDE_INSTALL_DIR ${KDE_INSTALL_INCLUDEDIR_KF5}/KContacts) install(FILES ${PRI_FILENAME} DESTINATION ${ECM_MKSPECS_INSTALL_DIR}) diff --git a/src/addresseelist.cpp b/src/addresseelist.cpp deleted file mode 100644 index f8540000..00000000 --- a/src/addresseelist.cpp +++ /dev/null @@ -1,361 +0,0 @@ -/* - This file is part of the KContacts framework. - Copyright (c) 2002 Jost Schenck - 2003 Tobias Koenig - - 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 "addresseelist.h" -#include "field.h" -#include "sortmode.h" -#include "kcontacts_debug.h" - -#include - -using namespace KContacts; - -// -// -// Traits -// -// - -SortingTraits::Uid::Uid() - : d(nullptr) -{ -} - -SortingTraits::Uid::~Uid() -{ -} - -bool SortingTraits::Uid::eq(const Addressee &a1, const Addressee &a2) -{ - // locale awareness doesn't make sense sorting ids - return QString::compare(a1.uid(), a2.uid()) == 0; -} - -bool SortingTraits::Uid::lt(const Addressee &a1, const Addressee &a2) -{ - // locale awareness doesn't make sense sorting ids - return QString::compare(a1.uid(), a2.uid()) < 0; -} - -SortingTraits::Name::Name() - : d(nullptr) -{ -} - -SortingTraits::Name::~Name() -{ -} - -bool SortingTraits::Name::eq(const Addressee &a1, const Addressee &a2) -{ - return QString::localeAwareCompare(a1.name(), a2.name()) == 0; -} - -bool SortingTraits::Name::lt(const Addressee &a1, const Addressee &a2) -{ - return QString::localeAwareCompare(a1.name(), a2.name()) < 0; -} - -SortingTraits::FormattedName::FormattedName() - : d(nullptr) -{ -} - -SortingTraits::FormattedName::~FormattedName() -{ -} - -bool SortingTraits::FormattedName::eq(const Addressee &a1, const Addressee &a2) -{ - return QString::localeAwareCompare(a1.formattedName(), a2.formattedName()) == 0; -} - -bool SortingTraits::FormattedName::lt(const Addressee &a1, const Addressee &a2) -{ - return QString::localeAwareCompare(a1.formattedName(), a2.formattedName()) < 0; -} - -SortingTraits::FamilyName::FamilyName() - : d(nullptr) -{ -} - -SortingTraits::FamilyName::~FamilyName() -{ -} - -bool SortingTraits::FamilyName::eq(const Addressee &a1, const Addressee &a2) -{ - return - QString::localeAwareCompare(a1.familyName(), a2.familyName()) == 0 - && QString::localeAwareCompare(a1.givenName(), a2.givenName()) == 0; -} - -bool SortingTraits::FamilyName::lt(const Addressee &a1, const Addressee &a2) -{ - int family = QString::localeAwareCompare(a1.familyName(), a2.familyName()); - if (0 == family) { - return QString::localeAwareCompare(a1.givenName(), a2.givenName()) < 0; - } else { - return family < 0; - } -} - -SortingTraits::GivenName::GivenName() - : d(nullptr) -{ -} - -SortingTraits::GivenName::~GivenName() -{ -} - -bool SortingTraits::GivenName::eq(const Addressee &a1, const Addressee &a2) -{ - return - QString::localeAwareCompare(a1.givenName(), a2.givenName()) == 0 - && QString::localeAwareCompare(a1.familyName(), a2.familyName()) == 0; -} - -bool SortingTraits::GivenName::lt(const Addressee &a1, const Addressee &a2) -{ - int given = QString::localeAwareCompare(a1.givenName(), a2.givenName()); - if (0 == given) { - return QString::localeAwareCompare(a1.familyName(), a2.familyName()) < 0; - } else { - return given < 0; - } -} - -// -// -// AddresseeList -// -// - -static Field *sActiveField = nullptr; - -class Q_DECL_HIDDEN AddresseeList::Private : public QSharedData -{ -public: - Private() - : mActiveSortingCriterion(FormattedName) - , mReverseSorting(false) - { - } - - Private(const Private &other) - : QSharedData(other) - { - mReverseSorting = other.mReverseSorting; - mActiveSortingCriterion = other.mActiveSortingCriterion; - } - - SortingCriterion mActiveSortingCriterion; - bool mReverseSorting; -}; - -AddresseeList::AddresseeList() - : QVector() - , d(new Private) -{ -} - -AddresseeList::~AddresseeList() -{ -} - -AddresseeList::AddresseeList(const AddresseeList &other) - : QVector(other) - , d(other.d) -{ -} - -AddresseeList::AddresseeList(const QVector &list) - : QVector(list) - , d(new Private) -{ -} - -AddresseeList &AddresseeList::operator=(const AddresseeList &other) -{ - if (this != &other) { - QVector::operator=(other); - d = other.d; - } - - return *this; -} - -QString AddresseeList::toString() const -{ - QString str = QLatin1String("AddresseeList {\n"); - str += QStringLiteral(" Reverse Order: %1\n").arg(d->mReverseSorting - ? QStringLiteral("true") - : QStringLiteral("false")); - - QString crit; - switch (d->mActiveSortingCriterion) { - case Uid: - crit = QStringLiteral("Uid"); - break; - case Name: - crit = QStringLiteral("Name"); - break; - case FormattedName: - crit = QStringLiteral("FormattedName"); - break; - case FamilyName: - crit = QStringLiteral("FamilyName"); - break; - case GivenName: - crit = QStringLiteral("GivenName"); - break; - default: - crit = QStringLiteral("unknown -- update dump method"); - break; - } - - str += QStringLiteral(" Sorting criterion: %1\n").arg(crit); -#if 0 //code commented in loop => comment it too - for (const_iterator it = begin(); it != end(); ++it) { -// str += (*it).toString(); - } -#endif - - str += QLatin1String("}\n"); - - return str; -} - -void AddresseeList::setReverseSorting(bool reverseSorting) -{ - d->mReverseSorting = reverseSorting; -} - -bool AddresseeList::reverseSorting() const -{ - return d->mReverseSorting; -} - -void AddresseeList::sortBy(SortingCriterion c) -{ - d->mActiveSortingCriterion = c; - if (Uid == c) { - sortByTrait(); - } else if (Name == c) { - sortByTrait(); - } else if (FormattedName == c) { - sortByTrait(); - } else if (FamilyName == c) { - sortByTrait(); - } else if (GivenName == c) { - sortByTrait(); - } else { - qCCritical(KCONTACTS_LOG) << "AddresseeList sorting criterion passed for which a trait is not known." - << "No sorting done."; - } -} - -void AddresseeList::sort() -{ - sortBy(d->mActiveSortingCriterion); -} - -template -void AddresseeList::sortByTrait() -{ - // FIXME: better sorting algorithm, bubblesort is not acceptable for larger lists. - // - // for i := 1 to n - 1 - // do for j := 1 to n - i - // do if A[j] > A[j+1] - // then temp := A[j] - // A[j] := A[j + 1] - // A[j + 1 ] := temp - - iterator i1 = begin(); - iterator endIt = end(); - --endIt; - if (i1 == endIt) { // don't need sorting - return; - } - - iterator i2 = endIt; - while (i1 != endIt) { - iterator j1 = begin(); - iterator j2 = j1; - ++j2; - while (j1 != i2) { - if ((!d->mReverseSorting && Trait::lt(*j2, *j1)) - || (d->mReverseSorting && Trait::lt(*j1, *j2))) { - qSwap(*j1, *j2); - } - ++j1; - ++j2; - } - ++i1; - --i2; - } -} - -void AddresseeList::sortByField(Field *field) -{ - if (!field) { - qCWarning(KCONTACTS_LOG) << "sortByField called with no active sort field"; - return; - } - - sActiveField = field; - - if (isEmpty()) { - return; - } - - KContacts::FieldSortMode *mode = new KContacts::FieldSortMode(sActiveField, !d->mReverseSorting); - - KContacts::Addressee::setSortMode(mode); - std::sort((*this).begin(), (*this).end()); - KContacts::Addressee::setSortMode(nullptr); - - delete mode; -} - -void AddresseeList::sortByMode(SortMode *mode) -{ - if (isEmpty()) { - return; - } - - KContacts::Addressee::setSortMode(mode); - std::sort((*this).begin(), (*this).end()); - KContacts::Addressee::setSortMode(nullptr); -} - -SortingCriterion AddresseeList::sortingCriterion() const -{ - return d->mActiveSortingCriterion; -} - -Field *AddresseeList::sortingField() const -{ - return sActiveField; -} diff --git a/src/addresseelist.h b/src/addresseelist.h index 2576d85a..581c0cf3 100644 --- a/src/addresseelist.h +++ b/src/addresseelist.h @@ -1,420 +1,37 @@ /* This file is part of the KContacts framework. Copyright (c) 2002 Jost Schenck 2003 Tobias Koenig 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 KCONTACTS_ADDRESSEELIST_H #define KCONTACTS_ADDRESSEELIST_H -#include "kcontacts_export.h" -#include #include namespace KContacts { -class Field; -class SortMode; class Addressee; /** - * Each trait must implement one static function for equality, one for "less - * than". Class name should be the field name. A trait does not necessarily - * have to stick to just one field: a trait sorting by family name can e.g. - * sort addressees with equal family name by given name. - * - * If you want to implement reverse sorting, you do not have to write another - * trait, as AddresseeList takes care of that. + * @short a QVector of Addressee. */ -namespace SortingTraits { -class KCONTACTS_EXPORT Uid -{ -public: - /** - * Creates an instance. - */ - Uid(); +typedef QVector AddresseeList; - /** - * Destroys the instance. - */ - ~Uid(); - - /** - * "Equal" compare method - * - * @return @c true if the first parameter is equal to the second - * when comparing the uid attribute. - * - * @see Addressee::uid() - * @see QString::compare() - */ - static bool eq(const Addressee &a1, const Addressee &a2); - - /** - * "Less-Than" compare method - * - * @return @c true if the first parameter is "less-than" the second - * when comparing the uid attribute. - * - * @see Addressee::uid() - * @see QString::compare() - */ - static bool lt(const Addressee &a1, const Addressee &a2); - -private: - Q_DISABLE_COPY(Uid) - class Private; - Private *const d; -}; - -class KCONTACTS_EXPORT Name -{ -public: - /** - * Creates an instance. - */ - Name(); - - /** - * Destroys the instance. - */ - ~Name(); - - /** - * "Equal" compare method - * - * @return @c true if the first parameter is equal to the second - * when comparing the name attribute. - * - * @see Addressee::name() - * @see QString::localeAwareCompare() - */ - static bool eq(const Addressee &a1, const Addressee &a2); - - /** - * "Less-Than" compare method - * - * @return @c true if the first parameter is "less-than" the second - * when comparing the name attribute. - * - * @see Addressee::name() - * @see QString::localeAwareCompare() - */ - static bool lt(const Addressee &a1, const Addressee &a2); - -private: - Q_DISABLE_COPY(Name) - class Private; - Private *const d; -}; - -class KCONTACTS_EXPORT FormattedName -{ -public: - /** - * Creates an instance. - */ - FormattedName(); - - /** - * Destroys the instance. - */ - ~FormattedName(); - - /** - * "Equal" compare method - * - * @return @c true if the first parameter is equal to the second - * when comparing the formatted name attribute. - * - * @see Addressee::formattedName() - * @see QString::localeAwareCompare() - */ - static bool eq(const Addressee &a1, const Addressee &a2); - - /** - * "Less-Than" compare method - * - * @return @c true if the first parameter is "less-than" the second - * when comparing the formatted name attribute. - * - * @see Addressee::formattedName() - * @see QString::localeAwareCompare() - */ - static bool lt(const Addressee &a1, const Addressee &a2); - -private: - Q_DISABLE_COPY(FormattedName) - class Private; - Private *const d; -}; - -class KCONTACTS_EXPORT FamilyName // fallback to given name -{ -public: - /** - * Creates an instance. - */ - FamilyName(); - - /** - * Destroys the instance. - */ - ~FamilyName(); - - /** - * "Equal" compare method - * - * @return @c true if the first parameter is equal to the second - * when comparing the family name and given name attributes. - * - * @see Addressee::familyName() - * @see Addressee::givenName() - * @see QString::localeAwareCompare() - */ - static bool eq(const Addressee &a1, const Addressee &a2); - - /** - * "Less-Than" compare method - * - * Falls back to comparing given name if equal - * - * @return @c true if the first parameter is "less-than" the second - * when comparing the family name attribute. - * - * @see Addressee::familyName() - * @see QString::localeAwareCompare() - */ - static bool lt(const Addressee &a1, const Addressee &a2); - -private: - Q_DISABLE_COPY(FamilyName) - class Private; - Private *const d; -}; - -class KCONTACTS_EXPORT GivenName // fallback to family name -{ -public: - /** - * Creates an instance. - */ - GivenName(); - - /** - * Destroys the instance. - */ - ~GivenName(); - - /** - * "Equal" compare method - * - * @return @c true if the first parameter is equal to the second - * when comparing the given name and family name attributes. - * - * @see Addressee::givenName() - * @see Addressee::familyName() - * @see QString::localeAwareCompare() - */ - static bool eq(const Addressee &a1, const Addressee &a2); - - /** - * "Less-Than" compare method - * - * Falls back to comparing family name if equal - * - * @return @c true if the first parameter is "less-than" the second - * when comparing the given name attribute. - * - * @see Addressee::givenName() - * @see QString::localeAwareCompare() - */ - static bool lt(const Addressee &a1, const Addressee &a2); - -private: - Q_DISABLE_COPY(GivenName) - class Private; - Private *const d; -}; -} - -/** - * Addressee attribute used for sorting. - */ -typedef enum { - Uid, - Name, - FormattedName, - FamilyName, - GivenName -} SortingCriterion; - -/** - * @short a QVector of Addressee, with sorting functionality - * - * This class extends the functionality of QVector with - * sorting methods specific to the Addressee class. It can be used - * just like any other QVector but is no template class. - * - * An AddresseeList does not automatically keep sorted when addressees - * are added or removed or the sorting order is changed, as this would - * slow down larger operations by sorting after every step. So after - * such operations you have to call {@link #sort} or {@link #sortBy} to - * create a defined order again. - * - * Iterator usage is inherited from QVector and extensively documented - * there. Please remember that the state of an iterator is undefined - * after any sorting operation. - * - * For the enumeration Type SortingCriterion, which specifies the - * field by the collection will be sorted, the following values exist: - * Uid, Name, FormattedName, FamilyName, GivenName. - * - * @author Jost Schenck jost@schenck.de - */ -class KCONTACTS_EXPORT AddresseeList : public QVector -{ -public: - /** - * Creates a new addressee list. - */ - AddresseeList(); - - /** - * Creates a new addressee list. - */ - AddresseeList(const AddresseeList &other); - - /** - * Creates a new addressee list. - */ - AddresseeList(const QVector &list); - - /** - * Destroys the addressee list. - */ - ~AddresseeList(); - - /** - * Assignment operator. - * - * @param other the list to assign from - * @return a reference to @c this - */ - AddresseeList &operator=(const AddresseeList &other); - - /** - * Determines the direction of sorting. On change, the list - * will not automatically be resorted. - * @param reverseSorting true if sorting should be done reverse, - * false otherwise - */ - void setReverseSorting(bool reverseSorting = true); - - /** - * Returns the direction of sorting. - * @return true if sorting is done reverse, false otherwise - */ - bool reverseSorting() const; - - /** - * Sorts this list by a specific criterion. - * @param c the criterion by which should be sorted - */ - void sortBy(SortingCriterion c); - - /** - * Sorts this list by a specific field. If no parameter is given, the - * last used Field object will be used. - * @param field pointer to the Field object to be sorted by - */ - void sortByField(Field *field = nullptr); - - /** - * Sorts this list by a specific sorting mode. - * @param mode pointer to the sorting mode object to be sorted by - */ - void sortByMode(SortMode *mode = nullptr); - - /** - * Sorts this list by its active sorting criterion. This normally is the - * criterion of the last sortBy operation or FormattedName if up - * to now there has been no sortBy operation. - * - * Please note that the sorting trait of the last {@link #sortByTrait} - * method call is not remembered and thus the action can not be repeated - * by this method. - */ - void sort(); - - /** - * Templated sort function. You normally will not want to use this but - * {@link #sortBy} and {@link #sort} instead as the existing sorting - * criteria completely suffice for most cases. - * - * However, if you do want to use some special sorting criterion, you can - * write a trait class that will be provided to this templated method. - * This trait class has to have a class declaration like the following: - * \code - * class MySortingTrait { - * public: - * // eq returns true if a1 and a2 are equal - * static bool eq(KContacts::Addressee a1, KContacts::Addressee a2); - * // lt returns true is a1 is "less than" a2 - * static bool lt(KContacts::Addressee a1, KContacts::Addressee a2); - * }; - * \endcode - * You can then pass this class to the sortByTrait method like this: - * \code - * myAddresseelist.sortByTrait<MySortingTrait>(); - * \endcode - * Please note that the {@link #sort} method can not be used to repeat the - * sorting of the last sortByTrait action. - * - * Right now this method uses the bubble sort algorithm. This should be - * replaced for a better one when I have time. - */ - template void sortByTrait(); - - /** - * Returns the active sorting criterion, ie the sorting criterion that - * will be used by a {@link #sort} call. - */ - SortingCriterion sortingCriterion() const; - - /** - * Returns the active sorting field, ie a pointer to the Field object - * which was used for the last {@link #sortByField} operation. - * This function returns the last GLOBAL sorting field, not - * the class specific one. - * You're a lot better off by keeping track of this locally. - */ - Field *sortingField() const; - - /** - * Returns a string representation of the addressee list. - */ - QString toString() const; - -private: - class Private; - QSharedDataPointer d; -}; } #endif