13 #include <QtConcurrentRun>
43 for (
const auto& list : Items_)
45 const auto pos = std::find_if (list.begin (), list.end (),
46 [&
id] (
const Item_ptr& item) { return item->GetPermanentID () == id; });
47 if (pos != list.end ())
56 using Cat2ID2Item_t = QHash<QString, QHash<QString, Item_ptr>>;
58 Cat2ID2Item_t ItemsList2Map (
const Cat2Items_t& items)
64 auto& map = result [pair.first];
65 for (
const auto& item : pair.second)
66 map [item->GetPermanentID ()] = item;
72 Cat2Items_t ItemsMap2List (
const Cat2ID2Item_t& items)
77 std::copy (pair.second.begin (), pair.second.end (),
78 std::back_inserter (result [pair.first]));
83 QStringList ScanDir (
const QString& path)
85 const auto& infos = QDir (path).entryInfoList ({ QStringLiteral (
"*.desktop") },
86 QDir::Files | QDir::AllDirs | QDir::NoDotAndDotDot);
89 [] (
const QFileInfo& info)
91 return info.isDir () ?
92 ScanDir (info.absoluteFilePath ()) :
93 QStringList { info.absoluteFilePath () };
97 Cat2ID2Item_t FindAndParse (
const QList<Type>& types)
102 for (
const auto& dir :
ToPaths (types))
103 paths << ScanDir (dir);
105 for (
const auto& path : paths)
112 catch (
const std::exception& e)
114 qWarning () << Q_FUNC_INFO
121 if (!item->IsValid ())
123 qWarning () << Q_FUNC_INFO
129 for (
const auto& cat : item->GetCategories ())
130 if (!cat.startsWith (
"X-"_ql))
131 result [cat] [item->GetPermanentID ()] = item;
144 DiffResult (T&& oldCont, T&& newCont)
146 std::set_difference (oldCont.begin (), oldCont.end (),
147 newCont.begin (), newCont.end (),
149 std::set_difference (newCont.begin (), newCont.end (),
150 oldCont.begin (), oldCont.end (),
151 std::back_inserter (
Added_));
153 std::set_intersection (oldCont.begin (), oldCont.end (),
154 newCont.begin (), newCont.end (),
158 bool HasChanges ()
const
164 template<
typename Container>
165 DiffResult<Container> CalcDiff (Container&& oldCont, Container&& newCont)
167 return { std::forward<Container> (oldCont), std::forward<Container> (newCont) };
170 std::optional<Cat2Items_t> Merge (
const Cat2Items_t& existing, Cat2ID2Item_t result)
172 auto ourItems = ItemsList2Map (existing);
176 const auto& diffCats = CalcDiff (
Util::Sorted (existing.keys ()),
179 for (
const auto& removed : diffCats.Removed_)
180 ourItems.remove (removed);
181 for (
const auto& added : diffCats.Added_)
182 swap (ourItems [added], result [added]);
184 bool changed = diffCats.HasChanges ();
186 for (
const auto& cat : diffCats.Intersection_)
188 auto& ourList = ourItems [cat];
189 auto& newList = result [cat];
190 const auto& diffItems = CalcDiff (
Util::Sorted (ourList.keys ()),
193 changed = changed || diffItems.HasChanges ();
195 for (
const auto& removed : diffItems.Removed_)
196 ourList.remove (removed);
197 for (
const auto& added : diffItems.Added_)
198 swap (ourList [added], newList [added]);
200 for (
const auto& existing : diffItems.Intersection_)
201 if (*ourList [existing] != *newList [existing])
203 swap (ourList [existing], newList [existing]);
211 return ItemsMap2List (ourItems);
222 Util::Sequence (
this, QtConcurrent::run (FindAndParse, Types_)) >>
223 [
this] (
const Cat2ID2Item_t& result)
225 return QtConcurrent::run (Merge,
Items_, result);
227 [
this] (
const std::optional<Cat2Items_t>& result)