1 /*
2  *  SPDX-FileCopyrightText: 2009 David Hubner <hubnerd@ntlworld.com>
3  *
4  *  SPDX-License-Identifier: GPL-2.0-or-later
5  *
6  */
7 
8 #include "devicelisting.h"
9 
10 // Solid
11 #include <solid/devicenotifier.h>
12 
13 #include <QContextMenuEvent>
14 #include <QMenu>
15 
16 // Local
17 #include "devinfo.h"
18 #include "infopanel.h"
19 #include "soldevicetypes.h"
20 #include "solidhelper.h"
21 //#include "nicsignals.h"
22 
DeviceListing(QWidget * parent,InfoPanel * info,DevInfoPlugin * stat)23 DeviceListing::DeviceListing(QWidget *parent, InfoPanel *info, DevInfoPlugin *stat)
24     : QTreeWidget(parent)
25     , iPanel(info)
26     , status(stat)
27 {
28     //     // Check nic changes
29     //    nicSig = new NicSignals();
30     //    connect(nicSig,SIGNAL(nicActivatedOrDisconnected()),this,SLOT(networkingChangedSlot()));
31     //
32     // Check if selection changed
33     connect(this, &DeviceListing::currentItemChanged, this, &DeviceListing::currentItemChangedSlot);
34 
35     // Check if item is added
36     connect(Solid::DeviceNotifier::instance(), &Solid::DeviceNotifier::deviceAdded, this, &DeviceListing::deviceAddedSlot);
37 
38     // Check if item is removed
39     connect(Solid::DeviceNotifier::instance(), &Solid::DeviceNotifier::deviceRemoved, this, &DeviceListing::deviceRemovedSlot);
40 
41     setWhatsThis(i18nc("Device Listing Whats This", "Shows all the devices that are currently listed."));
42 
43     createMenuActions();
44     setHeaderLabels(QStringList(i18n("Devices")));
45     populateListing();
46     setSortingEnabled(true);
47 }
48 
~DeviceListing()49 DeviceListing::~DeviceListing()
50 {
51     // delete nicSig;
52     clear();
53 }
54 
createMenuActions()55 void DeviceListing::createMenuActions()
56 {
57     colAct = new QAction(i18n("Collapse All"), this);
58     connect(colAct, &QAction::triggered, this, &DeviceListing::collapseAllDevicesSlot);
59 
60     expAct = new QAction(i18n("Expand All"), this);
61     connect(expAct, &QAction::triggered, this, &DeviceListing::expandAllDevicesSlot);
62 
63     allAct = new QAction(i18n("Show All Devices"), this);
64     connect(allAct, &QAction::triggered, this, &DeviceListing::showAllDevicesSlot);
65 
66     relAct = new QAction(i18n("Show Relevant Devices"), this);
67     connect(relAct, &QAction::triggered, this, &DeviceListing::showRelevantDevicesSlot);
68 }
69 
contextMenuEvent(QContextMenuEvent * event)70 void DeviceListing::contextMenuEvent(QContextMenuEvent *event)
71 {
72     QMenu menu(this);
73 
74     menu.addAction(colAct);
75     menu.addAction(expAct);
76     menu.addAction(allAct);
77     menu.addAction(relAct);
78     menu.exec(event->globalPos());
79 }
80 
createListItems(const Solid::DeviceInterface::Type & type)81 QTreeWidgetItem *DeviceListing::createListItems(const Solid::DeviceInterface::Type &type)
82 {
83     switch (type) {
84     case Solid::DeviceInterface::Processor:
85         return new SolProcessorDevice(type);
86     case Solid::DeviceInterface::StorageDrive:
87         return new SolStorageDevice(type);
88     case Solid::DeviceInterface::Camera:
89         return new SolCameraDevice(type);
90     case Solid::DeviceInterface::PortableMediaPlayer:
91         return new SolMediaPlayerDevice(type);
92     case Solid::DeviceInterface::Battery:
93         return new SolBatteryDevice(type);
94     default:
95         return new SolDevice(type, i18nc("unknown device type", "Unknown"));
96     }
97 }
98 
populateListing(const show showStatus)99 void DeviceListing::populateListing(const show showStatus)
100 {
101     const Solid::DeviceInterface::Type needHardware[] = {
102         Solid::DeviceInterface::Processor,
103         Solid::DeviceInterface::StorageDrive,
104         Solid::DeviceInterface::Battery,
105         Solid::DeviceInterface::PortableMediaPlayer,
106         Solid::DeviceInterface::Camera,
107     };
108 
109     clear();
110 
111     for (unsigned int i = 0; i < (sizeof(needHardware) / sizeof(Solid::DeviceInterface::Type)); i++) {
112         QTreeWidgetItem *tmpDevice = createListItems(needHardware[i]);
113         deviceMap[needHardware[i]] = static_cast<SolDevice *>(tmpDevice);
114 
115         if ((tmpDevice->childCount() > 0) || (showStatus == ALL)) {
116             addTopLevelItem(tmpDevice);
117         }
118     }
119 }
120 
currentItemChangedSlot(QTreeWidgetItem * listItemIn,QTreeWidgetItem * previous)121 void DeviceListing::currentItemChangedSlot(QTreeWidgetItem *listItemIn, QTreeWidgetItem *previous)
122 {
123     Q_UNUSED(previous);
124 
125     SolDevice *listItem = static_cast<SolDevice *>(listItemIn);
126     if (listItem && listItem->isDeviceSet()) {
127         iPanel->setTopInfo(listItem->deviceIcon(), listItem->device());
128 
129         QVListLayout *bottomLay = listItem->infoPanelLayout();
130         if (!bottomLay) {
131             return;
132         }
133 
134         iPanel->setBottomInfo(bottomLay);
135     } else {
136         status->updateStatus(i18nc("no device UDI", "None"));
137     }
138 }
139 
deviceAddedSlot(const QString & udi)140 void DeviceListing::deviceAddedSlot(const QString &udi)
141 {
142     SolidHelper *solhelp = new SolidHelper();
143 
144     Solid::Device dev(udi);
145     if (!dev.isValid()) {
146         // Probably the device already disappeared again.
147         return;
148     }
149 
150     Solid::DeviceInterface::Type deviceType = solhelp->deviceType(&dev);
151     QTreeWidgetItem *parent = getTreeWidgetItemFromUdi(this, dev.parentUdi());
152 
153     // Incase of bad index
154     if (deviceMap[deviceType] == nullptr) {
155         QTreeWidgetItem *topItem = topLevelItem(0);
156         if (!topItem) {
157             delete solhelp;
158             return;
159         }
160         deviceMap[deviceType] = static_cast<SolDevice *>(topItem);
161     }
162 
163     switch (deviceType) {
164     case Solid::DeviceInterface::Processor:
165         new SolProcessorDevice(deviceMap[deviceType], dev);
166         break;
167     case Solid::DeviceInterface::Camera:
168         new SolCameraDevice(deviceMap[deviceType], dev);
169         break;
170     case Solid::DeviceInterface::PortableMediaPlayer:
171         new SolMediaPlayerDevice(deviceMap[deviceType], dev);
172         break;
173     case Solid::DeviceInterface::Battery:
174         new SolBatteryDevice(deviceMap[deviceType], dev);
175         break;
176     case Solid::DeviceInterface::StorageDrive:
177         new SolStorageDevice(deviceMap[deviceType], dev, SolStorageDevice::NOCHILDREN);
178         break;
179     case Solid::DeviceInterface::StorageVolume:
180         if (parent == nullptr) {
181             break;
182         }
183         new SolVolumeDevice(parent, dev);
184         break;
185     default:
186         break;
187     }
188     delete solhelp;
189 }
190 
deviceRemovedSlot(const QString & udi)191 void DeviceListing::deviceRemovedSlot(const QString &udi)
192 {
193     const QTreeWidgetItem *item = getTreeWidgetItemFromUdi(this, udi);
194     if (item == nullptr) {
195         return;
196     }
197 
198     delete item;
199 }
200 
collapseAllDevicesSlot()201 void DeviceListing::collapseAllDevicesSlot()
202 {
203     collapseAll();
204 }
205 
expandAllDevicesSlot()206 void DeviceListing::expandAllDevicesSlot()
207 {
208     expandAll();
209 }
210 
showAllDevicesSlot()211 void DeviceListing::showAllDevicesSlot()
212 {
213     populateListing(ALL);
214 }
215 
showRelevantDevicesSlot()216 void DeviceListing::showRelevantDevicesSlot()
217 {
218     populateListing(RELEVANT);
219 }
220