Update packaging and use KF5 for about screen. Implement basic notifications for error messages. Use icon for app icon.

This commit is contained in:
2019-11-13 21:43:58 -05:00
parent 9c5c50ef95
commit 90da697f84
9 changed files with 192 additions and 118 deletions

View File

@@ -30,6 +30,7 @@ include(KDECompilerSettings NO_POLICY_SCOPE)
find_package(Qt5 ${QT_MIN_VERSION} REQUIRED NO_MODULE COMPONENTS Core Quick Test Gui Svg QuickControls2 Bluetooth Charts) find_package(Qt5 ${QT_MIN_VERSION} REQUIRED NO_MODULE COMPONENTS Core Quick Test Gui Svg QuickControls2 Bluetooth Charts)
find_package(KF5Kirigami2 ${KF5_MIN_VERSION} REQUIRED) find_package(KF5Kirigami2 ${KF5_MIN_VERSION} REQUIRED)
find_package(KF5CoreAddons ${KF5_MIN_VERSION} REQUIRED)
################# Enable C++11 features for clang and gcc ################# ################# Enable C++11 features for clang and gcc #################

View File

@@ -7,6 +7,8 @@
<project_license>GPL-3.0-or-later</project_license> <project_license>GPL-3.0-or-later</project_license>
<content_rating type="oars-1.1" /> <content_rating type="oars-1.1" />
<url type="homepage">https://git.eyecreate.org/eyecreate/qiflora</url> <url type="homepage">https://git.eyecreate.org/eyecreate/qiflora</url>
<url type="contact">mailto:eyecreate@eyecreate.org</url>
<url type="donation">monero:49DAuwzCytB8cWVA8RXGcv1cviG2QRtZWW4U7KeX9mAtLfAewk8LAAwAUhwCRXD9tz8LESmgaAPrjZ62G8Z6JrdhRmLx2kY?tx_description=donation</url>
<developer_name>eyecreate</developer_name> <developer_name>eyecreate</developer_name>
<description> <description>
<p>Mobile friendly application to monitor Mi Flora devices.</p> <p>Mobile friendly application to monitor Mi Flora devices.</p>
@@ -14,10 +16,15 @@
</description> </description>
<screenshots> <screenshots>
<screenshot type="default"> <screenshot type="default">
<image type="source">https://git.eyecreate.org/eyecreate/qiflora/raw/v1.0/packaging/main_window.png</image> <image type="source">https://git.eyecreate.org/eyecreate/qiflora/raw/v1.1/packaging/main_window.png</image>
</screenshot> </screenshot>
</screenshots> </screenshots>
<releases> <releases>
<release version="1.0" date="2019-11-8" type="stable"/> <release version="1.0" date="2019-11-8" type="stable"/>
<release version="1.1" date="2019-11-13" type="stable">
<description>
<p>This release adds history graph for the last 48 hours.</p>
</description>
</release>
</releases> </releases>
</component> </component>

View File

@@ -1,7 +1,7 @@
[Desktop Entry] [Desktop Entry]
Name=QiFlora Name=QiFlora
Comment=Monitor plants with Mi Flora sensors. Comment=Monitor plants with Mi Flora sensors.
Version=1.0 Version=1.1
Exec=qiflora Exec=qiflora
MimeType=application/x-qiflora; MimeType=application/x-qiflora;
Icon=org.eyecreate.qiflora Icon=org.eyecreate.qiflora

View File

@@ -87,7 +87,7 @@
{ {
"type": "git", "type": "git",
"url": "https://git.eyecreate.org/eyecreate/qiflora.git", "url": "https://git.eyecreate.org/eyecreate/qiflora.git",
"tag": "v1.0", "tag": "v1.1",
"commit": "bcdf831d0c64f84642f53a4f8376a26df412b819" "commit": "bcdf831d0c64f84642f53a4f8376a26df412b819"
} }
] ]

View File

