|
|
@ -52,6 +52,7 @@ |
|
|
|
#ifdef Q_OS_WIN |
|
|
|
#ifdef Q_OS_WIN |
|
|
|
#include <windows.h> |
|
|
|
#include <windows.h> |
|
|
|
#include <powrprof.h> |
|
|
|
#include <powrprof.h> |
|
|
|
|
|
|
|
#include <Shlobj.h> |
|
|
|
const int UNLEN = 256; |
|
|
|
const int UNLEN = 256; |
|
|
|
#else |
|
|
|
#else |
|
|
|
#include <unistd.h> |
|
|
|
#include <unistd.h> |
|
|
@ -233,6 +234,7 @@ QPoint Utils::Misc::screenCenter(QWidget *win) |
|
|
|
QRect desk(QApplication::desktop()->availableGeometry(scrn)); |
|
|
|
QRect desk(QApplication::desktop()->availableGeometry(scrn)); |
|
|
|
return QPoint((desk.width() - win->frameGeometry().width()) / 2, (desk.height() - win->frameGeometry().height()) / 2); |
|
|
|
return QPoint((desk.width() - win->frameGeometry().width()) / 2, (desk.height() - win->frameGeometry().height()) / 2); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -267,12 +269,12 @@ QString Utils::Misc::pythonExecutable() |
|
|
|
* http://legacy.python.org/dev/peps/pep-0394/
|
|
|
|
* http://legacy.python.org/dev/peps/pep-0394/
|
|
|
|
*/ |
|
|
|
*/ |
|
|
|
pythonProc.start("python3", QStringList() << "--version", QIODevice::ReadOnly); |
|
|
|
pythonProc.start("python3", QStringList() << "--version", QIODevice::ReadOnly); |
|
|
|
if (pythonProc.waitForFinished() && pythonProc.exitCode() == 0) { |
|
|
|
if (pythonProc.waitForFinished() && (pythonProc.exitCode() == 0)) { |
|
|
|
executable = "python3"; |
|
|
|
executable = "python3"; |
|
|
|
return executable; |
|
|
|
return executable; |
|
|
|
} |
|
|
|
} |
|
|
|
pythonProc.start("python2", QStringList() << "--version", QIODevice::ReadOnly); |
|
|
|
pythonProc.start("python2", QStringList() << "--version", QIODevice::ReadOnly); |
|
|
|
if (pythonProc.waitForFinished() && pythonProc.exitCode() == 0) { |
|
|
|
if (pythonProc.waitForFinished() && (pythonProc.exitCode() == 0)) { |
|
|
|
executable = "python2"; |
|
|
|
executable = "python2"; |
|
|
|
return executable; |
|
|
|
return executable; |
|
|
|
} |
|
|
|
} |
|
|
@ -280,7 +282,7 @@ QString Utils::Misc::pythonExecutable() |
|
|
|
// Look for "python" in Windows and in UNIX if "python2" and "python3" are
|
|
|
|
// Look for "python" in Windows and in UNIX if "python2" and "python3" are
|
|
|
|
// not detected.
|
|
|
|
// not detected.
|
|
|
|
pythonProc.start("python", QStringList() << "--version", QIODevice::ReadOnly); |
|
|
|
pythonProc.start("python", QStringList() << "--version", QIODevice::ReadOnly); |
|
|
|
if (pythonProc.waitForFinished() && pythonProc.exitCode() == 0) |
|
|
|
if (pythonProc.waitForFinished() && (pythonProc.exitCode() == 0)) |
|
|
|
executable = "python"; |
|
|
|
executable = "python"; |
|
|
|
else |
|
|
|
else |
|
|
|
Logger::instance()->addMessage(QCoreApplication::translate("misc", "Python not detected"), Log::INFO); |
|
|
|
Logger::instance()->addMessage(QCoreApplication::translate("misc", "Python not detected"), Log::INFO); |
|
|
@ -293,14 +295,15 @@ QString Utils::Misc::pythonExecutable() |
|
|
|
* eg 2.7.9 |
|
|
|
* eg 2.7.9 |
|
|
|
* Make sure to have setup python first |
|
|
|
* Make sure to have setup python first |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
QString Utils::Misc::pythonVersionComplete() { |
|
|
|
QString Utils::Misc::pythonVersionComplete() |
|
|
|
|
|
|
|
{ |
|
|
|
static QString version; |
|
|
|
static QString version; |
|
|
|
if (version.isEmpty()) { |
|
|
|
if (version.isEmpty()) { |
|
|
|
if (pythonExecutable().isEmpty()) |
|
|
|
if (pythonExecutable().isEmpty()) |
|
|
|
return version; |
|
|
|
return version; |
|
|
|
QProcess pythonProc; |
|
|
|
QProcess pythonProc; |
|
|
|
pythonProc.start(pythonExecutable(), QStringList() << "--version", QIODevice::ReadOnly); |
|
|
|
pythonProc.start(pythonExecutable(), QStringList() << "--version", QIODevice::ReadOnly); |
|
|
|
if (pythonProc.waitForFinished() && pythonProc.exitCode() == 0) { |
|
|
|
if (pythonProc.waitForFinished() && (pythonProc.exitCode() == 0)) { |
|
|
|
QByteArray output = pythonProc.readAllStandardOutput(); |
|
|
|
QByteArray output = pythonProc.readAllStandardOutput(); |
|
|
|
if (output.isEmpty()) |
|
|
|
if (output.isEmpty()) |
|
|
|
output = pythonProc.readAllStandardError(); |
|
|
|
output = pythonProc.readAllStandardError(); |
|
|
@ -349,9 +352,8 @@ QString Utils::Misc::friendlyUnit(qint64 bytesValue, bool isSpeed) |
|
|
|
{ |
|
|
|
{ |
|
|
|
SizeUnit unit; |
|
|
|
SizeUnit unit; |
|
|
|
qreal friendlyVal; |
|
|
|
qreal friendlyVal; |
|
|
|
if (!friendlyUnit(bytesValue, friendlyVal, unit)) { |
|
|
|
if (!friendlyUnit(bytesValue, friendlyVal, unit)) |
|
|
|
return QCoreApplication::translate("misc", "Unknown", "Unknown (size)"); |
|
|
|
return QCoreApplication::translate("misc", "Unknown", "Unknown (size)"); |
|
|
|
} |
|
|
|
|
|
|
|
QString ret; |
|
|
|
QString ret; |
|
|
|
if (unit == SizeUnit::Byte) |
|
|
|
if (unit == SizeUnit::Byte) |
|
|
|
ret = QString::number(bytesValue) + " " + unitString(unit); |
|
|
|
ret = QString::number(bytesValue) + " " + unitString(unit); |
|
|
@ -364,9 +366,8 @@ QString Utils::Misc::friendlyUnit(qint64 bytesValue, bool isSpeed) |
|
|
|
|
|
|
|
|
|
|
|
qlonglong Utils::Misc::sizeInBytes(qreal size, Utils::Misc::SizeUnit unit) |
|
|
|
qlonglong Utils::Misc::sizeInBytes(qreal size, Utils::Misc::SizeUnit unit) |
|
|
|
{ |
|
|
|
{ |
|
|
|
for (int i = 0; i < static_cast<int>(unit); ++i) { |
|
|
|
for (int i = 0; i < static_cast<int>(unit); ++i) |
|
|
|
size *= 1024; |
|
|
|
size *= 1024; |
|
|
|
} |
|
|
|
|
|
|
|
return size; |
|
|
|
return size; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -427,7 +428,7 @@ bool Utils::Misc::isPreviewable(const QString& extension) |
|
|
|
// time duration like "1d 2h 10m".
|
|
|
|
// time duration like "1d 2h 10m".
|
|
|
|
QString Utils::Misc::userFriendlyDuration(qlonglong seconds) |
|
|
|
QString Utils::Misc::userFriendlyDuration(qlonglong seconds) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (seconds < 0 || seconds >= MAX_ETA) |
|
|
|
if ((seconds < 0) || (seconds >= MAX_ETA)) |
|
|
|
return QString::fromUtf8(C_INFINITY); |
|
|
|
return QString::fromUtf8(C_INFINITY); |
|
|
|
if (seconds == 0) |
|
|
|
if (seconds == 0) |
|
|
|
return "0"; |
|
|
|
return "0"; |
|
|
@ -572,70 +573,42 @@ void Utils::Misc::openPath(const QString& absolutePath) |
|
|
|
void Utils::Misc::openFolderSelect(const QString &absolutePath) |
|
|
|
void Utils::Misc::openFolderSelect(const QString &absolutePath) |
|
|
|
{ |
|
|
|
{ |
|
|
|
const QString path = Utils::Fs::fromNativePath(absolutePath); |
|
|
|
const QString path = Utils::Fs::fromNativePath(absolutePath); |
|
|
|
#ifdef Q_OS_WIN |
|
|
|
|
|
|
|
if (QFileInfo(path).exists()) { |
|
|
|
|
|
|
|
// Syntax is: explorer /select, "C:\Folder1\Folder2\file_to_select"
|
|
|
|
|
|
|
|
// Dir separators MUST be win-style slashes
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// QProcess::startDetached() has an obscure bug. If the path has
|
|
|
|
|
|
|
|
// no spaces and a comma(and maybe other special characters) it doesn't
|
|
|
|
|
|
|
|
// get wrapped in quotes. So explorer.exe can't find the correct path and
|
|
|
|
|
|
|
|
// displays the default one. If we wrap the path in quotes and pass it to
|
|
|
|
|
|
|
|
// QProcess::startDetached() explorer.exe still shows the default path. In
|
|
|
|
|
|
|
|
// this case QProcess::startDetached() probably puts its own quotes around ours.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
STARTUPINFO startupInfo; |
|
|
|
|
|
|
|
::ZeroMemory(&startupInfo, sizeof(startupInfo)); |
|
|
|
|
|
|
|
startupInfo.cb = sizeof(startupInfo); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
PROCESS_INFORMATION processInfo; |
|
|
|
|
|
|
|
::ZeroMemory(&processInfo, sizeof(processInfo)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QString cmd = QString("explorer.exe /select,\"%1\"").arg(Utils::Fs::toNativePath(absolutePath)); |
|
|
|
|
|
|
|
LPWSTR lpCmd = new WCHAR[cmd.size() + 1]; |
|
|
|
|
|
|
|
cmd.toWCharArray(lpCmd); |
|
|
|
|
|
|
|
lpCmd[cmd.size()] = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool ret = ::CreateProcessW(NULL, lpCmd, NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInfo); |
|
|
|
|
|
|
|
delete [] lpCmd; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (ret) { |
|
|
|
|
|
|
|
::CloseHandle(processInfo.hProcess); |
|
|
|
|
|
|
|
::CloseHandle(processInfo.hThread); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
// If the item to select doesn't exist, try to open its parent
|
|
|
|
// If the item to select doesn't exist, try to open its parent
|
|
|
|
|
|
|
|
if (!QFileInfo(path).exists()) { |
|
|
|
openPath(path.left(path.lastIndexOf("/"))); |
|
|
|
openPath(path.left(path.lastIndexOf("/"))); |
|
|
|
|
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
#ifdef Q_OS_WIN |
|
|
|
|
|
|
|
HRESULT hresult = ::CoInitializeEx(nullptr, COINIT_MULTITHREADED); |
|
|
|
|
|
|
|
ITEMIDLIST *pidl = ::ILCreateFromPathW(reinterpret_cast<PCTSTR>(Utils::Fs::toNativePath(path).utf16())); |
|
|
|
|
|
|
|
if (pidl) { |
|
|
|
|
|
|
|
::SHOpenFolderAndSelectItems(pidl, 0, nullptr, 0); |
|
|
|
|
|
|
|
::ILFree(pidl); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if ((hresult == S_OK) || (hresult == S_FALSE)) |
|
|
|
|
|
|
|
::CoUninitialize(); |
|
|
|
#elif defined(Q_OS_UNIX) && !defined(Q_OS_MAC) |
|
|
|
#elif defined(Q_OS_UNIX) && !defined(Q_OS_MAC) |
|
|
|
if (QFileInfo(path).exists()) { |
|
|
|
|
|
|
|
QProcess proc; |
|
|
|
QProcess proc; |
|
|
|
proc.start("xdg-mime", QStringList() << "query" << "default" << "inode/directory"); |
|
|
|
proc.start("xdg-mime", QStringList() << "query" << "default" << "inode/directory"); |
|
|
|
proc.waitForFinished(); |
|
|
|
proc.waitForFinished(); |
|
|
|
QString output = proc.readLine().simplified(); |
|
|
|
QString output = proc.readLine().simplified(); |
|
|
|
if (output == "dolphin.desktop" || output == "org.kde.dolphin.desktop") |
|
|
|
if ((output == "dolphin.desktop") || (output == "org.kde.dolphin.desktop")) |
|
|
|
proc.startDetached("dolphin", QStringList() << "--select" << Utils::Fs::toNativePath(path)); |
|
|
|
proc.startDetached("dolphin", QStringList() << "--select" << Utils::Fs::toNativePath(path)); |
|
|
|
else if (output == "nautilus.desktop" || output == "org.gnome.Nautilus.desktop" |
|
|
|
else if ((output == "nautilus.desktop") || (output == "org.gnome.Nautilus.desktop") |
|
|
|
|| output == "nautilus-folder-handler.desktop") |
|
|
|
|| (output == "nautilus-folder-handler.desktop")) |
|
|
|
proc.startDetached("nautilus", QStringList() << "--no-desktop" << Utils::Fs::toNativePath(path)); |
|
|
|
proc.startDetached("nautilus", QStringList() << "--no-desktop" << Utils::Fs::toNativePath(path)); |
|
|
|
else if (output == "nemo.desktop") |
|
|
|
else if (output == "nemo.desktop") |
|
|
|
proc.startDetached("nemo", QStringList() << "--no-desktop" << Utils::Fs::toNativePath(path)); |
|
|
|
proc.startDetached("nemo", QStringList() << "--no-desktop" << Utils::Fs::toNativePath(path)); |
|
|
|
else if (output == "konqueror.desktop" || output == "kfmclient_dir.desktop") |
|
|
|
else if ((output == "konqueror.desktop") || (output == "kfmclient_dir.desktop")) |
|
|
|
proc.startDetached("konqueror", QStringList() << "--select" << Utils::Fs::toNativePath(path)); |
|
|
|
proc.startDetached("konqueror", QStringList() << "--select" << Utils::Fs::toNativePath(path)); |
|
|
|
else { |
|
|
|
else |
|
|
|
// "caja" manager can't pinpoint the file, see: https://github.com/qbittorrent/qBittorrent/issues/5003
|
|
|
|
// "caja" manager can't pinpoint the file, see: https://github.com/qbittorrent/qBittorrent/issues/5003
|
|
|
|
openPath(path.left(path.lastIndexOf("/"))); |
|
|
|
openPath(path.left(path.lastIndexOf("/"))); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
// If the item to select doesn't exist, try to open its parent
|
|
|
|
|
|
|
|
openPath(path.left(path.lastIndexOf("/"))); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
#else |
|
|
|
#else |
|
|
|
openPath(path.left(path.lastIndexOf("/"))); |
|
|
|
openPath(path.left(path.lastIndexOf("/"))); |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#endif // DISABLE_GUI
|
|
|
|
#endif // DISABLE_GUI
|
|
|
|
|
|
|
|
|
|
|
|
namespace |
|
|
|
namespace |
|
|
@ -663,6 +636,7 @@ QSize Utils::Misc::smallIconSize() |
|
|
|
int s = QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize); |
|
|
|
int s = QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize); |
|
|
|
return QSize(s, s); |
|
|
|
return QSize(s, s); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
QString Utils::Misc::osName() |
|
|
|
QString Utils::Misc::osName() |
|
|
|