--- a/cadMousePro-gui/nbproject/configurations.xml Tue Sep 03 23:55:00 2019 +0200
+++ b/cadMousePro-gui/nbproject/configurations.xml Wed Sep 04 19:41:21 2019 +0200
@@ -46,6 +46,8 @@
<df name="src">
<df name="generated-sources">
<in>Proxy.cpp</in>
+ <in>UPowerDeviceProxy.cpp</in>
+ <in>UPowerProxy.cpp</in>
</df>
</df>
</df>
@@ -75,6 +77,7 @@
</logicalFolder>
<logicalFolder name="S5VNLJ26FI" displayName="S5VNLJ26FI" projectFiles="true">
<itemPath>build/Debug/src/cadMousePro-gui_autogen/S5VNLJ26FI/moc_Proxy.cpp</itemPath>
+ <itemPath>build/Debug/src/cadMousePro-gui_autogen/S5VNLJ26FI/moc_UPowerProxy.cpp</itemPath>
</logicalFolder>
<itemPath>build/Debug/src/cadMousePro-gui_autogen/mocs_compilation.cpp</itemPath>
</logicalFolder>
@@ -143,6 +146,11 @@
tool="3"
flavor2="0">
</item>
+ <item path="build/Debug/src/cadMousePro-gui_autogen/S5VNLJ26FI/moc_UPowerProxy.cpp"
+ ex="true"
+ tool="3"
+ flavor2="0">
+ </item>
<item path="build/Debug/src/cadMousePro-gui_autogen/mocs_compilation.cpp"
ex="false"
tool="1"
@@ -157,6 +165,20 @@
<ccTool flags="0">
</ccTool>
</item>
+ <item path="build/Debug/src/generated-sources/UPowerDeviceProxy.cpp"
+ ex="false"
+ tool="1"
+ flavor2="8">
+ <ccTool flags="1">
+ </ccTool>
+ </item>
+ <item path="build/Debug/src/generated-sources/UPowerProxy.cpp"
+ ex="false"
+ tool="1"
+ flavor2="8">
+ <ccTool flags="0">
+ </ccTool>
+ </item>
<item path="build/qt/src/cadMousePro-gui_autogen/mocs_compilation.cpp"
ex="false"
tool="1"
--- a/cadMousePro-gui/src/CMakeLists.txt Tue Sep 03 23:55:00 2019 +0200
+++ b/cadMousePro-gui/src/CMakeLists.txt Wed Sep 04 19:41:21 2019 +0200
@@ -13,8 +13,9 @@
# Generate C++ interface classes from D-Bus XML:
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/generated-sources/)
+set(GENERATED_SOURCES ${CMAKE_CURRENT_BINARY_DIR}/generated-sources/)
+
set(DBUS_XML ${CMAKE_CURRENT_SOURCE_DIR}/../../d-bus/info.globalcode.mouse.cadMousePro.xml)
-set(GENERATED_SOURCES ${CMAKE_CURRENT_BINARY_DIR}/generated-sources/)
add_custom_command(
DEPENDS ${DBUS_XML}
OUTPUT ${GENERATED_SOURCES}/Proxy.h
@@ -22,6 +23,16 @@
COMMAND qdbusxml2cpp -p Proxy.h:Proxy.cpp ${DBUS_XML}
WORKING_DIRECTORY ${GENERATED_SOURCES}
)
+
+set(DBUS_XML ${CMAKE_CURRENT_SOURCE_DIR}/../../d-bus/org.freedesktop.UPower.xml)
+add_custom_command(
+ DEPENDS ${DBUS_XML}
+ OUTPUT ${GENERATED_SOURCES}/UPowerProxy.h
+ OUTPUT ${GENERATED_SOURCES}/UPowerProxy.cpp
+ COMMAND qdbusxml2cpp -N -p UPowerProxy.h:UPowerProxy.cpp ${DBUS_XML}
+ WORKING_DIRECTORY ${GENERATED_SOURCES}
+)
+
cmake_policy(SET CMP0071 NEW) # Let AUTOMOC and AUTOUIC process GENERATED files.
# Executable output:
@@ -29,6 +40,8 @@
${EXECUTABLE_FILE}
${CMAKE_CURRENT_BINARY_DIR}/generated-sources/Proxy.h
${CMAKE_CURRENT_BINARY_DIR}/generated-sources/Proxy.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/generated-sources/UPowerProxy.h
+ ${CMAKE_CURRENT_BINARY_DIR}/generated-sources/UPowerProxy.cpp
MouseMainWindow.h
MouseMainWindow.cpp
cadMouseProGUI.cpp
--- a/cadMousePro-gui/src/MouseMainWindow.cpp Tue Sep 03 23:55:00 2019 +0200
+++ b/cadMousePro-gui/src/MouseMainWindow.cpp Wed Sep 04 19:41:21 2019 +0200
@@ -17,11 +17,13 @@
*/
#include <QLabel>
#include <QPushButton>
+#include <qt5/QtDBus/qdbuspendingcall.h>
#include "MouseMainWindow.h"
MouseMainWindow::MouseMainWindow() {
proxy = new InfoGlobalcodeMouseCadMouseProInterface("info.globalcode.mouse.cadMousePro", "/info/globalcode/mouse/cadMousePro", connection, this);
+ upowerProxy = new OrgFreedesktopUPowerInterface("org.freedesktop.UPower", "/org/freedesktop/UPower", connection, this);
setWindowTitle("cadMousePro");
@@ -42,12 +44,19 @@
statusProxy->setEnabled(false);
statusUPower->setEnabled(false);
statusDevice->setEnabled(false);
+ statusBattery->setOrientation(Qt::Orientation::Horizontal);
+ statusBattery->setMinimum(0);
+ statusBattery->setMaximum(100);
+
+ statusUPower->setToolTip("UPower interface is used for getting the battery level");
statusName->setToolTip("name of the USB device – usually the wireless adaptor");
+ statusBattery->setToolTip("battery charge level");
layout->setWidget(f++, QFormLayout::FieldRole, statusProxy);
layout->setWidget(f++, QFormLayout::FieldRole, statusUPower);
layout->setWidget(f++, QFormLayout::FieldRole, statusDevice);
layout->setWidget(f++, QFormLayout::FieldRole, statusName);
+ layout->setWidget(f++, QFormLayout::FieldRole, statusBattery);
QPushButton* refreshButton = new QPushButton("Refresh", panel);
layout->setWidget(f++, QFormLayout::FieldRole, refreshButton);
@@ -86,10 +95,10 @@
void MouseMainWindow::appendAboutLine(QFormLayout* layout, const QString& label, const QString& value, QWidget* parent) {
QLabel* labelWidget = new QLabel(label, parent);
QLabel* textWidget = new QLabel(value, parent);
-
+
textWidget->setTextInteractionFlags(Qt::TextInteractionFlag::TextSelectableByMouse | Qt::TextInteractionFlag::TextBrowserInteraction);
textWidget->setOpenExternalLinks(true);
-
+
layout->addRow(labelWidget, textWidget);
}
@@ -107,10 +116,29 @@
tabs->addTab(panel, "About");
}
+/**
+ * Finds the first HID mouse managed by UPower and returns its battery level.
+ *
+ * @return percentage of the current battery charge or 0 if no suitable mouse was found
+ */
+int MouseMainWindow::getBatteryLevel() {
+ auto devices = upowerProxy->EnumerateDevices();
+ devices.waitForFinished();
+ for (auto device : devices.value()) {
+ if (device.path().startsWith(upowerProxy->path() + "/devices/mouse_hid_") && device.path().endsWith("_battery")) {
+ OrgFreedesktopUPowerDeviceInterface battery(upowerProxy->service(), device.path(), connection, this);
+ if (battery.isValid()) return battery.percentage();
+ }
+ }
+ return 0; // mouse with battery not found
+}
+
void MouseMainWindow::refresh() {
statusProxy->setChecked(proxy->isValid());
+ statusUPower->setChecked(upowerProxy->isValid());
statusDevice->setChecked(proxy->devicePresent());
statusName->setText(proxy->deviceName());
+ statusBattery->setValue(getBatteryLevel());
}
void MouseMainWindow::configure() {
--- a/cadMousePro-gui/src/MouseMainWindow.h Tue Sep 03 23:55:00 2019 +0200
+++ b/cadMousePro-gui/src/MouseMainWindow.h Wed Sep 04 19:41:21 2019 +0200
@@ -25,9 +25,11 @@
#include <QButtonGroup>
#include <QLineEdit>
#include <QLabel>
+#include <QProgressBar>
#include <QtDBus/QDBusConnection>
#include "generated-sources/Proxy.h"
+#include "generated-sources/UPowerProxy.h"
class MouseMainWindow : public QMainWindow {
Q_OBJECT
@@ -43,6 +45,7 @@
QCheckBox* statusUPower = new QCheckBox("connected to UPower", this);
QCheckBox* statusDevice = new QCheckBox("mouse found", this);
QLabel* statusName = new QLabel(this);
+ QProgressBar* statusBattery = new QProgressBar(this);
QCheckBox* configureSmartScrolling = new QCheckBox("smart scrolling (free wheel)", this);
QCheckBox* configureLiftOffDetection = new QCheckBox("lift-off detection", this);
@@ -55,12 +58,15 @@
QDBusConnection connection = QDBusConnection::systemBus();
InfoGlobalcodeMouseCadMouseProInterface* proxy;
+ OrgFreedesktopUPowerInterface* upowerProxy;
void initStatusPanel();
void initConfigurationPanel();
void initAboutPanel();
void appendAboutLine(QFormLayout* layout, const QString& label, const QString& value, QWidget* parent);
+
+ int getBatteryLevel();
private slots:
void refresh();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/d-bus/org.freedesktop.UPower.xml Wed Sep 04 19:41:21 2019 +0200
@@ -0,0 +1,13 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node>
+ <interface name="org.freedesktop.UPower">
+ <method name="EnumerateDevices">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <arg type="ao" name="devices" direction="out"/>
+ </method>
+ </interface>
+
+ <interface name="org.freedesktop.UPower.Device">
+ <property type="d" name="Percentage" access="read"/>
+ </interface>
+</node>