display the battery charge level (from UPower) v_0 v0.3
authorFrantišek Kučera <franta-hg@frantovo.cz>
Wed, 04 Sep 2019 19:41:21 +0200
branchv_0
changeset 21 642f32f76c9d
parent 20 cfb5f62ea048
child 22 e0e4fe5e7c03
display the battery charge level (from UPower)
cadMousePro-gui/nbproject/configurations.xml
cadMousePro-gui/src/CMakeLists.txt
cadMousePro-gui/src/MouseMainWindow.cpp
cadMousePro-gui/src/MouseMainWindow.h
d-bus/org.freedesktop.UPower.xml
--- 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>