qBittorrent
Utils::Misc Namespace Reference

Enumerations

enum class  SizeUnit {
  Byte , KibiByte , MebiByte , GibiByte ,
  TebiByte , PebiByte , ExbiByte
}
 

Functions

QString parseHtmlLinks (const QString &rawText)
 
void shutdownComputer (const ShutdownDialogAction &action)
 
QString osName ()
 
QString boostVersionString ()
 
QString libtorrentVersionString ()
 
QString opensslVersionString ()
 
QString zlibVersionString ()
 
QString unitString (SizeUnit unit, bool isSpeed=false)
 
QString friendlyUnit (qint64 bytes, bool isSpeed=false)
 
int friendlyUnitPrecision (SizeUnit unit)
 
qint64 sizeInBytes (qreal size, SizeUnit unit)
 
bool isPreviewable (const QString &filename)
 
QString userFriendlyDuration (qlonglong seconds, qlonglong maxCap=-1)
 
QString getUserIDString ()
 

Enumeration Type Documentation

◆ SizeUnit

enum Utils::Misc::SizeUnit
strong
Enumerator
Byte 
KibiByte 
MebiByte 
GibiByte 
TebiByte 
PebiByte 
ExbiByte 

Definition at line 48 of file misc.h.

49  {
50  Byte, // 1024^0,
51  KibiByte, // 1024^1,
52  MebiByte, // 1024^2,
53  GibiByte, // 1024^3,
54  TebiByte, // 1024^4,
55  PebiByte, // 1024^5,
56  ExbiByte // 1024^6,
57  // int64 is used for sizes and thus the next units can not be handled
58  // ZebiByte, // 1024^7,
59  // YobiByte, // 1024^8
60  };

Function Documentation

◆ boostVersionString()

QString Utils::Misc::boostVersionString ( )

Definition at line 477 of file misc.cpp.

478 {
479  // static initialization for usage in signal handler
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));
484  return ver;
485 }

Referenced by AboutDialog::AboutDialog(), AppController::buildInfoAction(), and StacktraceDialog::setStacktraceString().

Here is the caller graph for this function:

◆ friendlyUnit()

QString Utils::Misc::friendlyUnit ( qint64  bytes,
bool  isSpeed = false 
)

Definition at line 261 of file misc.cpp.

262 {
263  const std::optional<SplitToFriendlyUnitResult> result = splitToFriendlyUnit(bytes);
264  if (!result)
265  return QCoreApplication::translate("misc", "Unknown", "Unknown (size)");
266  return Utils::String::fromDouble(result->value, friendlyUnitPrecision(result->unit))
267  + QString::fromUtf8(C_NON_BREAKING_SPACE)
268  + unitString(result->unit, isSpeed);
269 }
QString unitString(SizeUnit unit, bool isSpeed=false)
Definition: misc.cpp:252
int friendlyUnitPrecision(SizeUnit unit)
Definition: misc.cpp:271
QString fromDouble(double n, int precision)
Definition: string.cpp:44
std::optional< SplitToFriendlyUnitResult > splitToFriendlyUnit(const qint64 bytes)
Definition: misc.cpp:93
const char C_NON_BREAKING_SPACE[]

References C_NON_BREAKING_SPACE, friendlyUnitPrecision(), Utils::String::fromDouble(), anonymous_namespace{misc.cpp}::splitToFriendlyUnit(), and unitString().

Referenced by SearchJobWidget::appendSearchResults(), DownloadHandlerImpl::checkDownloadSize(), TorrentContentModelItem::displayData(), TransferListModel::displayValue(), PropertiesWidget::loadDynamicData(), BitTorrent::TorrentInfo::loadFromFile(), PropertiesWidget::loadTorrentInfos(), PreviewListDelegate::paint(), MainWindow::reloadSessionStats(), WebApplication::sendFile(), Application::sendNotificationEmail(), PiecesBar::showToolTip(), StatsDialog::update(), AddNewTorrentDialog::updateDiskSpaceLabel(), PeerListWidget::updatePeer(), and StatusBar::updateSpeedLabels().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ friendlyUnitPrecision()

int Utils::Misc::friendlyUnitPrecision ( SizeUnit  unit)

Definition at line 271 of file misc.cpp.

272 {
273  // friendlyUnit's number of digits after the decimal point
274  switch (unit)
275  {
276  case SizeUnit::Byte:
277  return 0;
278  case SizeUnit::KibiByte:
279  case SizeUnit::MebiByte:
280  return 1;
281  case SizeUnit::GibiByte:
282  return 2;
283  default:
284  return 3;
285  }
286 }

Referenced by anonymous_namespace{speedplotview.cpp}::formatLabel(), and friendlyUnit().

Here is the caller graph for this function:

◆ getUserIDString()

QString Utils::Misc::getUserIDString ( )

Definition at line 389 of file misc.cpp.

390 {
391  QString uid = "0";
392 #ifdef Q_OS_WIN
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);
398 #else
399  uid = QString::number(getuid());
400 #endif
401  return uid;
402 }

◆ isPreviewable()

bool Utils::Misc::isPreviewable ( const QString &  filename)

Definition at line 295 of file misc.cpp.

296 {
297  const QString mime = QMimeDatabase().mimeTypeForFile(filename, QMimeDatabase::MatchExtension).name();
298 
299  if (mime.startsWith(QLatin1String("audio"), Qt::CaseInsensitive)
300  || mime.startsWith(QLatin1String("video"), Qt::CaseInsensitive))
301  {
302  return true;
303  }
304 
305  const QSet<QString> multimediaExtensions =
306  {
307  "3GP",
308  "AAC",
309  "AC3",
310  "AIF",
311  "AIFC",
312  "AIFF",
313  "ASF",
314  "AU",
315  "AVI",
316  "FLAC",
317  "FLV",
318  "M3U",
319  "M4A",
320  "M4P",
321  "M4V",
322  "MID",
323  "MKV",
324  "MOV",
325  "MP2",
326  "MP3",
327  "MP4",
328  "MPC",
329  "MPE",
330  "MPEG",
331  "MPG",
332  "MPP",
333  "OGG",
334  "OGM",
335  "OGV",
336  "QT",
337  "RA",
338  "RAM",
339  "RM",
340  "RMV",
341  "RMVB",
342  "SWA",
343  "SWF",
344  "TS",
345  "VOB",
346  "WAV",
347  "WMA",
348  "WMV"
349  };
350  return multimediaExtensions.contains(Utils::Fs::fileExtension(filename).toUpper());
351 }
QString fileExtension(const QString &filename)
Definition: fs.cpp:82

References Utils::Fs::fileExtension().

Referenced by PreviewSelectDialog::PreviewSelectDialog(), and anonymous_namespace{transferlistwidget.cpp}::torrentContainsPreviewableFiles().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ libtorrentVersionString()

QString Utils::Misc::libtorrentVersionString ( )

Definition at line 487 of file misc.cpp.

488 {
489  // static initialization for usage in signal handler
490  static const auto version {QString::fromLatin1(lt::version())};
491  return version;
492 }

Referenced by AboutDialog::AboutDialog(), AppController::buildInfoAction(), and StacktraceDialog::setStacktraceString().

Here is the caller graph for this function:

◆ opensslVersionString()

QString Utils::Misc::opensslVersionString ( )

Definition at line 494 of file misc.cpp.

495 {
496 #if (OPENSSL_VERSION_NUMBER >= 0x1010000f)
497  static const auto version {QString::fromLatin1(OpenSSL_version(OPENSSL_VERSION))};
498 #else
499  static const auto version {QString::fromLatin1(SSLeay_version(SSLEAY_VERSION))};
500 #endif
501  return QStringView(version).split(u' ', Qt::SkipEmptyParts).at(1).toString();
502 }

