1 /* @file categorymanager.cpp
2 * @brief Handles category management
4 * Copyright (C) 2018 Intevation GmbH
6 * This file is part of GpgOL.
8 * GpgOL is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * GpgOL is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, see <http://www.gnu.org/licenses/>.
22 #include "categorymanager.h"
25 #include "gpgoladdin.h"
28 #include <unordered_map>
30 class CategoryManager::Private
37 void createCategory (shared_disp_t store,
38 const std::string &category, int color)
41 LPDISPATCH categories = get_oom_object (store.get(), "Categories");
47 if (create_category (categories, category.c_str (), color))
49 log_debug ("%s:%s: Failed to create category %s",
50 SRCNAME, __func__, anonstr (category.c_str()));
56 void registerCategory (const std::string &storeID,
57 const std::string &category)
60 auto storeIt = mCategoryStoreMap.find (storeID);
61 if (storeIt == mCategoryStoreMap.end())
63 /* First category for this store. Create a new
65 std::unordered_map <std::string, int> categoryMap;
66 categoryMap.insert (std::make_pair (category, 1));
67 mCategoryStoreMap.insert (std::make_pair (storeID, categoryMap));
68 log_debug ("%s:%s: Register category %s in new store %s ref now 1",
69 SRCNAME, __func__, anonstr (category.c_str()),
70 anonstr (storeID.c_str()));
73 auto categoryIt = storeIt->second.find (category);
74 if (categoryIt == storeIt->second.end ())
76 storeIt->second.insert (std::make_pair (category, 1));
77 log_debug ("%s:%s: Register category %s in store %s ref now 1",
78 SRCNAME, __func__, anonstr (category.c_str()),
79 anonstr (storeID.c_str()));
84 log_debug ("%s:%s: Register category %s in store %s ref now %i",
85 SRCNAME, __func__, anonstr (category.c_str()),
86 anonstr (storeID.c_str()), categoryIt->second);
91 void unregisterCategory (const std::string &storeID,
92 const std::string &category)
95 auto storeIt = mCategoryStoreMap.find (storeID);
96 if (storeIt == mCategoryStoreMap.end ())
98 log_error ("%s:%s: Unregister called for unregistered store %s",
99 SRCNAME, __func__, anonstr (storeID.c_str()));
102 auto categoryIt = storeIt->second.find (category);
103 if (categoryIt == storeIt->second.end ())
105 log_debug ("%s:%s: Unregister %s not found for store %s",
106 SRCNAME, __func__, anonstr (category.c_str()),
107 anonstr (storeID.c_str()));
110 categoryIt->second--;
111 log_debug ("%s:%s: Unregister category %s in store %s ref now %i",
112 SRCNAME, __func__, anonstr (category.c_str()),
113 anonstr (storeID.c_str()), categoryIt->second);
114 if (categoryIt->second < 0)
116 log_debug ("%s:%s: Unregister %s negative for store %s",
117 SRCNAME, __func__, anonstr (category.c_str()),
118 anonstr (storeID.c_str()));
121 if (categoryIt->second == 0)
123 log_debug ("%s:%s: Deleting %s for store %s",
124 SRCNAME, __func__, anonstr (category.c_str()),
125 anonstr (storeID.c_str()));
127 LPDISPATCH store = get_store_for_id (storeID.c_str());
133 delete_category (store, category.c_str ());
134 storeIt->second.erase (categoryIt);
139 bool categoryExistsInMap (const std::string &storeID,
140 const std::string &category)
142 const auto it = mCategoryStoreMap.find (storeID);
143 if (it == mCategoryStoreMap.end ())
147 return it->second.find (category) != it->second.end();
151 /* Map from: store to map of category -> refs. */
152 std::unordered_map<std::string,
153 std::unordered_map<std::string, int> > mCategoryStoreMap;
157 std::shared_ptr <CategoryManager>
158 CategoryManager::instance ()
160 return GpgolAddin::get_instance ()->get_category_mngr ();
163 CategoryManager::CategoryManager():
169 CategoryManager::addCategoryToMail (Mail *mail, const std::string &category, int color)
173 if (!mail || category.empty())
178 auto store = MAKE_SHARED (get_oom_object (mail->item (), "Parent.Store"));
181 log_error ("%s:%s Failed to obtain store",
183 TRETURN std::string ();
185 char *storeID = get_oom_string (store.get (), "StoreID");
188 log_error ("%s:%s Failed to obtain storeID",
190 TRETURN std::string ();
195 if (!d->categoryExistsInMap (ret, category))
197 d->createCategory (store, category, color);
199 d->registerCategory (ret, category);
201 if (add_category (mail->item (), category.c_str()))
203 /* Probably the category already existed there
204 so it is not super worrysome. */
205 log_debug ("%s:%s Failed to add category.",
212 CategoryManager::removeCategory (Mail *mail, const std::string &category)
215 if (!mail || category.empty())
220 if (remove_category (mail->item (), category.c_str (), true))
222 log_debug ("%s:%s Failed to remvoe category.",
225 d->unregisterCategory (mail->storeID (), category.c_str ());
232 CategoryManager::removeAllGpgOLCategories ()
235 delete_all_categories_starting_with ("GpgOL: ");
241 CategoryManager::getEncMailCategory ()
243 static std::string decStr;
246 decStr = std::string ("GpgOL: ") +
247 std::string (_("Encrypted Message"));