diff --git a/src/interfaces/itemmodelstateserializeri.h b/src/interfaces/itemmodelstateserializeri.h index 47c77d2c957ce362330e1e592ac4ca02956a3f72..3ee1a8d7cee48c588e115c9dedef092b1bf73ba7 100644 --- a/src/interfaces/itemmodelstateserializeri.h +++ b/src/interfaces/itemmodelstateserializeri.h @@ -20,8 +20,9 @@ #include <typedefs.h> // Ring -class CollectionInterface; +#include <collectioninterface.h> class Account; +class CollectionManagerInterfaceBase; namespace Interfaces { @@ -31,14 +32,49 @@ namespace Interfaces { */ class ItemModelStateSerializerI { public: + /** + * Hints for the preferredCollection implementation about how to select + * the right collection. + */ + enum class Hints { + NONE = 0x0 << 0, + ASK_USER = 0x1 << 0, + DO_NOT_ASK_USER = 0x1 << 1, + }; + virtual ~ItemModelStateSerializerI() = default; + /** + * Called when the new enabled collection list need to be serialized + */ virtual bool save() = 0; + + /** + * Called when the enabled collection list is first needed + * + * @note You can call this manually if your collections depend on it + */ virtual bool load() = 0; //Getter virtual bool isChecked(const CollectionInterface* backend) const = 0; + /** + * Allow to overload the default algoritm used to look for a default + * collection to store something new. + * + * @param manager The likes of PersonModel::instance() or CategorizedHistoryModel::instance() + * @param features A list of must have collection features. If NONE is set \ + * the implementation is free to return whatever it want. If it is set, a \ + * collection must return a compliant collection or the result will be \ + * ignored. + */ + virtual CollectionInterface* preferredCollection(CollectionManagerInterfaceBase* manager, + FlagPack<CollectionInterface::SupportedFeatures> features + = FlagPack<CollectionInterface::SupportedFeatures>(CollectionInterface::SupportedFeatures::NONE), + FlagPack<Hints> hints = FlagPack<Hints>(Hints::NONE) + ) = 0; + //Setter virtual bool setChecked(const CollectionInterface* backend, bool enabled) = 0; }; diff --git a/src/private/useractions.h b/src/private/useractions.h index 22085edeec585513e4939e0062c2266f8d9081de..740b181828fb5e5b29badbe1b83e53aa77d13275 100644 --- a/src/private/useractions.h +++ b/src/private/useractions.h @@ -27,6 +27,7 @@ #include <categorizedhistorymodel.h> #include <personmodel.h> #include <interfaces/actionextenderi.h> +#include <interfaces/itemmodelstateserializeri.h> #include <mime.h> #include "media/media.h" @@ -387,9 +388,19 @@ bool editPerson( Person* p ) bool addPerson(ContactMethod* cm, CollectionInterface* col) { - if (cm->contact()) + // If the placeholder has not yet been replaced, it might point to a + // deleted contact, as the user initiated this action, lets comply + if (cm->contact() && !cm->contact()->isPlaceHolder()) return false; + // Try to get the best collection for this + if (!col) + col = GlobalInstances::itemModelStateSerializer().preferredCollection( + &PersonModel::instance(), + CollectionInterface::SupportedFeatures::ADD + ); + + // Take a random collection that match if (!col) { const QVector<CollectionInterface*> cols = PersonModel::instance() .collections(CollectionInterface::SupportedFeatures::ADD); diff --git a/src/useractionmodel.cpp b/src/useractionmodel.cpp index e9496ea03c55f63d1f66597956e192ebbb6128d4..f1595808462a520ed25c5f9ae4c6e689402f0cd2 100644 --- a/src/useractionmodel.cpp +++ b/src/useractionmodel.cpp @@ -478,7 +478,9 @@ const Matrix1D< UAM::Action, bool(*)(const ContactMethod*)> UserActionModelPriva { UAMA::JOIN , nullptr }, { UAMA::ADD_NEW , nullptr }, { UAMA::TOGGLE_VIDEO , nullptr }, - { UAMA::ADD_CONTACT , CM_CB { return !cm->contact(); }}, + { UAMA::ADD_CONTACT , CM_CB { return (!cm->contact()) + || cm->contact()->isPlaceHolder(); + }}, { UAMA::ADD_TO_CONTACT , CM_CB { return !cm->contact(); }}, { UAMA::DELETE_CONTACT , CM_CB { return cm->contact() && cm->contact()->collection() &&