Referenced by AboutDialog::AboutDialog(), AppController::buildInfoAction(), and StacktraceDialog::setStacktraceString().

Here is the caller graph for this function:

◆ osName()

QString Utils::Misc::osName ( )

Definition at line 466 of file misc.cpp.

467 {
468  // static initialization for usage in signal handler
469  static const QString name =
470  QString("%1 %2 %3")
471  .arg(QSysInfo::prettyProductName()
472  , QSysInfo::kernelVersion()
473  , QSysInfo::currentCpuArchitecture());
474  return name;
475 }

Referenced by StacktraceDialog::setStacktraceString().

Here is the caller graph for this function:

◆ parseHtmlLinks()

QString Utils::Misc::parseHtmlLinks ( const QString &  rawText)

Definition at line 404 of file misc.cpp.

405 {
406  QString result = rawText;
407  static const QRegularExpression reURL(
408  "(\\s|^)" // start with whitespace or beginning of line
409  "("
410  "(" // case 1 -- URL with scheme
411  "(http(s?))\\://" // start with scheme
412  "([a-zA-Z0-9_-]+\\.)+" // domainpart. at least one of these must exist
413  "([a-zA-Z0-9\\?%=&/_\\.:#;-]+)" // everything to 1st non-URI char, must be at least one char after the previous dot (cannot use ".*" because it can be too greedy)
414  ")"
415  "|"
416  "(" // case 2a -- no scheme, contains common TLD example.com
417  "([a-zA-Z0-9_-]+\\.)+" // domainpart. at least one of these must exist
418  "(?=" // must be followed by TLD
419  "AERO|aero|" // N.B. assertions are non-capturing
420  "ARPA|arpa|"
421  "ASIA|asia|"
422  "BIZ|biz|"
423  "CAT|cat|"
424  "COM|com|"
425  "COOP|coop|"
426  "EDU|edu|"
427  "GOV|gov|"
428  "INFO|info|"
429  "INT|int|"
430  "JOBS|jobs|"
431  "MIL|mil|"
432  "MOBI|mobi|"
433  "MUSEUM|museum|"
434  "NAME|name|"
435  "NET|net|"
436  "ORG|org|"
437  "PRO|pro|"
438  "RO|ro|"
439  "RU|ru|"
440  "TEL|tel|"
441  "TRAVEL|travel"
442  ")"
443  "([a-zA-Z0-9\\?%=&/_\\.:#;-]+)" // everything to 1st non-URI char, must be at least one char after the previous dot (cannot use ".*" because it can be too greedy)
444  ")"
445  "|"
446  "(" // case 2b no scheme, no TLD, must have at least 2 alphanum strings plus uncommon TLD string --> del.icio.us
447  "([a-zA-Z0-9_-]+\\.) {2,}" // 2 or more domainpart. --> del.icio.
448  "[a-zA-Z]{2,}" // one ab (2 char or longer) --> us
449  "([a-zA-Z0-9\\?%=&/_\\.:#;-]*)" // everything to 1st non-URI char, maybe nothing in case of del.icio.us/path
450  ")"
451  ")"
452  );
453 
454  // Capture links
455  result.replace(reURL, "\\1<a href=\"\\2\">\\2</a>");
456 
457  // Capture links without scheme
458  static const QRegularExpression reNoScheme("<a\\s+href=\"(?!https?)([a-zA-Z0-9\\?%=&/_\\.-:#]+)\\s*\">");
459  result.replace(reNoScheme, "<a href=\"http://\\1\">");
460 
461  // to preserve plain text formatting
462  result = "<p style=\"white-space: pre-wrap;\">" + result + "</p>";
463  return result;
464 }

Referenced by PropertiesWidget::loadTorrentInfos(), and AddNewTorrentDialog::setupTreeview().

Here is the caller graph for this function:

◆ shutdownComputer()

void Utils::Misc::shutdownComputer ( const ShutdownDialogAction action)

Definition at line 110 of file misc.cpp.

