34 #include <QtConcurrentRun> 53 QTimer::singleShot (1000,
this, SLOT (update ()));
68 for (
const auto& list : Items_)
70 const auto pos = std::find_if (list.begin (), list.end (),
71 [&id] (
const Item_ptr& item) {
return item->GetPermanentID () == id; });
72 if (pos != list.end ())
81 using Cat2ID2Item_t = QHash<QString, QHash<QString, Item_ptr>>;
83 Cat2ID2Item_t ItemsList2Map (
const Cat2Items_t& items)
89 auto& map = result [pair.first];
90 for (
const auto& item : pair.second)
91 map [item->GetPermanentID ()] = item;
97 Cat2Items_t ItemsMap2List (
const Cat2ID2Item_t& items)
102 std::copy (pair.second.begin (), pair.second.end (),
103 std::back_inserter (result [pair.first]));
108 QStringList ScanDir (
const QString& path)
110 const auto& infos = QDir (path).entryInfoList ({
"*.desktop" },
111 QDir::Files | QDir::AllDirs | QDir::NoDotAndDotDot);
114 [] (
const QFileInfo& info)
116 return info.isDir () ?
117 ScanDir (info.absoluteFilePath ()) :
118 QStringList { info.absoluteFilePath () };
122 Cat2ID2Item_t FindAndParse (
const QList<Type>& types)
124 Cat2ID2Item_t result;
127 for (
const auto& dir :
ToPaths (types))
128 paths << ScanDir (dir);
130 for (
const auto& path : paths)
137 catch (
const std::exception& e)
139 qWarning () << Q_FUNC_INFO
146 if (!item->IsValid ())
148 qWarning () << Q_FUNC_INFO
154 for (
const auto& cat : item->GetCategories ())
155 if (!cat.startsWith (
"X-"))
156 result [cat] [item->GetPermanentID ()] = item;
169 DiffResult (T&& oldCont, T&& newCont)
171 std::set_difference (oldCont.begin (), oldCont.end (),
172 newCont.begin (), newCont.end (),
174 std::set_difference (newCont.begin (), newCont.end (),
175 oldCont.begin (), oldCont.end (),
176 std::back_inserter (
Added_));
178 std::set_intersection (oldCont.begin (), oldCont.end (),
179 newCont.begin (), newCont.end (),
183 bool HasChanges ()
const 189 template<
typename Container>
190 DiffResult<Container> CalcDiff (Container&& oldCont, Container&& newCont)
192 return { std::forward<Container> (oldCont), std::forward<Container> (newCont) };
195 boost::optional<Cat2Items_t> Merge (
const Cat2Items_t& existing, Cat2ID2Item_t result)
197 auto ourItems = ItemsList2Map (existing);
201 const auto& diffCats = CalcDiff (
Util::Sorted (existing.keys ()),
204 for (
const auto& removed : diffCats.Removed_)
205 ourItems.remove (removed);
206 for (
const auto& added : diffCats.Added_)
207 swap (ourItems [added], result [added]);
209 bool changed = diffCats.HasChanges ();
211 for (
const auto& cat : diffCats.Intersection_)
213 auto& ourList = ourItems [cat];
214 auto& newList = result [cat];
215 const auto& diffItems = CalcDiff (
Util::Sorted (ourList.keys ()),
218 changed = changed || diffItems.HasChanges ();
220 for (
const auto& removed : diffItems.Removed_)
221 ourList.remove (removed);
222 for (
const auto& added : diffItems.Added_)
223 swap (ourList [added], newList [added]);
225 for (
const auto& existing : diffItems.Intersection_)
226 if (*ourList [existing] != *newList [existing])
228 swap (ourList [existing], newList [existing]);
236 return ItemsMap2List (ourItems);
247 Util::Sequence (
this, QtConcurrent::run (FindAndParse, Types_)) >>
248 [
this] (Cat2ID2Item_t result)
250 return QtConcurrent::run (Merge, Items_, result);
252 [
this] (
const boost::optional<Cat2Items_t>& result)
void itemsListChanged()
Notifies when the list of items changes in any way.
bool IsReady() const
Checks whether this items finder is ready.
auto Stlize(Assoc &&assoc)
Converts an Qt's associative sequence assoc to an STL-like iteratable range.
Item_ptr FindItem(const QString &permanentID) const
Finds an XDG item for the given permanent ID.
void swap(FDGuard &g1, FDGuard &g2)
void update()
Updates the list of items.
std::decay_t< T > Removed_
ItemsFinder(ICoreProxy_ptr, const QList< Type > &types, QObject *parent=nullptr)
Constructs the items finder for the given types.
Cat2Items_t GetItems() const
Returns the categorized list of XDG items.
decltype(auto) Sorted(Cont &&cont)
std::shared_ptr< ICoreProxy > ICoreProxy_ptr
std::decay_t< T > Intersection_
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.
QHash< QString, QList< Item_ptr > > Cat2Items_t
auto ConcatMap(Cont &&c, F &&f)
static Item_ptr FromDesktopFile(const QString &file)
Loads the XDG .desktop item from file.