diff --git a/src/core/feedsmodel.cpp b/src/core/feedsmodel.cpp index d564f7193..3a33c75bb 100755 --- a/src/core/feedsmodel.cpp +++ b/src/core/feedsmodel.cpp @@ -28,6 +28,11 @@ #include #include #include +#include +#include +#include +#include + #include @@ -140,8 +145,36 @@ int FeedsModel::rowCount(const QModelIndex &parent) const { } bool FeedsModel::exportToFile(FeedsModel::ExternalFeedsFileType type, QByteArray &result) { - // TODO: POkračovat tady. - return false; + switch (type) { + case OPML20: + return exportToOMPL20(result); + + default: + return false; + } +} + +bool FeedsModel::exportToOMPL20(QByteArray &result) { + QDomDocument opml_document; + QStack items_to_process; items_to_process.push(m_rootItem); + + // Adde OPML 2.0 metadata. + opml_document.appendChild(opml_document.createElement("opml")); + opml_document.documentElement().setAttribute("version", "2.0"); + + QDomElement elem_opml_title = opml_document.createElement("title"); + QDomText text_opml_title = opml_document.createTextNode(QString(APP_NAME) + tr(" feeds")); + elem_opml_title.appendChild(text_opml_title); + opml_document.documentElement().appendChild(elem_opml_title); + + // Process all unprocessed nodes. + /*while (!items_to_process.isEmpty()) { + + }*/ + + + result = opml_document.toByteArray(2); + return true; } bool FeedsModel::removeItem(const QModelIndex &index) { diff --git a/src/core/feedsmodel.h b/src/core/feedsmodel.h index a1cd12dd7..88dd1c1ef 100644 --- a/src/core/feedsmodel.h +++ b/src/core/feedsmodel.h @@ -40,7 +40,7 @@ class FeedsModel : public QAbstractItemModel { public: enum ExternalFeedsFileType { - OMPL20 + OPML20 = 0 }; // Constructors and destructors. @@ -75,6 +75,10 @@ class FeedsModel : public QAbstractItemModel { // Import/export. bool exportToFile(ExternalFeedsFileType type, QByteArray &result); + // Exports to OPML 2.0 + // NOTE: http://dev.opml.org/spec2.html + bool exportToOMPL20(QByteArray &result); + // Removes item with given index. bool removeItem(const QModelIndex &index); diff --git a/src/gui/formmain.cpp b/src/gui/formmain.cpp index 15d9e43e9..7d0a1bf5c 100755 --- a/src/gui/formmain.cpp +++ b/src/gui/formmain.cpp @@ -41,6 +41,8 @@ #include #include #include +#include +#include FormMain::FormMain(QWidget *parent, Qt::WindowFlags f) @@ -368,18 +370,16 @@ void FormMain::saveSize() { void FormMain::createConnections() { // Status bar connections. - connect(m_statusBar->fullscreenSwitcher(), SIGNAL(toggled(bool)), - m_ui->m_actionFullscreen, SLOT(setChecked(bool))); - connect(m_ui->m_actionFullscreen, SIGNAL(toggled(bool)), - m_statusBar->fullscreenSwitcher(), SLOT(setChecked(bool))); + connect(m_statusBar->fullscreenSwitcher(), SIGNAL(toggled(bool)), m_ui->m_actionFullscreen, SLOT(setChecked(bool))); + connect(m_ui->m_actionFullscreen, SIGNAL(toggled(bool)), m_statusBar->fullscreenSwitcher(), SLOT(setChecked(bool))); // Core connections. - connect(qApp, SIGNAL(commitDataRequest(QSessionManager&)), - this, SLOT(onCommitData(QSessionManager&))); - connect(qApp, SIGNAL(saveStateRequest(QSessionManager&)), - this, SLOT(onSaveState(QSessionManager&))); + connect(qApp, SIGNAL(commitDataRequest(QSessionManager&)), this, SLOT(onCommitData(QSessionManager&))); + connect(qApp, SIGNAL(saveStateRequest(QSessionManager&)), this, SLOT(onSaveState(QSessionManager&))); // Menu "File" connections. + connect(m_ui->m_actionExportFeeds, SIGNAL(triggered()), this, SLOT(exportFeeds())); + connect(m_ui->m_actionImportFeeds, SIGNAL(triggered()), this, SLOT(importFeeds())); connect(m_ui->m_actionQuit, SIGNAL(triggered()), this, SLOT(quit())); // Menu "View" connections. @@ -436,6 +436,52 @@ void FormMain::loadWebBrowserMenu(int index) { m_ui->m_actionCloseCurrentTab->setEnabled(m_ui->m_tabWidget->tabBar()->tabType(index) == TabBar::Closable); } +void FormMain::exportFeeds() { + QString filter_opml20 = tr("OPML 2.0 files (*.opml)"); + + QString filter; + QString selected_filter; + + // Add more filters here. + filter += filter_opml20; + + QString selected_file = QFileDialog::getSaveFileName(this, tr("Select file for feeds import"), + QDir::homePath(), filter, &selected_filter); + + + if (!selected_file.isEmpty()) { + bool export_result; + QByteArray result_data; + + if (selected_filter == filter_opml20) { + export_result = tabWidget()->feedMessageViewer()->feedsView()->sourceModel()->exportToFile(FeedsModel::OPML20, + result_data); + } + + if (!export_result) { + qApp->showGuiMessage(tr("Export failed"), + tr("Export of feeds failed, is target file writtable?"), + QSystemTrayIcon::Critical); + } + else { + // Save exported data. + QFile output_file(selected_file); + + if (output_file.open(QIODevice::Unbuffered | QIODevice::Truncate | QIODevice::WriteOnly)) { + QTextStream stream(&output_file); + + stream << result_data; + output_file.flush(); + output_file.close(); + } + } + } +} + +void FormMain::importFeeds() { + +} + void FormMain::changeEvent(QEvent *event) { switch (event->type()) { case QEvent::WindowStateChange: { diff --git a/src/gui/formmain.h b/src/gui/formmain.h index f7aedb673..956c0a6ce 100755 --- a/src/gui/formmain.h +++ b/src/gui/formmain.h @@ -108,6 +108,8 @@ class FormMain : public QMainWindow { void loadWebBrowserMenu(int index); // Displays various dialogs. + void exportFeeds(); + void importFeeds(); void showSettings(); void showAbout(); void showUpdates();