111 {
112 #if defined(Q_OS_WIN)
113  HANDLE hToken; // handle to process token
114  TOKEN_PRIVILEGES tkp; // pointer to token structure
115  if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
116  return;
117  // Get the LUID for shutdown privilege.
118  LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,
119  &tkp.Privileges[0].Luid);
120 
121  tkp.PrivilegeCount = 1; // one privilege to set
122  tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
123 
124  // Get shutdown privilege for this process.
125 
126  AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
127  (PTOKEN_PRIVILEGES) NULL, 0);
128 
129  // Cannot test the return value of AdjustTokenPrivileges.
130 
131  if (GetLastError() != ERROR_SUCCESS)
132  return;
133 
135  {
136  ::SetSuspendState(FALSE, FALSE, FALSE);
137  }
139  {
140  ::SetSuspendState(TRUE, FALSE, FALSE);
141  }
142  else
143  {
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);
148  }
149 
150  // Disable shutdown privilege.
151  tkp.Privileges[0].Attributes = 0;
152  AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0);
153 
154 #elif defined(Q_OS_MACOS)
155  AEEventID EventToSend;
157  EventToSend = kAESleep;
158  else
159  EventToSend = kAEShutDown;
160  AEAddressDesc targetDesc;
161  const ProcessSerialNumber kPSNOfSystemProcess = {0, kSystemProcess};
162  AppleEvent eventReply = {typeNull, NULL};
163  AppleEvent appleEventToSend = {typeNull, NULL};
164 
165  OSStatus error = AECreateDesc(typeProcessSerialNumber, &kPSNOfSystemProcess,
166  sizeof(kPSNOfSystemProcess), &targetDesc);
167 
168  if (error != noErr)
169  return;
170 
171  error = AECreateAppleEvent(kCoreEventClass, EventToSend, &targetDesc,
172  kAutoGenerateReturnID, kAnyTransactionID, &appleEventToSend);
173 
174  AEDisposeDesc(&targetDesc);
175  if (error != noErr)
176  return;
177 
178  error = AESend(&appleEventToSend, &eventReply, kAENoReply,
179  kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
180 
181  AEDisposeDesc(&appleEventToSend);
182  if (error != noErr)
183  return;
184 
185  AEDisposeDesc(&eventReply);
186 
187 #elif (defined(Q_OS_UNIX) && defined(QT_DBUS_LIB))
188  // Use dbus to power off / suspend the system
190  {
191  // Some recent systems use systemd's logind
192  QDBusInterface login1Iface("org.freedesktop.login1", "/org/freedesktop/login1",
193  "org.freedesktop.login1.Manager", QDBusConnection::systemBus());
194  if (login1Iface.isValid())
195  {
197  login1Iface.call("Suspend", false);
198  else
199  login1Iface.call("Hibernate", false);
200  return;
201  }
202  // Else, other recent systems use UPower
203  QDBusInterface upowerIface("org.freedesktop.UPower", "/org/freedesktop/UPower",
204  "org.freedesktop.UPower", QDBusConnection::systemBus());
205  if (upowerIface.isValid())
206  {
208  upowerIface.call("Suspend");
209  else
210  upowerIface.call("Hibernate");
211  return;
212  }
213  // HAL (older systems)
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);
219  else
220  halIface.call("Hibernate");
221  }
222  else
223  {
224  // Some recent systems use systemd's logind
225  QDBusInterface login1Iface("org.freedesktop.login1", "/org/freedesktop/login1",
226  "org.freedesktop.login1.Manager", QDBusConnection::systemBus());
227  if (login1Iface.isValid())
228  {
229  login1Iface.call("PowerOff", false);
230  return;
231  }
232  // Else, other recent systems use ConsoleKit
233  QDBusInterface consolekitIface("org.freedesktop.ConsoleKit", "/org/freedesktop/ConsoleKit/Manager",
234  "org.freedesktop.ConsoleKit.Manager", QDBusConnection::systemBus());
235  if (consolekitIface.isValid())
236  {
237  consolekitIface.call("Stop");
238  return;
239  }
240  // HAL (older systems)
241  QDBusInterface halIface("org.freedesktop.Hal", "/org/freedesktop/Hal/devices/computer",
242  "org.freedesktop.Hal.Device.SystemPowerManagement",
243  QDBusConnection::systemBus());
244  halIface.call("Shutdown");
245  }
246 
247 #else
248  Q_UNUSED(action);
249 #endif
250 }
action
Definition: tstool.py:143