@@ -8,5 +8,5 @@ set(qiflora_SRCS
qt5_add_resources(RESOURCES resources.qrc) qt5_add_resources(RESOURCES resources.qrc)
add_executable(qiflora ${qiflora_SRCS} ${RESOURCES}) add_executable(qiflora ${qiflora_SRCS} ${RESOURCES})
target_link_libraries(qiflora Qt5::Core Qt5::Qml Qt5::Quick Qt5::Svg Qt5::Bluetooth Qt5::Charts) target_link_libraries(qiflora Qt5::Core Qt5::Qml Qt5::Quick Qt5::Svg Qt5::Bluetooth Qt5::Charts KF5::CoreAddons)
install(TARGETS qiflora ${KF5_INSTALL_TARGETS_DEFAULT_ARGS}) install(TARGETS qiflora ${KF5_INSTALL_TARGETS_DEFAULT_ARGS})

View File

@@ -1,5 +1,5 @@
import QtQuick 2.6 import QtQuick 2.6
import org.kde.kirigami 2.4 as Kirigami import org.kde.kirigami 2.6 as Kirigami
import QtQuick.Controls 2.0 as Controls import QtQuick.Controls 2.0 as Controls
import QtQuick.Layouts 1.12 as Layouts import QtQuick.Layouts 1.12 as Layouts
import QtCharts 2.3 as Charts import QtCharts 2.3 as Charts
@@ -12,6 +12,7 @@ Kirigami.ApplicationWindow {
pageStack.initialPage: mainPageComponent pageStack.initialPage: mainPageComponent
contextDrawer: Kirigami.ContextDrawer {}
QiFlora { QiFlora {
id: qiflora id: qiflora
@@ -20,7 +21,8 @@ Kirigami.ApplicationWindow {
Component { Component {
id: mainPageComponent id: mainPageComponent
Kirigami.ScrollablePage { Kirigami.Page {
id: mainPage
mainAction: Kirigami.Action { mainAction: Kirigami.Action {
iconName: "view-refresh" iconName: "view-refresh"
text: i18n("Query Device") text: i18n("Query Device")
@@ -28,131 +30,165 @@ Kirigami.ApplicationWindow {
deviceSelect.open(); deviceSelect.open();
} }
} }
contextualActions: [
Kirigami.Action {
iconName: "help-about"
text: i18n("About")
onTriggered: {
pageStack.replace(aboutPageComponent);
}
}
]
title: "Monitor" title: "Monitor"
leftPadding: 0
rightPadding: 0
Kirigami.CardsListView { Layouts.ColumnLayout {
id: monitorView anchors.fill: parent
model: ListModel { Kirigami.InlineMessage {
id: monitorTypes Layouts.Layout.fillWidth: true
ListElement{ Layouts.Layout.leftMargin: 10
chartType: "temperature" Layouts.Layout.rightMargin: 10
title: "Temperature" z: 9997
icon: "filename-bpm-amarok" type: Kirigami.MessageType.Error
lineColor: "red" id: errorMessage
yMin: -20 showCloseButton: true
yMax: 40 Connections {
modelCol: 1 target: qiflora
} onErrorHappened: {
ListElement{ errorMessage.text = description;
chartType: "moisture" errorMessage.visible = true;
title: "Moisture" }
icon: "colors-chromablue"
lineColor: "cyan"
yMin: 0
yMax: 75
modelCol: 3
}
ListElement{
chartType: "conductivity"
title: "Conductivity"
icon: "quickopen"
lineColor: "gold"
yMin: 0
yMax: 6000
modelCol: 4
}
ListElement{
chartType: "brightness"
title: "Brightness"
icon: "contrast"
lineColor: "orange"
yMin: 0
yMax: 30000
modelCol: 2
} }
} }
delegate: Kirigami.Card { Kirigami.CardsListView {
id: card Layouts.Layout.fillWidth: true
banner { Layouts.Layout.fillHeight: true
title: i18n(model.title) id: monitorView
titleIcon: model.icon model: ListModel {
titleLevel: 2 id: monitorTypes
ListElement{
chartType: "temperature"
title: "Temperature"
icon: "filename-bpm-amarok"
lineColor: "red"
yMin: -20
yMax: 40
modelCol: 1
}
ListElement{
chartType: "moisture"
title: "Moisture"
icon: "colors-chromablue"
lineColor: "cyan"
yMin: 0
yMax: 75
modelCol: 3
}
ListElement{
chartType: "conductivity"
title: "Conductivity"
icon: "quickopen"
lineColor: "gold"
yMin: 0
yMax: 6000
modelCol: 4
}
ListElement{
chartType: "brightness"
title: "Brightness"
icon: "contrast"
lineColor: "orange"
yMin: 0
yMax: 30000
modelCol: 2
}
} }
header: Row {
layoutDirection: Qt.RightToLeft delegate: Kirigami.Card {
topPadding: 10.0 id: card
rightPadding: 10.0 banner {
Layouts.ColumnLayout { title: i18n(model.title)
Kirigami.Heading { titleIcon: model.icon
Layouts.Layout.alignment: Qt.AlignCenter titleLevel: 2
level: 4 }
text: i18n("Last Measured") header: Row {
} layoutDirection: Qt.RightToLeft
Kirigami.Heading { topPadding: 10.0
Layouts.Layout.alignment: Qt.AlignCenter rightPadding: 10.0
level: 3 Layouts.ColumnLayout {
text: { Kirigami.Heading {
if(model.chartType == "temperature") qiflora.temperature + "°C\n" + (qiflora.temperature*1.8+32) + "°F" Layouts.Layout.alignment: Qt.AlignCenter
else if(model.chartType == "moisture") qiflora.moisture + "%" level: 4
else if(model.chartType == "conductivity") qiflora.conduction + " µS/cm" text: i18n("Last Measured")
else if(model.chartType == "brightness") qiflora.brightness + " lux" }
Kirigami.Heading {
Layouts.Layout.alignment: Qt.AlignCenter
level: 3
text: {
if(model.chartType == "temperature") qiflora.temperature + "°C\n" + (qiflora.temperature*1.8+32) + "°F"
else if(model.chartType == "moisture") qiflora.moisture + "%"
else if(model.chartType == "conductivity") qiflora.conduction + " µS/cm"
else if(model.chartType == "brightness") qiflora.brightness + " lux"
}
} }
} }
} }
} contentItem: Item {
contentItem: Item { implicitWidth: 300
implicitWidth: 300 implicitHeight: 200
implicitHeight: 200 Charts.ChartView {
Charts.ChartView { id: chart
id: chart antialiasing: true
antialiasing: true backgroundColor: Kirigami.Theme.buttonBackgroundColor
backgroundColor: Kirigami.Theme.buttonBackgroundColor titleColor: Kirigami.Theme.textColor
titleColor: Kirigami.Theme.textColor legend.visible: false
legend.visible: false anchors.fill: parent
anchors.fill: parent
Charts.LineSeries { Charts.LineSeries {
id: series id: series
axisX: Charts.DateTimeAxis { axisX: Charts.DateTimeAxis {
id: dateAx id: dateAx
labelsColor: Kirigami.Theme.textColor labelsColor: Kirigami.Theme.textColor
format: "MMM d yyyy ha" format: "MMM d yyyy ha"
Component.onCompleted: {
//On load, change date span to last 24 to remove awkward 1969 empty dates.
var yesterday = new Date();
yesterday.setDate(yesterday.getDate() -1);
dateAx.min = yesterday;
dateAx.max = new Date();
}
}
axisY: Charts.ValueAxis {
id: valueAx
labelsColor: Kirigami.Theme.textColor
min: yMin
max: yMax
}
color: model.lineColor
name: model.title
Charts.VXYModelMapper {
model: qiflora.model
xColumn: 0
yColumn: modelCol
Component.onCompleted: {
//On load, change date span to last 24 to remove awkward 1969 empty dates.
var yesterday = new Date();
yesterday.setDate(yesterday.getDate() -1);
dateAx.min = yesterday;
dateAx.max = new Date();
} }
} }
axisY: Charts.ValueAxis { Connections {
id: valueAx target: qiflora.model
labelsColor: Kirigami.Theme.textColor onRowsInserted: {
min: yMin //Readjust graphs to show date range from earliest item.
max: yMax dateAx.max = new Date();
dateAx.min = qiflora.model.data(qiflora.model.index(0,0));
}
} }
color: model.lineColor }
name: model.title
Charts.VXYModelMapper {
model: qiflora.model
xColumn: 0
yColumn: modelCol
}
}
Connections {
target: qiflora.model
onRowsInserted: {
//Readjust graphs to show date range from earliest item.
dateAx.max = new Date();
dateAx.min = qiflora.model.data(qiflora.model.index(0,0));
}
}
} }
} }
Controls.ScrollBar.vertical: Controls.ScrollBar {}
} }
} }
@@ -202,4 +238,20 @@ Kirigami.ApplicationWindow {
} }
} }
} }
Component {
id:aboutPageComponent
Kirigami.AboutPage {
id: aboutPage
actions.main: Kirigami.Action {
iconName: "window-close"
text: "Close"
onTriggered: {
pageStack.clear();
pageStack.push(mainPageComponent);
}
}
aboutData: appAboutData
}
}
} }

View File

@@ -4,19 +4,30 @@
#include <QUrl> #include <QUrl>
#include "miflora/miflora.h" #include "miflora/miflora.h"
#include "miflora/bluetoothdevices.h" #include "miflora/bluetoothdevices.h"
#include <KAboutData>
#include <QIcon>
Q_DECL_EXPORT int main(int argc, char *argv[]) Q_DECL_EXPORT int main(int argc, char *argv[])
{ {
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication app(argc, argv); QApplication app(argc, argv);
KAboutData aboutData("org.eyecreate.qiflora", "QiFlora", "1.1", "Mobile friendly application to monitor Mi Flora devices.",KAboutLicense::GPL_V3);//TODO:i18n
aboutData.setProductName("qiflora");
aboutData.addAuthor("Kevin Whitaker",QString(),"eyecreate@eyecreate.org","https://www.eyecreate.org");
aboutData.setDesktopFileName("org.eyecreate.qiflora");
QCoreApplication::setOrganizationName("eyecreate"); QCoreApplication::setOrganizationName("eyecreate");
QCoreApplication::setOrganizationDomain("eyecreate.org"); QCoreApplication::setOrganizationDomain("eyecreate.org");
QCoreApplication::setApplicationName("qiflora"); QCoreApplication::setApplicationName(aboutData.productName());
QCoreApplication::setApplicationVersion(aboutData.version());
app.setWindowIcon(QIcon::fromTheme("org.eyecreate.qiflora"));
QQmlApplicationEngine engine; QQmlApplicationEngine engine;
qmlRegisterType<BluetoothDevices>(); qmlRegisterType<BluetoothDevices>();
qmlRegisterType<MiFlora>("org.eyecreate.qiflora",1,0,"QiFlora"); qmlRegisterType<MiFlora>("org.eyecreate.qiflora",1,0,"QiFlora");
engine.rootContext()->setContextProperty(QStringLiteral("appAboutData"), QVariant::fromValue(aboutData));
engine.load(QUrl(QStringLiteral("qrc:///main.qml"))); engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
if (engine.rootObjects().isEmpty()) { if (engine.rootObjects().isEmpty()) {

View File

@@ -77,11 +77,13 @@ QQmlListProperty<BluetoothDevices> MiFlora::getDeviceList()
void MiFlora::logControllerError ( QLowEnergyController::Error err ) void MiFlora::logControllerError ( QLowEnergyController::Error err )
{ {
qDebug() << "Error:" << err; qDebug() << "Error:" << err;
emit errorHappened(currentController->errorString());
} }
void MiFlora::logServiceError(QLowEnergyService::ServiceError err) void MiFlora::logServiceError(QLowEnergyService::ServiceError err)
{ {
qDebug() << "Service Error:" << err; qDebug() << "Service Error:" << err;
emit errorHappened("Possible Read/Write error!");
} }

View File

@@ -57,6 +57,7 @@ public:
signals: signals:
void newDeviceFound(); void newDeviceFound();
void modelUpdated(); void modelUpdated();
void errorHappened(QString description);
void temperatureChanged(float temperature); void temperatureChanged(float temperature);
void brightnessChanged(quint32 brightness); void brightnessChanged(quint32 brightness);
void moistureChanged(quint8 moisture); void moistureChanged(quint8 moisture);