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