|
|
|
@ -89,30 +89,36 @@ static struct { const char *source; const char *comment; } units[] = {
@@ -89,30 +89,36 @@ static struct { const char *source; const char *comment; } units[] = {
|
|
|
|
|
QT_TRANSLATE_NOOP3("misc", "TiB", "tebibytes (1024 gibibytes)") |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
QString misc::toQString(const std::string &str) { |
|
|
|
|
QString misc::toQString(const std::string &str) |
|
|
|
|
{ |
|
|
|
|
return QString::fromLocal8Bit(str.c_str()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
QString misc::toQString(const char* str) { |
|
|
|
|
QString misc::toQString(const char* str) |
|
|
|
|
{ |
|
|
|
|
return QString::fromLocal8Bit(str); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
QString misc::toQStringU(const std::string &str) { |
|
|
|
|
QString misc::toQStringU(const std::string &str) |
|
|
|
|
{ |
|
|
|
|
return QString::fromUtf8(str.c_str()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
QString misc::toQStringU(const char* str) { |
|
|
|
|
QString misc::toQStringU(const char* str) |
|
|
|
|
{ |
|
|
|
|
return QString::fromUtf8(str); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
QString misc::toQString(const libtorrent::sha1_hash &hash) { |
|
|
|
|
QString misc::toQString(const libtorrent::sha1_hash &hash) |
|
|
|
|
{ |
|
|
|
|
char out[41]; |
|
|
|
|
libtorrent::to_hex((char const*)&hash[0], libtorrent::sha1_hash::size, out); |
|
|
|
|
return QString(out); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#ifndef DISABLE_GUI |
|
|
|
|
void misc::shutdownComputer(shutDownAction action) { |
|
|
|
|
void misc::shutdownComputer(shutDownAction action) |
|
|
|
|
{ |
|
|
|
|
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC)) && defined(QT_DBUS_LIB) |
|
|
|
|
// Use dbus to power off / suspend the system
|
|
|
|
|
if (action != SHUTDOWN_COMPUTER) { |
|
|
|
@ -144,7 +150,8 @@ void misc::shutdownComputer(shutDownAction action) {
@@ -144,7 +150,8 @@ void misc::shutdownComputer(shutDownAction action) {
|
|
|
|
|
halIface.call("Suspend", 5); |
|
|
|
|
else |
|
|
|
|
halIface.call("Hibernate"); |
|
|
|
|
} else { |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
// Some recent systems use systemd's logind
|
|
|
|
|
QDBusInterface login1Iface("org.freedesktop.login1", "/org/freedesktop/login1", |
|
|
|
|
"org.freedesktop.login1.Manager", QDBusConnection::systemBus()); |
|
|
|
@ -183,27 +190,21 @@ void misc::shutdownComputer(shutDownAction action) {
@@ -183,27 +190,21 @@ void misc::shutdownComputer(shutDownAction action) {
|
|
|
|
|
sizeof(kPSNOfSystemProcess), &targetDesc); |
|
|
|
|
|
|
|
|
|
if (error != noErr) |
|
|
|
|
{ |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
error = AECreateAppleEvent(kCoreEventClass, EventToSend, &targetDesc, |
|
|
|
|
kAutoGenerateReturnID, kAnyTransactionID, &appleEventToSend); |
|
|
|
|
|
|
|
|
|
AEDisposeDesc(&targetDesc); |
|
|
|
|
if (error != noErr) |
|
|
|
|
{ |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
error = AESend(&appleEventToSend, &eventReply, kAENoReply, |
|
|
|
|
kAENormalPriority, kAEDefaultTimeout, NULL, NULL); |
|
|
|
|
|
|
|
|
|
AEDisposeDesc(&appleEventToSend); |
|
|
|
|
if (error != noErr) |
|
|
|
|
{ |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
AEDisposeDesc(&eventReply); |
|
|
|
|
#endif |
|
|
|
@ -246,7 +247,8 @@ void misc::shutdownComputer(shutDownAction action) {
@@ -246,7 +247,8 @@ void misc::shutdownComputer(shutDownAction action) {
|
|
|
|
|
|
|
|
|
|
#ifndef DISABLE_GUI |
|
|
|
|
// Get screen center
|
|
|
|
|
QPoint misc::screenCenter(QWidget *win) { |
|
|
|
|
QPoint misc::screenCenter(QWidget *win) |
|
|
|
|
{ |
|
|
|
|
int scrn = 0; |
|
|
|
|
const QWidget *w = win->window(); |
|
|
|
|
|
|
|
|
@ -266,7 +268,8 @@ QPoint misc::screenCenter(QWidget *win) {
@@ -266,7 +268,8 @@ QPoint misc::screenCenter(QWidget *win) {
|
|
|
|
|
* Detects the version of python by calling |
|
|
|
|
* "python --version" and parsing the output. |
|
|
|
|
*/ |
|
|
|
|
int misc::pythonVersion() { |
|
|
|
|
int misc::pythonVersion() |
|
|
|
|
{ |
|
|
|
|
static int version = -1; |
|
|
|
|
if (version < 0) { |
|
|
|
|
QProcess python_proc; |
|
|
|
@ -291,7 +294,8 @@ int misc::pythonVersion() {
@@ -291,7 +294,8 @@ int misc::pythonVersion() {
|
|
|
|
|
// see http://en.wikipedia.org/wiki/Kilobyte
|
|
|
|
|
// value must be given in bytes
|
|
|
|
|
// to send numbers instead of strings with suffixes
|
|
|
|
|
QString misc::friendlyUnit(qreal val, bool is_speed) { |
|
|
|
|
QString misc::friendlyUnit(qreal val, bool is_speed) |
|
|
|
|
{ |
|
|
|
|
if (val < 0) |
|
|
|
|
return QCoreApplication::translate("misc", "Unknown", "Unknown (size)"); |
|
|
|
|
int i = 0; |
|
|
|
@ -307,7 +311,8 @@ QString misc::friendlyUnit(qreal val, bool is_speed) {
@@ -307,7 +311,8 @@ QString misc::friendlyUnit(qreal val, bool is_speed) {
|
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool misc::isPreviewable(const QString& extension) { |
|
|
|
|
bool misc::isPreviewable(const QString& extension) |
|
|
|
|
{ |
|
|
|
|
static QSet<QString> multimedia_extensions; |
|
|
|
|
if (multimedia_extensions.empty()) { |
|
|
|
|
multimedia_extensions.insert("3GP"); |
|
|
|
@ -359,7 +364,8 @@ bool misc::isPreviewable(const QString& extension) {
@@ -359,7 +364,8 @@ bool misc::isPreviewable(const QString& extension) {
|
|
|
|
|
return multimedia_extensions.contains(extension.toUpper()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
QString misc::bcLinkToMagnet(QString bc_link) { |
|
|
|
|
QString misc::bcLinkToMagnet(QString bc_link) |
|
|
|
|
{ |
|
|
|
|
QByteArray raw_bc = bc_link.toUtf8(); |
|
|
|
|
raw_bc = raw_bc.mid(8); // skip bc://bt/
|
|
|
|
|
raw_bc = QByteArray::fromBase64(raw_bc); // Decode base64
|
|
|
|
@ -373,7 +379,8 @@ QString misc::bcLinkToMagnet(QString bc_link) {
@@ -373,7 +379,8 @@ QString misc::bcLinkToMagnet(QString bc_link) {
|
|
|
|
|
return magnet; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
QString misc::magnetUriToName(const QString& magnet_uri) { |
|
|
|
|
QString misc::magnetUriToName(const QString& magnet_uri) |
|
|
|
|
{ |
|
|
|
|
QString name = ""; |
|
|
|
|
QRegExp regHex("dn=([^&]+)"); |
|
|
|
|
const int pos = regHex.indexIn(magnet_uri); |
|
|
|
@ -401,7 +408,8 @@ QList<QUrl> misc::magnetUriToTrackers(const QString& magnet_uri)
@@ -401,7 +408,8 @@ QList<QUrl> misc::magnetUriToTrackers(const QString& magnet_uri)
|
|
|
|
|
return trackers; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
QString misc::magnetUriToHash(const QString& magnet_uri) { |
|
|
|
|
QString misc::magnetUriToHash(const QString& magnet_uri) |
|
|
|
|
{ |
|
|
|
|
QString hash = ""; |
|
|
|
|
QRegExp regHex("urn:btih:([0-9A-Za-z]+)"); |
|
|
|
|
// Hex
|
|
|
|
@ -420,7 +428,7 @@ QString misc::magnetUriToHash(const QString& magnet_uri) {
@@ -420,7 +428,7 @@ QString misc::magnetUriToHash(const QString& magnet_uri) {
|
|
|
|
|
pos = regBase32.indexIn(magnet_uri); |
|
|
|
|
if (pos > -1) { |
|
|
|
|
const QString found = regBase32.cap(1); |
|
|
|
|
if (found.length() > 20 && (found.length()*5)%40 == 0) { |
|
|
|
|
if (found.length() > 20 && (found.length() * 5) % 40 == 0) { |
|
|
|
|
const sha1_hash sha1(base32decode(regBase32.cap(1).toStdString())); |
|
|
|
|
hash = misc::toQString(sha1); |
|
|
|
|
} |
|
|
|
@ -431,37 +439,33 @@ QString misc::magnetUriToHash(const QString& magnet_uri) {
@@ -431,37 +439,33 @@ QString misc::magnetUriToHash(const QString& magnet_uri) {
|
|
|
|
|
|
|
|
|
|
// Take a number of seconds and return an user-friendly
|
|
|
|
|
// time duration like "1d 2h 10m".
|
|
|
|
|
QString misc::userFriendlyDuration(qlonglong seconds) { |
|
|
|
|
if (seconds < 0 || seconds >= MAX_ETA) { |
|
|
|
|
QString misc::userFriendlyDuration(qlonglong seconds) |
|
|
|
|
{ |
|
|
|
|
if (seconds < 0 || seconds >= MAX_ETA) |
|
|
|
|
return QString::fromUtf8("∞"); |
|
|
|
|
} |
|
|
|
|
if (seconds == 0) { |
|
|
|
|
if (seconds == 0) |
|
|
|
|
return "0"; |
|
|
|
|
} |
|
|
|
|
if (seconds < 60) { |
|
|
|
|
if (seconds < 60) |
|
|
|
|
return QCoreApplication::translate("misc", "< 1m", "< 1 minute"); |
|
|
|
|
} |
|
|
|
|
int minutes = seconds / 60; |
|
|
|
|
if (minutes < 60) { |
|
|
|
|
if (minutes < 60) |
|
|
|
|
return QCoreApplication::translate("misc", "%1m","e.g: 10minutes").arg(QString::number(minutes)); |
|
|
|
|
} |
|
|
|
|
int hours = minutes / 60; |
|
|
|
|
minutes = minutes - hours*60; |
|
|
|
|
if (hours < 24) { |
|
|
|
|
minutes = minutes - hours * 60; |
|
|
|
|
if (hours < 24) |
|
|
|
|
return QCoreApplication::translate("misc", "%1h %2m", "e.g: 3hours 5minutes").arg(QString::number(hours)).arg(QString::number(minutes)); |
|
|
|
|
} |
|
|
|
|
int days = hours / 24; |
|
|
|
|
hours = hours - days * 24; |
|
|
|
|
if (days < 100) { |
|
|
|
|
if (days < 100) |
|
|
|
|
return QCoreApplication::translate("misc", "%1d %2h", "e.g: 2days 10hours").arg(QString::number(days)).arg(QString::number(hours)); |
|
|
|
|
} |
|
|
|
|
return QString::fromUtf8("∞"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
QString misc::getUserIDString() { |
|
|
|
|
QString misc::getUserIDString() |
|
|
|
|
{ |
|
|
|
|
QString uid = "0"; |
|
|
|
|
#ifdef Q_OS_WIN |
|
|
|
|
char buffer[UNLEN+1] = {0}; |
|
|
|
|
char buffer[UNLEN + 1] = {0}; |
|
|
|
|
DWORD buffer_len = UNLEN + 1; |
|
|
|
|
if (!GetUserNameA(buffer, &buffer_len)) |
|
|
|
|
uid = QString(buffer); |
|
|
|
@ -471,27 +475,27 @@ QString misc::getUserIDString() {
@@ -471,27 +475,27 @@ QString misc::getUserIDString() {
|
|
|
|
|
return uid; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
QStringList misc::toStringList(const QList<bool> &l) { |
|
|
|
|
QStringList misc::toStringList(const QList<bool> &l) |
|
|
|
|
{ |
|
|
|
|
QStringList ret; |
|
|
|
|
foreach (const bool &b, l) { |
|
|
|
|
foreach (const bool &b, l) |
|
|
|
|
ret << (b ? "1" : "0"); |
|
|
|
|
} |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
QList<int> misc::intListfromStringList(const QStringList &l) { |
|
|
|
|
QList<int> misc::intListfromStringList(const QStringList &l) |
|
|
|
|
{ |
|
|
|
|
QList<int> ret; |
|
|
|
|
foreach (const QString &s, l) { |
|
|
|
|
foreach (const QString &s, l) |
|
|
|
|
ret << s.toInt(); |
|
|
|
|
} |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
QList<bool> misc::boolListfromStringList(const QStringList &l) { |
|
|
|
|
QList<bool> misc::boolListfromStringList(const QStringList &l) |
|
|
|
|
{ |
|
|
|
|
QList<bool> ret; |
|
|
|
|
foreach (const QString &s, l) { |
|
|
|
|
foreach (const QString &s, l) |
|
|
|
|
ret << (s=="1"); |
|
|
|
|
} |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -569,13 +573,13 @@ QString misc::toQString(time_t t)
@@ -569,13 +573,13 @@ QString misc::toQString(time_t t)
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#ifndef DISABLE_GUI |
|
|
|
|
bool misc::naturalSort(QString left, QString right, bool &result) { // uses lessThan comparison
|
|
|
|
|
// Return value indicates if functions was successful
|
|
|
|
|
bool misc::naturalSort(QString left, QString right, bool &result) // uses lessThan comparison
|
|
|
|
|
{ // Return value indicates if functions was successful
|
|
|
|
|
// result argument will contain actual comparison result if function was successful
|
|
|
|
|
int posL = 0; |
|
|
|
|
int posR = 0; |
|
|
|
|
do { |
|
|
|
|
for (;;) { |
|
|
|
|
for (;; ) { |
|
|
|
|
if (posL == left.size() || posR == right.size()) |
|
|
|
|
return false; // No data
|
|
|
|
|
|
|
|
|
@ -631,7 +635,8 @@ bool misc::naturalSort(QString left, QString right, bool &result) { // uses less
@@ -631,7 +635,8 @@ bool misc::naturalSort(QString left, QString right, bool &result) { // uses less
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
// to send numbers instead of strings with suffixes
|
|
|
|
|
QString misc::accurateDoubleToString(const double &n, const int &precision) { |
|
|
|
|
QString misc::accurateDoubleToString(const double &n, const int &precision) |
|
|
|
|
{ |
|
|
|
|
/* HACK because QString rounds up. Eg QString::number(0.999*100.0, 'f' ,1) == 99.9
|
|
|
|
|
** but QString::number(0.9999*100.0, 'f' ,1) == 100.0 The problem manifests when |
|
|
|
|
** the number has more digits after the decimal than we want AND the digit after |
|
|
|
@ -639,7 +644,7 @@ QString misc::accurateDoubleToString(const double &n, const int &precision) {
@@ -639,7 +644,7 @@ QString misc::accurateDoubleToString(const double &n, const int &precision) {
|
|
|
|
|
** precision we add an extra 0 behind 1 in the below algorithm. */ |
|
|
|
|
|
|
|
|
|
double prec = std::pow(10.0, precision); |
|
|
|
|
return QLocale::system().toString(std::floor(n*prec)/prec, 'f', precision); |
|
|
|
|
return QLocale::system().toString(std::floor(n * prec) / prec, 'f', precision); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Implements constant-time comparison to protect against timing attacks
|
|
|
|
@ -669,16 +674,17 @@ void misc::loadBencodedFile(const QString &filename, std::vector<char> &buffer,
@@ -669,16 +674,17 @@ void misc::loadBencodedFile(const QString &filename, std::vector<char> &buffer,
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
namespace { |
|
|
|
|
// Trick to get a portable sleep() function
|
|
|
|
|
class SleeperThread : public QThread { |
|
|
|
|
public: |
|
|
|
|
// Trick to get a portable sleep() function
|
|
|
|
|
class SleeperThread: public QThread { |
|
|
|
|
public: |
|
|
|
|
static void msleep(unsigned long msecs) |
|
|
|
|
{ |
|
|
|
|
QThread::msleep(msecs); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void misc::msleep(unsigned long msecs) { |
|
|
|
|
void misc::msleep(unsigned long msecs) |
|
|
|
|
{ |
|
|
|
|
SleeperThread::msleep(msecs); |
|
|
|
|
} |
|
|
|
|