/* Copyright (C) 2011 Lucio Carreras
* Copyright (C) 2017 J.F. Dockes
*
* This file is part of Upplay
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string>
#include <set>
#include <vector>
#include <list>
#include <time.h>
#include <QDir>
#include <QString>
#include <QDebug>
#include "HelperStructs/Helper.h"
#include "HelperStructs/MetaData.h"
#include "HelperStructs/globals.h"
#include "HelperStructs/CSettingsStorage.h"
using namespace std;
void Helper::msleep(int millis)
{
struct timespec spec;
spec.tv_sec = millis / 1000;
spec.tv_nsec = (millis % 1000) * 1000000;
nanosleep(&spec, 0);
}
QByteArray Helper::readFileToByteArray(const QString& fn)
{
QFile qf(fn);
QByteArray ret;
if (qf.open(QIODevice::ReadOnly)) {
ret = qf.read(1000 * 1000);
}
return ret;
}
static QString cvtNum2String(int num, int digits)
{
QString str = QString::number(num);
while (str.size() < digits) {
str.prepend("0");
}
return str;
}
QString Helper::cvtMsecs2TitleLengthString(long int msec, bool colon,
bool show_days)
{
QString sign;
if (msec < 0) {
msec = -msec;
sign = "-";
}
bool show_hrs = false;
int sec = msec / 1000;
int min = sec / 60;
int secs = sec % 60;
int hrs = min / 60;
int days = hrs / 24;
QString final_str;
if (days > 0 && show_days) {
final_str += QString::number(days) + "d ";
hrs = hrs % 24;
show_hrs = true;
}
if (!show_days) {
hrs += (days * 24);
}
if (hrs > 0 || show_hrs) {
final_str += QString::number(hrs) + "h ";
min = min % 60;
}
if (colon) {
final_str += cvtNum2String(min, 2) + ":" + cvtNum2String(secs, 2);
} else {
final_str += cvtNum2String(min, 2) + "m " + cvtNum2String(secs, 2);
}
return sign + final_str;
}
#ifdef Q_OS_WIN
#include <Shlwapi.h>
#pragma comment(lib, "shlwapi.lib")
QString GetExecPath()
{
TCHAR dest[MAX_PATH];
DWORD length = GetModuleFileName(NULL, dest, MAX_PATH);
#ifdef NTDDI_WIN8_future
PathCchRemoveFileSpec(dest, MAX_PATH);
#else
PathRemoveFileSpec(dest);
#endif
if (sizeof(TCHAR) == 2)
return QString::fromUtf16((const ushort*)dest);
else
return QString::fromUtf8((const char*)dest);
}
#endif
QString Helper::getSharePath()
{
QString path;
#if defined(Q_OS_WIN)
QDir execdir(GetExecPath());
QString rpath("Share");
execdir.mkpath(rpath);
path = execdir.absoluteFilePath(rpath);
#elif defined(Q_OS_MACOS)
path = QCoreApplication::applicationDirPath() + QString("/..");
path = QDir::cleanPath(path);
#else
if (QFile::exists(PREFIX "/share/upplay")) {
path = PREFIX "/share/upplay/";
} else {
path = "";
}
#endif
return path;
}
QString Helper::getCSSPath()
{
#if defined(Q_OS_MACOS) || defined(Q_OS_MAC)
return Helper::getSharePath() + "/Resources/";
#else
return Helper::getSharePath() + "/cdbrowser/";
#endif
}
static QString styleSubDir;
void Helper::setStyleSubDir(const QString& subd)
{
styleSubDir = subd;
}
QString Helper::getIconDir()
{
#if defined(Q_OS_MACOS)
return QDir(getSharePath()).filePath("Resources");
#else
return QDir(getSharePath()).filePath("icons");
#endif
}
QString Helper::getIconPath(const QString& icnm)
{
if (!styleSubDir.isEmpty()) {
QDir styledir(QDir(getIconDir()).filePath(styleSubDir));
if (QFile::exists(styledir.filePath(icnm))) {
return styledir.filePath(icnm);
}
}
return QDir(getIconDir()).filePath(icnm);
}
QString Helper::getHomeDataPath()
{
QDir homedir(QDir::home());
#ifndef Q_OS_WIN
QString rpath = QString::fromUtf8(".local/share/upplay");
#else
QString rpath = QString::fromUtf8("AppData/Local/upplay/");
#endif
homedir.mkpath(rpath);
return homedir.absoluteFilePath(rpath);
}
#define DARK_BLUE(x) QString("<font color=#0000FF>") + x + QString("</font>")
#define LIGHT_BLUE(x) QString("<font color=#8888FF>") + x + QString("</font>")
QString Helper::createLink(QString name, QString target, bool underline)
{
int dark = CSettingsStorage::getInstance()->getPlayerStyle();
if (target.size() == 0) {
target = name;
}
QString content;
QString style = "";
if (!underline) {
style = " style: \"text-decoration=none;\" ";
}
if (dark) {
content = LIGHT_BLUE(name);
} else {
content = DARK_BLUE(name);
}
return QString("<a href=\"") + target + "\"" + style + ">" +
content + "</a>";
}
bool Helper::read_file_into_str(QString filename, QString* content)
{
QFile file(filename);
content->clear();
if (!file.open(QIODevice::ReadOnly)) {
return false;
}
while (!file.atEnd()) {
QByteArray arr = file.readLine();
QString str = QString::fromLocal8Bit(arr);
content->append(str);
}
file.close();
if (content->size() > 0) {
return true;
}
return false;
}
// Escape things that would look like HTML markup
string Helper::escapeHtml(const string &in)
{
string out;
for (string::size_type pos = 0; pos < in.length(); pos++) {
switch(in.at(pos)) {
case '<': out += "<"; break;
case '>': out += ">"; break;
case '&': out += "&"; break;
case '"': out += """; break;
default: out += in.at(pos); break;
}
}
return out;
}
QString Helper::escapeHtml(const QString& in)
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
return in.toHtmlEscaped();
#else
return Qt::escape(in);
#endif
}
template <class T> void stringsToString(const T &tokens, string &s)
{
for (typename T::const_iterator it = tokens.begin();
it != tokens.end(); it++) {
bool hasblanks = false;
if (it->find_first_of(" \t\n") != string::npos)
hasblanks = true;
if (it != tokens.begin())
s.append(1, ' ');
if (hasblanks)
s.append(1, '"');
for (unsigned int i = 0; i < it->length(); i++) {
char car = it->at(i);
if (car == '"') {
s.append(1, '\\');
s.append(1, car);
} else {
s.append(1, car);
}
}
if (hasblanks)
s.append(1, '"');
}
}
template void stringsToString<list<string> >(const list<string> &, string &);
template void stringsToString<vector<string> >(const vector<string> &,string &);
template void stringsToString<set<string> >(const set<string> &, string &);
template <class T> string stringsToString(const T &tokens)
{
string out;
stringsToString<T>(tokens, out);
return out;
}
template string stringsToString<list<string> >(const list<string> &);
template string stringsToString<vector<string> >(const vector<string> &);
template string stringsToString<set<string> >(const set<string> &);
string ivtos(const vector<int>& nids)
{
string sids;
for (unsigned int i = 0; i < nids.size(); i++) {
char cbuf[30];
sprintf(cbuf, "%d", nids[i]);
sids += string(cbuf) + " ";
}
return sids;
}