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(KF5Kirigami2 ${KF5_MIN_VERSION} REQUIRED)
find_package(KF5CoreAddons ${KF5_MIN_VERSION} REQUIRED)
################# Enable C++11 features for clang and gcc #################

View File

@@ -7,6 +7,8 @@
<project_license>GPL-3.0-or-later</project_license>
<content_rating type="oars-1.1" />
<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>
<description>
<p>Mobile friendly application to monitor Mi Flora devices.</p>
@@ -14,10 +16,15 @@
</description>
<screenshots>
<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>
</screenshots>
<releases>
<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>
</component>

View File

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

View File

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

View File

@@ -8,5 +8,5 @@ set(qiflora_SRCS
qt5_add_resources(RESOURCES resources.qrc)
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})

View File

@@ -1,5 +1,5 @@
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.Layouts 1.12 as Layouts
import QtCharts 2.3 as Charts
@@ -12,6 +12,7 @@ Kirigami.ApplicationWindow {
pageStack.initialPage: mainPageComponent
contextDrawer: Kirigami.ContextDrawer {}
QiFlora {
id: qiflora
@@ -20,7 +21,8 @@ Kirigami.ApplicationWindow {
Component {
id: mainPageComponent
Kirigami.ScrollablePage {
Kirigami.Page {
id: mainPage
mainAction: Kirigami.Action {
iconName: "view-refresh"
text: i18n("Query Device")
@@ -28,131 +30,165 @@ Kirigami.ApplicationWindow {
deviceSelect.open();
}
}
contextualActions: [
Kirigami.Action {
iconName: "help-about"
text: i18n("About")
onTriggered: {
pageStack.replace(aboutPageComponent);
}
}
]
title: "Monitor"
leftPadding: 0
rightPadding: 0
Kirigami.CardsListView {
id: monitorView
model: ListModel {
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
Layouts.ColumnLayout {
anchors.fill: parent
Kirigami.InlineMessage {
Layouts.Layout.fillWidth: true
Layouts.Layout.leftMargin: 10
Layouts.Layout.rightMargin: 10
z: 9997
type: Kirigami.MessageType.Error
id: errorMessage
showCloseButton: true
Connections {
target: qiflora
onErrorHappened: {
errorMessage.text = description;
errorMessage.visible = true;
}
}
}
delegate: Kirigami.Card {
id: card
banner {
title: i18n(model.title)
titleIcon: model.icon
titleLevel: 2
}
header: Row {
layoutDirection: Qt.RightToLeft
topPadding: 10.0
rightPadding: 10.0
Layouts.ColumnLayout {
Kirigami.Heading {
Layouts.Layout.alignment: Qt.AlignCenter
level: 4
text: i18n("Last Measured")
}
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"
Kirigami.CardsListView {
Layouts.Layout.fillWidth: true
Layouts.Layout.fillHeight: true
id: monitorView
model: ListModel {
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
}
}
delegate: Kirigami.Card {
id: card
banner {
title: i18n(model.title)
titleIcon: model.icon
titleLevel: 2
}
header: Row {
layoutDirection: Qt.RightToLeft
topPadding: 10.0
rightPadding: 10.0
Layouts.ColumnLayout {
Kirigami.Heading {
Layouts.Layout.alignment: Qt.AlignCenter
level: 4
text: i18n("Last Measured")
}
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 {
implicitWidth: 300
implicitHeight: 200
Charts.ChartView {
id: chart
antialiasing: true
backgroundColor: Kirigami.Theme.buttonBackgroundColor
titleColor: Kirigami.Theme.textColor
legend.visible: false
anchors.fill: parent
Charts.LineSeries {
id: series
axisX: Charts.DateTimeAxis {
id: dateAx
labelsColor: Kirigami.Theme.textColor
format: "MMM d yyyy ha"
contentItem: Item {
implicitWidth: 300
implicitHeight: 200
Charts.ChartView {
id: chart
antialiasing: true
backgroundColor: Kirigami.Theme.buttonBackgroundColor
titleColor: Kirigami.Theme.textColor
legend.visible: false
anchors.fill: parent
Charts.LineSeries {
id: series
axisX: Charts.DateTimeAxis {
id: dateAx
labelsColor: Kirigami.Theme.textColor
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
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();
Charts.VXYModelMapper {
model: qiflora.model
xColumn: 0
yColumn: modelCol
}
}
axisY: Charts.ValueAxis {
id: valueAx
labelsColor: Kirigami.Theme.textColor
min: yMin
max: yMax
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));
}
}
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 "miflora/miflora.h"
#include "miflora/bluetoothdevices.h"
#include <KAboutData>
#include <QIcon>
Q_DECL_EXPORT int main(int argc, char *argv[])
{
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
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::setOrganizationDomain("eyecreate.org");
QCoreApplication::setApplicationName("qiflora");
QCoreApplication::setApplicationName(aboutData.productName());
QCoreApplication::setApplicationVersion(aboutData.version());
app.setWindowIcon(QIcon::fromTheme("org.eyecreate.qiflora"));
QQmlApplicationEngine engine;
qmlRegisterType<BluetoothDevices>();
qmlRegisterType<MiFlora>("org.eyecreate.qiflora",1,0,"QiFlora");
engine.rootContext()->setContextProperty(QStringLiteral("appAboutData"), QVariant::fromValue(aboutData));
engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
if (engine.rootObjects().isEmpty()) {

View File

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

View File

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