59 if (!QFileInfo(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)).exists()) {
60 QDir().mkpath(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation));
62 d->logFile.setFileName(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) +
"/krita.log");
63 d->sysInfoFile.setFileName(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) +
"/krita-sysinfo.log");
65 QFileInfo fi(
d->logFile.fileName());
66 if (fi.size() > 100 * 1000 * 1000) {
67 d->logFile.open(QIODevice::WriteOnly | QIODevice::Truncate);
74 d->logFile.open(QFile::Append | QFile::Text);
75 d->sysInfoFile.open(QFile::WriteOnly | QFile::Text);
100 systemInfo.append(
"Krita\n");
105 QString packageFamilyName;
106 QString packageFullName;
107 systemInfo.append(
"\n Installation type: ");
108 if (tryGetCurrentPackageFamilyName(&packageFamilyName) && tryGetCurrentPackageFullName(&packageFullName)) {
109 systemInfo.append(
"Store / MSIX package\n Family Name: ")
110 .append(packageFamilyName)
111 .append(
"\n Full Name: ")
112 .append(packageFullName);
114 systemInfo.append(
"installer / portable package");
118 systemInfo.append(
"\n Hidpi: ").append(QCoreApplication::testAttribute(Qt::AA_EnableHighDpiScaling) ?
"true" :
"false");
121 systemInfo.append(
"\n Sandbox: ").append((entitlements.
sandbox()) ?
"true" :
"false");
123 systemInfo.append(
"\n\n");
125 systemInfo.append(
"Qt\n");
126 systemInfo.append(
"\n Version (compiled): ").append(QT_VERSION_STR);
127 systemInfo.append(
"\n Version (loaded): ").append(qVersion());
128 systemInfo.append(
"\n\n");
131 systemInfo.append(
"OS Information\n");
132 systemInfo.append(
"\n Build ABI: ").append(QSysInfo::buildAbi());
133 systemInfo.append(
"\n Build CPU: ").append(QSysInfo::buildCpuArchitecture());
134 systemInfo.append(
"\n CPU: ").append(QSysInfo::currentCpuArchitecture());
135 systemInfo.append(
"\n Kernel Type: ").append(QSysInfo::kernelType());
136 systemInfo.append(
"\n Kernel Version: ").append(QSysInfo::kernelVersion());
137 systemInfo.append(
"\n Pretty Productname: ").append(QSysInfo::prettyProductName());
138 systemInfo.append(
"\n Product Type: ").append(QSysInfo::productType());
139 systemInfo.append(
"\n Product Version: ").append(QSysInfo::productVersion());
142 QString manufacturer =
143 QAndroidJniObject::getStaticObjectField(
"android/os/Build",
"MANUFACTURER",
"Ljava/lang/String;").toString();
144 const QString model =
145 QAndroidJniObject::getStaticObjectField(
"android/os/Build",
"MODEL",
"Ljava/lang/String;").toString();
146 manufacturer[0] = manufacturer[0].toUpper();
147 systemInfo.append(
"\n Product Model: ").append(manufacturer +
" " + model);
148#elif defined(Q_OS_LINUX)
149 systemInfo.append(
"\n Desktop: ").append(qgetenv(
"XDG_CURRENT_DESKTOP"));
151 systemInfo.append(
"\n Appimage build: ").append(qEnvironmentVariableIsSet(
"APPIMAGE") ?
"Yes" :
"No");
152#elif defined(Q_OS_WIN)
153 systemInfo.append(
"\n Result of IsWindows10OrGreater(): ").append(IsWindows10OrGreater() ?
"Yes" :
"No");
155 systemInfo.append(
"\n\n");
162 if (!s_instance->d->active) {
166 systemInfo.append(
"Locale\n");
167 systemInfo.append(
"\n Languages: ").append(KLocalizedString::languages().join(
", "));
168 systemInfo.append(
"\n C locale: ").append(std::setlocale(LC_ALL,
nullptr));
169 systemInfo.append(
"\n QLocale current: ").append(QLocale().bcp47Name());
170 systemInfo.append(
"\n QLocale system: ").append(QLocale::system().bcp47Name());
171 const QTextCodec *codecForLocale = QTextCodec::codecForLocale();
172 systemInfo.append(
"\n QTextCodec for locale: ").append(codecForLocale->name());
175 systemInfo.append(
"\n Process ACP: ");
177 if (GetCPInfoExW(CP_ACP, 0, &cpInfo)) {
178 systemInfo.append(QString::fromWCharArray(cpInfo.CodePageName));
181 systemInfo.append(QString::number(GetACP()));
184 int result = GetLocaleInfoEx(LOCALE_NAME_SYSTEM_DEFAULT, LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER, lcData,
sizeof(lcData) /
sizeof(lcData[0]));
186 systemInfo.append(
"\n System locale default ACP: ");
187 int systemACP = lcData[1] << 16 | lcData[0];
188 if (systemACP == CP_ACP) {
189 systemInfo.append(
"N/A");
190 }
else if (GetCPInfoExW(systemACP, 0, &cpInfo)) {
191 systemInfo.append(QString::fromWCharArray(cpInfo.CodePageName));
194 systemInfo.append(QString::number(systemACP));
199 systemInfo.append(
"\n\n");
200 s_instance->d->sysInfoFile.write(systemInfo.toUtf8());
249 Q_ASSERT(s_instance->d->sysInfoFile.isOpen());
252 QString sessionHeader = QString(
"SESSION: %1. Executing %2\n\n")
253 .arg(QDateTime::currentDateTime().toString(Qt::RFC2822Date))
254 .arg(qApp->arguments().join(
' '));
256 s_instance->d->logFile.write(sessionHeader.toUtf8());
258 QString KritaAndQtVersion;
260 .append(
", Qt version compiled: ").append(QT_VERSION_STR)
261 .append(
", loaded: ").append(qVersion())
262 .append(
". Process ID: ")
263 .append(QString::number(qApp->applicationPid())).append(
"\n");
265 KritaAndQtVersion.append(
"-- -- -- -- -- -- -- --\n");
266 s_instance->d->logFile.write(KritaAndQtVersion.toUtf8());
267 s_instance->d->logFile.flush();
268 log(QString(
"Style: %1. Available styles: %2")
269 .arg(qApp->style()->objectName(),
270 QStyleFactory::keys().join(
", ")));
279 info.append(
"Display Information");
280 info.append(
"\nNumber of screens: ").append(QString::number(screens.size()));
282 for (
int i = 0; i < screens.size(); ++i ) {
283 QScreen *screen = screens[i];
284 info.append(
"\n\tScreen: ").append(QString::number(i));
285 info.append(
"\n\t\tName: ").append(screen->name());
286 info.append(
"\n\t\tDepth: ").append(QString::number(screen->depth()));
287 info.append(
"\n\t\tScale: ").append(QString::number(screen->devicePixelRatio()));
288 info.append(
"\n\t\tPhysical DPI").append(QString::number(screen->physicalDotsPerInch()));
289 info.append(
"\n\t\tLogical DPI").append(QString::number(screen->logicalDotsPerInch()));
290 info.append(
"\n\t\tPhysical Size: ").append(QString::number(screen->physicalSize().width()))
292 .append(QString::number(screen->physicalSize().height()));
293 info.append(
"\n\t\tPosition: ").append(QString::number(screen->geometry().x()))
295 .append(QString::number(screen->geometry().y()));
296 info.append(
"\n\t\tResolution in pixels: ").append(QString::number(screen->geometry().width()))
298 .append(QString::number(screen->geometry().height()));
299 info.append(
"\n\t\tManufacturer: ").append(screen->manufacturer());
300 info.append(
"\n\t\tModel: ").append(screen->model());
301 info.append(
"\n\t\tRefresh Rate: ").append(QString::number(screen->refreshRate()));
302 info.append(
"\n\t\tSerial Number: ").append(screen->serialNumber());
311 if (
d->logFile.exists()) {
314 d->logFile.open(QFile::ReadOnly);
315 QString
log = QString::fromUtf8(
d->logFile.readAll());
317 log.append(
"\nKRITA DID NOT CLOSE CORRECTLY\n");
318 QString crashLog = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QStringLiteral(
"/kritacrash.log");
319 if (QFileInfo(crashLog).exists()) {
321 f.open(QFile::ReadOnly);
322 QString crashes = QString::fromUtf8(f.readAll());
325 QStringList crashlist = crashes.split(
"-------------------");
326 log.append(QString(
"\nThere were %1 crashes in total in the crash log.\n").arg(crashlist.size()));
328 if (crashes.size() > 0) {
329 log.append(crashlist.last());
333 d->logFile.open(QFile::WriteOnly);
334 d->logFile.write(
log.toUtf8());
342 d->logFile.open(QFile::ReadOnly);
343 QString
log = QString::fromUtf8(
d->logFile.readAll());
347 int sectionCount = logItems.size();
349 for (
int i = sectionCount -
s_maxLogs; i < sectionCount; ++i) {
350 if (logItems.size() > i ) {
351 keptItems.append(logItems[i]);
355 d->logFile.open(QFile::WriteOnly);
356 d->logFile.write(keptItems.join(
"\nSESSION:").toUtf8());