1 /*
2     SPDX-FileCopyrightText: 2013 Ivan Cukic <ivan.cukic(at)kde.org>
3 
4     SPDX-License-Identifier: LGPL-2.1-or-later
5 */
6 
7 #ifndef SOLID_DECALARATIVE_DEVICES_H
8 #define SOLID_DECALARATIVE_DEVICES_H
9 
10 #include <QObject>
11 #include <solid/deviceinterface.h>
12 #include <solid/predicate.h>
13 
14 #include <QSharedPointer>
15 
16 namespace Solid
17 {
18 class DeviceNotifier;
19 class DevicesQueryPrivate;
20 
21 /**
22  * A class that watches the devices known to the solid system.
23  *
24  * It behaves similarly to Solid::DeviceNotifier, but
25  * adds some convenience methods which allow it to
26  * watch only the devices matching a specified query
27  * (formatted for Solid::Predicate).
28  *
29  * It is intended to be used from QML like this:
30  *
31  * @code
32  *    Solid.Devices {
33  *        id: allDevices
34  *    }
35  *
36  *    Solid.Devices {
37  *        id: networkShares
38  *        query: "IS NetworkShare"
39  *    }
40  *
41  *    Solid.Devices {
42  *        id: mice
43  *        query: "PointingDevice.type == 'Mouse'"
44  *    }
45  *
46  *    Text {
47  *        text: "Total number of devices: " + allDevices.count
48  *    }
49  *
50  *    Text {
51  *        text: "NFS url: " + networkShares.device(
52  *            networkShares.devices[0], "NetworkShare"
53  *        ).url
54  *    }
55  * @endcode
56  */
57 class Devices : public QObject
58 {
59     Q_OBJECT
60 
61     Q_PROPERTY(QString query READ query WRITE setQuery NOTIFY queryChanged)
62     Q_PROPERTY(int count READ count NOTIFY countChanged)
63     Q_PROPERTY(bool empty READ isEmpty NOTIFY emptyChanged)
64     Q_PROPERTY(QStringList devices READ devices NOTIFY devicesChanged)
65 
66 public:
67     explicit Devices(QObject *parent = nullptr);
68     ~Devices() override;
69 
70 Q_SIGNALS:
71     /**
72      * Emitted when a new device matching the specified
73      * query arrives
74      * @param udi UDI of the new device
75      */
76     void deviceAdded(const QString &udi) const;
77 
78     /**
79      * Emitted when a device matching the specified
80      * query disappears
81      * @param udi UDI of the device
82      */
83     void deviceRemoved(const QString &udi) const;
84 
85     /**
86      * Emitted when the number of devices that
87      * match the specified query has changed
88      * @param count new device count
89      */
90     void countChanged(int count) const;
91 
92     /**
93      * Emitted when the list of devices that
94      * match the specified query has changed
95      * @param devices list of UDIs
96      */
97     void devicesChanged(const QStringList &devices) const;
98 
99     /**
100      * Emitted when the query has changed
101      * @param query new query
102      */
103     void queryChanged(const QString &query) const;
104 
105     /**
106      * Emitted when the empty property changes
107      * @param empty is the device list empty
108      */
109     void emptyChanged(bool empty) const;
110 
111 public:
112     /**
113      * Retrieves the number of the devices that
114      * match the specified query
115      * @return device count
116      */
117     int count() const;
118 
119     /**
120      * Retrieves whether there are devices matching
121      * the specified query
122      * @return true if there are no matching devices
123      */
124     bool isEmpty() const;
125 
126     /**
127      * Retrieves the list of UDIs of the devices that
128      * match the specified query
129      */
130     QStringList devices() const;
131 
132     /**
133      * Query to check the devices against. It needs
134      * to be formatted for Solid::Predicate.
135      * @see Solid::Predicate
136      */
137     QString query() const;
138 
139     /**
140      * Sets the query to filter the devices.
141      * @param query new query
142      */
143     void setQuery(const QString &query);
144 
145 public Q_SLOTS:
146     /**
147      * Retrieves an interface object to the specified device
148      * @param udi udi of the desired device
149      * @param type how to interpret the device
150      * @see Solid::Device::asDeviceInterface
151      */
152     QObject *device(const QString &udi, const QString &type);
153 
154 private Q_SLOTS:
155     void addDevice(const QString &udi);
156     void removeDevice(const QString &udi);
157 
158     /**
159      * Initializes the backend object
160      */
161     void initialize() const;
162 
163     /**
164      * Frees up the backend and sends the appropriate events
165      */
166     void reset();
167 
168 private:
169     QString m_query;
170 
171     mutable QSharedPointer<DevicesQueryPrivate> m_backend;
172 };
173 
174 } // namespace Solid
175 
176 #endif
177