813 lines
22 KiB
C++
813 lines
22 KiB
C++
/*
|
|
Copyright (C) 2014 Michal Kosciesza <michal@mkiol.net>
|
|
|
|
This file is part of Kaktus.
|
|
|
|
Kaktus 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.
|
|
|
|
Kaktus 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 Kaktus. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <QtGui/QClipboard>
|
|
#include <QDebug>
|
|
#include <QDateTime>
|
|
#include <QtCore/qmath.h>
|
|
#include <QCryptographicHash>
|
|
#include <QRegExp>
|
|
#include <QFile>
|
|
#include <QDir>
|
|
#include <QFileInfo>
|
|
#include <QFileInfoList>
|
|
|
|
#ifdef SAILFISH
|
|
#include <sailfishapp.h>
|
|
#endif
|
|
#ifdef ANDROID
|
|
#include <QtAndroidExtras/QAndroidJniObject>
|
|
#include <QtGui/QGuiApplication>
|
|
#endif
|
|
#ifdef BB10
|
|
#include <bps/navigator.h>
|
|
#include <QtGui/QApplication>
|
|
#include <bb/cascades/QmlDocument>
|
|
#include <bb/cascades/ThemeSupport>
|
|
#include <bb/cascades/Theme>
|
|
#include <bb/cascades/Application>
|
|
#include <bb/cascades/ColorTheme>
|
|
#include <bb/cascades/VisualStyle>
|
|
#include <bb/cascades/SystemDefaults>
|
|
#include <bb/cascades/TextStyle>
|
|
#include <bb/cascades/FontSize>
|
|
#include <bb/platform/PlatformInfo>
|
|
#include <bb/device/DisplayTechnology>
|
|
#include <bb/platform/PlatformInfo>
|
|
#include <QtCore/QString>
|
|
#include <QtCore/QList>
|
|
#include <bb/system/Clipboard>
|
|
#include <QtGui/QTextDocument>
|
|
#else
|
|
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
|
#include <QGuiApplication>
|
|
#include <QQmlContext>
|
|
#include <QStandardPaths>
|
|
#else
|
|
#include <QtGui/QDesktopServices>
|
|
#include <QtGui/QApplication>
|
|
#include <QDeclarativeContext>
|
|
#endif
|
|
#include <QTextDocument>
|
|
#endif
|
|
|
|
#include "utils.h"
|
|
#include "fetcher.h"
|
|
#include "oldreaderfetcher.h"
|
|
#include "nvfetcher.h"
|
|
#include "ttrssfetcher.h"
|
|
#include "databasemanager.h"
|
|
|
|
Utils::Utils(QObject *parent) :
|
|
QObject(parent)//, ncm(new QNetworkConfigurationManager(parent))
|
|
{
|
|
dashboardModel = nullptr;
|
|
entryModel = nullptr;
|
|
tabModel = nullptr;
|
|
feedModel = nullptr;
|
|
#ifdef ANDROID
|
|
screen = QGuiApplication::screens().at(0);
|
|
#endif
|
|
}
|
|
|
|
bool Utils::isLight()
|
|
{
|
|
#ifdef KAKTUS_LIGHT
|
|
return true;
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
#ifdef ANDROID
|
|
int Utils::dp(float value)
|
|
{
|
|
//float dp = value * (screen->physicalDotsPerInch() / 160) + 0.5;
|
|
//dp = (10 * dp + 5) / 10;
|
|
//qDebug() << "value=" << value << "dp=" << value * (screen->physicalDotsPerInch() / 160) << "dpp=" << dp;
|
|
return value * (screen->physicalDotsPerInch() / 160) + 0.5;
|
|
}
|
|
|
|
int Utils::mm(float value)
|
|
{
|
|
return value * (screen->physicalDotsPerInch() / 25.4);
|
|
}
|
|
|
|
int Utils::in(float value)
|
|
{
|
|
return value * screen->physicalDotsPerInch();
|
|
}
|
|
|
|
int Utils::pt(float value)
|
|
{
|
|
return value * (screen->physicalDotsPerInch() / 72);
|
|
}
|
|
|
|
int Utils::sp(float value)
|
|
{
|
|
return dp(value);
|
|
}
|
|
|
|
void Utils::showNotification(const QString &title, const QString &text)
|
|
{
|
|
QAndroidJniObject jTitle = QAndroidJniObject::fromString(title);
|
|
QAndroidJniObject jText = QAndroidJniObject::fromString(text);
|
|
QAndroidJniObject::callStaticMethod<void>("net/mkiol/kaktus/KaktusActivity",
|
|
"notify",
|
|
"(Ljava/lang/String;Ljava/lang/String;)V",
|
|
jTitle.object<jstring>(), jText.object<jstring>());
|
|
}
|
|
|
|
void Utils::setStatusBarColor(const QColor &color)
|
|
{
|
|
int acolor = (color.alpha() << 24) | (color.red() << 16) | (color.green() << 8) | color.blue();
|
|
QAndroidJniObject::callStaticMethod<void>("net/mkiol/kaktus/KaktusActivity",
|
|
"setStatusBarColor",
|
|
"(I)V", acolor);
|
|
}
|
|
|
|
#endif
|
|
|
|
#ifdef BB10
|
|
void Utils::launchBrowser(const QString &url)
|
|
{
|
|
navigator_invoke(url.toStdString().c_str(),0);
|
|
}
|
|
#endif
|
|
|
|
QString Utils::readAsset(const QString &path)
|
|
{
|
|
#ifdef BB10
|
|
QFile file("app/native/assets/" + path);
|
|
#endif
|
|
#ifdef ANDROID
|
|
QFile file(":/" + path);
|
|
#endif
|
|
#ifdef SAILFISH
|
|
QFile file(SailfishApp::pathTo(path).toLocalFile());
|
|
#endif
|
|
if (!file.open(QIODevice::ReadOnly)) {
|
|
qWarning() << "Could not open" << path << "for reading: " << file.errorString();
|
|
file.close();
|
|
return "";
|
|
}
|
|
|
|
QString data = QString(file.readAll());
|
|
file.close();
|
|
|
|
return data;
|
|
}
|
|
|
|
void Utils::copyToClipboard(const QString &text)
|
|
{
|
|
#ifdef BB10
|
|
bb::system::Clipboard clipboard;
|
|
clipboard.clear();
|
|
clipboard.insert("text/plain", text.toUtf8());
|
|
#else
|
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
|
|
QClipboard *clipboard = QGuiApplication::clipboard();
|
|
#else
|
|
QClipboard *clipboard = QApplication::clipboard();
|
|
#endif
|
|
clipboard->setText(text);
|
|
#endif
|
|
}
|
|
|
|
void Utils::resetQtWebKit()
|
|
{
|
|
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
|
QStringList dataDirs = QStandardPaths::standardLocations(QStandardPaths::DataLocation);
|
|
if(dataDirs.size() > 0) {
|
|
QDir dir(QDir(dataDirs.at(0)).filePath(".QtWebKit"));
|
|
qDebug() << dir.path();
|
|
if (dir.exists())
|
|
dir.removeRecursively();
|
|
}
|
|
#else
|
|
QString value = QDir(QDesktopServices::storageLocation(QDesktopServices::DataLocation)).path();
|
|
value = value + "/.QtWebKit";
|
|
removeDir(value);
|
|
#endif
|
|
}
|
|
|
|
void Utils::log(const QString & data)
|
|
{
|
|
int l = data.length();
|
|
int n = 120;
|
|
QString d;
|
|
for (int i = 0; i < l; ++i) {
|
|
d += data.at(i);
|
|
if (i % n == 0) {
|
|
qDebug() << i << d;
|
|
d.clear();
|
|
}
|
|
}
|
|
}
|
|
|
|
QString Utils::formatHtml(const QString & data, bool offline, const QString & style)
|
|
{
|
|
QRegExp rxImg("<img[^>]*>", Qt::CaseInsensitive);
|
|
QRegExp rxWidth("\\s*width\\s*=\\s*(\"[^\"]*\"|'[^']*')", Qt::CaseInsensitive);
|
|
QRegExp rxTarget("\\s*target\\s*=\\s*(\"[^\"]*\"|'[^']*')", Qt::CaseInsensitive);
|
|
QRegExp rxHeight("\\s*height\\s*=\\s*(\"[^\"]*\"|'[^']*')", Qt::CaseInsensitive);
|
|
QRegExp rxSizes("\\s*sizes\\s*=\\s*(\"[^\"]*\"|'[^']*')", Qt::CaseInsensitive);
|
|
QRegExp rxA("<a[^>]*></a>", Qt::CaseInsensitive);
|
|
QRegExp rxP("<p[^>]*></p>", Qt::CaseInsensitive);
|
|
|
|
QString content = data;
|
|
|
|
content.remove(rxTarget);
|
|
if (offline) {
|
|
content.remove(rxImg); content.remove("</img>", Qt::CaseInsensitive);
|
|
content.remove(rxA);
|
|
content.remove(rxP);
|
|
} else {
|
|
content.remove(rxWidth);
|
|
content.remove(rxHeight);
|
|
content.remove(rxSizes);
|
|
}
|
|
|
|
content = "<html><head><meta name=\"viewport\" content=\"width=device-width, maximum-scale=1.0, initial-scale=1.0\">" +
|
|
(style.isEmpty() ? "" : "<style>" + style + "</style>") +
|
|
"</head><body>" + content + "</body></html>";
|
|
|
|
return content;
|
|
}
|
|
|
|
/*
|
|
* Copyright (c) 2009 John Schember <john@nachtimwald.com>
|
|
* http://john.nachtimwald.com/2010/06/08/qt-remove-directory-and-its-contents/
|
|
*/
|
|
bool Utils::removeDir(const QString &dirName)
|
|
{
|
|
bool result = true;
|
|
QDir dir(dirName);
|
|
|
|
if (dir.exists(dirName)) {
|
|
QFileInfoList infoList = dir.entryInfoList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst);
|
|
foreach (const QFileInfo& info, infoList) {
|
|
if (info.isDir())
|
|
result = removeDir(info.absoluteFilePath());
|
|
else
|
|
result = QFile::remove(info.absoluteFilePath());
|
|
if (!result)
|
|
return result;
|
|
}
|
|
result = dir.rmdir(dirName);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
#ifdef BB10
|
|
// Source: http://hecgeek.blogspot.com/2014/10/blackberry-10-multiple-os-versions-from.html
|
|
bool Utils::checkOSVersion(int major, int minor, int patch, int build)
|
|
{
|
|
bb::platform::PlatformInfo platformInfo;
|
|
const QString osVersion = platformInfo.osVersion();
|
|
const QStringList parts = osVersion.split('.');
|
|
const int partCount = parts.size();
|
|
|
|
if(partCount < 4) {
|
|
// Invalid OS version format, assume check failed
|
|
return false;
|
|
}
|
|
|
|
// Compare the base OS version using the same method as the macros
|
|
// in bbndk.h, which are duplicated here for maximum compatibility.
|
|
int platformEncoded = (((parts[0].toInt())*1000000)+((parts[1].toInt())*1000)+(parts[2].toInt()));
|
|
int checkEncoded = (((major)*1000000)+((minor)*1000)+(patch));
|
|
|
|
if(platformEncoded < checkEncoded) {
|
|
return false;
|
|
}
|
|
else if(platformEncoded > checkEncoded) {
|
|
return true;
|
|
}
|
|
else {
|
|
// The platform and check OS versions are equal, so compare the build version
|
|
int platformBuild = parts[3].toInt();
|
|
return platformBuild >= build;
|
|
}
|
|
}
|
|
|
|
int Utils::du(float value)
|
|
{
|
|
int width = display.pixelSize().width();
|
|
int height = display.pixelSize().height();
|
|
|
|
/*qDebug() << "display id is " << display.displayId();
|
|
qDebug() << "display name is " << display.displayName();
|
|
qDebug() << "display size is " << display.pixelSize().width() << ", "
|
|
<< display.pixelSize().height();*/
|
|
|
|
if (width==720 && height==1280) {
|
|
return value*8;
|
|
}
|
|
|
|
if (width==720 && height==720) {
|
|
return value*8;
|
|
}
|
|
|
|
if (width==768 && height==1280) {
|
|
return value*10;
|
|
}
|
|
|
|
if (width==1440 && height==1440) {
|
|
return value*12;
|
|
}
|
|
|
|
return 8*value;
|
|
}
|
|
|
|
bb::cascades::Color Utils::background()
|
|
{
|
|
bb::cascades::ColorTheme* colorTheme = bb::cascades::Application::instance()->themeSupport()->theme()->colorTheme();
|
|
bool isOled = display.displayTechnology()==bb::device::DisplayTechnology::Oled;
|
|
bool is103 = checkOSVersion(10,3);
|
|
|
|
switch (colorTheme->style()) {
|
|
case bb::cascades::VisualStyle::Bright:
|
|
if (is103)
|
|
return bb::cascades::Color::White;
|
|
if (isOled)
|
|
return bb::cascades::Color::fromARGB(0xfff2f2f2);
|
|
return bb::cascades::Color::fromARGB(0xfff8f8f8);
|
|
break;
|
|
case bb::cascades::VisualStyle::Dark:
|
|
if (is103)
|
|
return bb::cascades::Color::Black;
|
|
return bb::cascades::Color::fromARGB(0xff121212);
|
|
break;
|
|
}
|
|
|
|
return bb::cascades::Color::Black;
|
|
}
|
|
|
|
bb::cascades::Color Utils::plain()
|
|
{
|
|
bb::cascades::ColorTheme* colorTheme = bb::cascades::Application::instance()->themeSupport()->theme()->colorTheme();
|
|
|
|
switch (colorTheme->style()) {
|
|
case bb::cascades::VisualStyle::Bright:
|
|
return bb::cascades::Color::fromARGB(0xfff0f0f0);
|
|
break;
|
|
case bb::cascades::VisualStyle::Dark:
|
|
return bb::cascades::Color::fromARGB(0xff323232);
|
|
break;
|
|
}
|
|
|
|
return bb::cascades::Color::fromARGB(0xff323232);
|
|
}
|
|
|
|
bb::cascades::Color Utils::plainBase()
|
|
{
|
|
bb::cascades::ColorTheme* colorTheme = bb::cascades::Application::instance()->themeSupport()->theme()->colorTheme();
|
|
|
|
switch (colorTheme->style()) {
|
|
case bb::cascades::VisualStyle::Bright:
|
|
return bb::cascades::Color::fromARGB(0xffe6e6e6);
|
|
break;
|
|
case bb::cascades::VisualStyle::Dark:
|
|
return bb::cascades::Color::fromARGB(0xff282828);
|
|
break;
|
|
}
|
|
|
|
return bb::cascades::Color::fromARGB(0xff282828);
|
|
}
|
|
|
|
bb::cascades::Color Utils::text()
|
|
{
|
|
bb::cascades::ColorTheme* colorTheme = bb::cascades::Application::instance()->themeSupport()->theme()->colorTheme();
|
|
|
|
switch (colorTheme->style()) {
|
|
case bb::cascades::VisualStyle::Bright:
|
|
return bb::cascades::Color::fromARGB(0xff323232);
|
|
break;
|
|
case bb::cascades::VisualStyle::Dark:
|
|
return bb::cascades::Color::fromARGB(0xfff0f0f0);
|
|
break;
|
|
}
|
|
|
|
return bb::cascades::Color::fromARGB(0xfff0f0f0);
|
|
}
|
|
|
|
bb::cascades::Color Utils::secondaryText()
|
|
{
|
|
bb::cascades::ColorTheme* colorTheme = bb::cascades::Application::instance()->themeSupport()->theme()->colorTheme();
|
|
|
|
switch (colorTheme->style()) {
|
|
case bb::cascades::VisualStyle::Bright:
|
|
return bb::cascades::Color::fromARGB(0xff646464);
|
|
break;
|
|
case bb::cascades::VisualStyle::Dark:
|
|
return bb::cascades::Color::fromARGB(0xff969696);
|
|
break;
|
|
}
|
|
|
|
return bb::cascades::Color::fromARGB(0xff969696);
|
|
}
|
|
|
|
bb::cascades::Color Utils::primary()
|
|
{
|
|
return bb::cascades::Color::fromARGB(0xff0092cc);
|
|
}
|
|
|
|
bb::cascades::Color Utils::textOnPlain()
|
|
{
|
|
return text();
|
|
}
|
|
|
|
/*float Utils::primaryTextFontSize()
|
|
{
|
|
bb::cascades::TextStyle style = bb::cascades::SystemDefaults::TextStyles::primaryText();
|
|
qDebug() << "primaryText:" << style.fontSize() << bb::cascades::FontSize::Medium;
|
|
return bb::cascades::SystemDefaults::TextStyles::primaryText().fontSizeValue();
|
|
}
|
|
|
|
QString Utils::primaryTextFontFamily()
|
|
{
|
|
return bb::cascades::SystemDefaults::TextStyles::primaryText().fontFamily();
|
|
}
|
|
|
|
float Utils::titleTextFontSize()
|
|
{
|
|
return bb::cascades::SystemDefaults::TextStyles::titleText().fontSizeValue();
|
|
}
|
|
|
|
QString Utils::titleTextFontFamily()
|
|
{
|
|
return bb::cascades::SystemDefaults::TextStyles::titleText().fontFamily();
|
|
}*/
|
|
#endif
|
|
|
|
void Utils::setRootModel()
|
|
{
|
|
TabModel *oldTabModel = tabModel;
|
|
FeedModel *oldFeedModel = feedModel;
|
|
EntryModel *oldEntryModel = entryModel;
|
|
|
|
//qDebug() << "utils tid:" << QThread::currentThreadId();
|
|
|
|
Settings *s = Settings::instance();
|
|
int mode = s->getViewMode();
|
|
|
|
switch (mode) {
|
|
case 0:
|
|
// View mode: Tabs->Feeds->Entries
|
|
tabModel = new TabModel();
|
|
tabModel->init(s->getDashboardInUse());
|
|
#ifdef BB10
|
|
s->qml->setContextProperty("tabModel", tabModel);
|
|
#else
|
|
s->context->setContextProperty("tabModel", tabModel);
|
|
#endif
|
|
if (oldTabModel != nullptr) {
|
|
delete oldTabModel;
|
|
}
|
|
if (feedModel != nullptr) {
|
|
delete feedModel; feedModel = nullptr;
|
|
}
|
|
if (entryModel != nullptr) {
|
|
delete entryModel; entryModel = nullptr;
|
|
}
|
|
break;
|
|
case 1:
|
|
// View mode: Tabs->Entries
|
|
tabModel = new TabModel();
|
|
tabModel->init(s->getDashboardInUse());
|
|
#ifdef BB10
|
|
s->qml->setContextProperty("tabModel", tabModel);
|
|
#else
|
|
s->context->setContextProperty("tabModel", tabModel);
|
|
#endif
|
|
if (oldTabModel != nullptr) {
|
|
delete oldTabModel;
|
|
}
|
|
if (feedModel != nullptr) {
|
|
delete feedModel; feedModel = nullptr;
|
|
}
|
|
if (entryModel != nullptr) {
|
|
delete entryModel; entryModel = nullptr;
|
|
}
|
|
break;
|
|
case 2:
|
|
// View mode: Feeds->Entries
|
|
feedModel = new FeedModel();
|
|
feedModel->init("root");
|
|
#ifdef BB10
|
|
s->qml->setContextProperty("feedModel", feedModel);
|
|
#else
|
|
s->context->setContextProperty("feedModel", feedModel);
|
|
#endif
|
|
if (tabModel != nullptr)
|
|
delete tabModel; tabModel = nullptr;
|
|
if (oldFeedModel != nullptr) {
|
|
delete oldFeedModel;
|
|
}
|
|
if (entryModel != nullptr) {
|
|
delete entryModel; entryModel = nullptr;
|
|
}
|
|
break;
|
|
case 3:
|
|
// View mode: Entries
|
|
case 4:
|
|
// View mode: Saved
|
|
case 5:
|
|
// View mode: Slow
|
|
case 6:
|
|
// View mode: Liked
|
|
case 7:
|
|
// View mode: Broadcast
|
|
entryModel = new EntryModel();
|
|
entryModel->init("root");
|
|
#ifdef BB10
|
|
s->qml->setContextProperty("entryModel", entryModel);
|
|
#else
|
|
s->context->setContextProperty("entryModel", entryModel);
|
|
#endif
|
|
if (tabModel != nullptr)
|
|
delete tabModel; tabModel = nullptr;
|
|
if (feedModel != nullptr) {
|
|
delete feedModel; feedModel = nullptr;
|
|
}
|
|
if (oldEntryModel != nullptr) {
|
|
delete oldEntryModel;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void Utils::setFeedModel(const QString &tabId)
|
|
{
|
|
FeedModel* oldFeedModel = feedModel;
|
|
Settings *s = Settings::instance();
|
|
|
|
feedModel = new FeedModel();
|
|
feedModel->init(tabId);
|
|
|
|
#ifdef BB10
|
|
s->qml->setContextProperty("feedModel", feedModel);
|
|
#else
|
|
s->context->setContextProperty("feedModel", feedModel);
|
|
#endif
|
|
|
|
if (oldFeedModel != nullptr) {
|
|
delete oldFeedModel;
|
|
}
|
|
}
|
|
|
|
void Utils::setEntryModel(const QString &feedId)
|
|
{
|
|
EntryModel* oldEntryModel = entryModel;
|
|
Settings *s = Settings::instance();
|
|
|
|
entryModel = new EntryModel();
|
|
entryModel->initInThread(feedId);
|
|
|
|
#ifdef BB10
|
|
s->qml->setContextProperty("entryModel", entryModel);
|
|
#else
|
|
s->context->setContextProperty("entryModel", entryModel);
|
|
#endif
|
|
|
|
if (oldEntryModel != nullptr) {
|
|
delete oldEntryModel;
|
|
}
|
|
}
|
|
|
|
void Utils::setDashboardModel()
|
|
{
|
|
DashboardModel* oldDashboardModel = dashboardModel;
|
|
Settings *s = Settings::instance();
|
|
|
|
dashboardModel = new DashboardModel();
|
|
dashboardModel->init();
|
|
|
|
#ifdef BB10
|
|
s->qml->setContextProperty("dashboardModel", dashboardModel);
|
|
#else
|
|
s->context->setContextProperty("dashboardModel", dashboardModel);
|
|
#endif
|
|
|
|
if (oldDashboardModel != nullptr)
|
|
delete oldDashboardModel;
|
|
}
|
|
|
|
void Utils::updateModels()
|
|
{
|
|
if (dashboardModel != nullptr)
|
|
dashboardModel->init();
|
|
|
|
if (tabModel != nullptr)
|
|
tabModel->init();
|
|
|
|
if (feedModel != nullptr)
|
|
feedModel->init();
|
|
|
|
if (entryModel != nullptr)
|
|
entryModel->init();
|
|
}
|
|
|
|
Utils::~Utils()
|
|
{
|
|
if (entryModel != nullptr)
|
|
delete entryModel;
|
|
|
|
if (feedModel != nullptr)
|
|
delete feedModel;
|
|
|
|
if (tabModel != nullptr)
|
|
delete tabModel;
|
|
|
|
if (dashboardModel != nullptr)
|
|
delete dashboardModel;
|
|
}
|
|
|
|
QList<QString> Utils::dashboards()
|
|
{
|
|
auto db = DatabaseManager::instance();
|
|
|
|
QList<QString> simpleList;
|
|
QList<DatabaseManager::Dashboard> list = db->readDashboards();
|
|
QList<DatabaseManager::Dashboard>::iterator i = list.begin();
|
|
while (i != list.end()) {
|
|
simpleList.append((*i).title);
|
|
++i;
|
|
}
|
|
return simpleList;
|
|
}
|
|
|
|
QString Utils::defaultDashboardName()
|
|
{
|
|
auto s = Settings::instance();
|
|
auto db = DatabaseManager::instance();
|
|
|
|
DatabaseManager::Dashboard d = db->readDashboard(s->getDashboardInUse());
|
|
return d.title;
|
|
}
|
|
|
|
int Utils::countUnread()
|
|
{
|
|
auto s = Settings::instance();
|
|
auto db = DatabaseManager::instance();
|
|
|
|
return db->countEntriesUnreadByDashboard(s->getDashboardInUse());
|
|
}
|
|
|
|
QString Utils::getHumanFriendlySizeString(int size)
|
|
{
|
|
if (size==0) {
|
|
return tr("empty");
|
|
}
|
|
if (size<1024) {
|
|
return QString("%1 B").arg(size);
|
|
}
|
|
if (size<1048576) {
|
|
return QString("%1 kB").arg(qFloor(size/1024));
|
|
}
|
|
if (size<1073741824) {
|
|
return QString("%1 MB").arg(qFloor(size/1048576));
|
|
}
|
|
return QString("%1 GB").arg(size/1073741824);
|
|
}
|
|
|
|
QString Utils::getHumanFriendlyTimeString(int date)
|
|
{
|
|
QDateTime qdate = QDateTime::fromTime_t(date);
|
|
int secs = qdate.secsTo(QDateTime::currentDateTimeUtc());
|
|
|
|
//qDebug() << ">>>>>>>>date" << date << "QDateTime::fromTime_t(date)" << qdate;
|
|
//qDebug() << "QDateTime::currentDateTimeUtc()" << QDateTime::currentDateTimeUtc();
|
|
//qDebug() << "qdate.secsTo(QDateTime::currentDateTimeUtc())" << secs;
|
|
|
|
if (secs<=-18000) {
|
|
return tr("unknown date");
|
|
}
|
|
if (secs<=0) {
|
|
return tr("just now");
|
|
}
|
|
if (secs<60) {
|
|
return tr("%n second(s) ago", "", secs);
|
|
}
|
|
if (secs<3600) {
|
|
return tr("%n minute(s) ago", "", qFloor(secs/60));
|
|
}
|
|
if (secs<86400) {
|
|
return tr("%n hour(s) ago", "", qFloor(secs/3600));
|
|
}
|
|
|
|
int days = qdate.daysTo(QDateTime::currentDateTimeUtc());
|
|
|
|
if (days<8) {
|
|
return tr("%n day(s) ago", "", days);
|
|
}
|
|
|
|
return qdate.toString("dddd, d MMMM yy");
|
|
}
|
|
|
|
QString Utils::hash(const QString &url)
|
|
{
|
|
return QString(QCryptographicHash::hash(url.toLatin1(), QCryptographicHash::Md5).toHex());
|
|
}
|
|
|
|
// Source: https://github.com/radekp/qtmoko
|
|
int Utils::monthsTo(const QDate &from, const QDate &to)
|
|
{
|
|
int result = 12 * (to.year() - from.year());
|
|
result += (to.month() - from.month());
|
|
|
|
return result;
|
|
}
|
|
|
|
int Utils::yearsTo(const QDate &from, const QDate &to)
|
|
{
|
|
return to.year() - from.year();
|
|
}
|
|
|
|
bool Utils::isSameWeek(const QDate &date1, const QDate &date2)
|
|
{
|
|
int y1, y2;
|
|
int w1 = date1.weekNumber(&y1);
|
|
int w2 = date2.weekNumber(&y2);
|
|
//qDebug() << date1 << date2 << y1 << y2 << w1 << w2;
|
|
if (w1==w2 && y1==y2 && w1!=0 && w2!=0)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
void Utils::resetFetcher(int type)
|
|
{
|
|
Settings *s = Settings::instance();
|
|
|
|
if (s->fetcher != nullptr) {
|
|
s->fetcher->disconnect();
|
|
delete s->fetcher;
|
|
s->fetcher = nullptr;
|
|
}
|
|
|
|
if (type == 1) {
|
|
// Netvibes fetcher
|
|
s->fetcher = new NvFetcher();
|
|
}
|
|
|
|
if (type == 2) {
|
|
// Old Reader fetcher
|
|
s->fetcher = new OldReaderFetcher();
|
|
}
|
|
|
|
if (type == 4) {
|
|
// Tiny Tiny Rss fetcher
|
|
s->fetcher = new TTRssFetcher();
|
|
}
|
|
|
|
if (s->fetcher != nullptr)
|
|
#ifdef BB10
|
|
s->qml->setContextProperty("fetcher", s->fetcher);
|
|
#else
|
|
s->context->setContextProperty("fetcher", s->fetcher);
|
|
#endif
|
|
}
|
|
|
|
QString Utils::nameFromPath(const QString &path)
|
|
{
|
|
return QFileInfo(path).fileName();
|
|
}
|
|
|
|
void Utils::addExtension(const QString &contentType, QString &path)
|
|
{
|
|
auto orig_ext = QFileInfo(path).suffix();
|
|
|
|
QString new_ext;
|
|
if (contentType == "image/jpeg") {
|
|
new_ext = "jpg";
|
|
} else if (contentType == "image/png") {
|
|
new_ext = "png";
|
|
} else if (contentType == "image/gif") {
|
|
new_ext = "gif";
|
|
} else if (contentType == "image/svg+xml") {
|
|
new_ext = "svg";
|
|
} else {
|
|
new_ext = orig_ext;
|
|
}
|
|
|
|
if (new_ext != orig_ext) {
|
|
path.append("." + new_ext);
|
|
}
|
|
}
|