1 /* BEGIN_COMMON_COPYRIGHT_HEADER
2 * (c)LGPL2+
3 *
4 * LXQt - a lightweight, Qt based, desktop toolset
5 * https://lxqt.org
6 *
7 * Copyright: 2011-2013 Razor team
8 * Authors:
9 * Petr Vanek <petr@scribus.info>
10 * Alexander Sokoloff <sokoloff.a@gmail.com>
11 *
12 * This program or library is free software; you can redistribute it
13 * and/or modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2.1 of the License, or (at your option) any later version.
16 *
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
21
22 * You should have received a copy of the GNU Lesser General
23 * Public License along with this library; if not, write to the
24 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25 * Boston, MA 02110-1301 USA
26 *
27 * END_COMMON_COPYRIGHT_HEADER */
28
29 #include "popup.h"
30 #include "../panel/ilxqtpanelplugin.h"
31
32 #include <QDesktopWidget>
33 #include <QVBoxLayout>
34 #include <QTimer>
35 #include <Solid/StorageAccess>
36 #include <Solid/StorageDrive>
37 #include <Solid/DeviceNotifier>
38
39 // Paulo: I'm not sure what this is for
hasRemovableParent(Solid::Device device)40 static bool hasRemovableParent(Solid::Device device)
41 {
42 // qDebug() << "acess:" << device.udi();
43 for ( ; !device.udi().isEmpty(); device = device.parent())
44 {
45 Solid::StorageDrive* drive = device.as<Solid::StorageDrive>();
46 if (drive && drive->isRemovable())
47 {
48 // qDebug() << "removable parent drive:" << device.udi();
49 return true;
50 }
51 }
52 return false;
53 }
54
Popup(ILXQtPanelPlugin * plugin,QWidget * parent)55 Popup::Popup(ILXQtPanelPlugin * plugin, QWidget* parent):
56 QDialog(parent, Qt::Window | Qt::WindowStaysOnTopHint | Qt::CustomizeWindowHint | Qt::Popup | Qt::X11BypassWindowManagerHint),
57 mPlugin(plugin),
58 mPlaceholder(nullptr),
59 mDisplayCount(0)
60 {
61 setObjectName(QStringLiteral("LXQtMountPopup"));
62 setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
63 setLayout(new QVBoxLayout(this));
64 layout()->setMargin(0);
65
66 setAttribute(Qt::WA_AlwaysShowToolTips);
67
68 mPlaceholder = new QLabel(tr("No devices are available"), this);
69 mPlaceholder->setObjectName(QStringLiteral("NoDiskLabel"));
70 layout()->addWidget(mPlaceholder);
71
72 //Perform the potential long time operation after object construction
73 //Note: can't use QTimer::singleShot with lambda in pre QT 5.4 code
74 QTimer * aux_timer = new QTimer;
75 connect(aux_timer, &QTimer::timeout, this, [this, aux_timer] {
76 delete aux_timer; //cleanup
77 const auto devices = Solid::Device::listFromType(Solid::DeviceInterface::StorageAccess);
78 for (const Solid::Device& device : devices)
79 if (hasRemovableParent(device))
80 addItem(device);
81 });
82 aux_timer->setSingleShot(true);
83 aux_timer->start(0);
84
85 connect(Solid::DeviceNotifier::instance(), &Solid::DeviceNotifier::deviceAdded,
86 this, &Popup::onDeviceAdded);
87 connect(Solid::DeviceNotifier::instance(), &Solid::DeviceNotifier::deviceRemoved,
88 this, &Popup::onDeviceRemoved);
89 }
90
showHide()91 void Popup::showHide()
92 {
93 if (isHidden())
94 {
95 mPlugin->willShowWindow(this);
96 show();
97 } else
98 close();
99 }
100
onDeviceAdded(QString const & udi)101 void Popup::onDeviceAdded(QString const & udi)
102 {
103 Solid::Device device(udi);
104 if (device.is<Solid::StorageAccess>() && hasRemovableParent(device))
105 addItem(device);
106 }
107
onDeviceRemoved(QString const & udi)108 void Popup::onDeviceRemoved(QString const & udi)
109 {
110 MenuDiskItem* item = nullptr;
111 const int size = layout()->count() - 1;
112 for (int i = size; 0 <= i; --i)
113 {
114 QWidget *w = layout()->itemAt(i)->widget();
115 if (w == mPlaceholder)
116 continue;
117
118 MenuDiskItem *it = static_cast<MenuDiskItem *>(w);
119 if (udi == it->deviceUdi())
120 {
121 item = it;
122 break;
123 }
124 }
125
126 if (item != nullptr)
127 {
128 layout()->removeWidget(item);
129 item->deleteLater();
130
131 --mDisplayCount;
132 if (mDisplayCount == 0)
133 mPlaceholder->show();
134
135 emit deviceRemoved(Solid::Device{udi});
136 }
137 }
138
showEvent(QShowEvent * event)139 void Popup::showEvent(QShowEvent *event)
140 {
141 mPlaceholder->setVisible(mDisplayCount == 0);
142 realign();
143 setFocus();
144 activateWindow();
145 QWidget::showEvent(event);
146 emit visibilityChanged(true);
147 }
148
hideEvent(QHideEvent * event)149 void Popup::hideEvent(QHideEvent *event)
150 {
151 QWidget::hideEvent(event);
152 emit visibilityChanged(false);
153 }
154
addItem(Solid::Device device)155 void Popup::addItem(Solid::Device device)
156 {
157 MenuDiskItem *item = new MenuDiskItem(device, this);
158 connect(item, &MenuDiskItem::invalid, this, &Popup::onDeviceRemoved);
159 item->setVisible(true);
160 layout()->addWidget(item);
161
162 mDisplayCount++;
163 if (mDisplayCount != 0)
164 mPlaceholder->hide();
165
166 if (isVisible())
167 realign();
168
169 emit deviceAdded(device);
170 }
171
realign()172 void Popup::realign()
173 {
174 adjustSize();
175 setGeometry(mPlugin->calculatePopupWindowPos(sizeHint()));
176 }
177