38 #include <sys/types.h>
43 #include <Carbon/Carbon.h>
44 #include <CoreServices/CoreServices.h>
47 #include <boost/version.hpp>
48 #include <libtorrent/version.hpp>
49 #include <openssl/crypto.h>
50 #include <openssl/opensslv.h>
53 #include <QCoreApplication>
54 #include <QMimeDatabase>
55 #include <QRegularExpression>
60 #if (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)) && defined(QT_DBUS_LIB)
61 #include <QDBusInterface>
73 QT_TRANSLATE_NOOP3(
"misc",
"B",
"bytes"),
74 QT_TRANSLATE_NOOP3(
"misc",
"KiB",
"kibibytes (1024 bytes)"),
75 QT_TRANSLATE_NOOP3(
"misc",
"MiB",
"mebibytes (1024 kibibytes)"),
76 QT_TRANSLATE_NOOP3(
"misc",
"GiB",
"gibibytes (1024 mibibytes)"),
77 QT_TRANSLATE_NOOP3(
"misc",
"TiB",
"tebibytes (1024 gibibytes)"),
78 QT_TRANSLATE_NOOP3(
"misc",
"PiB",
"pebibytes (1024 tebibytes)"),
79 QT_TRANSLATE_NOOP3(
"misc",
"EiB",
"exbibytes (1024 pebibytes)")
99 auto value =
static_cast<qreal
>(bytes);
112 #if defined(Q_OS_WIN)
114 TOKEN_PRIVILEGES tkp;
115 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
118 LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,
119 &tkp.Privileges[0].Luid);
121 tkp.PrivilegeCount = 1;
122 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
126 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
127 (PTOKEN_PRIVILEGES) NULL, 0);
131 if (GetLastError() != ERROR_SUCCESS)
136 ::SetSuspendState(FALSE, FALSE, FALSE);
140 ::SetSuspendState(TRUE, FALSE, FALSE);
144 const QString msg = QCoreApplication::translate(
"misc",
"qBittorrent will shutdown the computer now because all downloads are complete.");
145 auto msgWchar = std::make_unique<wchar_t[]>(msg.length() + 1);
146 msg.toWCharArray(msgWchar.get());
147 ::InitiateSystemShutdownW(
nullptr, msgWchar.get(), 10, TRUE, FALSE);
151 tkp.Privileges[0].Attributes = 0;
152 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0);
154 #elif defined(Q_OS_MACOS)
155 AEEventID EventToSend;
157 EventToSend = kAESleep;
159 EventToSend = kAEShutDown;
160 AEAddressDesc targetDesc;
161 const ProcessSerialNumber kPSNOfSystemProcess = {0, kSystemProcess};
162 AppleEvent eventReply = {typeNull, NULL};
163 AppleEvent appleEventToSend = {typeNull, NULL};
165 OSStatus error = AECreateDesc(typeProcessSerialNumber, &kPSNOfSystemProcess,
166 sizeof(kPSNOfSystemProcess), &targetDesc);
171 error = AECreateAppleEvent(kCoreEventClass, EventToSend, &targetDesc,
172 kAutoGenerateReturnID, kAnyTransactionID, &appleEventToSend);
174 AEDisposeDesc(&targetDesc);
178 error = AESend(&appleEventToSend, &eventReply, kAENoReply,
179 kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
181 AEDisposeDesc(&appleEventToSend);
185 AEDisposeDesc(&eventReply);
187 #elif (defined(Q_OS_UNIX) && defined(QT_DBUS_LIB))
192 QDBusInterface login1Iface(
"org.freedesktop.login1",
"/org/freedesktop/login1",
193 "org.freedesktop.login1.Manager", QDBusConnection::systemBus());
194 if (login1Iface.isValid())
197 login1Iface.call(
"Suspend",
false);
199 login1Iface.call(
"Hibernate",
false);
203 QDBusInterface upowerIface(
"org.freedesktop.UPower",
"/org/freedesktop/UPower",
204 "org.freedesktop.UPower", QDBusConnection::systemBus());
205 if (upowerIface.isValid())
208 upowerIface.call(
"Suspend");
210 upowerIface.call(
"Hibernate");
214 QDBusInterface halIface(
"org.freedesktop.Hal",
"/org/freedesktop/Hal/devices/computer",
215 "org.freedesktop.Hal.Device.SystemPowerManagement",
216 QDBusConnection::systemBus());
218 halIface.call(
"Suspend", 5);
220 halIface.call(
"Hibernate");
225 QDBusInterface login1Iface(
"org.freedesktop.login1",
"/org/freedesktop/login1",
226 "org.freedesktop.login1.Manager", QDBusConnection::systemBus());
227 if (login1Iface.isValid())
229 login1Iface.call(
"PowerOff",
false);
233 QDBusInterface consolekitIface(
"org.freedesktop.ConsoleKit",
"/org/freedesktop/ConsoleKit/Manager",
234 "org.freedesktop.ConsoleKit.Manager", QDBusConnection::systemBus());
235 if (consolekitIface.isValid())
237 consolekitIface.call(
"Stop");
241 QDBusInterface halIface(
"org.freedesktop.Hal",
"/org/freedesktop/Hal/devices/computer",
242 "org.freedesktop.Hal.Device.SystemPowerManagement",
243 QDBusConnection::systemBus());
244 halIface.call(
"Shutdown");
257 ret += QCoreApplication::translate(
"misc",
"/s",
"per second");
265 return QCoreApplication::translate(
"misc",
"Unknown",
"Unknown (size)");
278 case SizeUnit::KibiByte:
279 case SizeUnit::MebiByte:
281 case SizeUnit::GibiByte:
290 for (
int i = 0; i < static_cast<int>(unit); ++i)
297 const QString mime = QMimeDatabase().mimeTypeForFile(filename, QMimeDatabase::MatchExtension).name();
299 if (mime.startsWith(QLatin1String(
"audio"), Qt::CaseInsensitive)
300 || mime.startsWith(QLatin1String(
"video"), Qt::CaseInsensitive))
305 const QSet<QString> multimediaExtensions =
357 if ((maxCap >= 0) && (seconds >= maxCap))
364 return QCoreApplication::translate(
"misc",
"< 1m",
"< 1 minute");
366 qlonglong minutes = (seconds / 60);
368 return QCoreApplication::translate(
"misc",
"%1m",
"e.g: 10minutes").arg(QString::number(minutes));
370 qlonglong hours = (minutes / 60);
373 minutes -= (hours * 60);
374 return QCoreApplication::translate(
"misc",
"%1h %2m",
"e.g: 3hours 5minutes").arg(QString::number(hours), QString::number(minutes));
377 qlonglong days = (hours / 24);
380 hours -= (days * 24);
381 return QCoreApplication::translate(
"misc",
"%1d %2h",
"e.g: 2days 10hours").arg(QString::number(days), QString::number(hours));
384 qlonglong years = (days / 365);
385 days -= (years * 365);
386 return QCoreApplication::translate(
"misc",
"%1y %2d",
"e.g: 2years 10days").arg(QString::number(years), QString::number(days));
393 const int UNLEN = 256;
394 WCHAR buffer[UNLEN + 1] = {0};
395 DWORD buffer_len =
sizeof(buffer) /
sizeof(*buffer);
396 if (GetUserNameW(buffer, &buffer_len))
397 uid = QString::fromWCharArray(buffer);
399 uid = QString::number(getuid());
406 QString result = rawText;
407 static const QRegularExpression reURL(
412 "([a-zA-Z0-9_-]+\\.)+"
413 "([a-zA-Z0-9\\?%=&/_\\.:#;-]+)"
417 "([a-zA-Z0-9_-]+\\.)+"
443 "([a-zA-Z0-9\\?%=&/_\\.:#;-]+)"
447 "([a-zA-Z0-9_-]+\\.) {2,}"
449 "([a-zA-Z0-9\\?%=&/_\\.:#;-]*)"
455 result.replace(reURL,
"\\1<a href=\"\\2\">\\2</a>");
458 static const QRegularExpression reNoScheme(
"<a\\s+href=\"(?!https?)([a-zA-Z0-9\\?%=&/_\\.-:#]+)\\s*\">");
459 result.replace(reNoScheme,
"<a href=\"http://\\1\">");
462 result =
"<p style=\"white-space: pre-wrap;\">" + result +
"</p>";
469 static const QString name =
471 .arg(QSysInfo::prettyProductName()
472 , QSysInfo::kernelVersion()
473 , QSysInfo::currentCpuArchitecture());
480 static const QString ver = QString(
"%1.%2.%3")
481 .arg(QString::number(BOOST_VERSION / 100000)
482 , QString::number((BOOST_VERSION / 100) % 1000)
483 , QString::number(BOOST_VERSION % 100));
490 static const auto version {QString::fromLatin1(lt::version())};
496 #if (OPENSSL_VERSION_NUMBER >= 0x1010000f)
497 static const auto version {QString::fromLatin1(OpenSSL_version(OPENSSL_VERSION))};
499 static const auto version {QString::fromLatin1(SSLeay_version(SSLEAY_VERSION))};
501 return QStringView(version).split(u
' ', Qt::SkipEmptyParts).at(1).toString();
507 static const auto version {QString::fromLatin1(zlibVersion())};
512 QString Utils::Misc::windowsSystemPath()
514 static const QString path = []() -> QString
516 WCHAR systemPath[MAX_PATH] = {0};
517 GetSystemDirectoryW(systemPath,
sizeof(systemPath) /
sizeof(WCHAR));
518 return QString::fromWCharArray(systemPath);
QString fileExtension(const QString &filename)
QString libtorrentVersionString()
QString opensslVersionString()
QString parseHtmlLinks(const QString &rawText)
void shutdownComputer(const ShutdownDialogAction &action)
QString unitString(SizeUnit unit, bool isSpeed=false)
qint64 sizeInBytes(qreal size, SizeUnit unit)
QString boostVersionString()
bool isPreviewable(const QString &filename)
int friendlyUnitPrecision(SizeUnit unit)
QString zlibVersionString()
QString userFriendlyDuration(qlonglong seconds, qlonglong maxCap=-1)
QString friendlyUnit(qint64 bytes, bool isSpeed=false)
QString getUserIDString()
QString fromDouble(double n, int precision)
std::optional< SplitToFriendlyUnitResult > splitToFriendlyUnit(const qint64 bytes)
const struct anonymous_namespace{misc.cpp}::@6 units[]
T value(const QString &key, const T &defaultValue={})
Utils::Misc::SizeUnit unit
const char C_NON_BREAKING_SPACE[]