System to collect usage statistic.
This commit is contained in:
parent
53dc4135e3
commit
eaf9d65339
|
@ -22,7 +22,8 @@ DEPENDPATH += \
|
||||||
../../src/libs/vtools \
|
../../src/libs/vtools \
|
||||||
../../src/libs/vformat \
|
../../src/libs/vformat \
|
||||||
../../src/libs/fervor \
|
../../src/libs/fervor \
|
||||||
../../src/libs/vwidgets
|
../../src/libs/vwidgets \
|
||||||
|
../../src/libs/vganalytics
|
||||||
|
|
||||||
include(../../src/app/valentina/valentina.pri)
|
include(../../src/app/valentina/valentina.pri)
|
||||||
include(../../src/app/tape/tape.pri)
|
include(../../src/app/tape/tape.pri)
|
||||||
|
@ -39,6 +40,7 @@ include(../../src/libs/vtools/vtools.pri)
|
||||||
include(../../src/libs/vformat/vformat.pri)
|
include(../../src/libs/vformat/vformat.pri)
|
||||||
include(../../src/libs/fervor/fervor.pri)
|
include(../../src/libs/fervor/fervor.pri)
|
||||||
include(../../src/libs/vwidgets/vwidgets.pri)
|
include(../../src/libs/vwidgets/vwidgets.pri)
|
||||||
|
include(../../src/libs/vganalytics/vganalytics.pri)
|
||||||
|
|
||||||
# Add here path to new translation file with name "valentina_*_*.ts" if you want to add new language.
|
# Add here path to new translation file with name "valentina_*_*.ts" if you want to add new language.
|
||||||
# Same paths in variable INSTALL_TRANSLATIONS (translations.pri).
|
# Same paths in variable INSTALL_TRANSLATIONS (translations.pri).
|
||||||
|
|
|
@ -33,6 +33,8 @@
|
||||||
#include "../vmisc/backport/qoverload.h"
|
#include "../vmisc/backport/qoverload.h"
|
||||||
#endif // QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
|
#endif // QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
|
||||||
|
|
||||||
|
#include "../vganalytics/vganalytics.h"
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
PuzzlePreferencesConfigurationPage::PuzzlePreferencesConfigurationPage(QWidget *parent)
|
PuzzlePreferencesConfigurationPage::PuzzlePreferencesConfigurationPage(QWidget *parent)
|
||||||
: QWidget(parent),
|
: QWidget(parent),
|
||||||
|
@ -89,6 +91,9 @@ PuzzlePreferencesConfigurationPage::PuzzlePreferencesConfigurationPage(QWidget *
|
||||||
ui->doubleSpinBoxAcceleration->setMinimum(VCommonSettings::scrollingAccelerationMin);
|
ui->doubleSpinBoxAcceleration->setMinimum(VCommonSettings::scrollingAccelerationMin);
|
||||||
ui->doubleSpinBoxAcceleration->setMaximum(VCommonSettings::scrollingAccelerationMax);
|
ui->doubleSpinBoxAcceleration->setMaximum(VCommonSettings::scrollingAccelerationMax);
|
||||||
ui->doubleSpinBoxAcceleration->setValue(settings->GetScrollingAcceleration());
|
ui->doubleSpinBoxAcceleration->setValue(settings->GetScrollingAcceleration());
|
||||||
|
|
||||||
|
// Tab Privacy
|
||||||
|
ui->checkBoxSendUsageStatistics->setChecked(settings->IsCollectStatistic());
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -166,6 +171,10 @@ auto PuzzlePreferencesConfigurationPage::Apply() -> QStringList
|
||||||
settings->SetWheelMouseScale(ui->doubleSpinBoxWheel->value());
|
settings->SetWheelMouseScale(ui->doubleSpinBoxWheel->value());
|
||||||
settings->SetScrollingAcceleration(ui->doubleSpinBoxAcceleration->value());
|
settings->SetScrollingAcceleration(ui->doubleSpinBoxAcceleration->value());
|
||||||
|
|
||||||
|
// Tab Privacy
|
||||||
|
settings->SetCollectStatistic(ui->checkBoxSendUsageStatistics->isChecked());
|
||||||
|
VGAnalytics::Instance()->Enable(ui->checkBoxSendUsageStatistics->isChecked());
|
||||||
|
|
||||||
return preferences;
|
return preferences;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>545</width>
|
<width>539</width>
|
||||||
<height>696</height>
|
<height>702</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
@ -34,8 +34,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>503</width>
|
<width>497</width>
|
||||||
<height>627</height>
|
<height>633</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_10">
|
<layout class="QVBoxLayout" name="verticalLayout_10">
|
||||||
|
@ -424,6 +424,43 @@ This option will take an affect after restart.</string>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QWidget" name="tabPrivacy">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Privacy</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_11">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkBoxSendUsageStatistics">
|
||||||
|
<property name="text">
|
||||||
|
<string>Send usage statistics</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Please help to improve Valentina's quality by automatically sending usage statistics. Sent data contains <span style=" font-weight:700;">no potentially sensitive information</span> like user names, email addresses, file contents or file paths.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_3">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>540</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|
|
@ -282,6 +282,15 @@ DEPENDPATH += $$PWD/../../libs/vdxf
|
||||||
win32:!win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vdxf/$${DESTDIR}/vdxf.lib
|
win32:!win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vdxf/$${DESTDIR}/vdxf.lib
|
||||||
else:unix|win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vdxf/$${DESTDIR}/libvdxf.a
|
else:unix|win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vdxf/$${DESTDIR}/libvdxf.a
|
||||||
|
|
||||||
|
# VGAnalytics static library
|
||||||
|
unix|win32: LIBS += -L$$OUT_PWD/../../libs/vganalytics/$${DESTDIR}/ -lvganalytics
|
||||||
|
|
||||||
|
INCLUDEPATH += $$PWD/../../libs/vganalytics
|
||||||
|
DEPENDPATH += $$PWD/../../libs/vganalytics
|
||||||
|
|
||||||
|
win32:!win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vganalytics/$${DESTDIR}/vganalytics.lib
|
||||||
|
else:unix|win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vganalytics/$${DESTDIR}/libvganalytics.a
|
||||||
|
|
||||||
# QMuParser library
|
# QMuParser library
|
||||||
win32:CONFIG(release, debug|release): LIBS += -L$${OUT_PWD}/../../libs/qmuparser/$${DESTDIR} -lqmuparser2
|
win32:CONFIG(release, debug|release): LIBS += -L$${OUT_PWD}/../../libs/qmuparser/$${DESTDIR} -lqmuparser2
|
||||||
else:win32:CONFIG(debug, debug|release): LIBS += -L$${OUT_PWD}/../../libs/qmuparser/$${DESTDIR} -lqmuparser2
|
else:win32:CONFIG(debug, debug|release): LIBS += -L$${OUT_PWD}/../../libs/qmuparser/$${DESTDIR} -lqmuparser2
|
||||||
|
|
|
@ -12,6 +12,7 @@ VToolApp {
|
||||||
Depends { name: "VWidgetsLib" }
|
Depends { name: "VWidgetsLib" }
|
||||||
Depends { name: "FervorLib" }
|
Depends { name: "FervorLib" }
|
||||||
Depends { name: "multibundle"; }
|
Depends { name: "multibundle"; }
|
||||||
|
Depends { name: "VGAnalyticsLib" }
|
||||||
|
|
||||||
name: "Puzzle"
|
name: "Puzzle"
|
||||||
buildconfig.appTarget: qbs.targetOS.contains("macos") ? "Puzzle" : "puzzle"
|
buildconfig.appTarget: qbs.targetOS.contains("macos") ? "Puzzle" : "puzzle"
|
||||||
|
|
|
@ -32,6 +32,8 @@
|
||||||
#include "../ifc/exception/vexceptionemptyparameter.h"
|
#include "../ifc/exception/vexceptionemptyparameter.h"
|
||||||
#include "../ifc/exception/vexceptionobjecterror.h"
|
#include "../ifc/exception/vexceptionobjecterror.h"
|
||||||
#include "../ifc/exception/vexceptionwrongid.h"
|
#include "../ifc/exception/vexceptionwrongid.h"
|
||||||
|
#include "../vganalytics/def.h"
|
||||||
|
#include "../vganalytics/vganalytics.h"
|
||||||
#include "../vmisc/vsysexits.h"
|
#include "../vmisc/vsysexits.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "vpmainwindow.h"
|
#include "vpmainwindow.h"
|
||||||
|
@ -277,6 +279,17 @@ VPApplication::VPApplication(int &argc, char **argv)
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
VPApplication::~VPApplication()
|
VPApplication::~VPApplication()
|
||||||
{
|
{
|
||||||
|
if (settings->IsCollectStatistic())
|
||||||
|
{
|
||||||
|
auto *statistic = VGAnalytics::Instance();
|
||||||
|
|
||||||
|
QString clientID = settings->GetClientID();
|
||||||
|
if (!clientID.isEmpty())
|
||||||
|
{
|
||||||
|
statistic->SendAppCloseEvent(m_uptimeTimer.elapsed());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
qDeleteAll(m_mainWindows);
|
qDeleteAll(m_mainWindows);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -430,6 +443,19 @@ void VPApplication::InitOptions()
|
||||||
QIcon::setThemeName(QStringLiteral("win.icon.theme"));
|
QIcon::setThemeName(QStringLiteral("win.icon.theme"));
|
||||||
}
|
}
|
||||||
ActivateDarkMode();
|
ActivateDarkMode();
|
||||||
|
|
||||||
|
auto *statistic = VGAnalytics::Instance();
|
||||||
|
QString clientID = settings->GetClientID();
|
||||||
|
if (clientID.isEmpty())
|
||||||
|
{
|
||||||
|
clientID = QUuid::createUuid().toString();
|
||||||
|
settings->SetClientID(clientID);
|
||||||
|
}
|
||||||
|
statistic->SetClientID(clientID);
|
||||||
|
statistic->SetGUILanguage(settings->GetLocale());
|
||||||
|
statistic->SetMeasurementId(GA_MEASUREMENT_ID);
|
||||||
|
statistic->SetApiSecret(GA_API_SECRET);
|
||||||
|
statistic->Enable(settings->IsCollectStatistic());
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
#include "../vlayout/vlayoutexporter.h"
|
#include "../vlayout/vlayoutexporter.h"
|
||||||
#include "../vlayout/vprintlayout.h"
|
#include "../vlayout/vprintlayout.h"
|
||||||
#include "../vlayout/vrawlayout.h"
|
#include "../vlayout/vrawlayout.h"
|
||||||
|
#include "../vmisc/dialogs/dialogaskcollectstatistic.h"
|
||||||
#include "../vmisc/dialogs/dialogselectlanguage.h"
|
#include "../vmisc/dialogs/dialogselectlanguage.h"
|
||||||
#include "../vmisc/lambdaconstants.h"
|
#include "../vmisc/lambdaconstants.h"
|
||||||
#include "../vmisc/projectversion.h"
|
#include "../vmisc/projectversion.h"
|
||||||
|
@ -67,6 +68,7 @@
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
|
#if QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
|
||||||
#include "../vmisc/backport/qoverload.h"
|
#include "../vmisc/backport/qoverload.h"
|
||||||
#endif // QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
|
#endif // QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
|
||||||
|
#include "../vganalytics/vganalytics.h"
|
||||||
#include "layout/vppiece.h"
|
#include "layout/vppiece.h"
|
||||||
#include "vptilefactory.h"
|
#include "vptilefactory.h"
|
||||||
|
|
||||||
|
@ -389,7 +391,7 @@ VPMainWindow::VPMainWindow(const VPCommandLinePtr &cmd, QWidget *parent)
|
||||||
|
|
||||||
if (m_cmd->IsGuiEnabled())
|
if (m_cmd->IsGuiEnabled())
|
||||||
{
|
{
|
||||||
QTimer::singleShot(V_SECONDS(1), this, &VPMainWindow::SetDefaultGUILanguage);
|
QTimer::singleShot(V_SECONDS(1), this, &VPMainWindow::AskDefaultSettings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4536,7 +4538,7 @@ void VPMainWindow::RemoveWatermark()
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
void VPMainWindow::SetDefaultGUILanguage()
|
void VPMainWindow::AskDefaultSettings()
|
||||||
{
|
{
|
||||||
if (m_cmd->IsGuiEnabled())
|
if (m_cmd->IsGuiEnabled())
|
||||||
{
|
{
|
||||||
|
@ -4554,6 +4556,38 @@ void VPMainWindow::SetDefaultGUILanguage()
|
||||||
VAbstractApplication::VApp()->LoadTranslation(locale);
|
VAbstractApplication::VApp()->LoadTranslation(locale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (settings->IsAskCollectStatistic())
|
||||||
|
{
|
||||||
|
DialogAskCollectStatistic dialog(this);
|
||||||
|
if (dialog.exec() == QDialog::Accepted)
|
||||||
|
{
|
||||||
|
settings->SetCollectStatistic(dialog.CollectStatistic());
|
||||||
|
}
|
||||||
|
|
||||||
|
settings->SetAskCollectStatistic(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings->IsCollectStatistic())
|
||||||
|
{
|
||||||
|
auto *statistic = VGAnalytics::Instance();
|
||||||
|
statistic->SetGUILanguage(settings->GetLocale());
|
||||||
|
|
||||||
|
QString clientID = settings->GetClientID();
|
||||||
|
bool freshID = false;
|
||||||
|
if (clientID.isEmpty())
|
||||||
|
{
|
||||||
|
clientID = QUuid::createUuid().toString();
|
||||||
|
settings->SetClientID(clientID);
|
||||||
|
statistic->SetClientID(clientID);
|
||||||
|
freshID = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
statistic->Enable(true);
|
||||||
|
|
||||||
|
const qint64 uptime = VPApplication::VApp()->AppUptime();
|
||||||
|
freshID ? statistic->SendAppFreshInstallEvent(uptime) : statistic->SendAppStartEvent(uptime);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -286,7 +286,7 @@ private slots:
|
||||||
void AboutToShowDockMenu();
|
void AboutToShowDockMenu();
|
||||||
#endif //defined(Q_OS_MAC)
|
#endif //defined(Q_OS_MAC)
|
||||||
|
|
||||||
void SetDefaultGUILanguage();
|
void AskDefaultSettings();
|
||||||
|
|
||||||
void HorizontalScaleChanged(double value);
|
void HorizontalScaleChanged(double value);
|
||||||
void VerticalScaleChanged(double value);
|
void VerticalScaleChanged(double value);
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include "../vmisc/backport/qoverload.h"
|
#include "../vmisc/backport/qoverload.h"
|
||||||
#endif // QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
|
#endif // QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
|
||||||
#include "../qmuparser/qmudef.h"
|
#include "../qmuparser/qmudef.h"
|
||||||
|
#include "../vganalytics/vganalytics.h"
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
TapePreferencesConfigurationPage::TapePreferencesConfigurationPage(QWidget *parent)
|
TapePreferencesConfigurationPage::TapePreferencesConfigurationPage(QWidget *parent)
|
||||||
|
@ -53,13 +54,13 @@ TapePreferencesConfigurationPage::TapePreferencesConfigurationPage(QWidget *pare
|
||||||
VTapeSettings *settings = MApplication::VApp()->TapeSettings();
|
VTapeSettings *settings = MApplication::VApp()->TapeSettings();
|
||||||
|
|
||||||
//-------------------- Decimal separator setup
|
//-------------------- Decimal separator setup
|
||||||
ui->osOptionCheck->setChecked(MApplication::VApp()->TapeSettings()->GetOsSeparator());
|
ui->osOptionCheck->setChecked(settings->GetOsSeparator());
|
||||||
|
|
||||||
// Theme
|
// Theme
|
||||||
ui->darkModeCheck->setChecked(MApplication::VApp()->TapeSettings()->GetDarkMode());
|
ui->darkModeCheck->setChecked(settings->GetDarkMode());
|
||||||
|
|
||||||
// Native dialogs
|
// Native dialogs
|
||||||
ui->checkBoxDontUseNativeDialog->setChecked(MApplication::VApp()->TapeSettings()->IsDontUseNativeDialog());
|
ui->checkBoxDontUseNativeDialog->setChecked(settings->IsDontUseNativeDialog());
|
||||||
|
|
||||||
//---------------------- Pattern making system
|
//---------------------- Pattern making system
|
||||||
ui->systemBookValueLabel->setFixedHeight(4 * QFontMetrics(ui->systemBookValueLabel->font()).lineSpacing());
|
ui->systemBookValueLabel->setFixedHeight(4 * QFontMetrics(ui->systemBookValueLabel->font()).lineSpacing());
|
||||||
|
@ -77,7 +78,7 @@ TapePreferencesConfigurationPage::TapePreferencesConfigurationPage(QWidget *pare
|
||||||
});
|
});
|
||||||
|
|
||||||
// set default pattern making system
|
// set default pattern making system
|
||||||
int index = ui->systemCombo->findData(MApplication::VApp()->TapeSettings()->GetPMSystemCode());
|
int index = ui->systemCombo->findData(settings->GetPMSystemCode());
|
||||||
if (index != -1)
|
if (index != -1)
|
||||||
{
|
{
|
||||||
ui->systemCombo->setCurrentIndex(index);
|
ui->systemCombo->setCurrentIndex(index);
|
||||||
|
@ -88,11 +89,13 @@ TapePreferencesConfigurationPage::TapePreferencesConfigurationPage(QWidget *pare
|
||||||
[]() { MApplication::VApp()->TapeSettings()->SetConfirmFormatRewriting(true); });
|
[]() { MApplication::VApp()->TapeSettings()->SetConfirmFormatRewriting(true); });
|
||||||
|
|
||||||
//----------------------- Toolbar
|
//----------------------- Toolbar
|
||||||
ui->toolBarStyleCheck->setChecked(MApplication::VApp()->TapeSettings()->GetToolBarStyle());
|
ui->toolBarStyleCheck->setChecked(settings->GetToolBarStyle());
|
||||||
|
|
||||||
//----------------------- Update
|
//----------------------- Update
|
||||||
ui->checkBoxAutomaticallyCheckUpdates->setChecked(
|
ui->checkBoxAutomaticallyCheckUpdates->setChecked(settings->IsAutomaticallyCheckUpdates());
|
||||||
MApplication::VApp()->TapeSettings()->IsAutomaticallyCheckUpdates());
|
|
||||||
|
// Tab Privacy
|
||||||
|
ui->checkBoxSendUsageStatistics->setChecked(settings->IsCollectStatistic());
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -144,6 +147,10 @@ auto TapePreferencesConfigurationPage::Apply() -> QStringList
|
||||||
settings->SetAutomaticallyCheckUpdates(ui->checkBoxAutomaticallyCheckUpdates->isChecked());
|
settings->SetAutomaticallyCheckUpdates(ui->checkBoxAutomaticallyCheckUpdates->isChecked());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tab Privacy
|
||||||
|
settings->SetCollectStatistic(ui->checkBoxSendUsageStatistics->isChecked());
|
||||||
|
VGAnalytics::Instance()->Enable(ui->checkBoxSendUsageStatistics->isChecked());
|
||||||
|
|
||||||
return preferences;
|
return preferences;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,13 +6,23 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>544</width>
|
<width>564</width>
|
||||||
<height>636</height>
|
<height>686</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string notr="true">Configuration</string>
|
<string notr="true">Configuration</string>
|
||||||
</property>
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||||
|
<item>
|
||||||
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="tabGeneral">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>General</string>
|
||||||
|
</attribute>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QScrollArea" name="scrollArea">
|
<widget class="QScrollArea" name="scrollArea">
|
||||||
|
@ -24,8 +34,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>524</width>
|
<width>522</width>
|
||||||
<height>616</height>
|
<height>617</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
@ -216,6 +226,47 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QWidget" name="tabPrivacy">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Privacy</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkBoxSendUsageStatistics">
|
||||||
|
<property name="text">
|
||||||
|
<string>Send usage statistics</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Please help to improve Valentina's quality by automatically sending usage statistics. Sent data contains <span style=" font-weight:700;">no potentially sensitive information</span> like user names, email addresses, file contents or file paths.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>530</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
</ui>
|
</ui>
|
||||||
|
|
|
@ -32,6 +32,8 @@
|
||||||
#include "../ifc/exception/vexceptionemptyparameter.h"
|
#include "../ifc/exception/vexceptionemptyparameter.h"
|
||||||
#include "../ifc/exception/vexceptionobjecterror.h"
|
#include "../ifc/exception/vexceptionobjecterror.h"
|
||||||
#include "../ifc/exception/vexceptionwrongid.h"
|
#include "../ifc/exception/vexceptionwrongid.h"
|
||||||
|
#include "../vganalytics/def.h"
|
||||||
|
#include "../vganalytics/vganalytics.h"
|
||||||
#include "../vmisc/projectversion.h"
|
#include "../vmisc/projectversion.h"
|
||||||
#include "../vmisc/vsysexits.h"
|
#include "../vmisc/vsysexits.h"
|
||||||
#include "tmainwindow.h"
|
#include "tmainwindow.h"
|
||||||
|
@ -77,6 +79,7 @@ Q_LOGGING_CATEGORY(mApp, "m.application") // NOLINT
|
||||||
QT_WARNING_POP
|
QT_WARNING_POP
|
||||||
|
|
||||||
#include <QCommandLineParser>
|
#include <QCommandLineParser>
|
||||||
|
#include <QUuid>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
@ -318,6 +321,17 @@ MApplication::MApplication(int &argc, char **argv)
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
MApplication::~MApplication()
|
MApplication::~MApplication()
|
||||||
{
|
{
|
||||||
|
if (settings->IsCollectStatistic())
|
||||||
|
{
|
||||||
|
auto *statistic = VGAnalytics::Instance();
|
||||||
|
|
||||||
|
QString clientID = settings->GetClientID();
|
||||||
|
if (!clientID.isEmpty())
|
||||||
|
{
|
||||||
|
statistic->SendAppCloseEvent(m_uptimeTimer.elapsed());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
qDeleteAll(m_mainWindows);
|
qDeleteAll(m_mainWindows);
|
||||||
|
|
||||||
delete m_trVars;
|
delete m_trVars;
|
||||||
|
@ -473,6 +487,19 @@ void MApplication::InitOptions()
|
||||||
}
|
}
|
||||||
ActivateDarkMode();
|
ActivateDarkMode();
|
||||||
QResource::registerResource(diagramsPath());
|
QResource::registerResource(diagramsPath());
|
||||||
|
|
||||||
|
auto *statistic = VGAnalytics::Instance();
|
||||||
|
QString clientID = settings->GetClientID();
|
||||||
|
if (clientID.isEmpty())
|
||||||
|
{
|
||||||
|
clientID = QUuid::createUuid().toString();
|
||||||
|
settings->SetClientID(clientID);
|
||||||
|
}
|
||||||
|
statistic->SetClientID(clientID);
|
||||||
|
statistic->SetGUILanguage(settings->GetLocale());
|
||||||
|
statistic->SetMeasurementId(GA_MEASUREMENT_ID);
|
||||||
|
statistic->SetApiSecret(GA_API_SECRET);
|
||||||
|
statistic->Enable(settings->IsCollectStatistic());
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -408,6 +408,15 @@ DEPENDPATH += $$PWD/../../libs/vmisc
|
||||||
win32:!win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vmisc/$${DESTDIR}/vmisc.lib
|
win32:!win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vmisc/$${DESTDIR}/vmisc.lib
|
||||||
else:unix|win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vmisc/$${DESTDIR}/libvmisc.a
|
else:unix|win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vmisc/$${DESTDIR}/libvmisc.a
|
||||||
|
|
||||||
|
# VGAnalytics static library
|
||||||
|
unix|win32: LIBS += -L$$OUT_PWD/../../libs/vganalytics/$${DESTDIR}/ -lvganalytics
|
||||||
|
|
||||||
|
INCLUDEPATH += $$PWD/../../libs/vganalytics
|
||||||
|
DEPENDPATH += $$PWD/../../libs/vganalytics
|
||||||
|
|
||||||
|
win32:!win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vganalytics/$${DESTDIR}/vganalytics.lib
|
||||||
|
else:unix|win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vganalytics/$${DESTDIR}/libvganalytics.a
|
||||||
|
|
||||||
# QMuParser library
|
# QMuParser library
|
||||||
win32:CONFIG(release, debug|release): LIBS += -L$${OUT_PWD}/../../libs/qmuparser/$${DESTDIR} -lqmuparser2
|
win32:CONFIG(release, debug|release): LIBS += -L$${OUT_PWD}/../../libs/qmuparser/$${DESTDIR} -lqmuparser2
|
||||||
else:win32:CONFIG(debug, debug|release): LIBS += -L$${OUT_PWD}/../../libs/qmuparser/$${DESTDIR} -lqmuparser2
|
else:win32:CONFIG(debug, debug|release): LIBS += -L$${OUT_PWD}/../../libs/qmuparser/$${DESTDIR} -lqmuparser2
|
||||||
|
|
|
@ -14,6 +14,7 @@ VToolApp {
|
||||||
Depends { name: "VToolsLib"; }
|
Depends { name: "VToolsLib"; }
|
||||||
Depends { name: "ebr" }
|
Depends { name: "ebr" }
|
||||||
Depends { name: "multibundle"; }
|
Depends { name: "multibundle"; }
|
||||||
|
Depends { name: "VGAnalyticsLib" }
|
||||||
Depends { name: "conan.XercesC"; condition: buildconfig.useConanPackages }
|
Depends { name: "conan.XercesC"; condition: buildconfig.useConanPackages }
|
||||||
|
|
||||||
name: "Tape"
|
name: "Tape"
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include "../ifc/xml/vvitconverter.h"
|
#include "../ifc/xml/vvitconverter.h"
|
||||||
#include "../ifc/xml/vvstconverter.h"
|
#include "../ifc/xml/vvstconverter.h"
|
||||||
#include "../vmisc/compatibility.h"
|
#include "../vmisc/compatibility.h"
|
||||||
|
#include "../vmisc/dialogs/dialogaskcollectstatistic.h"
|
||||||
#include "../vmisc/dialogs/dialogexporttocsv.h"
|
#include "../vmisc/dialogs/dialogexporttocsv.h"
|
||||||
#include "../vmisc/qxtcsvmodel.h"
|
#include "../vmisc/qxtcsvmodel.h"
|
||||||
#include "../vmisc/vsysexits.h"
|
#include "../vmisc/vsysexits.h"
|
||||||
|
@ -56,6 +57,7 @@
|
||||||
#include "../vmisc/backport/qoverload.h"
|
#include "../vmisc/backport/qoverload.h"
|
||||||
#endif // QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
|
#endif // QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
|
||||||
#include "../qmuparser/qmudef.h"
|
#include "../qmuparser/qmudef.h"
|
||||||
|
#include "../vganalytics/vganalytics.h"
|
||||||
#include "../vmisc/dialogs/dialogselectlanguage.h"
|
#include "../vmisc/dialogs/dialogselectlanguage.h"
|
||||||
#include "../vtools/dialogs/support/dialogeditwrongformula.h"
|
#include "../vtools/dialogs/support/dialogeditwrongformula.h"
|
||||||
#include "mapplication.h" // Should be last because of definning qApp
|
#include "mapplication.h" // Should be last because of definning qApp
|
||||||
|
@ -304,7 +306,7 @@ TMainWindow::TMainWindow(QWidget *parent)
|
||||||
|
|
||||||
if (MApplication::VApp()->IsAppInGUIMode())
|
if (MApplication::VApp()->IsAppInGUIMode())
|
||||||
{
|
{
|
||||||
QTimer::singleShot(V_SECONDS(1), this, &TMainWindow::SetDefaultGUILanguage);
|
QTimer::singleShot(V_SECONDS(1), this, &TMainWindow::AskDefaultSettings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2534,7 +2536,7 @@ void TMainWindow::DimensionCustomNames()
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
void TMainWindow::SetDefaultGUILanguage()
|
void TMainWindow::AskDefaultSettings()
|
||||||
{
|
{
|
||||||
if (MApplication::VApp()->IsAppInGUIMode())
|
if (MApplication::VApp()->IsAppInGUIMode())
|
||||||
{
|
{
|
||||||
|
@ -2552,6 +2554,38 @@ void TMainWindow::SetDefaultGUILanguage()
|
||||||
VAbstractApplication::VApp()->LoadTranslation(locale);
|
VAbstractApplication::VApp()->LoadTranslation(locale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (settings->IsAskCollectStatistic())
|
||||||
|
{
|
||||||
|
DialogAskCollectStatistic dialog(this);
|
||||||
|
if (dialog.exec() == QDialog::Accepted)
|
||||||
|
{
|
||||||
|
settings->SetCollectStatistic(dialog.CollectStatistic());
|
||||||
|
}
|
||||||
|
|
||||||
|
settings->SetAskCollectStatistic(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings->IsCollectStatistic())
|
||||||
|
{
|
||||||
|
auto *statistic = VGAnalytics::Instance();
|
||||||
|
statistic->SetGUILanguage(settings->GetLocale());
|
||||||
|
|
||||||
|
QString clientID = settings->GetClientID();
|
||||||
|
bool freshID = false;
|
||||||
|
if (clientID.isEmpty())
|
||||||
|
{
|
||||||
|
clientID = QUuid::createUuid().toString();
|
||||||
|
settings->SetClientID(clientID);
|
||||||
|
statistic->SetClientID(clientID);
|
||||||
|
freshID = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
statistic->Enable(true);
|
||||||
|
|
||||||
|
const qint64 uptime = MApplication::VApp()->AppUptime();
|
||||||
|
freshID ? statistic->SendAppFreshInstallEvent(uptime) : statistic->SendAppStartEvent(uptime);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -146,7 +146,7 @@ private slots:
|
||||||
void EditDimensionLabels();
|
void EditDimensionLabels();
|
||||||
void DimensionCustomNames();
|
void DimensionCustomNames();
|
||||||
|
|
||||||
void SetDefaultGUILanguage();
|
void AskDefaultSettings();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// cppcheck-suppress unknownMacro
|
// cppcheck-suppress unknownMacro
|
||||||
|
|
|
@ -36,10 +36,11 @@
|
||||||
#include "../mainwindow.h"
|
#include "../mainwindow.h"
|
||||||
#include "../qmuparser/qmuparsererror.h"
|
#include "../qmuparser/qmuparsererror.h"
|
||||||
#include "../version.h"
|
#include "../version.h"
|
||||||
|
#include "../vganalytics/def.h"
|
||||||
|
#include "../vganalytics/vganalytics.h"
|
||||||
#include "../vmisc/qt_dispatch/qt_dispatch.h"
|
#include "../vmisc/qt_dispatch/qt_dispatch.h"
|
||||||
#include "../vmisc/vsysexits.h"
|
#include "../vmisc/vsysexits.h"
|
||||||
#include "../vmisc/vvalentinasettings.h"
|
#include "../vmisc/vvalentinasettings.h"
|
||||||
#include <qstringliteral.h>
|
|
||||||
|
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
||||||
#include "../vmisc/backport/text.h"
|
#include "../vmisc/backport/text.h"
|
||||||
|
@ -383,6 +384,18 @@ VApplication::VApplication(int &argc, char **argv)
|
||||||
VApplication::~VApplication()
|
VApplication::~VApplication()
|
||||||
{
|
{
|
||||||
qCDebug(vApp, "Application closing.");
|
qCDebug(vApp, "Application closing.");
|
||||||
|
|
||||||
|
if (settings->IsCollectStatistic())
|
||||||
|
{
|
||||||
|
auto *statistic = VGAnalytics::Instance();
|
||||||
|
|
||||||
|
QString clientID = settings->GetClientID();
|
||||||
|
if (!clientID.isEmpty())
|
||||||
|
{
|
||||||
|
statistic->SendAppCloseEvent(m_uptimeTimer.elapsed());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
qInstallMessageHandler(nullptr); // Resore the message handler
|
qInstallMessageHandler(nullptr); // Resore the message handler
|
||||||
delete m_trVars;
|
delete m_trVars;
|
||||||
VCommandLine::Reset();
|
VCommandLine::Reset();
|
||||||
|
@ -695,6 +708,19 @@ void VApplication::InitOptions()
|
||||||
QIcon::setThemeName(QStringLiteral("win.icon.theme"));
|
QIcon::setThemeName(QStringLiteral("win.icon.theme"));
|
||||||
}
|
}
|
||||||
ActivateDarkMode();
|
ActivateDarkMode();
|
||||||
|
|
||||||
|
auto *statistic = VGAnalytics::Instance();
|
||||||
|
QString clientID = settings->GetClientID();
|
||||||
|
if (clientID.isEmpty())
|
||||||
|
{
|
||||||
|
clientID = QUuid::createUuid().toString();
|
||||||
|
settings->SetClientID(clientID);
|
||||||
|
}
|
||||||
|
statistic->SetClientID(clientID);
|
||||||
|
statistic->SetGUILanguage(settings->GetLocale());
|
||||||
|
statistic->SetMeasurementId(GA_MEASUREMENT_ID);
|
||||||
|
statistic->SetApiSecret(GA_API_SECRET);
|
||||||
|
statistic->Enable(settings->IsCollectStatistic());
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -31,12 +31,12 @@
|
||||||
#include "../vmisc/literals.h"
|
#include "../vmisc/literals.h"
|
||||||
#include "../vmisc/vvalentinasettings.h"
|
#include "../vmisc/vvalentinasettings.h"
|
||||||
#include "../vpatterndb/pmsystems.h"
|
#include "../vpatterndb/pmsystems.h"
|
||||||
#include "def.h"
|
|
||||||
#include "ui_preferencesconfigurationpage.h"
|
#include "ui_preferencesconfigurationpage.h"
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
|
#if QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
|
||||||
#include "../vmisc/backport/qoverload.h"
|
#include "../vmisc/backport/qoverload.h"
|
||||||
#endif // QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
|
#endif // QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
|
||||||
#include "../qmuparser/qmudef.h"
|
#include "../qmuparser/qmudef.h"
|
||||||
|
#include "../vganalytics/vganalytics.h"
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QDirIterator>
|
#include <QDirIterator>
|
||||||
|
@ -162,6 +162,9 @@ PreferencesConfigurationPage::PreferencesConfigurationPage(QWidget *parent)
|
||||||
ui->doubleSpinBoxAcceleration->setMinimum(VCommonSettings::scrollingAccelerationMin);
|
ui->doubleSpinBoxAcceleration->setMinimum(VCommonSettings::scrollingAccelerationMin);
|
||||||
ui->doubleSpinBoxAcceleration->setMaximum(VCommonSettings::scrollingAccelerationMax);
|
ui->doubleSpinBoxAcceleration->setMaximum(VCommonSettings::scrollingAccelerationMax);
|
||||||
ui->doubleSpinBoxAcceleration->setValue(settings->GetScrollingAcceleration());
|
ui->doubleSpinBoxAcceleration->setValue(settings->GetScrollingAcceleration());
|
||||||
|
|
||||||
|
// Tab Privacy
|
||||||
|
ui->checkBoxSendUsageStatistics->setChecked(settings->IsCollectStatistic());
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -254,6 +257,10 @@ auto PreferencesConfigurationPage::Apply() -> QStringList
|
||||||
settings->SetWheelMouseScale(ui->doubleSpinBoxWheel->value());
|
settings->SetWheelMouseScale(ui->doubleSpinBoxWheel->value());
|
||||||
settings->SetScrollingAcceleration(ui->doubleSpinBoxAcceleration->value());
|
settings->SetScrollingAcceleration(ui->doubleSpinBoxAcceleration->value());
|
||||||
|
|
||||||
|
// Tab Privacy
|
||||||
|
settings->SetCollectStatistic(ui->checkBoxSendUsageStatistics->isChecked());
|
||||||
|
VGAnalytics::Instance()->Enable(ui->checkBoxSendUsageStatistics->isChecked());
|
||||||
|
|
||||||
return preferences;
|
return preferences;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -527,6 +527,43 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QWidget" name="tabPrivacy">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Privacy</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_9">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkBoxSendUsageStatistics">
|
||||||
|
<property name="text">
|
||||||
|
<string>Send usage statistics</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_15">
|
||||||
|
<property name="text">
|
||||||
|
<string>Please help to improve Valentina's quality by automatically sending usage statistics. Sent data contains <span style=" font-weight:700;">no potentially sensitive information</span> like user names, email addresses, file contents or file paths.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>716</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|
|
@ -38,9 +38,11 @@
|
||||||
#include "../ifc/xml/vvstconverter.h"
|
#include "../ifc/xml/vvstconverter.h"
|
||||||
#include "../vformat/vmeasurements.h"
|
#include "../vformat/vmeasurements.h"
|
||||||
#include "../vformat/vpatternrecipe.h"
|
#include "../vformat/vpatternrecipe.h"
|
||||||
|
#include "../vganalytics/vganalytics.h"
|
||||||
#include "../vlayout/dialogs/watermarkwindow.h"
|
#include "../vlayout/dialogs/watermarkwindow.h"
|
||||||
#include "../vmisc/customevents.h"
|
#include "../vmisc/customevents.h"
|
||||||
#include "../vmisc/def.h"
|
#include "../vmisc/def.h"
|
||||||
|
#include "../vmisc/dialogs/dialogaskcollectstatistic.h"
|
||||||
#include "../vmisc/qxtcsvmodel.h"
|
#include "../vmisc/qxtcsvmodel.h"
|
||||||
#include "../vmisc/vmodifierkey.h"
|
#include "../vmisc/vmodifierkey.h"
|
||||||
#include "../vmisc/vsysexits.h"
|
#include "../vmisc/vsysexits.h"
|
||||||
|
@ -505,7 +507,7 @@ MainWindow::MainWindow(QWidget *parent)
|
||||||
|
|
||||||
if (VApplication::IsGUIMode())
|
if (VApplication::IsGUIMode())
|
||||||
{
|
{
|
||||||
QTimer::singleShot(V_SECONDS(1), this, &MainWindow::SetDefaultGUILanguage);
|
QTimer::singleShot(V_SECONDS(1), this, &MainWindow::AskDefaultSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->actionExportFontCorrections->setEnabled(settings->GetSingleStrokeOutlineFont());
|
ui->actionExportFontCorrections->setEnabled(settings->GetSingleStrokeOutlineFont());
|
||||||
|
@ -4548,7 +4550,7 @@ void MainWindow::ClearPatternMessages()
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
void MainWindow::SetDefaultGUILanguage()
|
void MainWindow::AskDefaultSettings()
|
||||||
{
|
{
|
||||||
if (VApplication::IsGUIMode())
|
if (VApplication::IsGUIMode())
|
||||||
{
|
{
|
||||||
|
@ -4565,6 +4567,38 @@ void MainWindow::SetDefaultGUILanguage()
|
||||||
VAbstractApplication::VApp()->LoadTranslation(locale);
|
VAbstractApplication::VApp()->LoadTranslation(locale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (settings->IsAskCollectStatistic())
|
||||||
|
{
|
||||||
|
DialogAskCollectStatistic dialog(this);
|
||||||
|
if (dialog.exec() == QDialog::Accepted)
|
||||||
|
{
|
||||||
|
settings->SetCollectStatistic(dialog.CollectStatistic());
|
||||||
|
}
|
||||||
|
|
||||||
|
settings->SetAskCollectStatistic(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings->IsCollectStatistic())
|
||||||
|
{
|
||||||
|
auto *statistic = VGAnalytics::Instance();
|
||||||
|
statistic->SetGUILanguage(settings->GetLocale());
|
||||||
|
|
||||||
|
QString clientID = settings->GetClientID();
|
||||||
|
bool freshID = false;
|
||||||
|
if (clientID.isEmpty())
|
||||||
|
{
|
||||||
|
clientID = QUuid::createUuid().toString();
|
||||||
|
settings->SetClientID(clientID);
|
||||||
|
statistic->SetClientID(clientID);
|
||||||
|
freshID = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
statistic->Enable(true);
|
||||||
|
|
||||||
|
const qint64 uptime = VAbstractValApplication::VApp()->AppUptime();
|
||||||
|
freshID ? statistic->SendAppFreshInstallEvent(uptime) : statistic->SendAppStartEvent(uptime);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -237,7 +237,7 @@ private slots:
|
||||||
void ShowProgress();
|
void ShowProgress();
|
||||||
void ClearPatternMessages();
|
void ClearPatternMessages();
|
||||||
|
|
||||||
void SetDefaultGUILanguage();
|
void AskDefaultSettings();
|
||||||
|
|
||||||
void AddBackgroundImageItem(const QUuid &id);
|
void AddBackgroundImageItem(const QUuid &id);
|
||||||
void DeleteBackgroundImageItem(const QUuid &id);
|
void DeleteBackgroundImageItem(const QUuid &id);
|
||||||
|
|
|
@ -698,6 +698,15 @@ DEPENDPATH += $$PWD/../../libs/vdxf
|
||||||
win32:!win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vdxf/$${DESTDIR}/vdxf.lib
|
win32:!win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vdxf/$${DESTDIR}/vdxf.lib
|
||||||
else:unix|win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vdxf/$${DESTDIR}/libvdxf.a
|
else:unix|win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vdxf/$${DESTDIR}/libvdxf.a
|
||||||
|
|
||||||
|
# VGAnalytics static library
|
||||||
|
unix|win32: LIBS += -L$$OUT_PWD/../../libs/vganalytics/$${DESTDIR}/ -lvganalytics
|
||||||
|
|
||||||
|
INCLUDEPATH += $$PWD/../../libs/vganalytics
|
||||||
|
DEPENDPATH += $$PWD/../../libs/vganalytics
|
||||||
|
|
||||||
|
win32:!win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vganalytics/$${DESTDIR}/vganalytics.lib
|
||||||
|
else:unix|win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vganalytics/$${DESTDIR}/libvganalytics.a
|
||||||
|
|
||||||
# QMuParser library
|
# QMuParser library
|
||||||
win32:CONFIG(release, debug|release): LIBS += -L$${OUT_PWD}/../../libs/qmuparser/$${DESTDIR} -lqmuparser2
|
win32:CONFIG(release, debug|release): LIBS += -L$${OUT_PWD}/../../libs/qmuparser/$${DESTDIR} -lqmuparser2
|
||||||
else:win32:CONFIG(debug, debug|release): LIBS += -L$${OUT_PWD}/../../libs/qmuparser/$${DESTDIR} -lqmuparser2
|
else:win32:CONFIG(debug, debug|release): LIBS += -L$${OUT_PWD}/../../libs/qmuparser/$${DESTDIR} -lqmuparser2
|
||||||
|
|
|
@ -14,6 +14,7 @@ VToolApp {
|
||||||
Depends { name: "VToolsLib"; }
|
Depends { name: "VToolsLib"; }
|
||||||
Depends { name: "VFormatLib"; }
|
Depends { name: "VFormatLib"; }
|
||||||
Depends { name: "VMiscLib"; }
|
Depends { name: "VMiscLib"; }
|
||||||
|
Depends { name: "VGAnalyticsLib" }
|
||||||
|
|
||||||
Depends {
|
Depends {
|
||||||
name: "Qt.xmlpatterns"
|
name: "Qt.xmlpatterns"
|
||||||
|
|
|
@ -33,3 +33,6 @@ INCLUDEPATH += $${PWD}/vpropertyexplorer
|
||||||
|
|
||||||
#VTools static library
|
#VTools static library
|
||||||
INCLUDEPATH += $${PWD}/vtest
|
INCLUDEPATH += $${PWD}/vtest
|
||||||
|
|
||||||
|
#VGAnalytics static library
|
||||||
|
INCLUDEPATH += $${PWD}/vganalytics
|
||||||
|
|
|
@ -13,4 +13,5 @@ SUBDIRS = \
|
||||||
vtools \
|
vtools \
|
||||||
vformat \
|
vformat \
|
||||||
fervor \
|
fervor \
|
||||||
vtest
|
vtest \
|
||||||
|
vganalytics
|
||||||
|
|
|
@ -14,5 +14,6 @@ Project {
|
||||||
"vtest/vtest.qbs",
|
"vtest/vtest.qbs",
|
||||||
"vtools/vtools.qbs",
|
"vtools/vtools.qbs",
|
||||||
"vwidgets/vwidgets.qbs",
|
"vwidgets/vwidgets.qbs",
|
||||||
|
"vganalytics/vganalytics.qbs",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
36
src/libs/vganalytics/def.h
Normal file
36
src/libs/vganalytics/def.h
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
/************************************************************************
|
||||||
|
**
|
||||||
|
** @file def.h
|
||||||
|
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||||
|
** @date 26 6, 2023
|
||||||
|
**
|
||||||
|
** @brief
|
||||||
|
** @copyright
|
||||||
|
** This source code is part of the Valentina project, a pattern making
|
||||||
|
** program, whose allow create and modeling patterns of clothing.
|
||||||
|
** Copyright (C) 2023 Valentina project
|
||||||
|
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
|
||||||
|
**
|
||||||
|
** Valentina is free software: you can redistribute it and/or modify
|
||||||
|
** it under the terms of the GNU General Public License as published by
|
||||||
|
** the Free Software Foundation, either version 3 of the License, or
|
||||||
|
** (at your option) any later version.
|
||||||
|
**
|
||||||
|
** Valentina is distributed in the hope that it will be useful,
|
||||||
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
** GNU General Public License for more details.
|
||||||
|
**
|
||||||
|
** You should have received a copy of the GNU General Public License
|
||||||
|
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
**
|
||||||
|
*************************************************************************/
|
||||||
|
#ifndef GADEF_H
|
||||||
|
#define GADEF_H
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
const QString GA_MEASUREMENT_ID = QStringLiteral("G-KH8CCG06VJ"); // NOLINT(clazy-non-pod-global-static)
|
||||||
|
const QString GA_API_SECRET = QStringLiteral("vnXM9BlCQXC9nvaXid_lAA"); // NOLINT(clazy-non-pod-global-static)
|
||||||
|
|
||||||
|
#endif // GADEF_H
|
306
src/libs/vganalytics/vganalytics.cpp
Normal file
306
src/libs/vganalytics/vganalytics.cpp
Normal file
|
@ -0,0 +1,306 @@
|
||||||
|
/************************************************************************
|
||||||
|
**
|
||||||
|
** @file vganalytics.cpp
|
||||||
|
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||||
|
** @date 26 6, 2023
|
||||||
|
**
|
||||||
|
** @brief
|
||||||
|
** @copyright
|
||||||
|
** This source code is part of the Valentina project, a pattern making
|
||||||
|
** program, whose allow create and modeling patterns of clothing.
|
||||||
|
** Copyright (C) 2023 Valentina project
|
||||||
|
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
|
||||||
|
**
|
||||||
|
** Valentina is free software: you can redistribute it and/or modify
|
||||||
|
** it under the terms of the GNU General Public License as published by
|
||||||
|
** the Free Software Foundation, either version 3 of the License, or
|
||||||
|
** (at your option) any later version.
|
||||||
|
**
|
||||||
|
** Valentina is distributed in the hope that it will be useful,
|
||||||
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
** GNU General Public License for more details.
|
||||||
|
**
|
||||||
|
** You should have received a copy of the GNU General Public License
|
||||||
|
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
**
|
||||||
|
*************************************************************************/
|
||||||
|
#include "vganalytics.h"
|
||||||
|
#include "qguiapplication.h"
|
||||||
|
#include "qstringliteral.h"
|
||||||
|
#include "vganalyticsworker.h"
|
||||||
|
|
||||||
|
#include <QDataStream>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QGuiApplication>
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QLocale>
|
||||||
|
#include <QNetworkAccessManager>
|
||||||
|
#include <QNetworkReply>
|
||||||
|
#include <QNetworkRequest>
|
||||||
|
#include <QQueue>
|
||||||
|
#include <QScreen>
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QUrlQuery>
|
||||||
|
#include <QUuid>
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
VGAnalytics::VGAnalytics(QObject *parent)
|
||||||
|
: QObject{parent},
|
||||||
|
d(new VGAnalyticsWorker(this))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
VGAnalytics::~VGAnalytics()
|
||||||
|
{
|
||||||
|
delete d;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
auto VGAnalytics::Instance() -> VGAnalytics *
|
||||||
|
{
|
||||||
|
static VGAnalytics *instance = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||||
|
if (instance == nullptr)
|
||||||
|
{
|
||||||
|
instance = new VGAnalytics();
|
||||||
|
}
|
||||||
|
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void VGAnalytics::SetLogLevel(enum VGAnalytics::LogLevel logLevel)
|
||||||
|
{
|
||||||
|
d->m_logLevel = logLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
auto VGAnalytics::LogLevel() const -> enum VGAnalytics::LogLevel { return d->m_logLevel; }
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void VGAnalytics::SetRepoRevision(const QString &rev)
|
||||||
|
{
|
||||||
|
d->m_repoRevision = rev;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
auto VGAnalytics::RepoRevision() const -> QString
|
||||||
|
{
|
||||||
|
return d->m_repoRevision;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void VGAnalytics::SetGUILanguage(const QString &language)
|
||||||
|
{
|
||||||
|
d->m_guiLanguage = language.toLower().replace(QChar('_'), QChar('-'));
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
auto VGAnalytics::GUILanguage() const -> QString
|
||||||
|
{
|
||||||
|
return d->m_guiLanguage;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void VGAnalytics::SetSendInterval(int milliseconds)
|
||||||
|
{
|
||||||
|
d->m_timer.setInterval(milliseconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
auto VGAnalytics::SendInterval() const -> int
|
||||||
|
{
|
||||||
|
return (d->m_timer.interval());
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
auto VGAnalytics::IsEnabled() -> bool
|
||||||
|
{
|
||||||
|
return d->m_isEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void VGAnalytics::SetMeasurementId(const QString &measurementId)
|
||||||
|
{
|
||||||
|
d->m_measurementId = measurementId;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void VGAnalytics::SetApiSecret(const QString &apiSecret)
|
||||||
|
{
|
||||||
|
d->m_apiSecret = apiSecret;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void VGAnalytics::SetClientID(const QString &clientID)
|
||||||
|
{
|
||||||
|
d->m_clientID = clientID;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void VGAnalytics::Enable(bool state)
|
||||||
|
{
|
||||||
|
d->Enable(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void VGAnalytics::SetNetworkAccessManager(QNetworkAccessManager *networkAccessManager)
|
||||||
|
{
|
||||||
|
if (d->networkManager != networkAccessManager)
|
||||||
|
{
|
||||||
|
// Delete the old network manager if it was our child
|
||||||
|
if (d->networkManager && d->networkManager->parent() == this)
|
||||||
|
{
|
||||||
|
d->networkManager->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
d->networkManager = networkAccessManager;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
auto VGAnalytics::NetworkAccessManager() const -> QNetworkAccessManager *
|
||||||
|
{
|
||||||
|
return d->networkManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void VGAnalytics::SendAppFreshInstallEvent(qint64 engagementTimeMsec)
|
||||||
|
{
|
||||||
|
SendEvent(QStringLiteral("vapp_fresh_install"), InitAppStartEventParams(engagementTimeMsec));
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void VGAnalytics::SendAppStartEvent(qint64 engagementTimeMsec)
|
||||||
|
{
|
||||||
|
SendEvent(QStringLiteral("vapp_start"), InitAppStartEventParams(engagementTimeMsec));
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void VGAnalytics::SendAppCloseEvent(qint64 engagementTimeMsec)
|
||||||
|
{
|
||||||
|
QHash<QString, QJsonValue> params{
|
||||||
|
// {QStringLiteral("category"), ""},
|
||||||
|
// In order for user activity to display in standard reports like Realtime, engagement_time_msec and session_id
|
||||||
|
// must be supplied as part of the params for an event.
|
||||||
|
// https://developers.google.com/analytics/devguides/collection/protocol/ga4/sending-events?client_type=gtag#optional_parameters_for_reports
|
||||||
|
{QStringLiteral("engagement_time_msec"), engagementTimeMsec},
|
||||||
|
};
|
||||||
|
|
||||||
|
SendEvent(QStringLiteral("vapp_close"), params);
|
||||||
|
QNetworkReply *reply = d->PostMessage();
|
||||||
|
if (reply)
|
||||||
|
{
|
||||||
|
QTimer timer;
|
||||||
|
const int timeoutSeconds = 3; // Wait for 3 seconds
|
||||||
|
timer.setSingleShot(true);
|
||||||
|
timer.start(timeoutSeconds * 1000);
|
||||||
|
|
||||||
|
QEventLoop loop;
|
||||||
|
connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit);
|
||||||
|
QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
|
||||||
|
loop.exec(); // wait for finished
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* A query for a POST message will be created to report this event. The
|
||||||
|
* created query will be stored in a message queue.
|
||||||
|
*/
|
||||||
|
void VGAnalytics::SendEvent(const QString &eventName, const QHash<QString, QJsonValue> ¶ms)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
// event body example
|
||||||
|
{
|
||||||
|
"client_id": "XXXXXXXXXX.YYYYYYYYYY",
|
||||||
|
"events": [{
|
||||||
|
"name": "refund",
|
||||||
|
"params": {
|
||||||
|
"currency": "USD",
|
||||||
|
"value": "9.99",
|
||||||
|
"transaction_id": "ABC-123"
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
QJsonObject root;
|
||||||
|
root[QStringLiteral("client_id")] = d->m_clientID;
|
||||||
|
|
||||||
|
QJsonObject event;
|
||||||
|
event[QStringLiteral("name")] = eventName;
|
||||||
|
|
||||||
|
QJsonObject eventParams;
|
||||||
|
|
||||||
|
auto i = params.constBegin();
|
||||||
|
while (i != params.constEnd())
|
||||||
|
{
|
||||||
|
eventParams[i.key()] = i.value();
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// In order for user activity to display in standard reports like Realtime, engagement_time_msec and session_id must
|
||||||
|
// be supplied as part of the params for an event.
|
||||||
|
// https://developers.google.com/analytics/devguides/collection/protocol/ga4/sending-events?client_type=gtag#optional_parameters_for_reports
|
||||||
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-static-cast-downcast)
|
||||||
|
eventParams[QStringLiteral("session_id")] = qApp->sessionId();
|
||||||
|
event[QStringLiteral("params")] = eventParams;
|
||||||
|
|
||||||
|
QJsonArray eventArray;
|
||||||
|
eventArray.append(event);
|
||||||
|
root[QStringLiteral("events")] = eventArray;
|
||||||
|
|
||||||
|
d->EnqueQueryWithCurrentTime(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
auto VGAnalytics::InitAppStartEventParams(qint64 engagementTimeMsec) const -> QHash<QString, QJsonValue>
|
||||||
|
{
|
||||||
|
|
||||||
|
QHash<QString, QJsonValue> params{
|
||||||
|
// {QStringLiteral("category"), ""},
|
||||||
|
{QStringLiteral("qt_version"), QT_VERSION_STR},
|
||||||
|
{QStringLiteral("app_version"), d->m_appVersion},
|
||||||
|
{QStringLiteral("word_size"), QStringLiteral("%1 bit").arg(QSysInfo::WordSize)},
|
||||||
|
{QStringLiteral("cpu_architecture"), QSysInfo::currentCpuArchitecture()},
|
||||||
|
{QStringLiteral("revision"), d->m_repoRevision},
|
||||||
|
{QStringLiteral("os_version"), QSysInfo::prettyProductName()},
|
||||||
|
{QStringLiteral("screen_size"), d->m_screenResolution},
|
||||||
|
{QStringLiteral("screen_scale_factor"), d->m_screenScaleFactor},
|
||||||
|
// In order for user activity to display in standard reports like Realtime, engagement_time_msec and session_id
|
||||||
|
// must be supplied as part of the params for an event.
|
||||||
|
// https://developers.google.com/analytics/devguides/collection/protocol/ga4/sending-events?client_type=gtag#optional_parameters_for_reports
|
||||||
|
{QStringLiteral("engagement_time_msec"), engagementTimeMsec},
|
||||||
|
{QStringLiteral("gui_language"), d->m_guiLanguage},
|
||||||
|
};
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* Qut stream to persist class GAnalytics.
|
||||||
|
*/
|
||||||
|
auto operator<<(QDataStream &outStream, const VGAnalytics &analytics) -> QDataStream &
|
||||||
|
{
|
||||||
|
outStream << analytics.d->PersistMessageQueue();
|
||||||
|
|
||||||
|
return outStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* In stream to read GAnalytics from file.
|
||||||
|
*/
|
||||||
|
auto operator>>(QDataStream &inStream, VGAnalytics &analytics) -> QDataStream &
|
||||||
|
{
|
||||||
|
QList<QString> dataList;
|
||||||
|
inStream >> dataList;
|
||||||
|
analytics.d->ReadMessagesFromFile(dataList);
|
||||||
|
|
||||||
|
return inStream;
|
||||||
|
}
|
99
src/libs/vganalytics/vganalytics.h
Normal file
99
src/libs/vganalytics/vganalytics.h
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
/************************************************************************
|
||||||
|
**
|
||||||
|
** @file vganalytics.h
|
||||||
|
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||||
|
** @date 26 6, 2023
|
||||||
|
**
|
||||||
|
** @brief
|
||||||
|
** @copyright
|
||||||
|
** This source code is part of the Valentina project, a pattern making
|
||||||
|
** program, whose allow create and modeling patterns of clothing.
|
||||||
|
** Copyright (C) 2023 Valentina project
|
||||||
|
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
|
||||||
|
**
|
||||||
|
** Valentina is free software: you can redistribute it and/or modify
|
||||||
|
** it under the terms of the GNU General Public License as published by
|
||||||
|
** the Free Software Foundation, either version 3 of the License, or
|
||||||
|
** (at your option) any later version.
|
||||||
|
**
|
||||||
|
** Valentina is distributed in the hope that it will be useful,
|
||||||
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
** GNU General Public License for more details.
|
||||||
|
**
|
||||||
|
** You should have received a copy of the GNU General Public License
|
||||||
|
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
**
|
||||||
|
*************************************************************************/
|
||||||
|
#ifndef VGANALYTICS_H
|
||||||
|
#define VGANALYTICS_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class QNetworkAccessManager;
|
||||||
|
class VGAnalyticsWorker;
|
||||||
|
|
||||||
|
// https://developers.google.com/analytics/devguides/collection/protocol/ga4/verify-implementation?client_type=gtag
|
||||||
|
class VGAnalytics : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT // NOLINT
|
||||||
|
|
||||||
|
public:
|
||||||
|
~VGAnalytics() override;
|
||||||
|
|
||||||
|
static auto Instance() -> VGAnalytics *;
|
||||||
|
|
||||||
|
enum LogLevel
|
||||||
|
{
|
||||||
|
Debug,
|
||||||
|
Info,
|
||||||
|
Error
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_ENUM(LogLevel) // NOLINT
|
||||||
|
|
||||||
|
void SetMeasurementId(const QString &measurementId);
|
||||||
|
void SetApiSecret(const QString &apiSecret);
|
||||||
|
void SetClientID(const QString &clientID);
|
||||||
|
|
||||||
|
void SetLogLevel(LogLevel logLevel);
|
||||||
|
auto LogLevel() const -> LogLevel;
|
||||||
|
|
||||||
|
void SetRepoRevision(const QString &rev);
|
||||||
|
auto RepoRevision() const -> QString;
|
||||||
|
|
||||||
|
void SetGUILanguage(const QString &language);
|
||||||
|
auto GUILanguage() const -> QString;
|
||||||
|
|
||||||
|
void SetSendInterval(int milliseconds);
|
||||||
|
auto SendInterval() const -> int;
|
||||||
|
|
||||||
|
void Enable(bool state = true);
|
||||||
|
auto IsEnabled() -> bool;
|
||||||
|
|
||||||
|
/// Get or set the network access manager. If none is set, the class creates its own on the first request
|
||||||
|
void SetNetworkAccessManager(QNetworkAccessManager *networkAccessManager);
|
||||||
|
auto NetworkAccessManager() const -> QNetworkAccessManager *;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void SendAppFreshInstallEvent(qint64 engagementTimeMsec);
|
||||||
|
void SendAppStartEvent(qint64 engagementTimeMsec);
|
||||||
|
void SendAppCloseEvent(qint64 engagementTimeMsec);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Q_DISABLE_COPY_MOVE(VGAnalytics) // NOLINT
|
||||||
|
|
||||||
|
explicit VGAnalytics(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
private:
|
||||||
|
VGAnalyticsWorker *d;
|
||||||
|
|
||||||
|
void SendEvent(const QString &eventName, const QHash<QString, QJsonValue> ¶ms);
|
||||||
|
|
||||||
|
auto InitAppStartEventParams(qint64 engagementTimeMsec) const -> QHash<QString, QJsonValue>;
|
||||||
|
|
||||||
|
friend auto operator<<(QDataStream &outStream, const VGAnalytics &analytics) -> QDataStream &;
|
||||||
|
friend auto operator>>(QDataStream &inStream, VGAnalytics &analytics) -> QDataStream &;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // VGANALYTICS_H
|
8
src/libs/vganalytics/vganalytics.pri
Normal file
8
src/libs/vganalytics/vganalytics.pri
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
HEADERS += \
|
||||||
|
$$PWD/def.h \
|
||||||
|
$$PWD/vganalytics.h \
|
||||||
|
$$PWD/vganalyticsworker.h
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
$$PWD/vganalytics.cpp \
|
||||||
|
$$PWD/vganalyticsworker.cpp
|
80
src/libs/vganalytics/vganalytics.pro
Normal file
80
src/libs/vganalytics/vganalytics.pro
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
# File with common stuff for whole project
|
||||||
|
include(../../../common.pri)
|
||||||
|
|
||||||
|
QT += network gui
|
||||||
|
|
||||||
|
# Name of library
|
||||||
|
TARGET = vganalytics
|
||||||
|
|
||||||
|
# We want to create a library
|
||||||
|
TEMPLATE = lib
|
||||||
|
|
||||||
|
CONFIG += staticlib # Making static library
|
||||||
|
|
||||||
|
# Since Q5.12 available support for C++17
|
||||||
|
equals(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 11) {
|
||||||
|
CONFIG += c++17
|
||||||
|
} else {
|
||||||
|
CONFIG += c++14
|
||||||
|
}
|
||||||
|
|
||||||
|
# Use out-of-source builds (shadow builds)
|
||||||
|
CONFIG -= debug_and_release debug_and_release_target
|
||||||
|
|
||||||
|
# The following define makes your compiler emit warnings if you use
|
||||||
|
# any feature of Qt which has been marked as deprecated (the exact warnings
|
||||||
|
# depend on your compiler). Please consult the documentation of the
|
||||||
|
# deprecated API in order to know how to port your code away from it.
|
||||||
|
DEFINES += QT_DEPRECATED_WARNINGS
|
||||||
|
|
||||||
|
# You can also make your code fail to compile if you use deprecated APIs.
|
||||||
|
# In order to do so, uncomment the following line.
|
||||||
|
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
||||||
|
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||||
|
|
||||||
|
# Since Qt 5.4.0 the source code location is recorded only in debug builds.
|
||||||
|
# We need this information also in release builds. For this need define QT_MESSAGELOGCONTEXT.
|
||||||
|
DEFINES += QT_MESSAGELOGCONTEXT
|
||||||
|
|
||||||
|
include(vganalytics.pri)
|
||||||
|
|
||||||
|
# This is static library so no need in "make install"
|
||||||
|
|
||||||
|
# directory for executable file
|
||||||
|
DESTDIR = bin
|
||||||
|
|
||||||
|
# files created moc
|
||||||
|
MOC_DIR = moc
|
||||||
|
|
||||||
|
# objecs files
|
||||||
|
OBJECTS_DIR = obj
|
||||||
|
|
||||||
|
# Set using ccache. Function enable_ccache() defined in common.pri.
|
||||||
|
$$enable_ccache()
|
||||||
|
|
||||||
|
include(warnings.pri)
|
||||||
|
|
||||||
|
CONFIG(debug, debug|release){
|
||||||
|
# Debug mode
|
||||||
|
}else{
|
||||||
|
# Release mode
|
||||||
|
!*msvc*:CONFIG += silent
|
||||||
|
DEFINES += V_NO_ASSERT
|
||||||
|
!unix:*g++*{
|
||||||
|
QMAKE_CXXFLAGS += -fno-omit-frame-pointer # Need for exchndl.dll
|
||||||
|
}
|
||||||
|
|
||||||
|
noDebugSymbols{ # For enable run qmake with CONFIG+=noDebugSymbols
|
||||||
|
# do nothing
|
||||||
|
} else {
|
||||||
|
!macx:!*msvc*{
|
||||||
|
# Turn on debug symbols in release mode on Unix systems.
|
||||||
|
# On Mac OS X temporarily disabled. TODO: find way how to strip binary file.
|
||||||
|
QMAKE_CXXFLAGS_RELEASE += -g -gdwarf-3
|
||||||
|
QMAKE_CFLAGS_RELEASE += -g -gdwarf-3
|
||||||
|
QMAKE_LFLAGS_RELEASE =
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
include (../libs.pri)
|
16
src/libs/vganalytics/vganalytics.qbs
Normal file
16
src/libs/vganalytics/vganalytics.qbs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
VLib {
|
||||||
|
name: "VGAnalyticsLib"
|
||||||
|
files: [
|
||||||
|
"def.h",
|
||||||
|
"vganalytics.cpp",
|
||||||
|
"vganalytics.h",
|
||||||
|
"vganalyticsworker.cpp",
|
||||||
|
"vganalyticsworker.h",
|
||||||
|
]
|
||||||
|
Depends { name: "Qt"; submodules: ["core", "network", "gui"] }
|
||||||
|
|
||||||
|
Export {
|
||||||
|
Depends { name: "cpp" }
|
||||||
|
cpp.includePaths: [exportingProduct.sourceDirectory]
|
||||||
|
}
|
||||||
|
}
|
281
src/libs/vganalytics/vganalyticsworker.cpp
Normal file
281
src/libs/vganalytics/vganalyticsworker.cpp
Normal file
|
@ -0,0 +1,281 @@
|
||||||
|
/************************************************************************
|
||||||
|
**
|
||||||
|
** @file vganalyticsworker.cpp
|
||||||
|
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||||
|
** @date 26 6, 2023
|
||||||
|
**
|
||||||
|
** @brief
|
||||||
|
** @copyright
|
||||||
|
** This source code is part of the Valentina project, a pattern making
|
||||||
|
** program, whose allow create and modeling patterns of clothing.
|
||||||
|
** Copyright (C) 2023 Valentina project
|
||||||
|
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
|
||||||
|
**
|
||||||
|
** Valentina is free software: you can redistribute it and/or modify
|
||||||
|
** it under the terms of the GNU General Public License as published by
|
||||||
|
** the Free Software Foundation, either version 3 of the License, or
|
||||||
|
** (at your option) any later version.
|
||||||
|
**
|
||||||
|
** Valentina is distributed in the hope that it will be useful,
|
||||||
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
** GNU General Public License for more details.
|
||||||
|
**
|
||||||
|
** You should have received a copy of the GNU General Public License
|
||||||
|
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
**
|
||||||
|
*************************************************************************/
|
||||||
|
#include "vganalyticsworker.h"
|
||||||
|
#include "vganalytics.h"
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QNetworkAccessManager>
|
||||||
|
#include <QNetworkReply>
|
||||||
|
|
||||||
|
#include <QGuiApplication>
|
||||||
|
#include <QScreen>
|
||||||
|
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
|
|
||||||
|
const QLatin1String VGAnalyticsWorker::dateTimeFormat("yyyy,MM,dd-hh:mm::ss:zzz");
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
constexpr int fourHours = 4 * 60 * 60 * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
VGAnalyticsWorker::VGAnalyticsWorker(QObject *parent)
|
||||||
|
: QObject(parent),
|
||||||
|
m_logLevel(VGAnalytics::Error)
|
||||||
|
{
|
||||||
|
m_appName = QCoreApplication::applicationName();
|
||||||
|
m_appVersion = QCoreApplication::applicationVersion();
|
||||||
|
m_request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json; charset=utf-8");
|
||||||
|
m_request.setHeader(QNetworkRequest::UserAgentHeader, GetUserAgent());
|
||||||
|
|
||||||
|
m_guiLanguage = QLocale::system().name().toLower().replace(QChar('_'), QChar('-'));
|
||||||
|
|
||||||
|
QScreen *screen = QGuiApplication::primaryScreen();
|
||||||
|
QSize size = screen->size();
|
||||||
|
|
||||||
|
m_screenResolution = QStringLiteral("%1x%2").arg(size.width()).arg(size.height());
|
||||||
|
m_screenScaleFactor = screen->logicalDotsPerInchX() / 96.0;
|
||||||
|
|
||||||
|
m_timer.setInterval(m_timerInterval);
|
||||||
|
connect(&m_timer, &QTimer::timeout, this, &VGAnalyticsWorker::PostMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void VGAnalyticsWorker::Enable(bool state)
|
||||||
|
{
|
||||||
|
// state change to the same is not valid.
|
||||||
|
if (m_isEnabled == state)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_isEnabled = state;
|
||||||
|
if (m_isEnabled)
|
||||||
|
{
|
||||||
|
// enable -> start doing things :)
|
||||||
|
m_timer.start();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// disable -> stop the timer
|
||||||
|
m_timer.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void VGAnalyticsWorker::LogMessage(enum VGAnalytics::LogLevel level, const QString &message) const
|
||||||
|
{
|
||||||
|
if (m_logLevel > level)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "[Analytics]" << message;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* Try to gain information about the system where this application
|
||||||
|
* is running. It needs to get the name and version of the operating
|
||||||
|
* system, the language and screen resolution.
|
||||||
|
* All this information will be send in POST messages.
|
||||||
|
* @return agent A QString with all the information formatted for a POST message.
|
||||||
|
*/
|
||||||
|
auto VGAnalyticsWorker::GetUserAgent() const -> QString
|
||||||
|
{
|
||||||
|
return QStringLiteral("%1/%2").arg(m_appName, m_appVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* The message queue contains a list of QueryBuffer object.
|
||||||
|
* QueryBuffer holds a QUrlQuery object and a QDateTime object.
|
||||||
|
* These both object are freed from the buffer object and
|
||||||
|
* inserted as QString objects in a QList.
|
||||||
|
* @return dataList The list with concartinated queue data.
|
||||||
|
*/
|
||||||
|
auto VGAnalyticsWorker::PersistMessageQueue() -> QList<QString>
|
||||||
|
{
|
||||||
|
QList<QString> dataList;
|
||||||
|
dataList.reserve(m_messageQueue.size() * 2);
|
||||||
|
|
||||||
|
for (const auto &buffer : m_messageQueue)
|
||||||
|
{
|
||||||
|
dataList << QJsonDocument(buffer.postQuery).toJson();
|
||||||
|
dataList << buffer.time.toString(dateTimeFormat);
|
||||||
|
}
|
||||||
|
return dataList;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* Reads persistent messages from a file.
|
||||||
|
* Gets all message data as a QList<QString>.
|
||||||
|
* Two lines in the list build a QueryBuffer object.
|
||||||
|
*/
|
||||||
|
void VGAnalyticsWorker::ReadMessagesFromFile(const QList<QString> &dataList)
|
||||||
|
{
|
||||||
|
QListIterator<QString> iter(dataList);
|
||||||
|
while (iter.hasNext())
|
||||||
|
{
|
||||||
|
QString queryString = iter.next();
|
||||||
|
QString dateString = iter.next();
|
||||||
|
QDateTime dateTime = QDateTime::fromString(dateString, dateTimeFormat);
|
||||||
|
QueryBuffer buffer;
|
||||||
|
|
||||||
|
QJsonDocument jsonDocument = QJsonDocument::fromJson(queryString.toUtf8());
|
||||||
|
if (jsonDocument.isNull())
|
||||||
|
{
|
||||||
|
qDebug() << "===> please check the string " << queryString.toUtf8();
|
||||||
|
}
|
||||||
|
QJsonObject jsonObject = jsonDocument.object();
|
||||||
|
|
||||||
|
buffer.postQuery = jsonObject;
|
||||||
|
buffer.time = dateTime;
|
||||||
|
m_messageQueue.enqueue(buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* Takes a QUrlQuery object and wrapp it together with
|
||||||
|
* a QTime object into a QueryBuffer struct. These struct
|
||||||
|
* will be stored in the message queue.
|
||||||
|
*/
|
||||||
|
void VGAnalyticsWorker::EnqueQueryWithCurrentTime(const QJsonObject &query)
|
||||||
|
{
|
||||||
|
QueryBuffer buffer;
|
||||||
|
buffer.postQuery = query;
|
||||||
|
buffer.time = QDateTime::currentDateTime();
|
||||||
|
|
||||||
|
m_messageQueue.enqueue(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* This function is called by a timer interval.
|
||||||
|
* The function tries to send a messages from the queue.
|
||||||
|
* If message was successfully send then this function
|
||||||
|
* will be called back to send next message.
|
||||||
|
* If message queue contains more than one message then
|
||||||
|
* the connection will kept open.
|
||||||
|
* The message POST is asyncroniously when the server
|
||||||
|
* answered a signal will be emitted.
|
||||||
|
*/
|
||||||
|
auto VGAnalyticsWorker::PostMessage() -> QNetworkReply *
|
||||||
|
{
|
||||||
|
if (m_messageQueue.isEmpty())
|
||||||
|
{
|
||||||
|
// queue empty -> try sending later
|
||||||
|
m_timer.start();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// queue has messages -> stop timer and start sending
|
||||||
|
m_timer.stop();
|
||||||
|
|
||||||
|
QString connection = QStringLiteral("close");
|
||||||
|
if (m_messageQueue.count() > 1)
|
||||||
|
{
|
||||||
|
connection = QLatin1String("keep-alive");
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuffer buffer = m_messageQueue.head();
|
||||||
|
QDateTime sendTime = QDateTime::currentDateTime();
|
||||||
|
qint64 timeDiff = buffer.time.msecsTo(sendTime);
|
||||||
|
|
||||||
|
if (timeDiff > fourHours)
|
||||||
|
{
|
||||||
|
// too old.
|
||||||
|
m_messageQueue.dequeue();
|
||||||
|
return PostMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray requestJson = QJsonDocument(buffer.postQuery).toJson(QJsonDocument::Compact);
|
||||||
|
m_request.setRawHeader("Connection", connection.toUtf8());
|
||||||
|
m_request.setHeader(QNetworkRequest::ContentLengthHeader, requestJson.length());
|
||||||
|
|
||||||
|
if (m_measurementId.isEmpty())
|
||||||
|
{
|
||||||
|
LogMessage(VGAnalytics::Error, QStringLiteral("google analytics measurement id was not set!"));
|
||||||
|
}
|
||||||
|
if (m_apiSecret.isEmpty())
|
||||||
|
{
|
||||||
|
LogMessage(VGAnalytics::Error, QStringLiteral("google analytics api seceret was not set!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
QString requestUrl = QStringLiteral("https://www.google-analytics.com/mp/collect?measurement_id=%1&api_secret=%2");
|
||||||
|
requestUrl = requestUrl.arg(m_measurementId, m_apiSecret);
|
||||||
|
m_request.setUrl(QUrl(requestUrl));
|
||||||
|
|
||||||
|
LogMessage(VGAnalytics::Debug, "GA Query string = " + requestJson);
|
||||||
|
|
||||||
|
// Create a new network access manager if we don't have one yet
|
||||||
|
if (networkManager == nullptr)
|
||||||
|
{
|
||||||
|
networkManager = new QNetworkAccessManager(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
QNetworkReply *reply = networkManager->post(m_request, requestJson);
|
||||||
|
connect(reply, &QNetworkReply::finished, this, &VGAnalyticsWorker::PostMessageFinished);
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* NetworkAccsessManager has finished to POST a message.
|
||||||
|
* If POST message was successfully send then the message
|
||||||
|
* query should be removed from queue.
|
||||||
|
* SIGNAL "postMessage" will be emitted to send next message
|
||||||
|
* if there is any.
|
||||||
|
* If message couldn't be send then next try is when the
|
||||||
|
* timer emits its signal.
|
||||||
|
*/
|
||||||
|
void VGAnalyticsWorker::PostMessageFinished()
|
||||||
|
{
|
||||||
|
auto *reply = qobject_cast<QNetworkReply *>(sender());
|
||||||
|
|
||||||
|
int httpStausCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||||
|
if (httpStausCode < 200 || httpStausCode > 299)
|
||||||
|
{
|
||||||
|
LogMessage(VGAnalytics::Error, QStringLiteral("Error posting message: %1").arg(reply->errorString()));
|
||||||
|
|
||||||
|
// An error ocurred. Try sending later.
|
||||||
|
m_timer.start();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogMessage(VGAnalytics::Debug, QStringLiteral("Message sent"));
|
||||||
|
|
||||||
|
m_messageQueue.dequeue();
|
||||||
|
PostMessage();
|
||||||
|
reply->deleteLater();
|
||||||
|
}
|
97
src/libs/vganalytics/vganalyticsworker.h
Normal file
97
src/libs/vganalytics/vganalyticsworker.h
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
/************************************************************************
|
||||||
|
**
|
||||||
|
** @file vganalyticsworker.h
|
||||||
|
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||||
|
** @date 26 6, 2023
|
||||||
|
**
|
||||||
|
** @brief
|
||||||
|
** @copyright
|
||||||
|
** This source code is part of the Valentina project, a pattern making
|
||||||
|
** program, whose allow create and modeling patterns of clothing.
|
||||||
|
** Copyright (C) 2023 Valentina project
|
||||||
|
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
|
||||||
|
**
|
||||||
|
** Valentina is free software: you can redistribute it and/or modify
|
||||||
|
** it under the terms of the GNU General Public License as published by
|
||||||
|
** the Free Software Foundation, either version 3 of the License, or
|
||||||
|
** (at your option) any later version.
|
||||||
|
**
|
||||||
|
** Valentina is distributed in the hope that it will be useful,
|
||||||
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
** GNU General Public License for more details.
|
||||||
|
**
|
||||||
|
** You should have received a copy of the GNU General Public License
|
||||||
|
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
**
|
||||||
|
*************************************************************************/
|
||||||
|
#ifndef VGANALYTICSWORKER_H
|
||||||
|
#define VGANALYTICSWORKER_H
|
||||||
|
|
||||||
|
#include "vganalytics.h"
|
||||||
|
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QNetworkRequest>
|
||||||
|
#include <QObject>
|
||||||
|
#include <QQueue>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QUrlQuery>
|
||||||
|
#include <qglobal.h>
|
||||||
|
|
||||||
|
class QNetworkReply;
|
||||||
|
|
||||||
|
struct QueryBuffer
|
||||||
|
{
|
||||||
|
QJsonObject postQuery{};
|
||||||
|
QDateTime time{};
|
||||||
|
};
|
||||||
|
|
||||||
|
class VGAnalyticsWorker : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT // NOLINT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit VGAnalyticsWorker(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
QNetworkAccessManager *networkManager{nullptr}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||||
|
|
||||||
|
QQueue<QueryBuffer> m_messageQueue{}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||||
|
QTimer m_timer{}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||||
|
QNetworkRequest m_request{}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||||
|
enum VGAnalytics::LogLevel m_logLevel{VGAnalytics::Debug}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||||
|
|
||||||
|
QString m_measurementId{}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||||
|
QString m_apiSecret{}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||||
|
QString m_clientID{}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||||
|
QString m_userID{}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||||
|
QString m_appName{}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||||
|
QString m_appVersion{}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||||
|
QString m_guiLanguage{}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||||
|
QString m_screenResolution{}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||||
|
QString m_repoRevision{}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||||
|
|
||||||
|
bool m_isEnabled{false}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||||
|
int m_timerInterval{30000}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||||
|
qreal m_screenScaleFactor{}; // NOLINT(misc-non-private-member-variables-in-classes)
|
||||||
|
|
||||||
|
const static QLatin1String dateTimeFormat;
|
||||||
|
|
||||||
|
void LogMessage(enum VGAnalytics::LogLevel level, const QString &message) const;
|
||||||
|
|
||||||
|
auto GetUserAgent() const -> QString;
|
||||||
|
auto PersistMessageQueue() -> QList<QString>;
|
||||||
|
void ReadMessagesFromFile(const QList<QString> &dataList);
|
||||||
|
|
||||||
|
void EnqueQueryWithCurrentTime(const QJsonObject &query);
|
||||||
|
void Enable(bool state);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
QNetworkReply *PostMessage(); // NOLINT(modernize-use-trailing-return-type)
|
||||||
|
void PostMessageFinished();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Q_DISABLE_COPY_MOVE(VGAnalyticsWorker)
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // VGANALYTICSWORKER_H
|
82
src/libs/vganalytics/warnings.pri
Normal file
82
src/libs/vganalytics/warnings.pri
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
#Turn on compilers warnings.
|
||||||
|
unix {
|
||||||
|
*g++*{
|
||||||
|
QMAKE_CXXFLAGS += \
|
||||||
|
# Key -isystem disable checking errors in system headers.
|
||||||
|
-isystem "$${OUT_PWD}/$${MOC_DIR}" \
|
||||||
|
-isystem "$${OUT_PWD}/$${UI_DIR}" \
|
||||||
|
$$GCC_DEBUG_CXXFLAGS # See common.pri for more details.
|
||||||
|
|
||||||
|
checkWarnings{ # For enable run qmake with CONFIG+=checkWarnings
|
||||||
|
QMAKE_CXXFLAGS += -Werror
|
||||||
|
}
|
||||||
|
|
||||||
|
noAddressSanitizer{ # For enable run qmake with CONFIG+=noAddressSanitizer
|
||||||
|
# do nothing
|
||||||
|
} else {
|
||||||
|
CONFIG(debug, debug|release){
|
||||||
|
# Debug mode
|
||||||
|
#gcc’s 4.8.0 Address Sanitizer
|
||||||
|
#http://blog.qt.digia.com/blog/2013/04/17/using-gccs-4-8-0-address-sanitizer-with-qt/
|
||||||
|
QMAKE_CXXFLAGS += -fsanitize=address -fno-omit-frame-pointer
|
||||||
|
QMAKE_CFLAGS += -fsanitize=address -fno-omit-frame-pointer
|
||||||
|
QMAKE_LFLAGS += -fsanitize=address
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gccUbsan{ # For enable run qmake with CONFIG+=gccUbsan
|
||||||
|
CONFIG(debug, debug|release){
|
||||||
|
# Debug mode
|
||||||
|
#gcc’s 4.9.0 Undefined Behavior Sanitizer (ubsan)
|
||||||
|
QMAKE_CXXFLAGS += -fsanitize=undefined
|
||||||
|
QMAKE_CFLAGS += -fsanitize=undefined
|
||||||
|
QMAKE_LFLAGS += -fsanitize=undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*clang*{
|
||||||
|
QMAKE_CXXFLAGS += \
|
||||||
|
# Key -isystem disable checking errors in system headers.
|
||||||
|
-isystem "$${OUT_PWD}/$${MOC_DIR}" \
|
||||||
|
-isystem "$${OUT_PWD}/$${UI_DIR}" \
|
||||||
|
$$CLANG_DEBUG_CXXFLAGS # See common.pri for more details.
|
||||||
|
|
||||||
|
checkWarnings{ # For enable run qmake with CONFIG+=checkWarnings
|
||||||
|
QMAKE_CXXFLAGS += -Werror
|
||||||
|
}
|
||||||
|
|
||||||
|
# -isystem key works only for headers. In some cases it's not enough. But we can't delete these warnings and
|
||||||
|
# want them in global list. Compromise decision delete them from local list.
|
||||||
|
QMAKE_CXXFLAGS -= \
|
||||||
|
-Wmissing-prototypes \
|
||||||
|
-Wundefined-reinterpret-cast
|
||||||
|
}
|
||||||
|
|
||||||
|
*-icc-*{
|
||||||
|
QMAKE_CXXFLAGS += \
|
||||||
|
-isystem "$${OUT_PWD}/$${MOC_DIR}" \
|
||||||
|
-isystem "$${OUT_PWD}/$${UI_DIR}" \
|
||||||
|
$$ICC_DEBUG_CXXFLAGS
|
||||||
|
|
||||||
|
checkWarnings{ # For enable run qmake with CONFIG+=checkWarnings
|
||||||
|
QMAKE_CXXFLAGS += -Werror
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else { # Windows
|
||||||
|
*g++*{
|
||||||
|
QMAKE_CXXFLAGS += $$GCC_DEBUG_CXXFLAGS # See common.pri for more details.
|
||||||
|
|
||||||
|
checkWarnings{ # For enable run qmake with CONFIG+=checkWarnings
|
||||||
|
QMAKE_CXXFLAGS += -Werror
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*msvc*{
|
||||||
|
QMAKE_CXXFLAGS += $$MSVC_DEBUG_CXXFLAGS # See common.pri for more details.
|
||||||
|
|
||||||
|
checkWarnings{ # For enable run qmake with CONFIG+=checkWarnings
|
||||||
|
QMAKE_CXXFLAGS += -WX
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
49
src/libs/vmisc/dialogs/dialogaskcollectstatistic.cpp
Normal file
49
src/libs/vmisc/dialogs/dialogaskcollectstatistic.cpp
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/************************************************************************
|
||||||
|
**
|
||||||
|
** @file dialogaskcollectstatistic.cpp
|
||||||
|
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||||
|
** @date 26 6, 2023
|
||||||
|
**
|
||||||
|
** @brief
|
||||||
|
** @copyright
|
||||||
|
** This source code is part of the Valentina project, a pattern making
|
||||||
|
** program, whose allow create and modeling patterns of clothing.
|
||||||
|
** Copyright (C) 2023 Valentina project
|
||||||
|
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
|
||||||
|
**
|
||||||
|
** Valentina is free software: you can redistribute it and/or modify
|
||||||
|
** it under the terms of the GNU General Public License as published by
|
||||||
|
** the Free Software Foundation, either version 3 of the License, or
|
||||||
|
** (at your option) any later version.
|
||||||
|
**
|
||||||
|
** Valentina is distributed in the hope that it will be useful,
|
||||||
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
** GNU General Public License for more details.
|
||||||
|
**
|
||||||
|
** You should have received a copy of the GNU General Public License
|
||||||
|
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
**
|
||||||
|
*************************************************************************/
|
||||||
|
#include "dialogaskcollectstatistic.h"
|
||||||
|
#include "ui_dialogaskcollectstatistic.h"
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
DialogAskCollectStatistic::DialogAskCollectStatistic(QWidget *parent)
|
||||||
|
: QDialog(parent),
|
||||||
|
ui(new Ui::DialogAskCollectStatistic)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
DialogAskCollectStatistic::~DialogAskCollectStatistic()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
auto DialogAskCollectStatistic::CollectStatistic() -> bool
|
||||||
|
{
|
||||||
|
return ui->checkBoxSendUsageStatistics->isChecked();
|
||||||
|
}
|
57
src/libs/vmisc/dialogs/dialogaskcollectstatistic.h
Normal file
57
src/libs/vmisc/dialogs/dialogaskcollectstatistic.h
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
/************************************************************************
|
||||||
|
**
|
||||||
|
** @file dialogaskcollectstatistic.h
|
||||||
|
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
||||||
|
** @date 26 6, 2023
|
||||||
|
**
|
||||||
|
** @brief
|
||||||
|
** @copyright
|
||||||
|
** This source code is part of the Valentina project, a pattern making
|
||||||
|
** program, whose allow create and modeling patterns of clothing.
|
||||||
|
** Copyright (C) 2023 Valentina project
|
||||||
|
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
|
||||||
|
**
|
||||||
|
** Valentina is free software: you can redistribute it and/or modify
|
||||||
|
** it under the terms of the GNU General Public License as published by
|
||||||
|
** the Free Software Foundation, either version 3 of the License, or
|
||||||
|
** (at your option) any later version.
|
||||||
|
**
|
||||||
|
** Valentina is distributed in the hope that it will be useful,
|
||||||
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
** GNU General Public License for more details.
|
||||||
|
**
|
||||||
|
** You should have received a copy of the GNU General Public License
|
||||||
|
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
**
|
||||||
|
*************************************************************************/
|
||||||
|
#ifndef DIALOGASKCOLLECTSTATISTIC_H
|
||||||
|
#define DIALOGASKCOLLECTSTATISTIC_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QtGlobal>
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
|
||||||
|
#include "../defglobal.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Ui
|
||||||
|
{
|
||||||
|
class DialogAskCollectStatistic;
|
||||||
|
}
|
||||||
|
|
||||||
|
class DialogAskCollectStatistic : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT // NOLINT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit DialogAskCollectStatistic(QWidget *parent = nullptr);
|
||||||
|
~DialogAskCollectStatistic() override;
|
||||||
|
|
||||||
|
auto CollectStatistic() -> bool;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Q_DISABLE_COPY_MOVE(DialogAskCollectStatistic) // NOLINT
|
||||||
|
Ui::DialogAskCollectStatistic *ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DIALOGASKCOLLECTSTATISTIC_H
|
103
src/libs/vmisc/dialogs/dialogaskcollectstatistic.ui
Normal file
103
src/libs/vmisc/dialogs/dialogaskcollectstatistic.ui
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>DialogAskCollectStatistic</class>
|
||||||
|
<widget class="QDialog" name="DialogAskCollectStatistic">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>376</width>
|
||||||
|
<height>183</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Privacy</string>
|
||||||
|
</property>
|
||||||
|
<property name="windowIcon">
|
||||||
|
<iconset resource="../share/resources/icon.qrc">
|
||||||
|
<normaloff>:/icon/64x64/icon64x64.png</normaloff>:/icon/64x64/icon64x64.png</iconset>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkBoxSendUsageStatistics">
|
||||||
|
<property name="text">
|
||||||
|
<string>Send usage statistics</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Please help to improve Valentina's quality by automatically sending usage statistics. Sent data contains <span style=" font-weight:700;">no potentially sensitive information</span> like user names, email addresses, file contents or file paths.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources>
|
||||||
|
<include location="../share/resources/icon.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>DialogAskCollectStatistic</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>DialogAskCollectStatistic</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
|
@ -153,6 +153,8 @@ VAbstractApplication::VAbstractApplication(int &argc, char **argv)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
connect(this, &QApplication::aboutToQuit, this, &VAbstractApplication::AboutToQuit);
|
connect(this, &QApplication::aboutToQuit, this, &VAbstractApplication::AboutToQuit);
|
||||||
|
|
||||||
|
m_uptimeTimer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -433,6 +435,12 @@ void VAbstractApplication::RestartSVGFontDatabaseWatcher()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
auto VAbstractApplication::AppUptime() const -> qint64
|
||||||
|
{
|
||||||
|
return m_uptimeTimer.elapsed();
|
||||||
|
}
|
||||||
|
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
auto VAbstractApplication::TextCodecCache(QStringConverter::Encoding encoding) const -> VTextCodec *
|
auto VAbstractApplication::TextCodecCache(QStringConverter::Encoding encoding) const -> VTextCodec *
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
|
#include <QElapsedTimer>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QLocale>
|
#include <QLocale>
|
||||||
#include <QMetaObject>
|
#include <QMetaObject>
|
||||||
|
@ -104,6 +105,8 @@ public:
|
||||||
auto SVGFontDatabase() -> VSvgFontDatabase *;
|
auto SVGFontDatabase() -> VSvgFontDatabase *;
|
||||||
void RestartSVGFontDatabaseWatcher();
|
void RestartSVGFontDatabaseWatcher();
|
||||||
|
|
||||||
|
auto AppUptime() const -> qint64;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QUndoStack *undoStack;
|
QUndoStack *undoStack;
|
||||||
|
|
||||||
|
@ -120,6 +123,8 @@ protected:
|
||||||
QPointer<QTranslator> appTranslator{nullptr};
|
QPointer<QTranslator> appTranslator{nullptr};
|
||||||
QPointer<QTranslator> pmsTranslator{nullptr};
|
QPointer<QTranslator> pmsTranslator{nullptr};
|
||||||
|
|
||||||
|
QElapsedTimer m_uptimeTimer{};
|
||||||
|
|
||||||
virtual void InitTrVars() = 0;
|
virtual void InitTrVars() = 0;
|
||||||
|
|
||||||
static void CheckSystemLocale();
|
static void CheckSystemLocale();
|
||||||
|
|
|
@ -233,6 +233,10 @@ Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingWatermarkEditorSize, (QLatin1Str
|
||||||
// NOLINTNEXTLINE
|
// NOLINTNEXTLINE
|
||||||
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingWatermarkCustomColors, (QLatin1String("watermarkCustomColors")))
|
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingWatermarkCustomColors, (QLatin1String("watermarkCustomColors")))
|
||||||
|
|
||||||
|
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingsStatistictAskCollect, (QLatin1String("askCollect"))) // NOLINT
|
||||||
|
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingsStatistictCollect, (QLatin1String("collect"))) // NOLINT
|
||||||
|
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingsStatistictClientID, (QLatin1String("clientID"))) // NOLINT
|
||||||
|
|
||||||
// Reading settings file is very expensive, cache curve approximation to speed up getting value
|
// Reading settings file is very expensive, cache curve approximation to speed up getting value
|
||||||
qreal curveApproximationCached = -1; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
qreal curveApproximationCached = -1; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||||
Q_GLOBAL_STATIC(QString, localeCached) // NOLINT
|
Q_GLOBAL_STATIC(QString, localeCached) // NOLINT
|
||||||
|
@ -1116,20 +1120,20 @@ auto VCommonSettings::GetCSVSeparator() const -> QChar
|
||||||
switch (separator)
|
switch (separator)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
return QChar('\t');
|
return QChar('\t'); // NOLINT(modernize-return-braced-init-list)
|
||||||
case 1:
|
case 1:
|
||||||
return QChar(';');
|
return QChar(';'); // NOLINT(modernize-return-braced-init-list)
|
||||||
case 2:
|
case 2:
|
||||||
return QChar(' ');
|
return QChar(' '); // NOLINT(modernize-return-braced-init-list)
|
||||||
default:
|
default:
|
||||||
return QChar(',');
|
return QChar(','); // NOLINT(modernize-return-braced-init-list)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
auto VCommonSettings::GetDefCSVSeparator() -> QChar
|
auto VCommonSettings::GetDefCSVSeparator() -> QChar
|
||||||
{
|
{
|
||||||
return QChar(',');
|
return QChar(','); // NOLINT(modernize-return-braced-init-list)
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -1751,6 +1755,51 @@ void VCommonSettings::SetWatermarkCustomColors(QVector<QColor> colors)
|
||||||
settings.sync();
|
settings.sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
auto VCommonSettings::IsAskCollectStatistic() const -> bool
|
||||||
|
{
|
||||||
|
QSettings settings(this->format(), this->scope(), this->organizationName(), *commonIniFilename);
|
||||||
|
return settings.value(*settingsStatistictAskCollect, 1).toBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void VCommonSettings::SetAskCollectStatistic(bool value)
|
||||||
|
{
|
||||||
|
QSettings settings(this->format(), this->scope(), this->organizationName(), *commonIniFilename);
|
||||||
|
settings.setValue(*settingsStatistictAskCollect, value);
|
||||||
|
settings.sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
auto VCommonSettings::IsCollectStatistic() const -> bool
|
||||||
|
{
|
||||||
|
QSettings settings(this->format(), this->scope(), this->organizationName(), *commonIniFilename);
|
||||||
|
return settings.value(*settingsStatistictCollect, 1).toBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void VCommonSettings::SetCollectStatistic(bool value)
|
||||||
|
{
|
||||||
|
QSettings settings(this->format(), this->scope(), this->organizationName(), *commonIniFilename);
|
||||||
|
settings.setValue(*settingsStatistictCollect, value);
|
||||||
|
settings.sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
auto VCommonSettings::GetClientID() const -> QString
|
||||||
|
{
|
||||||
|
QSettings settings(this->format(), this->scope(), this->organizationName(), *commonIniFilename);
|
||||||
|
return settings.value(*settingsStatistictClientID, QString()).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
void VCommonSettings::SetClientID(const QString &clientID)
|
||||||
|
{
|
||||||
|
QSettings settings(this->format(), this->scope(), this->organizationName(), *commonIniFilename);
|
||||||
|
settings.setValue(*settingsStatistictClientID, clientID);
|
||||||
|
settings.sync();
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
auto VCommonSettings::PrepareStandardFiles(const QString ¤tPath, const QString &standardPath,
|
auto VCommonSettings::PrepareStandardFiles(const QString ¤tPath, const QString &standardPath,
|
||||||
const QString &defPath) -> QString
|
const QString &defPath) -> QString
|
||||||
|
|
|
@ -321,6 +321,15 @@ public:
|
||||||
auto GetWatermarkCustomColors() const -> QVector<QColor>;
|
auto GetWatermarkCustomColors() const -> QVector<QColor>;
|
||||||
void SetWatermarkCustomColors(QVector<QColor> colors);
|
void SetWatermarkCustomColors(QVector<QColor> colors);
|
||||||
|
|
||||||
|
auto IsAskCollectStatistic() const -> bool;
|
||||||
|
void SetAskCollectStatistic(bool value);
|
||||||
|
|
||||||
|
auto IsCollectStatistic() const -> bool;
|
||||||
|
void SetCollectStatistic(bool value);
|
||||||
|
|
||||||
|
auto GetClientID() const -> QString;
|
||||||
|
void SetClientID(const QString &clientID);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void SVGFontsPathChanged(const QString &oldPath, const QString &newPath);
|
void SVGFontsPathChanged(const QString &oldPath, const QString &newPath);
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
$$PWD/def.cpp \
|
$$PWD/def.cpp \
|
||||||
|
$$PWD/dialogs/dialogaskcollectstatistic.cpp \
|
||||||
$$PWD/svgfont/svgdef.cpp \
|
$$PWD/svgfont/svgdef.cpp \
|
||||||
$$PWD/svgfont/vsvgfont.cpp \
|
$$PWD/svgfont/vsvgfont.cpp \
|
||||||
$$PWD/svgfont/vsvgfontdatabase.cpp \
|
$$PWD/svgfont/vsvgfontdatabase.cpp \
|
||||||
|
@ -61,6 +62,7 @@ HEADERS += \
|
||||||
$$PWD/bpstd/utility.hpp \
|
$$PWD/bpstd/utility.hpp \
|
||||||
$$PWD/bpstd/variant.hpp \
|
$$PWD/bpstd/variant.hpp \
|
||||||
$$PWD/compatibility.h \
|
$$PWD/compatibility.h \
|
||||||
|
$$PWD/dialogs/dialogaskcollectstatistic.h \
|
||||||
$$PWD/lambdaconstants.h \
|
$$PWD/lambdaconstants.h \
|
||||||
$$PWD/stable.h \
|
$$PWD/stable.h \
|
||||||
$$PWD/def.h \
|
$$PWD/def.h \
|
||||||
|
@ -122,5 +124,6 @@ contains(QT_VERSION, ^5\\.[0-2]\\.[0-2]$) { # Since Qt 5.3.0
|
||||||
}
|
}
|
||||||
|
|
||||||
FORMS += \
|
FORMS += \
|
||||||
|
$$PWD/dialogs/dialogaskcollectstatistic.ui \
|
||||||
$$PWD/dialogs/dialogexporttocsv.ui \
|
$$PWD/dialogs/dialogexporttocsv.ui \
|
||||||
$$PWD/dialogs/dialogselectlanguage.ui
|
$$PWD/dialogs/dialogselectlanguage.ui
|
||||||
|
|
|
@ -67,12 +67,15 @@ VLib {
|
||||||
name: "dialogs"
|
name: "dialogs"
|
||||||
prefix: "dialogs/"
|
prefix: "dialogs/"
|
||||||
files: [
|
files: [
|
||||||
|
"dialogaskcollectstatistic.cpp",
|
||||||
|
"dialogaskcollectstatistic.h",
|
||||||
|
"dialogaskcollectstatistic.ui",
|
||||||
"dialogexporttocsv.cpp",
|
"dialogexporttocsv.cpp",
|
||||||
"dialogselectlanguage.cpp",
|
"dialogselectlanguage.cpp",
|
||||||
"dialogexporttocsv.h",
|
"dialogexporttocsv.h",
|
||||||
"dialogselectlanguage.h",
|
"dialogselectlanguage.h",
|
||||||
"dialogexporttocsv.ui",
|
"dialogexporttocsv.ui",
|
||||||
"dialogselectlanguage.ui"
|
"dialogselectlanguage.ui",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user