References tstool::action, Hibernate, Shutdown, and Suspend.

Referenced by Application::cleanup().

Here is the caller graph for this function:

◆ sizeInBytes()

qlonglong Utils::Misc::sizeInBytes ( qreal  size,
SizeUnit  unit 
)

Definition at line 288 of file misc.cpp.

289 {
290  for (int i = 0; i < static_cast<int>(unit); ++i)
291  size *= 1024;
292  return size;
293 }

Referenced by anonymous_namespace{speedplotview.cpp}::SplittedValue::sizeInBytes(), and SearchJobWidget::updateFilter().

Here is the caller graph for this function:

◆ unitString()

QString Utils::Misc::unitString ( SizeUnit  unit,
bool  isSpeed = false 
)

Definition at line 252 of file misc.cpp.

253 {
254  const auto &unitString = units[static_cast<int>(unit)];
255  QString ret = QCoreApplication::translate("misc", unitString.source, unitString.comment);
256  if (isSpeed)
257  ret += QCoreApplication::translate("misc", "/s", "per second");
258  return ret;
259 }
const struct anonymous_namespace{misc.cpp}::@6 units[]

References anonymous_namespace{misc.cpp}::units.

Referenced by TransferListModel::displayValue(), SearchJobWidget::fillFilterComboBoxes(), anonymous_namespace{speedplotview.cpp}::formatLabel(), and friendlyUnit().

Here is the caller graph for this function:

◆ userFriendlyDuration()

QString Utils::Misc::userFriendlyDuration ( qlonglong  seconds,
qlonglong  maxCap = -1 
)

Definition at line 353 of file misc.cpp.

354 {
355  if (seconds < 0)
356  return QString::fromUtf8(C_INFINITY);
357  if ((maxCap >= 0) && (seconds >= maxCap))
358  return QString::fromUtf8(C_INFINITY);
359 
360  if (seconds == 0)
361  return "0";
362 
363  if (seconds < 60)
364  return QCoreApplication::translate("misc", "< 1m", "< 1 minute");
365 
366  qlonglong minutes = (seconds / 60);
367  if (minutes < 60)
368  return QCoreApplication::translate("misc", "%1m", "e.g: 10minutes").arg(QString::number(minutes));
369 
370  qlonglong hours = (minutes / 60);
371  if (hours < 24)
372  {
373  minutes -= (hours * 60);
374  return QCoreApplication::translate("misc", "%1h %2m", "e.g: 3hours 5minutes").arg(QString::number(hours), QString::number(minutes));
375  }
376 
377  qlonglong days = (hours / 24);
378  if (days < 365)
379  {
380  hours -= (days * 24);
381  return QCoreApplication::translate("misc", "%1d %2h", "e.g: 2days 10hours").arg(QString::number(days), QString::number(hours));
382  }
383 
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));
387 }
const char C_INFINITY[]

References C_INFINITY.

Referenced by TransferListModel::displayValue(), PropertiesWidget::loadDynamicData(), and Application::sendNotificationEmail().

Here is the caller graph for this function:

◆ zlibVersionString()

QString Utils::Misc::zlibVersionString ( )

Definition at line 504 of file misc.cpp.

505 {
506  // static initialization for usage in signal handler
507  static const auto version {QString::fromLatin1(zlibVersion())};
508  return version;
509 }

Referenced by AboutDialog::AboutDialog(), AppController::buildInfoAction(), and StacktraceDialog::setStacktraceString().

Here is the caller graph for this function: