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)
static Item_ptr FromDesktopFile(const QString &file)
Loads the XDG .desktop item from file.
bool IsReady() const
Checks whether this items finder is ready.
ItemsFinder(const ICoreProxy_ptr &, const QList< Type > &types, QObject *parent=nullptr)
Constructs the items finder for the given types.
Item_ptr FindItem(const QString &permanentID) const
Finds an XDG item for the given permanent ID.
void itemsListChanged()
Notifies when the list of items changes in any way.
Cat2Items_t GetItems() const
Returns the categorized list of XDG items.
QList< QNetworkCookie > Added_
QList< QNetworkCookie > Removed_
std::shared_ptr< ICoreProxy > ICoreProxy_ptr
std::decay_t< T > Intersection_
QHash< QString, QList< Item_ptr > > Cat2Items_t
std::shared_ptr< Item > Item_ptr
QStringList ToPaths(const QList< Type > &types)
Returns a set of typical directories with desktop files of the given types.
auto Stlize(Assoc &&assoc) noexcept
Converts an Qt's associative sequence assoc to an STL-like iteratable range.
auto ConcatMap(Cont &&c, F &&f)
decltype(auto) Sorted(Cont &&cont)
void swap(FDGuard &g1, FDGuard &g2)