mirror of
https://github.com/ONLYOFFICE/desktop-apps.git
synced 2026-04-07 14:09:22 +08:00
325 lines
10 KiB
C++
325 lines
10 KiB
C++
/*
|
|
* (c) Copyright Ascensio System SIA 2010-2017
|
|
*
|
|
* This program is a free software product. You can redistribute it and/or
|
|
* modify it under the terms of the GNU Affero General Public License (AGPL)
|
|
* version 3 as published by the Free Software Foundation. In accordance with
|
|
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
|
|
* that Ascensio System SIA expressly excludes the warranty of non-infringement
|
|
* of any third-party rights.
|
|
*
|
|
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
|
|
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
|
|
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
|
*
|
|
* You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia,
|
|
* EU, LV-1021.
|
|
*
|
|
* The interactive user interfaces in modified source and object code versions
|
|
* of the Program must display Appropriate Legal Notices, as required under
|
|
* Section 5 of the GNU AGPL version 3.
|
|
*
|
|
* Pursuant to Section 7(b) of the License you must retain the original Product
|
|
* logo when distributing the program. Pursuant to Section 7(e) we decline to
|
|
* grant you any rights under trademark law for use of our trademarks.
|
|
*
|
|
* All the Product's GUI elements, including illustrations and icon sets, as
|
|
* well as technical writing content are licensed under the terms of the
|
|
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
|
|
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
|
*
|
|
*/
|
|
|
|
#include "utils.h"
|
|
#include "defines.h"
|
|
#include <QSettings>
|
|
#include <QStandardPaths>
|
|
#include <QDir>
|
|
#include <QRegularExpression>
|
|
#include <QIcon>
|
|
#include <QSysInfo>
|
|
#include <QApplication>
|
|
#include <QDesktopWidget>
|
|
#include <QDesktopServices>
|
|
#include <QUrl>
|
|
#include <QJsonDocument>
|
|
#include <QProcess>
|
|
#include <QScreen>
|
|
|
|
#include "applicationmanager.h"
|
|
#include "applicationmanager_events.h"
|
|
|
|
#ifdef _WIN32
|
|
#include "shlobj.h"
|
|
#else
|
|
#include <sys/stat.h>
|
|
#endif
|
|
|
|
#include <QDebug>
|
|
|
|
bool is_file_browser_supported = true;
|
|
|
|
QStringList * Utils::getInputFiles(const QStringList& inlist)
|
|
{
|
|
QStringList * _ret_files_list = new QStringList;
|
|
|
|
QStringListIterator i(inlist); i.next();
|
|
while (i.hasNext()) {
|
|
QString arg = i.next();
|
|
|
|
if ( arg.startsWith("--new:") )
|
|
_ret_files_list->append( arg );
|
|
else {
|
|
QFileInfo info( arg );
|
|
if ( info.isFile() ) {
|
|
_ret_files_list->append(info.absoluteFilePath());
|
|
}
|
|
}
|
|
}
|
|
|
|
return _ret_files_list;
|
|
}
|
|
|
|
QString Utils::lastPath(int t)
|
|
{
|
|
GET_REGISTRY_USER(_reg_user)
|
|
|
|
QString _path;
|
|
if (t == LOCAL_PATH_OPEN)
|
|
_path = _reg_user.value("openPath").value<QString>(); else
|
|
_path = _reg_user.value("savePath").value<QString>();
|
|
|
|
return _path.length() > 0 && QDir(_path).exists() ?
|
|
_path : QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
|
|
}
|
|
|
|
void Utils::keepLastPath(int t, const QString& p)
|
|
{
|
|
GET_REGISTRY_USER(_reg_user)
|
|
if (t == LOCAL_PATH_OPEN)
|
|
_reg_user.setValue("openPath", p); else
|
|
_reg_user.setValue("savePath", p);
|
|
}
|
|
|
|
bool Utils::makepath(const QString& p)
|
|
{
|
|
#ifdef __linux
|
|
mode_t _mask = umask(0);
|
|
(_mask & S_IRWXO) && umask(_mask & ~S_IRWXO);
|
|
#endif
|
|
return QDir().mkpath(p);
|
|
}
|
|
|
|
QRect Utils::getScreenGeometry(const QPoint& leftTop)
|
|
{
|
|
// int _scr_num = QApplication::desktop()->screenNumber(leftTop); - return the wrong number
|
|
// return QApplication::desktop()->screenGeometry(_scr_num);
|
|
|
|
auto pointToRect = [](const QPoint &p, const QRect &r) -> int {
|
|
int dx = 0, dy = 0;
|
|
if (p.x() < r.left()) dx = r.left() - p.x(); else
|
|
if (p.x() > r.right()) dx = p.x() - r.right();
|
|
|
|
if (p.y() < r.top()) dy = r.top() - p.y(); else
|
|
if (p.y() > r.bottom()) dy = p.y() - r.bottom();
|
|
|
|
return dx + dy;
|
|
};
|
|
|
|
int closestScreen = 0;
|
|
int shortestDistance = pointToRect(leftTop, QApplication::desktop()->screenGeometry(0));
|
|
|
|
for (int i = 0; ++i < QApplication::desktop()->screenCount(); ) {
|
|
int thisDistance = pointToRect(leftTop, QApplication::desktop()->screenGeometry(i));
|
|
if (thisDistance < shortestDistance) {
|
|
shortestDistance = thisDistance;
|
|
closestScreen = i;
|
|
}
|
|
}
|
|
|
|
return QApplication::desktop()->screenGeometry(closestScreen);
|
|
}
|
|
|
|
QString Utils::systemLocationCode()
|
|
{
|
|
#define LOCATION_MAX_LEN 9
|
|
#ifdef _WIN32
|
|
WCHAR _country_code[LOCATION_MAX_LEN]{0};
|
|
// "no entry point for GetLocaleInfoEx" error on win_xp
|
|
// if ( QSysInfo::windowsVersion() >= QSysInfo::WV_VISTA ) {
|
|
// if (!GetLocaleInfoEx(LOCALE_NAME_SYSTEM_DEFAULT, LOCALE_SISO3166CTRYNAME, _country_code, LOCATION_MAX_LEN))
|
|
// return "unknown";
|
|
// } else {
|
|
if (!GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SISO3166CTRYNAME, _country_code, LOCATION_MAX_LEN))
|
|
return "unknown";
|
|
// }
|
|
|
|
return QString::fromWCharArray(_country_code);
|
|
#else
|
|
return QLocale().name().split('_').at(1);
|
|
#endif
|
|
}
|
|
|
|
void Utils::openUrl(const QString& url)
|
|
{
|
|
#ifdef __linux
|
|
QUrl _url(url);
|
|
if ( _url.scheme() == "mailto" ) {
|
|
system(QString("LD_LIBRARY_PATH='' xdg-email %1") // xdg-email filepath email
|
|
.arg(QString( _url.toEncoded() )).toUtf8());
|
|
} else {
|
|
system(QString("LD_LIBRARY_PATH='' xdg-open %1") // xdg-open workingpath path
|
|
.arg(QString( _url.toEncoded() )).toUtf8());
|
|
}
|
|
#else
|
|
QDesktopServices::openUrl(QUrl(url));
|
|
#endif
|
|
}
|
|
|
|
void Utils::openFileLocation(const QString& path)
|
|
{
|
|
#if defined(Q_OS_WIN)
|
|
QStringList args{"/select,", QDir::toNativeSeparators(path)};
|
|
QProcess::startDetached("explorer", args);
|
|
#else
|
|
static QString is_browser_checked;
|
|
if ( is_browser_checked.isEmpty() ) {
|
|
is_browser_checked = "checked";
|
|
|
|
auto _get_cmd_output = [](const QString& cmd, const QStringList& args, QString& error) {
|
|
QProcess process;
|
|
process.start(cmd, args);
|
|
process.waitForFinished(-1);
|
|
|
|
error = process.readAllStandardError();
|
|
return process.readAllStandardOutput();
|
|
};
|
|
|
|
QString _error;
|
|
QString _file_browser = _get_cmd_output("xdg-mime", QStringList{"query", "default", "inode/directory"}, _error);
|
|
|
|
// if ( _error.isEmpty() )
|
|
{
|
|
bool is_file_browser_nautilus =
|
|
_file_browser.contains(QRegularExpression("nautilus\\.desktop", QRegularExpression::CaseInsensitiveOption)) ||
|
|
_file_browser.contains(QRegularExpression("nautilus-folder-handler\\.desktop", QRegularExpression::CaseInsensitiveOption));
|
|
|
|
if ( is_file_browser_nautilus ) {
|
|
QString _version = _get_cmd_output("nautilus", QStringList{"--version"}, _error);
|
|
|
|
// if ( _error.isEmpty() )
|
|
{
|
|
QRegularExpression _regex("nautilus\\s(\\d{1,3})\\.(\\d{1,3})(?:\\.(\\d{1,5}))?");
|
|
QRegularExpressionMatch match = _regex.match(_version);
|
|
if ( match.hasMatch() ) {
|
|
bool is_verion_supported = match.captured(1).toInt() > 3;
|
|
if ( !is_verion_supported && match.captured(1).toInt() == 3 ) {
|
|
is_verion_supported = match.captured(2).toInt() > 0;
|
|
|
|
if ( !is_verion_supported && !match.captured(3).isEmpty() )
|
|
is_verion_supported = !(match.captured(3).toInt() < 2);
|
|
}
|
|
|
|
is_file_browser_supported = is_verion_supported;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
QFileInfo fileInfo(path);
|
|
is_file_browser_supported ?
|
|
system(QString("nautilus \"" + fileInfo.absoluteFilePath() + "\"").toUtf8()) :
|
|
system(QString("LD_LIBRARY_PATH='' xdg-open \"%1\"").arg(fileInfo.path()).toUtf8());
|
|
#endif
|
|
}
|
|
|
|
QString Utils::getPortalName(const QString& url)
|
|
{
|
|
if ( !url.isEmpty() ) {
|
|
QRegularExpressionMatch match = QRegularExpression(rePortalName).match(url);
|
|
if (match.hasMatch()) {
|
|
QString out = match.captured(1);
|
|
return out.endsWith('/') ? out.remove(-1, 1) : out;
|
|
}
|
|
}
|
|
|
|
return url;
|
|
}
|
|
|
|
QString Utils::encodeJson(const QJsonObject& obj)
|
|
{
|
|
return Utils::encodeJson(
|
|
QJsonDocument(obj).toJson(QJsonDocument::Compact) );
|
|
}
|
|
|
|
QString Utils::encodeJson(const QString& s)
|
|
{
|
|
return QString(s).replace("\"", "\\\"");
|
|
}
|
|
|
|
unsigned Utils::getScreenDpiRatio(int scrnum)
|
|
{
|
|
#ifdef __linux
|
|
double _k = _k = QApplication::primaryScreen()->logicalDotsPerInch() / 96.f;
|
|
#else
|
|
UINT _dpi_x = 0,
|
|
_dpi_y = 0;
|
|
double _k;
|
|
|
|
if ( Core_GetMonitorRawDpiByIndex(scrnum, &_dpi_x, &_dpi_y) == S_OK ) {
|
|
_k = _dpi_x / 96.f;
|
|
} else {
|
|
_k = QApplication::primaryScreen()->logicalDotsPerInch() / 96.f;
|
|
}
|
|
#endif
|
|
|
|
return !(_k < 1.5) ? 2 : 1;
|
|
}
|
|
|
|
unsigned Utils::getScreenDpiRatioByHWND(int hwnd)
|
|
{
|
|
#ifdef __linux
|
|
return 1;
|
|
#else
|
|
UINT _dpi_x = 0,
|
|
_dpi_y = 0;
|
|
double _k;
|
|
|
|
if ( Core_GetMonitorRawDpi((HWND)hwnd, &_dpi_x, &_dpi_y) == S_OK ) {
|
|
_k = _dpi_x;
|
|
} else {
|
|
_k = QApplication::primaryScreen()->logicalDotsPerInch();
|
|
}
|
|
|
|
return _k / 96.f < 1.5 ? 1 : 2;
|
|
#endif
|
|
}
|
|
|
|
QByteArray Utils::getAppStylesheets(int scale)
|
|
{
|
|
auto read_styles = [](const QString& dir) {
|
|
QByteArray _css;
|
|
QFile file;
|
|
QFileInfoList files = QDir(dir).entryInfoList(QStringList("*.qss"), QDir::Files);
|
|
foreach(const QFileInfo &info, files) {
|
|
file.setFileName(info.absoluteFilePath());
|
|
if ( file.open(QIODevice::ReadOnly | QIODevice::Text) ) {
|
|
_css.append(file.readAll());
|
|
file.close();
|
|
}
|
|
}
|
|
|
|
return _css;
|
|
};
|
|
|
|
QByteArray _out( read_styles(QString(":styles/res/styles")) );
|
|
|
|
if ( scale > 1 ) {
|
|
_out.append( read_styles(QString(":styles@2x")) );
|
|
}
|
|
|
|
return _out;
|
|
}
|