Work on export/import and other magics.
This commit is contained in:
parent
942dcf3adb
commit
3429228d41
23 changed files with 224 additions and 46 deletions
|
@ -384,6 +384,10 @@ set(APP_SOURCES
|
||||||
src/miscellaneous/iofactory.cpp
|
src/miscellaneous/iofactory.cpp
|
||||||
src/miscellaneous/autosaver.cpp
|
src/miscellaneous/autosaver.cpp
|
||||||
|
|
||||||
|
# EXCEPTIONS sources.
|
||||||
|
src/exceptions/applicationexception.cpp
|
||||||
|
src/exceptions/ioexception.cpp
|
||||||
|
|
||||||
# CORE sources.
|
# CORE sources.
|
||||||
src/core/messagesmodel.cpp
|
src/core/messagesmodel.cpp
|
||||||
src/core/messagesproxymodel.cpp
|
src/core/messagesproxymodel.cpp
|
||||||
|
|
|
@ -2,17 +2,17 @@
|
||||||
<opml version="2.0">
|
<opml version="2.0">
|
||||||
<head>
|
<head>
|
||||||
<title>RSS Guard</title>
|
<title>RSS Guard</title>
|
||||||
<dateCreated>Wed, 27 May 2015 16:15:55 GMT</dateCreated>
|
<dateCreated>Fri, 29 May 2015 06:54:31 GMT</dateCreated>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<outline text="Linux" description="Collections of GNU/Linux-related feeds.">
|
<outline description="Collections of GNU/Linux-related feeds." rssguard:icon="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" text="Linux">
|
||||||
<outline xmlUrl="http://feeds.feedburner.com/linuxtoday/linux?format=xml" text="Linux Today" version="RSS" description="Linux Today - Linux News on Internet Time." encoding="UTF-8" title="Linux Today"/>
|
<outline xmlUrl="http://feeds.feedburner.com/linuxtoday/linux?format=xml" description="Linux Today - Linux News on Internet Time." encoding="UTF-8" rssguard:icon="AAAAIgBRAFAAaQB4AG0AYQBwAEkAYwBvAG4ARQBuAGcAaQBuAGUAAAABAAAAAYlQTkcNChoKAAAADUlIRFIAAAAQAAAAEAgCAAAAkJFoNgAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAXpJREFUKJGV0k9LG0EcxvHvjLsbcMH0kB4MBIl7CEEMBHIIvfSYi+/AsxZ8HQEpHj3pW+ilkC54Eikl0EOhBAIrCTGHVEUCLWV3bbK7Mx42iFmkrc9thvnw+8MI9k94SQxAn+z/52vx7lQ+PbfbbSFEs9n8i1kCvV4PKBaL/2gpTRRFw+EQcBwH0EmYTL8k159kftvc3HumwmQyGQwGQKVSAeIfH+8/t+bDY4xVAHQWuK7r+76UslqtAurnt/R+fnkUXrz983U3C/r9PmDbdrlc1nEQ37iAMNeIA/Xru9Z6aQalVAocxykUCjrwVHAFmM5BbvtQJ6EQ5lKFMAxHo1EKLMtSwRVqDsh8DRArq8hlMB6Pp9MpsBjgtwcgrZX8VmatC+B53mw2A1qtFhDfngFCWhhr6BgVZUG60FKpVK/XAT27A3Tsh+dvfHcjmnzIgm63CzQaDdu2gVztvczXhPkKnYAUudePYLGlTqfztFFjfcdY3+G5iJd+7wdysI9hnZlHjQAAAABJRU5ErkJggv////8AAAAQAAAAEAAAAAAAAAAB" title="Linux Today" version="RSS" text="Linux Today"/>
|
||||||
<outline xmlUrl="http://www.linuxinsider.com/perl/syndication/rssfull.pl" text="LinuxInsider" version="RSS" description="LinuxInsider: Linux News & Information from Around the World." encoding="UTF-8" title="LinuxInsider"/>
|
<outline xmlUrl="http://www.linuxinsider.com/perl/syndication/rssfull.pl" description="LinuxInsider: Linux News & Information from Around the World." encoding="UTF-8" rssguard:icon="AAAAIgBRAFAAaQB4AG0AYQBwAEkAYwBvAG4ARQBuAGcAaQBuAGUAAAABAAAAAYlQTkcNChoKAAAADUlIRFIAAAAQAAAAEAgCAAAAkJFoNgAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAFtJREFUKJFjNM8OYiAFsDAwMJyYspZI1RY5wSwQFiMjIwMDw////+FyEBFkAJFlIsk9UCdhBRDzMG0m2YZRDcQAlHiAx+7///+RYxo5Nsi1ATkucYlAbSM1eQMA4PEdCz0mjK8AAAAASUVORK5CYIL/////AAAAEAAAABAAAAAAAAAAAQ==" title="LinuxInsider" version="RSS" text="LinuxInsider"/>
|
||||||
<outline xmlUrl="http://lxer.com/module/newswire/headlines.rss" text="LXer: Linux News" version="RSS1" description="The world is talking about GNU/Linux and Free/Open Source Software." encoding="UTF-8" title="LXer: Linux News"/>
|
<outline xmlUrl="http://lxer.com/module/newswire/headlines.rss" description="The world is talking about GNU/Linux and Free/Open Source Software." encoding="UTF-8" rssguard:icon="AAAAIgBRAFAAaQB4AG0AYQBwAEkAYwBvAG4ARQBuAGcAaQBuAGUAAAABAAAAAYlQTkcNChoKAAAADUlIRFIAAAAQAAAAEAgGAAAAH/P/YQAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAmNJREFUOI2lkt1L03EUxj+//eY0X6DhTOcUwgq1cIPQDDWnMoglWorRlXoV6P+QF4GXlczsooswEEzEMA1SEMWRF3WTOmlKpelyzbc2N5fbmu7bTZN8yYKeq3Nxns95zuHAf0qKFvb3dmF/0U8osE0kIoiNiyOrtJT8sjKpt71dhLd8CCE4laZFX1lJmlYrASijgBXXV9afPCU9+B31jowj6KWzs5OORx3iw737GJaXiQFmJRhuasa16hLaVK2kiAIqTCZpq+k2bZEIO6oI7hglz/1+goEgDqORhDNZtCkU3E1KYt3jwbvp3b9CVBaLRTi6uqiWZbq3twkXFFCpVjMzNIRlxUVjQyM1NTUYjUYJQHEQUF9fz0ZOLouyzM2EBHTeTeTJSR4vOzFfNVNbW7tn/qOmbdPiRlGRGC0uFtaSEnElNVXk6fNEX1+fONh7KAGAQW+Qzl4uZCcjA8JhTicmYtAbqKurOzT5SMD4+LjIV8Vin5vjsyzTkJKCd34eq9X69wROp1NMjY2RPDND28ICDxwOkGWuh8P09vTgWHKIYwGvBl9yccXFw6kp4rRaCs1m+gMBzskyijdvGRkdwePxiCMBHydei/SlRTYdX/CoT1JdVU15WRmq3BxCGg1VsSo+DQ3zbmJiz7PvKK2XCkTMdgCAb0CgopwLuedxdz9D6XGz+6tvITGRW62tmEwmSfk7YOREPKu+LUKhELJS5hoSTc3NUsudFjEwOIDP62M3skuyrKR8be1wAgCbzSb8fj9CCDQaDdnZ2RLA7NyscG+4Cf0IER8fj06nIzMz8/iH+hf9BPHg9ZQiSgntAAAAAElFTkSuQmCC/////wAAABAAAAAQAAAAAAAAAAE=" title="LXer: Linux News" version="RSS1" text="LXer: Linux News"/>
|
||||||
<outline xmlUrl="http://feeds2.feedburner.com/littleatomspodcast" text="Little Atoms" version="RSS" description="A Show About Ideas" encoding="UTF-8" title="Little Atoms"/>
|
<outline xmlUrl="http://feeds2.feedburner.com/littleatomspodcast" description="A Show About Ideas" encoding="UTF-8" rssguard:icon="AAAAIgBRAFAAaQB4AG0AYQBwAEkAYwBvAG4ARQBuAGcAaQBuAGUAAAABAAAAAYlQTkcNChoKAAAADUlIRFIAAAAQAAAAEAgCAAAAkJFoNgAAAAlwSFlzAAAOxAAADsQBlSsOGwAAArpJREFUKJEl0rtK81AAAOBcTkzIaWzMaWxDq1SQUnFxUoqIUHeHTqKTDyD4DD6HUydnJydXL1SxSkWtRKO1KEZy4+Tec/7hf4Fv+ther+f7fhzHpVJJFMVCocBxHKU0yzKe5wVBIIT4vh8EQRRFjuOAOI4BAJqmYYyTJEmSRJIkWZanpqbSNGVZlhAiCAIAgFKaJAmIoojjOAjh9/e3oii1Wk2SJIZhCCGKokiSlGXZf55SGgQB+Pn5qVarAIA0TRVFwRiHYTg9PZ3n+Wg0GgwGHx8fpVJJ1/U0TVVVBTzPAwAkSUqSZH9/fzAYdDqdg4OD2dnZk5OTwWCgqqqu65ZlnZ+fV6tVEMcxIaTb7X5+fs7Pz2ua5nlep9NBCK2trUEIX15eer0eQuj5+bnRaACMcRRFp6enm5ub19fXEMKtra1ms3l4eHh0dNRut23bRggpinJxcbG7u8tvb2/zPF+v1+v1uqqqrVbLcZyNjY1ms0kIeXt7y7KMUur7frvdzrIMUEpd11UUxTRNAMDT0xNCaGFhIY7jlZUVTdMghLIsVyoVjPHd3R2IoohhmDzPTdPc29trNBo3Nzeu6xaLxeFw6LquYRgIoTiObdseDofAdV1K6WQyeXh4uL+/hxCenZ11u92dnZ3JZFKpVEzTNAxjaWnJNM3X11d+dXWVZVmO42ZmZvr9vmVZt7e3rVbLMIzl5WWEUBRFl5eXgiC8v79nWQZYlpVlWZKkcrns+/7j4yOEUNO0QqEQBAHG2PM8x3Ewxl9fXwzDAEqpKIr/tywuLvb7/bm5OY7jEEIAAEIIhLBcLo9GI8/z/v7+AM/zhJAwDBmGqdVqlNLf31/Lso6PjwVBqNfrxWKRYZjxeCyKYhiG/Pr6epIkeZ5HUZSmqSAIV1dXuq4rilKtVlVVtSxrPB5jjG3bliTpH5t5g55F2LrNAAAAAElFTkSuQmCC/////wAAABAAAAAQAAAAAAAAAAE=" title="Little Atoms" version="RSS" text="Little Atoms"/>
|
||||||
</outline>
|
</outline>
|
||||||
<outline text="RSS Guard" description="News and updates on RSS Guard.">
|
<outline description="News and updates on RSS Guard." rssguard:icon="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" text="RSS Guard">
|
||||||
<outline xmlUrl="http://bitbucket.org/skunkos/rssguard/rss" text="Recent Commits" version="RSS" description="Recent commits for RSS Guard project." encoding="UTF-8" title="Recent Commits"/>
|
<outline xmlUrl="http://bitbucket.org/skunkos/rssguard/rss" description="Recent commits for RSS Guard project." encoding="UTF-8" rssguard:icon="AAAAIgBRAFAAaQB4AG0AYQBwAEkAYwBvAG4ARQBuAGcAaQBuAGUAAAABAAAAAYlQTkcNChoKAAAADUlIRFIAAAAQAAAAEAgGAAAAH/P/YQAAAAlwSFlzAAAOxAAADsQBlSsOGwAAApdJREFUOI1lUl1IU3EU//3vrnPD3eXWLMiPTQOHJn3oImahY+mTHwX10EuUDyVRaI8VK6Qekp7SkqBe9CHrYUngKCqTKRTzgwxdiYRtGhqK3oXb0Ll777+H7V6u7sCBwznn9zu/c/5/ApVVtA22s3rOtbW+UCJsblik5BYHAEyWLsrqjWu6vdbfwmbUH+xu6pIxBABqe2nboq+zC5II85GGV4m1hYDJcSbACkgAgMAiOzLx1qm1FDkjMx/OgRC2qPFW+8hl0s0CwPJQj4cK29DkmP6KMf5j8MnZXmTaeOWdL+us3ngyGVsvWB7q8QDoJgBw6OagPx7+VgsAhNGktRGAMKmYSgCl6VAEAOTYKkd+PG5yMQCgMxWsymOoJKZcFECF7ZSLgpKXTcYwABBfnAkqk5XrMDCV13lN5XVeRYlS0iC+OBNUCPafuvh+N9jW7HHmllZ35JZWd9iaPc7dJDKGAYCRFjKhLmq5vJC/hQTCvs5g2NcZ9LeQQBZnCat7ZAwrJxi9cU2MRywAkIzzhQDAlZx4J9eFeKRA3SvHCsEea9UYPzvcACqBiknW3to/Nf3IfQwA7K39U4mVX6y83h5r1ZiyrVrW8QfB+/zs5xvSVtSUGpU+bPr6jI6LmMtOP524W3EvQ4G7j+avjL85ON/fbgYA13PauDr5+jAA7HNcmPZfJT4A0F33vnT30fzhS2QpQ0Hx+YcUVILB5vj0b270j9nu+g4A/Jz/aK69pjAWnqwHYRDy3iYZCgBAa8wLJfil4uh8oJ7V6rERSq3KavWIzgcAANnm/JAas+NxDVbHANGkOJUfqfqBRMPCYHUMqDE7VgCAmhfUHQ19vRZf/lkmJmJmANBkG/icA+WzXHH1s9ErZFjd/x/h2QrkdqsYGwAAAABJRU5ErkJggv////8AAAAQAAAAEAAAAAAAAAAB" title="Recent Commits" version="RSS" text="Recent Commits"/>
|
||||||
</outline>
|
</outline>
|
||||||
</body>
|
</body>
|
||||||
</opml>
|
</opml>
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
<center><h2>2.4.0</h2></center>
|
<center><h2>2.4.0</h2></center>
|
||||||
Added:
|
Added:
|
||||||
<ul>
|
<ul>
|
||||||
|
<li>RSS Guard is now able to export/import feed/category icons to/from OPML 2.0 files.</li>
|
||||||
|
<li>Localizations now load their titles for localization list automatically.</li>
|
||||||
|
<li>All feeds are by default checked when exporting/importing them.</li>
|
||||||
<li>Message previewer now displays MIME type of all podcasts too. This MIME type is also stored in DB.</li>
|
<li>Message previewer now displays MIME type of all podcasts too. This MIME type is also stored in DB.</li>
|
||||||
<li>Ability to fetch only new icon for feed from its online source.</li>
|
<li>Ability to fetch only new icon for feed from its online source.</li>
|
||||||
<li>Option to search highlighted text in web browser via Google, available from context menu. (issue #72)</li>
|
<li>Option to search highlighted text in web browser via Google, available from context menu. (issue #72)</li>
|
||||||
|
@ -9,6 +12,7 @@ Added:
|
||||||
|
|
||||||
Fixed:
|
Fixed:
|
||||||
<ul>
|
<ul>
|
||||||
|
<li>Reworked DB initialization scripts.</li>
|
||||||
<li>Titles and descriptions of feeds are now fetched correctly in feed add/edit dialog.</li>
|
<li>Titles and descriptions of feeds are now fetched correctly in feed add/edit dialog.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
|
@ -103,6 +103,7 @@ bool FeedsImportExportModel::exportToOMPL20(QByteArray &result) {
|
||||||
QDomElement outline_category = opml_document.createElement("outline");
|
QDomElement outline_category = opml_document.createElement("outline");
|
||||||
outline_category.setAttribute("text", child_item->title());
|
outline_category.setAttribute("text", child_item->title());
|
||||||
outline_category.setAttribute("description", child_item->description());
|
outline_category.setAttribute("description", child_item->description());
|
||||||
|
outline_category.setAttribute("rssguard:icon", QString(qApp->icons()->toByteArray(child_item->icon())));
|
||||||
active_element.appendChild(outline_category);
|
active_element.appendChild(outline_category);
|
||||||
items_to_process.push(child_item);
|
items_to_process.push(child_item);
|
||||||
elements_to_use.push(outline_category);
|
elements_to_use.push(outline_category);
|
||||||
|
@ -117,6 +118,7 @@ bool FeedsImportExportModel::exportToOMPL20(QByteArray &result) {
|
||||||
outline_feed.setAttribute("description", child_feed->description());
|
outline_feed.setAttribute("description", child_feed->description());
|
||||||
outline_feed.setAttribute("encoding", child_feed->encoding());
|
outline_feed.setAttribute("encoding", child_feed->encoding());
|
||||||
outline_feed.setAttribute("title", child_feed->title());
|
outline_feed.setAttribute("title", child_feed->title());
|
||||||
|
outline_feed.setAttribute("rssguard:icon", QString(qApp->icons()->toByteArray(child_feed->icon())));
|
||||||
|
|
||||||
switch (child_feed->type()) {
|
switch (child_feed->type()) {
|
||||||
case FeedsModelFeed::Rss0X:
|
case FeedsModelFeed::Rss0X:
|
||||||
|
@ -188,6 +190,7 @@ bool FeedsImportExportModel::importAsOPML20(const QByteArray &data) {
|
||||||
QString feed_encoding = child_element.attribute("encoding", DEFAULT_FEED_ENCODING);
|
QString feed_encoding = child_element.attribute("encoding", DEFAULT_FEED_ENCODING);
|
||||||
QString feed_type = child_element.attribute("version", DEFAULT_FEED_TYPE).toUpper();
|
QString feed_type = child_element.attribute("version", DEFAULT_FEED_TYPE).toUpper();
|
||||||
QString feed_description = child_element.attribute("description");
|
QString feed_description = child_element.attribute("description");
|
||||||
|
QIcon feed_icon = qApp->icons()->fromByteArray(child_element.attribute("rssguard:icon").toLocal8Bit());
|
||||||
|
|
||||||
FeedsModelFeed *new_feed = new FeedsModelFeed(active_model_item);
|
FeedsModelFeed *new_feed = new FeedsModelFeed(active_model_item);
|
||||||
new_feed->setTitle(feed_title);
|
new_feed->setTitle(feed_title);
|
||||||
|
@ -195,7 +198,7 @@ bool FeedsImportExportModel::importAsOPML20(const QByteArray &data) {
|
||||||
new_feed->setEncoding(feed_encoding);
|
new_feed->setEncoding(feed_encoding);
|
||||||
new_feed->setUrl(feed_url);
|
new_feed->setUrl(feed_url);
|
||||||
new_feed->setCreationDate(QDateTime::currentDateTime());
|
new_feed->setCreationDate(QDateTime::currentDateTime());
|
||||||
new_feed->setIcon(qApp->icons()->fromTheme("folder-feed"));
|
new_feed->setIcon(feed_icon.isNull() ? qApp->icons()->fromTheme("folder-feed") : feed_icon);
|
||||||
new_feed->setAutoUpdateType(FeedsModelFeed::DefaultAutoUpdate);
|
new_feed->setAutoUpdateType(FeedsModelFeed::DefaultAutoUpdate);
|
||||||
|
|
||||||
if (feed_type == "RSS1") {
|
if (feed_type == "RSS1") {
|
||||||
|
@ -215,6 +218,7 @@ bool FeedsImportExportModel::importAsOPML20(const QByteArray &data) {
|
||||||
// Add category and continue.
|
// Add category and continue.
|
||||||
QString category_title = child_element.attribute("text");
|
QString category_title = child_element.attribute("text");
|
||||||
QString category_description = child_element.attribute("description");
|
QString category_description = child_element.attribute("description");
|
||||||
|
QIcon category_icon = qApp->icons()->fromByteArray(child_element.attribute("rssguard:icon").toLocal8Bit());
|
||||||
|
|
||||||
if (category_title.isEmpty()) {
|
if (category_title.isEmpty()) {
|
||||||
qWarning("Given OMPL file provided category without valid text attribute. Using fallback name.");
|
qWarning("Given OMPL file provided category without valid text attribute. Using fallback name.");
|
||||||
|
@ -228,7 +232,7 @@ bool FeedsImportExportModel::importAsOPML20(const QByteArray &data) {
|
||||||
|
|
||||||
FeedsModelCategory *new_category = new FeedsModelCategory(active_model_item);
|
FeedsModelCategory *new_category = new FeedsModelCategory(active_model_item);
|
||||||
new_category->setTitle(category_title);
|
new_category->setTitle(category_title);
|
||||||
new_category->setIcon(qApp->icons()->fromTheme("folder-category"));
|
new_category->setIcon(category_icon.isNull() ? qApp->icons()->fromTheme("folder-category") : category_icon);
|
||||||
new_category->setCreationDate(QDateTime::currentDateTime());
|
new_category->setCreationDate(QDateTime::currentDateTime());
|
||||||
new_category->setDescription(category_description);
|
new_category->setDescription(category_description);
|
||||||
|
|
||||||
|
@ -260,15 +264,19 @@ void FeedsImportExportModel::setMode(const FeedsImportExportModel::Mode &mode) {
|
||||||
|
|
||||||
void FeedsImportExportModel::checkAllItems() {
|
void FeedsImportExportModel::checkAllItems() {
|
||||||
foreach (FeedsModelRootItem *root_child, m_rootItem->childItems()) {
|
foreach (FeedsModelRootItem *root_child, m_rootItem->childItems()) {
|
||||||
|
if (root_child->kind() != FeedsModelRootItem::RecycleBin) {
|
||||||
setData(indexForItem(root_child), Qt::Checked, Qt::CheckStateRole);
|
setData(indexForItem(root_child), Qt::Checked, Qt::CheckStateRole);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void FeedsImportExportModel::uncheckAllItems() {
|
void FeedsImportExportModel::uncheckAllItems() {
|
||||||
foreach (FeedsModelRootItem *root_child, m_rootItem->childItems()) {
|
foreach (FeedsModelRootItem *root_child, m_rootItem->childItems()) {
|
||||||
|
if (root_child->kind() != FeedsModelRootItem::RecycleBin) {
|
||||||
setData(indexForItem(root_child), Qt::Unchecked, Qt::CheckStateRole);
|
setData(indexForItem(root_child), Qt::Unchecked, Qt::CheckStateRole);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QModelIndex FeedsImportExportModel::index(int row, int column, const QModelIndex &parent) const {
|
QModelIndex FeedsImportExportModel::index(int row, int column, const QModelIndex &parent) const {
|
||||||
if (!hasIndex(row, column, parent)) {
|
if (!hasIndex(row, column, parent)) {
|
||||||
|
@ -373,6 +381,17 @@ QVariant FeedsImportExportModel::data(const QModelIndex &index, int role) const
|
||||||
return static_cast<int>(Qt::Unchecked);
|
return static_cast<int>(Qt::Unchecked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (role == Qt::DecorationRole) {
|
||||||
|
switch (item->kind()) {
|
||||||
|
case FeedsModelRootItem::Category:
|
||||||
|
case FeedsModelRootItem::RecycleBin:
|
||||||
|
case FeedsModelRootItem::Feed:
|
||||||
|
return item->icon();
|
||||||
|
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (role == Qt::DisplayRole) {
|
else if (role == Qt::DisplayRole) {
|
||||||
switch (item->kind()) {
|
switch (item->kind()) {
|
||||||
case FeedsModelRootItem::Category:
|
case FeedsModelRootItem::Category:
|
||||||
|
|
|
@ -644,7 +644,7 @@ bool FeedsModel::mergeModel(FeedsImportExportModel *model, QString &output_messa
|
||||||
bool some_feed_category_error = false;
|
bool some_feed_category_error = false;
|
||||||
|
|
||||||
// We are definitely about to add some new items into the model.
|
// We are definitely about to add some new items into the model.
|
||||||
emit layoutAboutToBeChanged();
|
//emit layoutAboutToBeChanged();
|
||||||
|
|
||||||
// Iterate all new items we would like to merge into current model.
|
// Iterate all new items we would like to merge into current model.
|
||||||
while (!new_parents.isEmpty()) {
|
while (!new_parents.isEmpty()) {
|
||||||
|
@ -698,7 +698,7 @@ bool FeedsModel::mergeModel(FeedsImportExportModel *model, QString &output_messa
|
||||||
}
|
}
|
||||||
|
|
||||||
// Changes are done now. Finalize the new model.
|
// Changes are done now. Finalize the new model.
|
||||||
emit layoutChanged();
|
//emit layoutChanged();
|
||||||
|
|
||||||
if (some_feed_category_error) {
|
if (some_feed_category_error) {
|
||||||
output_message = tr("Import successfull, but some feeds/categories were not imported due to error.");
|
output_message = tr("Import successfull, but some feeds/categories were not imported due to error.");
|
||||||
|
|
|
@ -83,6 +83,8 @@
|
||||||
#define DOWNLOADER_ICON_SIZE 48
|
#define DOWNLOADER_ICON_SIZE 48
|
||||||
#define GOOGLE_SEARCH_URL "https://www.google.com/search?q=%1&ie=utf-8&oe=utf-8"
|
#define GOOGLE_SEARCH_URL "https://www.google.com/search?q=%1&ie=utf-8&oe=utf-8"
|
||||||
|
|
||||||
|
#define FEED_INITIAL_OPML_PATTERN "feeds-%1.opml"
|
||||||
|
|
||||||
#define FEED_REGEX_MATCHER "<link[^>]+type=\\\"application/(atom|rss)\\+xml\\\"[^>]*>"
|
#define FEED_REGEX_MATCHER "<link[^>]+type=\\\"application/(atom|rss)\\+xml\\\"[^>]*>"
|
||||||
#define FEED_HREF_REGEX_MATCHER "href\\=\\\"[^\\\"]+\\\""
|
#define FEED_HREF_REGEX_MATCHER "href\\=\\\"[^\\\"]+\\\""
|
||||||
|
|
||||||
|
|
29
src/exceptions/applicationexception.cpp
Normal file
29
src/exceptions/applicationexception.cpp
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
// This file is part of RSS Guard.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2011-2015 by Martin Rotter <rotter.martinos@gmail.com>
|
||||||
|
//
|
||||||
|
// RSS Guard 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.
|
||||||
|
//
|
||||||
|
// RSS Guard 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 RSS Guard. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "exceptions/applicationexception.h"
|
||||||
|
|
||||||
|
|
||||||
|
ApplicationException::ApplicationException(const QString &message) : m_message(message) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ApplicationException::~ApplicationException() {
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ApplicationException::message() const {
|
||||||
|
return m_message;
|
||||||
|
}
|
35
src/exceptions/applicationexception.h
Normal file
35
src/exceptions/applicationexception.h
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
// This file is part of RSS Guard.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2011-2015 by Martin Rotter <rotter.martinos@gmail.com>
|
||||||
|
//
|
||||||
|
// RSS Guard 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.
|
||||||
|
//
|
||||||
|
// RSS Guard 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 RSS Guard. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef APPLICATIONEXCEPTION_H
|
||||||
|
#define APPLICATIONEXCEPTION_H
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
|
||||||
|
class ApplicationException {
|
||||||
|
public:
|
||||||
|
explicit ApplicationException(const QString &message = QString());
|
||||||
|
virtual ~ApplicationException();
|
||||||
|
|
||||||
|
QString message() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_message;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // APPLICATIONEXCEPTION_H
|
25
src/exceptions/ioexception.cpp
Normal file
25
src/exceptions/ioexception.cpp
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
// This file is part of RSS Guard.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2011-2015 by Martin Rotter <rotter.martinos@gmail.com>
|
||||||
|
//
|
||||||
|
// RSS Guard 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.
|
||||||
|
//
|
||||||
|
// RSS Guard 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 RSS Guard. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "exceptions/ioexception.h"
|
||||||
|
|
||||||
|
|
||||||
|
IOException::IOException(const QString &message) : ApplicationException(message) {
|
||||||
|
}
|
||||||
|
|
||||||
|
IOException::~IOException() {
|
||||||
|
}
|
14
src/exceptions/ioexception.h
Normal file
14
src/exceptions/ioexception.h
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#ifndef IOEXCEPTION_H
|
||||||
|
#define IOEXCEPTION_H
|
||||||
|
|
||||||
|
#include "exceptions/applicationexception.h"
|
||||||
|
|
||||||
|
|
||||||
|
class IOException : public ApplicationException
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit IOException(const QString &message = QString());
|
||||||
|
virtual ~IOException();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // IOEXCEPTION_H
|
|
@ -25,6 +25,7 @@
|
||||||
#include "core/feeddownloader.h"
|
#include "core/feeddownloader.h"
|
||||||
#include "core/feedsmodelfeed.h"
|
#include "core/feedsmodelfeed.h"
|
||||||
#include "core/feedsselection.h"
|
#include "core/feedsselection.h"
|
||||||
|
#include "core/feedsimportexportmodel.h"
|
||||||
#include "network-web/webbrowser.h"
|
#include "network-web/webbrowser.h"
|
||||||
#include "gui/formmain.h"
|
#include "gui/formmain.h"
|
||||||
#include "gui/messagesview.h"
|
#include "gui/messagesview.h"
|
||||||
|
@ -34,6 +35,7 @@
|
||||||
#include "gui/messagebox.h"
|
#include "gui/messagebox.h"
|
||||||
#include "gui/messagestoolbar.h"
|
#include "gui/messagestoolbar.h"
|
||||||
#include "gui/feedstoolbar.h"
|
#include "gui/feedstoolbar.h"
|
||||||
|
#include <exceptions/applicationexception.h>
|
||||||
|
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
#include <QSplitter>
|
#include <QSplitter>
|
||||||
|
@ -134,6 +136,34 @@ void FeedMessageViewer::quit() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FeedMessageViewer::loadInitialFeeds() {
|
||||||
|
QString target_opml_file = APP_INITIAL_FEEDS_PATH + QDir::separator() + FEED_INITIAL_OPML_PATTERN;
|
||||||
|
QString current_locale = qApp->localization()->loadedLanguage();
|
||||||
|
QString file_to_load;
|
||||||
|
|
||||||
|
if (QFile::exists(target_opml_file.arg(current_locale))) {
|
||||||
|
file_to_load = target_opml_file.arg(current_locale);
|
||||||
|
}
|
||||||
|
else if (QFile::exists(target_opml_file.arg(DEFAULT_LOCALE))) {
|
||||||
|
file_to_load = target_opml_file.arg(DEFAULT_LOCALE);
|
||||||
|
}
|
||||||
|
|
||||||
|
FeedsImportExportModel model;
|
||||||
|
QString output_msg;
|
||||||
|
|
||||||
|
try {
|
||||||
|
model.importAsOPML20(IOFactory::readTextFile(file_to_load));
|
||||||
|
model.checkAllItems();
|
||||||
|
|
||||||
|
if (m_feedsView->sourceModel()->mergeModel(&model, output_msg)) {
|
||||||
|
m_feedsView->expandAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ApplicationException &ex) {
|
||||||
|
MessageBox::show(this, QMessageBox::Critical, tr("Error when loading initial feeds"), ex.message());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void FeedMessageViewer::switchMessageSplitterOrientation() {
|
void FeedMessageViewer::switchMessageSplitterOrientation() {
|
||||||
if (m_messageSplitter->orientation() == Qt::Vertical) {
|
if (m_messageSplitter->orientation() == Qt::Vertical) {
|
||||||
m_messageSplitter->setOrientation(Qt::Horizontal);
|
m_messageSplitter->setOrientation(Qt::Horizontal);
|
||||||
|
|
|
@ -83,6 +83,9 @@ class FeedMessageViewer : public TabContent {
|
||||||
}
|
}
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
void loadInitialFeeds();
|
||||||
|
|
||||||
|
// Switches orientation horizontal/vertical.
|
||||||
void switchMessageSplitterOrientation();
|
void switchMessageSplitterOrientation();
|
||||||
|
|
||||||
// Enables/disables main toolbars or list headers.
|
// Enables/disables main toolbars or list headers.
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include "miscellaneous/application.h"
|
#include "miscellaneous/application.h"
|
||||||
#include "miscellaneous/iconfactory.h"
|
#include "miscellaneous/iconfactory.h"
|
||||||
|
#include "exceptions/applicationexception.h"
|
||||||
|
|
||||||
#include <QDialogButtonBox>
|
#include <QDialogButtonBox>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
|
|
|
@ -54,12 +54,13 @@ void FormImportExport::setMode(const FeedsImportExportModel::Mode &mode) {
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case FeedsImportExportModel::Export: {
|
case FeedsImportExportModel::Export: {
|
||||||
m_model->setRootItem(qApp->mainForm()->tabWidget()->feedMessageViewer()->feedsView()->sourceModel()->rootItem());
|
m_model->setRootItem(qApp->mainForm()->tabWidget()->feedMessageViewer()->feedsView()->sourceModel()->rootItem());
|
||||||
|
m_model->checkAllItems();
|
||||||
m_ui->m_treeFeeds->setModel(m_model);
|
m_ui->m_treeFeeds->setModel(m_model);
|
||||||
m_ui->m_treeFeeds->expandAll();
|
m_ui->m_treeFeeds->expandAll();
|
||||||
setWindowTitle(tr("Export feeds"));
|
|
||||||
setWindowIcon(qApp->icons()->fromTheme("document-export"));
|
|
||||||
m_ui->m_groupFile->setTitle(tr("Destination file"));
|
m_ui->m_groupFile->setTitle(tr("Destination file"));
|
||||||
m_ui->m_groupFeeds->setTitle(tr("Source feeds && categories"));
|
m_ui->m_groupFeeds->setTitle(tr("Source feeds && categories"));
|
||||||
|
setWindowTitle(tr("Export feeds"));
|
||||||
|
setWindowIcon(qApp->icons()->fromTheme("document-export"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,6 +144,7 @@ void FormImportExport::selectImportFile() {
|
||||||
|
|
||||||
m_ui->m_lblSelectFile->setStatus(WidgetWithStatus::Ok, QDir::toNativeSeparators(selected_file), tr("File is selected."));
|
m_ui->m_lblSelectFile->setStatus(WidgetWithStatus::Ok, QDir::toNativeSeparators(selected_file), tr("File is selected."));
|
||||||
parseImportFile(selected_file);
|
parseImportFile(selected_file);
|
||||||
|
m_model->checkAllItems();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "gui/messagebox.h"
|
#include "gui/messagebox.h"
|
||||||
#include "gui/formmain.h"
|
#include "gui/formmain.h"
|
||||||
#include "miscellaneous/iconfactory.h"
|
#include "miscellaneous/iconfactory.h"
|
||||||
|
#include "exceptions/applicationexception.h"
|
||||||
|
|
||||||
#include "QFileDialog"
|
#include "QFileDialog"
|
||||||
|
|
||||||
|
|
|
@ -75,8 +75,7 @@ FormSettings::FormSettings(QWidget *parent) : QDialog(parent), m_ui(new Ui::Form
|
||||||
<< /*: Language column of language list. */ tr("Language")
|
<< /*: Language column of language list. */ tr("Language")
|
||||||
<< /*: Lang. code column of language list. */ tr("Code")
|
<< /*: Lang. code column of language list. */ tr("Code")
|
||||||
<< tr("Version")
|
<< tr("Version")
|
||||||
<< tr("Author")
|
<< tr("Author"));
|
||||||
<< tr("Email"));
|
|
||||||
|
|
||||||
m_ui->m_treeSkins->setColumnCount(4);
|
m_ui->m_treeSkins->setColumnCount(4);
|
||||||
m_ui->m_treeSkins->setHeaderHidden(false);
|
m_ui->m_treeSkins->setHeaderHidden(false);
|
||||||
|
@ -468,7 +467,6 @@ void FormSettings::loadLanguage() {
|
||||||
item->setText(1, language.m_code);
|
item->setText(1, language.m_code);
|
||||||
item->setText(2, language.m_version);
|
item->setText(2, language.m_version);
|
||||||
item->setText(3, language.m_author);
|
item->setText(3, language.m_author);
|
||||||
item->setText(4, language.m_email);
|
|
||||||
item->setIcon(0, qApp->icons()->fromTheme(QString(FLAG_ICON_SUBFOLDER) + QDir::separator() + language.m_code));
|
item->setIcon(0, qApp->icons()->fromTheme(QString(FLAG_ICON_SUBFOLDER) + QDir::separator() + language.m_code));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,7 @@
|
||||||
<item row="0" column="1">
|
<item row="0" column="1">
|
||||||
<widget class="QStackedWidget" name="m_stackedSettings">
|
<widget class="QStackedWidget" name="m_stackedSettings">
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>5</number>
|
<number>4</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="m_pageGeneral">
|
<widget class="QWidget" name="m_pageGeneral">
|
||||||
<layout class="QFormLayout" name="formLayout_5">
|
<layout class="QFormLayout" name="formLayout_5">
|
||||||
|
|
17
src/main.cpp
17
src/main.cpp
|
@ -24,6 +24,7 @@
|
||||||
#include "gui/formmain.h"
|
#include "gui/formmain.h"
|
||||||
#include "gui/feedmessageviewer.h"
|
#include "gui/feedmessageviewer.h"
|
||||||
#include "gui/feedsview.h"
|
#include "gui/feedsview.h"
|
||||||
|
#include "gui/messagebox.h"
|
||||||
#include "network-web/silentnetworkaccessmanager.h"
|
#include "network-web/silentnetworkaccessmanager.h"
|
||||||
|
|
||||||
// Needed for setting ini file format on Mac OS.
|
// Needed for setting ini file format on Mac OS.
|
||||||
|
@ -38,8 +39,6 @@
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
//: Name of language, e.g. English.
|
|
||||||
QObject::tr("LANG_NAME");
|
|
||||||
//: Abbreviation of language, e.g. en.
|
//: Abbreviation of language, e.g. en.
|
||||||
//: Use ISO 639-1 code here combined with ISO 3166-1 (alpha-2) code.
|
//: Use ISO 639-1 code here combined with ISO 3166-1 (alpha-2) code.
|
||||||
//: Examples: "cs_CZ", "en_GB", "en_US".
|
//: Examples: "cs_CZ", "en_GB", "en_US".
|
||||||
|
@ -48,8 +47,6 @@ int main(int argc, char *argv[]) {
|
||||||
QObject::tr("LANG_VERSION");
|
QObject::tr("LANG_VERSION");
|
||||||
//: Name of translator - optional.
|
//: Name of translator - optional.
|
||||||
QObject::tr("LANG_AUTHOR");
|
QObject::tr("LANG_AUTHOR");
|
||||||
//: Email of translator - optional.
|
|
||||||
QObject::tr("LANG_EMAIL");
|
|
||||||
|
|
||||||
// Ensure that ini format is used as application settings storage on Mac OS.
|
// Ensure that ini format is used as application settings storage on Mac OS.
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
|
@ -108,6 +105,18 @@ int main(int argc, char *argv[]) {
|
||||||
else {
|
else {
|
||||||
qDebug("Showing the main window when the application is starting.");
|
qDebug("Showing the main window when the application is starting.");
|
||||||
main_window.show();
|
main_window.show();
|
||||||
|
|
||||||
|
if (qApp->settings()->value(GROUP(General), SETTING(General::FirstRun)).toBool()) {
|
||||||
|
// This is the first time user runs this application.
|
||||||
|
qApp->settings()->setValue(GROUP(General), General::FirstRun, false);
|
||||||
|
|
||||||
|
if (MessageBox::show(&main_window, QMessageBox::Question, QObject::tr("Load initial feeds"),
|
||||||
|
QObject::tr("Your started %1 for the first time, now you can load initial set of feeds.").arg(APP_NAME),
|
||||||
|
QObject::tr("Do you want to load initial set of feeds?"),
|
||||||
|
QString(), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
|
||||||
|
qApp->mainForm()->tabWidget()->feedMessageViewer()->loadInitialFeeds();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display tray icon if it is enabled and available.
|
// Display tray icon if it is enabled and available.
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "gui/messagebox.h"
|
#include "gui/messagebox.h"
|
||||||
#include "gui/formmain.h"
|
#include "gui/formmain.h"
|
||||||
#include "gui/statusbar.h"
|
#include "gui/statusbar.h"
|
||||||
|
#include "exceptions/applicationexception.h"
|
||||||
|
|
||||||
#include <QSessionManager>
|
#include <QSessionManager>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
@ -242,13 +243,3 @@ void Application::restart() {
|
||||||
m_shouldRestart = true;
|
m_shouldRestart = true;
|
||||||
quit();
|
quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplicationException::ApplicationException(const QString &message) : m_message(message) {
|
|
||||||
}
|
|
||||||
|
|
||||||
ApplicationException::~ApplicationException() {
|
|
||||||
}
|
|
||||||
|
|
||||||
QString ApplicationException::message() const {
|
|
||||||
return m_message;
|
|
||||||
}
|
|
||||||
|
|
|
@ -45,17 +45,6 @@ class FormMain;
|
||||||
class IconFactory;
|
class IconFactory;
|
||||||
class QAction;
|
class QAction;
|
||||||
|
|
||||||
class ApplicationException {
|
|
||||||
public:
|
|
||||||
explicit ApplicationException(const QString &message = QString());
|
|
||||||
virtual ~ApplicationException();
|
|
||||||
|
|
||||||
QString message() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
QString m_message;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Application : public QtSingleApplication {
|
class Application : public QtSingleApplication {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
|
|
@ -17,9 +17,12 @@
|
||||||
|
|
||||||
#include "miscellaneous/iofactory.h"
|
#include "miscellaneous/iofactory.h"
|
||||||
|
|
||||||
|
#include <exceptions/ioexception.h>
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
|
||||||
IOFactory::IOFactory() {
|
IOFactory::IOFactory() {
|
||||||
|
@ -33,6 +36,20 @@ QString IOFactory::getSystemFolder(SYSTEM_FOLDER_ENUM::StandardLocation location
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QByteArray IOFactory::readTextFile(const QString &file_path) {
|
||||||
|
QFile input_file(file_path);
|
||||||
|
QByteArray input_data;
|
||||||
|
|
||||||
|
if (input_file.open(QIODevice::Text | QIODevice::Unbuffered | QIODevice::ReadOnly)) {
|
||||||
|
input_data = input_file.readAll();
|
||||||
|
input_file.close();
|
||||||
|
return input_data;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw IOException(tr("Cannot open file '%s' for reading.").arg(QDir::toNativeSeparators(file_path)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool IOFactory::copyFile(const QString &source, const QString &destination) {
|
bool IOFactory::copyFile(const QString &source, const QString &destination) {
|
||||||
if (QFile::exists(destination)) {
|
if (QFile::exists(destination)) {
|
||||||
if (!QFile::remove(destination)) {
|
if (!QFile::remove(destination)) {
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#define IOFACTORY_H
|
#define IOFACTORY_H
|
||||||
|
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
#include <QCoreApplication>
|
||||||
|
|
||||||
#if QT_VERSION >= 0x050000
|
#if QT_VERSION >= 0x050000
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
|
@ -30,6 +31,8 @@
|
||||||
|
|
||||||
|
|
||||||
class IOFactory {
|
class IOFactory {
|
||||||
|
Q_DECLARE_TR_FUNCTIONS(IOFactory)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IOFactory();
|
IOFactory();
|
||||||
|
|
||||||
|
@ -37,6 +40,8 @@ class IOFactory {
|
||||||
// Returns system-wide folder according to type.
|
// Returns system-wide folder according to type.
|
||||||
static QString getSystemFolder(SYSTEM_FOLDER_ENUM::StandardLocation location);
|
static QString getSystemFolder(SYSTEM_FOLDER_ENUM::StandardLocation location);
|
||||||
|
|
||||||
|
static QByteArray readTextFile(const QString &file_path);
|
||||||
|
|
||||||
// Copies file, overwrites destination.
|
// Copies file, overwrites destination.
|
||||||
static bool copyFile(const QString &source, const QString &destination);
|
static bool copyFile(const QString &source, const QString &destination);
|
||||||
|
|
||||||
|
|
|
@ -74,11 +74,11 @@ QList<Language> Localization::installedLanguages() {
|
||||||
QDir::Name)) {
|
QDir::Name)) {
|
||||||
if (translator.load(file.absoluteFilePath())) {
|
if (translator.load(file.absoluteFilePath())) {
|
||||||
Language new_language;
|
Language new_language;
|
||||||
new_language.m_name = translator.translate("QObject", "LANG_NAME");
|
|
||||||
new_language.m_code = translator.translate("QObject", "LANG_ABBREV");
|
new_language.m_code = translator.translate("QObject", "LANG_ABBREV");
|
||||||
new_language.m_version = translator.translate("QObject", "LANG_VERSION");
|
new_language.m_version = translator.translate("QObject", "LANG_VERSION");
|
||||||
new_language.m_author = translator.translate("QObject", "LANG_AUTHOR");
|
new_language.m_author = translator.translate("QObject", "LANG_AUTHOR");
|
||||||
new_language.m_email = translator.translate("QObject", "LANG_EMAIL");
|
new_language.m_email = translator.translate("QObject", "LANG_EMAIL");
|
||||||
|
new_language.m_name = QLocale(new_language.m_code).nativeLanguageName();
|
||||||
|
|
||||||
languages << new_language;
|
languages << new_language;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue