1 /*
2     SPDX-FileCopyrightText: 2017 Jasem Mutlaq <mutlaqja@ikarustech.com>
3 
4     SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #include "opslogs.h"
8 
9 #include "kstars.h"
10 #include "Options.h"
11 #include "auxiliary/kspaths.h"
12 #include "indi/indilistener.h"
13 
14 #include <KConfigDialog>
15 #include <KFormat>
16 #include <KMessageBox>
17 
18 #include <QFrame>
19 #include <QUrl>
20 #include <QDesktopServices>
21 
22 #include <basedevice.h>
23 
24 namespace Ekos
25 {
OpsLogs()26 OpsLogs::OpsLogs() : QFrame(KStars::Instance())
27 {
28     setupUi(this);
29 
30     refreshInterface();
31 
32     //Get a pointer to the KConfigDialog
33     KConfigDialog *m_ConfigDialog = KConfigDialog::exists("logssettings");
34     connect(m_ConfigDialog->button(QDialogButtonBox::Apply), SIGNAL(clicked()), SLOT(refreshInterface()));
35     connect(m_ConfigDialog->button(QDialogButtonBox::Ok), SIGNAL(clicked()), SLOT(refreshInterface()));
36 
37     connect(clearLogsB, SIGNAL(clicked()), this, SLOT(slotClearLogs()));
38     connect(kcfg_VerboseLogging, SIGNAL(toggled(bool)), this, SLOT(slotToggleVerbosityOptions()));
39 
40     connect(kcfg_LogToFile, SIGNAL(toggled(bool)), this, SLOT(slotToggleOutputOptions()));
41 
42     connect(showLogsB, &QPushButton::clicked, []()
43     {
44         QDesktopServices::openUrl(QUrl::fromLocalFile(QDir(KSPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("logs")));
45     });
46 
47     for (auto &b : modulesGroup->buttons())
48         b->setEnabled(kcfg_VerboseLogging->isChecked());
49     for (auto &b : driversGroup->buttons())
50         b->setEnabled(kcfg_VerboseLogging->isChecked());
51 
52     qint64 totalSize = getDirSize(QDir(KSPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("logs"));
53     totalSize += getDirSize(QDir(KSPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("autofocus"));
54 
55     clearLogsB->setToolTip(i18n("Clear all logs (%1)", KFormat().formatByteSize(totalSize)));
56 
57 }
58 
slotToggleVerbosityOptions()59 void OpsLogs::slotToggleVerbosityOptions()
60 {
61     if (kcfg_DisableLogging->isChecked())
62         KSUtils::Logging::Disable();
63 
64     foreach (QAbstractButton *b, modulesGroup->buttons())
65     {
66         b->setEnabled(kcfg_VerboseLogging->isChecked());
67         // If verbose is not checked, CLEAR all selections
68         b->setChecked(kcfg_VerboseLogging->isChecked() ? b->isChecked() : false);
69     }
70 
71     foreach (QAbstractButton *b, driversGroup->buttons())
72     {
73         b->setEnabled(kcfg_VerboseLogging->isChecked());
74         // If verbose is not checked, CLEAR all selections
75         b->setChecked(kcfg_VerboseLogging->isChecked() ? b->isChecked() : false);
76     }
77 }
78 
slotToggleOutputOptions()79 void OpsLogs::slotToggleOutputOptions()
80 {
81     if (kcfg_LogToDefault->isChecked())
82     {
83         if (kcfg_DisableLogging->isChecked() == false)
84             KSUtils::Logging::UseDefault();
85     }
86     else
87         KSUtils::Logging::UseFile();
88 }
89 
refreshInterface()90 void OpsLogs::refreshInterface()
91 {
92     uint16_t previousInterface = m_INDIDebugInterface;
93 
94     m_INDIDebugInterface = 0;
95 
96     if (Options::iNDIMountLogging())
97         m_INDIDebugInterface |= INDI::BaseDevice::TELESCOPE_INTERFACE;
98     if (Options::iNDICCDLogging())
99         m_INDIDebugInterface |= INDI::BaseDevice::CCD_INTERFACE;
100     if (Options::iNDIFocuserLogging())
101         m_INDIDebugInterface |= INDI::BaseDevice::FOCUSER_INTERFACE;
102     if (Options::iNDIFilterWheelLogging())
103         m_INDIDebugInterface |= INDI::BaseDevice::FILTER_INTERFACE;
104     if (Options::iNDIDomeLogging())
105         m_INDIDebugInterface |= INDI::BaseDevice::DOME_INTERFACE;
106     if (Options::iNDIWeatherLogging())
107         m_INDIDebugInterface |= INDI::BaseDevice::WEATHER_INTERFACE;
108     if (Options::iNDIDetectorLogging())
109         m_INDIDebugInterface |= INDI::BaseDevice::DETECTOR_INTERFACE;
110     if (Options::iNDIRotatorLogging())
111         m_INDIDebugInterface |= INDI::BaseDevice::ROTATOR_INTERFACE;
112     if (Options::iNDIGPSLogging())
113         m_INDIDebugInterface |= INDI::BaseDevice::GPS_INTERFACE;
114     if (Options::iNDIAOLogging())
115         m_INDIDebugInterface |= INDI::BaseDevice::AO_INTERFACE;
116     if (Options::iNDIAuxiliaryLogging())
117         m_INDIDebugInterface |= INDI::BaseDevice::AUX_INTERFACE;
118 
119     Options::setINDILogging((m_INDIDebugInterface > 0));
120 
121     m_SettingsChanged = (previousInterface != m_INDIDebugInterface);
122 }
123 
124 // Following 2 functions from Stackoverflow #47854288
getDirSize(const QString & dirPath)125 qint64 OpsLogs::getDirSize(const QString &dirPath)
126 {
127     qint64 size = 0;
128     QDir dir(dirPath);
129 
130     QDir::Filters fileFilters = QDir::Files | QDir::System | QDir::Hidden;
131 
132     for (QString &filePath : dir.entryList(fileFilters))
133     {
134         QFileInfo fi(dir, filePath);
135 
136         size += fi.size();
137     }
138 
139     QDir::Filters dirFilters = QDir::Dirs | QDir::NoDotAndDotDot | QDir::System | QDir::Hidden;
140 
141     for (QString &childDirPath : dir.entryList(dirFilters))
142         size += getDirSize(dirPath + QDir::separator() + childDirPath);
143 
144     return size;
145 }
146 
slotClearLogs()147 void OpsLogs::slotClearLogs()
148 {
149     if (KMessageBox::questionYesNo(nullptr, i18n("Are you sure you want to delete all logs?")) == KMessageBox::Yes)
150     {
151         QDir logDir(QDir(KSPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("logs"));
152         logDir.removeRecursively();
153         logDir.mkpath(".");
154 
155         QDir autoFocusDir(QDir(KSPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("autofocus"));
156         autoFocusDir.removeRecursively();
157         autoFocusDir.mkpath(".");
158 
159         clearLogsB->setToolTip(i18n("Clear all logs"));
160     }
161 }
162 
163 }
164