Simplification of add/edit feed boxes.

This commit is contained in:
Martin Rotter 2016-05-09 09:38:16 +02:00
parent 0683068352
commit db59f4b1e7
23 changed files with 825 additions and 1514 deletions

View File

@ -282,6 +282,7 @@ file( GLOB APP_SOURCES_GL
"src/miscellaneous/simplecrypt/*.cpp"
"src/exceptions/*.cpp"
"src/core/*.cpp"
"src/services/abstract/gui/*.cpp"
"src/services/abstract/*.cpp"
"src/services/standard/*.cpp"
"src/services/standard/gui/*.cpp"
@ -313,6 +314,7 @@ file( GLOB APP_HEADERS
"src/miscellaneous/*.h"
"src/miscellaneous/simplecrypt/*.h"
"src/core/*.h"
"src/services/abstract/gui/*.h"
"src/services/abstract/*.h"
"src/services/standard/*.h"
"src/services/standard/gui/*.h"
@ -328,6 +330,7 @@ file( GLOB APP_HEADERS
file( GLOB APP_FORMS
"src/gui/dialogs/*.ui"
"src/gui/*.ui"
"src/services/abstract/gui/*.ui"
"src/services/standard/gui/*.ui"
"src/services/tt-rss/gui/*.ui"
"src/services/owncloud/gui/*.ui"

View File

@ -32,7 +32,6 @@
#include "services/standard/standardcategory.h"
#include "services/standard/standardfeed.h"
#include "services/standard/gui/formstandardcategorydetails.h"
#include "services/standard/gui/formstandardfeeddetails.h"
#include <QMenu>
#include <QHeaderView>

View File

@ -0,0 +1,426 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2016 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 "services/abstract/gui/formfeeddetails.h"
#include "definitions/definitions.h"
#include "core/feedsmodel.h"
#include "services/abstract/rootitem.h"
#include "services/abstract/category.h"
#include "services/standard/standardserviceroot.h"
#include "services/standard/standardfeed.h"
#include "miscellaneous/textfactory.h"
#include "miscellaneous/iconfactory.h"
#include "network-web/networkfactory.h"
#include "gui/baselineedit.h"
#include "gui/messagebox.h"
#include "gui/systemtrayicon.h"
#include <QPushButton>
#include <QTextCodec>
#include <QFileDialog>
#include <QMenu>
#include <QPair>
#include <QNetworkReply>
#include <QClipboard>
#include <QMimeData>
FormFeedDetails::FormFeedDetails(ServiceRoot *service_root, QWidget *parent)
: QDialog(parent),
m_editableFeed(NULL),
m_serviceRoot(service_root) {
initialize();
createConnections();
// Initialize that shit.
onTitleChanged(QString());
onDescriptionChanged(QString());
onUrlChanged(QString());
onUsernameChanged(QString());
onPasswordChanged(QString());
}
FormFeedDetails::~FormFeedDetails() {
}
int FormFeedDetails::exec(Feed *input_feed, RootItem *parent_to_select, const QString &url) {
// Load categories.
loadCategories(m_serviceRoot->getSubTreeCategories(), m_serviceRoot);
if (input_feed == NULL) {
// User is adding new category.
setWindowTitle(tr("Add new feed"));
// Make sure that "default" icon is used as the default option for new
// feed.
m_actionUseDefaultIcon->trigger();
int default_encoding_index = m_ui->m_cmbEncoding->findText(DEFAULT_FEED_ENCODING);
if (default_encoding_index >= 0) {
m_ui->m_cmbEncoding->setCurrentIndex(default_encoding_index);
}
if (parent_to_select != NULL) {
if (parent_to_select->kind() == RootItemKind::Category) {
m_ui->m_cmbParentCategory->setCurrentIndex(m_ui->m_cmbParentCategory->findData(QVariant::fromValue((void*) parent_to_select)));
}
else if (parent_to_select->kind() == RootItemKind::Feed) {
int target_item = m_ui->m_cmbParentCategory->findData(QVariant::fromValue((void*) parent_to_select->parent()));
if (target_item >= 0) {
m_ui->m_cmbParentCategory->setCurrentIndex(target_item);
}
}
}
if (!url.isEmpty()) {
m_ui->m_txtUrl->lineEdit()->setText(url);
}
else if (Application::clipboard()->mimeData()->hasText()) {
m_ui->m_txtUrl->lineEdit()->setText(Application::clipboard()->text());
}
}
else {
// User is editing existing category.
setWindowTitle(tr("Edit feed '%1'").arg(input_feed->title()));
setEditableFeed(input_feed);
}
// Run the dialog.
return QDialog::exec();
}
void FormFeedDetails::onTitleChanged(const QString &new_title){
if (new_title.simplified().size() >= MIN_CATEGORY_NAME_LENGTH) {
m_ui->m_txtTitle->setStatus(LineEditWithStatus::Ok, tr("Feed name is ok."));
}
else {
m_ui->m_txtTitle->setStatus(LineEditWithStatus::Error, tr("Feed name is too short."));
}
}
void FormFeedDetails::onDescriptionChanged(const QString &new_description) {
if (new_description.simplified().isEmpty()) {
m_ui->m_txtDescription->setStatus(LineEditWithStatus::Warning, tr("Description is empty."));
}
else {
m_ui->m_txtDescription->setStatus(LineEditWithStatus::Ok, tr("The description is ok."));
}
}
void FormFeedDetails::onUrlChanged(const QString &new_url) {
if (QRegExp(URL_REGEXP).exactMatch(new_url)) {
// New url is well-formed.
m_ui->m_txtUrl->setStatus(LineEditWithStatus::Ok, tr("The URL is ok."));
}
else if (!new_url.simplified().isEmpty()) {
// New url is not well-formed but is not empty on the other hand.
m_ui->m_txtUrl->setStatus(LineEditWithStatus::Warning, tr("The URL does not meet standard pattern. Does your URL start with \"http://\" or \"https://\" prefix."));
}
else {
// New url is empty.
m_ui->m_txtUrl->setStatus(LineEditWithStatus::Error, tr("The URL is empty."));
}
}
void FormFeedDetails::onUsernameChanged(const QString &new_username) {
bool is_username_ok = !m_ui->m_gbAuthentication->isChecked() || !new_username.simplified().isEmpty();
m_ui->m_txtUsername->setStatus(is_username_ok ?
LineEditWithStatus::Ok :
LineEditWithStatus::Warning,
is_username_ok ?
tr("Username is ok or it is not needed.") :
tr("Username is empty."));
}
void FormFeedDetails::onPasswordChanged(const QString &new_password) {
bool is_password_ok = !m_ui->m_gbAuthentication->isChecked() || !new_password.simplified().isEmpty();
m_ui->m_txtPassword->setStatus(is_password_ok ?
LineEditWithStatus::Ok :
LineEditWithStatus::Warning,
is_password_ok ?
tr("Password is ok or it is not needed.") :
tr("Password is empty."));
}
void FormFeedDetails::onAuthenticationSwitched() {
onUsernameChanged(m_ui->m_txtUsername->lineEdit()->text());
onPasswordChanged(m_ui->m_txtPassword->lineEdit()->text());
}
void FormFeedDetails::onAutoUpdateTypeChanged(int new_index) {
Feed::AutoUpdateType auto_update_type = static_cast<Feed::AutoUpdateType>(m_ui->m_cmbAutoUpdateType->itemData(new_index).toInt());
switch (auto_update_type) {
case Feed::DontAutoUpdate:
case Feed::DefaultAutoUpdate:
m_ui->m_spinAutoUpdateInterval->setEnabled(false);
break;
case Feed::SpecificAutoUpdate:
default:
m_ui->m_spinAutoUpdateInterval->setEnabled(true);
}
}
void FormFeedDetails::onNoIconSelected() {
m_ui->m_btnIcon->setIcon(QIcon());
}
void FormFeedDetails::onLoadIconFromFile() {
QFileDialog dialog(this, tr("Select icon file for the feed"),
qApp->homeFolderPath(), tr("Images (*.bmp *.jpg *.jpeg *.png *.svg *.tga)"));
dialog.setFileMode(QFileDialog::ExistingFile);
dialog.setWindowIcon(qApp->icons()->fromTheme(QSL("image-x-generic")));
dialog.setOptions(QFileDialog::DontUseNativeDialog | QFileDialog::ReadOnly);
dialog.setViewMode(QFileDialog::Detail);
dialog.setLabelText(QFileDialog::Accept, tr("Select icon"));
dialog.setLabelText(QFileDialog::Reject, tr("Cancel"));
//: Label for field with icon file name textbox for selection dialog.
dialog.setLabelText(QFileDialog::LookIn, tr("Look in:"));
dialog.setLabelText(QFileDialog::FileName, tr("Icon name:"));
dialog.setLabelText(QFileDialog::FileType, tr("Icon type:"));
if (dialog.exec() == QDialog::Accepted) {
m_ui->m_btnIcon->setIcon(QIcon(dialog.selectedFiles().value(0)));
}
}
void FormFeedDetails::onUseDefaultIcon() {
m_ui->m_btnIcon->setIcon(qApp->icons()->fromTheme(QSL("application-rss+xml")));
}
void FormFeedDetails::apply() {
}
void FormFeedDetails::guessFeed() {
QPair<StandardFeed*, QNetworkReply::NetworkError> result = StandardFeed::guessFeed(m_ui->m_txtUrl->lineEdit()->text(),
m_ui->m_txtUsername->lineEdit()->text(),
m_ui->m_txtPassword->lineEdit()->text());
if (result.first != NULL) {
// Icon or whole feed was guessed.
m_ui->m_btnIcon->setIcon(result.first->icon());
m_ui->m_txtTitle->lineEdit()->setText(result.first->title());
m_ui->m_txtDescription->lineEdit()->setText(result.first->description());
m_ui->m_cmbType->setCurrentIndex(m_ui->m_cmbType->findData(QVariant::fromValue((int) result.first->type())));
int encoding_index = m_ui->m_cmbEncoding->findText(result.first->encoding(), Qt::MatchFixedString);
if (encoding_index >= 0) {
m_ui->m_cmbEncoding->setCurrentIndex(encoding_index);
}
else {
m_ui->m_cmbEncoding->setCurrentIndex(m_ui->m_cmbEncoding->findText(DEFAULT_FEED_ENCODING,
Qt::MatchFixedString));
}
if (result.second == QNetworkReply::NoError) {
m_ui->m_lblFetchMetadata->setStatus(WidgetWithStatus::Ok,
tr("All metadata fetched successfully."),
tr("Feed and icon metadata fetched."));
}
else {
m_ui->m_lblFetchMetadata->setStatus(WidgetWithStatus::Warning,
tr("Result: %1.").arg(NetworkFactory::networkErrorText(result.second)),
tr("Feed or icon metadata not fetched."));
}
// Remove temporary feed object.
delete result.first;
}
else {
// No feed guessed, even no icon available.
m_ui->m_lblFetchMetadata->setStatus(WidgetWithStatus::Error,
tr("Error: %1.").arg(NetworkFactory::networkErrorText(result.second)),
tr("No metadata fetched."));
}
}
void FormFeedDetails::guessIconOnly() {
QPair<StandardFeed*, QNetworkReply::NetworkError> result = StandardFeed::guessFeed(m_ui->m_txtUrl->lineEdit()->text(),
m_ui->m_txtUsername->lineEdit()->text(),
m_ui->m_txtPassword->lineEdit()->text());
if (result.first != NULL) {
// Icon or whole feed was guessed.
m_ui->m_btnIcon->setIcon(result.first->icon());
if (result.second == QNetworkReply::NoError) {
m_ui->m_lblFetchMetadata->setStatus(WidgetWithStatus::Ok,
tr("Icon fetched successfully."),
tr("Icon metadata fetched."));
}
else {
m_ui->m_lblFetchMetadata->setStatus(WidgetWithStatus::Warning,
tr("Result: %1.").arg(NetworkFactory::networkErrorText(result.second)),
tr("Icon metadata not fetched."));
}
// Remove temporary feed object.
delete result.first;
}
else {
// No feed guessed, even no icon available.
m_ui->m_lblFetchMetadata->setStatus(WidgetWithStatus::Error,
tr("Error: %1.").arg(NetworkFactory::networkErrorText(result.second)),
tr("No icon fetched."));
}
}
void FormFeedDetails::createConnections() {
// General connections.
connect(m_ui->m_buttonBox, SIGNAL(accepted()), this, SLOT(apply()));
connect(m_ui->m_txtTitle->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(onTitleChanged(QString)));
connect(m_ui->m_txtDescription->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(onDescriptionChanged(QString)));
connect(m_ui->m_txtUrl->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(onUrlChanged(QString)));
connect(m_ui->m_txtUsername->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(onUsernameChanged(QString)));
connect(m_ui->m_txtPassword->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(onPasswordChanged(QString)));
connect(m_ui->m_gbAuthentication, SIGNAL(toggled(bool)), this, SLOT(onAuthenticationSwitched()));
connect(m_ui->m_cmbAutoUpdateType, SIGNAL(currentIndexChanged(int)), this, SLOT(onAutoUpdateTypeChanged(int)));
connect(m_ui->m_btnFetchMetadata, SIGNAL(clicked()), this, SLOT(guessFeed()));
// Icon connections.
connect(m_actionFetchIcon, SIGNAL(triggered()), this, SLOT(guessIconOnly()));
connect(m_actionLoadIconFromFile, SIGNAL(triggered()), this, SLOT(onLoadIconFromFile()));
connect(m_actionNoIcon, SIGNAL(triggered()), this, SLOT(onNoIconSelected()));
connect(m_actionUseDefaultIcon, SIGNAL(triggered()), this, SLOT(onUseDefaultIcon()));
}
void FormFeedDetails::setEditableFeed(Feed *editable_feed) {
m_editableFeed = editable_feed;
m_ui->m_cmbParentCategory->setCurrentIndex(m_ui->m_cmbParentCategory->findData(QVariant::fromValue((void*) editable_feed->parent())));
m_ui->m_txtTitle->lineEdit()->setText(editable_feed->title());
m_ui->m_txtDescription->lineEdit()->setText(editable_feed->description());
m_ui->m_btnIcon->setIcon(editable_feed->icon());
m_ui->m_txtUrl->lineEdit()->setText(editable_feed->url());
m_ui->m_cmbAutoUpdateType->setCurrentIndex(m_ui->m_cmbAutoUpdateType->findData(QVariant::fromValue((int) editable_feed->autoUpdateType())));
m_ui->m_spinAutoUpdateInterval->setValue(editable_feed->autoUpdateInitialInterval());
}
void FormFeedDetails::initialize() {
m_ui.reset(new Ui::FormFeedDetails());
m_ui->setupUi(this);
// Set flags and attributes.
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint);
setWindowIcon(qApp->icons()->fromTheme(QSL("application-rss+xml")));
// Set text boxes.
m_ui->m_txtTitle->lineEdit()->setPlaceholderText(tr("Feed title"));
m_ui->m_txtTitle->lineEdit()->setToolTip(tr("Set title for your feed."));
m_ui->m_txtDescription->lineEdit()->setPlaceholderText(tr("Feed description"));
m_ui->m_txtDescription->lineEdit()->setToolTip(tr("Set description for your feed."));
m_ui->m_txtUrl->lineEdit()->setPlaceholderText(tr("Full feed url including scheme"));
m_ui->m_txtUrl->lineEdit()->setToolTip(tr("Set url for your feed."));
m_ui->m_txtUsername->lineEdit()->setPlaceholderText(tr("Username"));
m_ui->m_txtUsername->lineEdit()->setToolTip(tr("Set username to access the feed."));
m_ui->m_txtPassword->lineEdit()->setPlaceholderText(tr("Password"));
m_ui->m_txtPassword->lineEdit()->setToolTip(tr("Set password to access the feed."));
// Add standard feed types.
m_ui->m_cmbType->addItem(StandardFeed::typeToString(StandardFeed::Atom10), QVariant::fromValue((int) StandardFeed::Atom10));
m_ui->m_cmbType->addItem(StandardFeed::typeToString(StandardFeed::Rdf), QVariant::fromValue((int) StandardFeed::Rdf));
m_ui->m_cmbType->addItem(StandardFeed::typeToString(StandardFeed::Rss0X), QVariant::fromValue((int) StandardFeed::Rss0X));
m_ui->m_cmbType->addItem(StandardFeed::typeToString(StandardFeed::Rss2X), QVariant::fromValue((int) StandardFeed::Rss2X));
// Load available encodings.
const QList<QByteArray> encodings = QTextCodec::availableCodecs();
QStringList encoded_encodings;
foreach (const QByteArray &encoding, encodings) {
encoded_encodings.append(encoding);
}
// Sort encodings and add them.
qSort(encoded_encodings.begin(), encoded_encodings.end(), TextFactory::isCaseInsensitiveLessThan);
m_ui->m_cmbEncoding->addItems(encoded_encodings);
// Setup menu & actions for icon selection.
m_iconMenu = new QMenu(tr("Icon selection"), this);
m_actionLoadIconFromFile = new QAction(qApp->icons()->fromTheme(QSL("image-x-generic")),
tr("Load icon from file..."),
this);
m_actionNoIcon = new QAction(qApp->icons()->fromTheme(QSL("dialog-error")),
tr("Do not use icon"),
this);
m_actionUseDefaultIcon = new QAction(qApp->icons()->fromTheme(QSL("application-rss+xml")),
tr("Use default icon"),
this);
m_actionFetchIcon = new QAction(qApp->icons()->fromTheme(QSL("emblem-downloads")),
tr("Fetch icon from feed"),
this);
m_iconMenu->addAction(m_actionFetchIcon);
m_iconMenu->addAction(m_actionLoadIconFromFile);
m_iconMenu->addAction(m_actionUseDefaultIcon);
m_iconMenu->addAction(m_actionNoIcon);
m_ui->m_btnIcon->setMenu(m_iconMenu);
// Set feed metadata fetch label.
m_ui->m_lblFetchMetadata->setStatus(WidgetWithStatus::Information,
tr("No metadata fetched so far."),
tr("No metadata fetched so far."));
// Setup auto-update options.
m_ui->m_spinAutoUpdateInterval->setValue(DEFAULT_AUTO_UPDATE_INTERVAL);
m_ui->m_cmbAutoUpdateType->addItem(tr("Auto-update using global interval"), QVariant::fromValue((int) Feed::DefaultAutoUpdate));
m_ui->m_cmbAutoUpdateType->addItem(tr("Auto-update every"), QVariant::fromValue((int) Feed::SpecificAutoUpdate));
m_ui->m_cmbAutoUpdateType->addItem(tr("Do not auto-update at all"), QVariant::fromValue((int) Feed::DontAutoUpdate));
// Set tab order.
setTabOrder(m_ui->m_cmbParentCategory, m_ui->m_cmbType);
setTabOrder(m_ui->m_cmbType, m_ui->m_cmbEncoding);
setTabOrder(m_ui->m_cmbEncoding, m_ui->m_cmbAutoUpdateType);
setTabOrder(m_ui->m_cmbAutoUpdateType, m_ui->m_spinAutoUpdateInterval);
setTabOrder(m_ui->m_spinAutoUpdateInterval, m_ui->m_txtTitle->lineEdit());
setTabOrder(m_ui->m_txtTitle->lineEdit(), m_ui->m_txtDescription->lineEdit());
setTabOrder(m_ui->m_txtDescription->lineEdit(), m_ui->m_txtUrl->lineEdit());
setTabOrder(m_ui->m_txtUrl->lineEdit(), m_ui->m_btnFetchMetadata);
setTabOrder(m_ui->m_btnFetchMetadata, m_ui->m_btnIcon);
setTabOrder(m_ui->m_btnIcon, m_ui->m_gbAuthentication);
setTabOrder(m_ui->m_gbAuthentication, m_ui->m_txtUsername->lineEdit());
setTabOrder(m_ui->m_txtUsername->lineEdit(), m_ui->m_txtPassword->lineEdit());
m_ui->m_txtUrl->lineEdit()->setFocus(Qt::TabFocusReason);
}
void FormFeedDetails::loadCategories(const QList<Category*> categories, RootItem *root_item) {
m_ui->m_cmbParentCategory->addItem(root_item->icon(),
root_item->title(),
QVariant::fromValue((void*) root_item));
foreach (Category *category, categories) {
m_ui->m_cmbParentCategory->addItem(category->icon(),
category->title(),
QVariant::fromValue((void*) category));
}
}

View File

@ -0,0 +1,97 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2016 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 FORMFEEDDETAILS_H
#define FORMFEEDDETAILS_H
#include <QDialog>
#include "ui_formfeeddetails.h"
namespace Ui {
class FormFeedDetails;
}
class ServiceRoot;
class Feed;
class Category;
class RootItem;
class FormFeedDetails : public QDialog {
Q_OBJECT
public:
// Constructors and destructors.
explicit FormFeedDetails(ServiceRoot *service_root, QWidget *parent = 0);
virtual ~FormFeedDetails();
public slots:
// Executes add/edit standard feed dialog.
int exec(Feed *input_feed, RootItem *parent_to_select, const QString &url = QString());
protected slots:
// Applies changes.
// NOTE: This must be reimplemented in subclasses. Also this
// base implementation must be called first.
virtual void apply() = 0;
void guessFeed();
void guessIconOnly();
// Trigerred when title/description/url/username/password changes.
void onTitleChanged(const QString &new_title);
void onDescriptionChanged(const QString &new_description);
void onUrlChanged(const QString &new_url);
void onUsernameChanged(const QString &new_username);
void onPasswordChanged(const QString &new_password);
void onAuthenticationSwitched();
void onAutoUpdateTypeChanged(int new_index);
// Icon selectors.
void onNoIconSelected();
void onLoadIconFromFile();
void onUseDefaultIcon();
protected:
// Sets the feed which will be edited.
// NOTE: This must be reimplemented in subclasses. Also this
// base implementation must be called first.
void virtual setEditableFeed(Feed *editable_feed);
// Creates needed connections.
void createConnections();
// Initializes the dialog.
void initialize();
// Loads categories into the dialog from the model.
void loadCategories(const QList<Category*> categories, RootItem *root_item);
protected:
QScopedPointer<Ui::FormFeedDetails> m_ui;
Feed *m_editableFeed;
ServiceRoot *m_serviceRoot;
QMenu *m_iconMenu;
QAction *m_actionLoadIconFromFile;
QAction *m_actionUseDefaultIcon;
QAction *m_actionFetchIcon;
QAction *m_actionNoIcon;
};
#endif // FORMFEEDDETAILS_H

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FormStandardFeedDetails</class>
<widget class="QDialog" name="FormStandardFeedDetails">
<class>FormFeedDetails</class>
<widget class="QDialog" name="FormFeedDetails">
<property name="geometry">
<rect>
<x>0</x>
@ -312,7 +312,7 @@
<connection>
<sender>m_buttonBox</sender>
<signal>rejected()</signal>
<receiver>FormStandardFeedDetails</receiver>
<receiver>FormFeedDetails</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">

View File

@ -15,7 +15,6 @@
// 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 FORMEDITOWNCLOUDACCOUNT_H
#define FORMEDITOWNCLOUDACCOUNT_H

View File

@ -1,263 +0,0 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2016 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 "services/owncloud/gui/formeditowncloudfeed.h"
#include "services/abstract/category.h"
#include "services/owncloud/definitions.h"
#include "services/owncloud/owncloudfeed.h"
#include "services/owncloud/owncloudcategory.h"
#include "services/owncloud/owncloudserviceroot.h"
#include "services/owncloud/network/owncloudnetworkfactory.h"
#include "gui/dialogs/formmain.h"
#include "miscellaneous/iconfactory.h"
#include "miscellaneous/application.h"
#include <QClipboard>
#include <QMimeData>
#include <QTimer>
FormEditOwnCloudFeed::FormEditOwnCloudFeed(OwnCloudServiceRoot *root, QWidget *parent)
: QDialog(parent), m_ui(new Ui::FormEditOwnCloudFeed), m_root(root), m_loadedFeed(NULL) {
m_ui->setupUi(this);
initialize();
connect(m_ui->m_txtUrl->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(onUrlChanged(QString)));
connect(m_ui->m_gbAuthentication, SIGNAL(toggled(bool)), this, SLOT(onAuthenticationSwitched()));
connect(m_ui->m_cmbAutoUpdateType, SIGNAL(currentIndexChanged(int)), this, SLOT(onAutoUpdateTypeChanged(int)));
connect(m_ui->m_buttonBox, SIGNAL(accepted()), this, SLOT(performAction()));
connect(m_ui->m_txtTitle->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(onTitleChanged(QString)));
}
FormEditOwnCloudFeed::~FormEditOwnCloudFeed() {
}
int FormEditOwnCloudFeed::execForEdit(OwnCloudFeed *input_feed) {
loadCategories(m_root->getSubTreeCategories(), m_root);
loadFeed(input_feed);
m_ui->m_txtUrl->lineEdit()->setFocus();
return QDialog::exec();
}
int FormEditOwnCloudFeed::execForAdd(const QString &url) {
m_ui->m_txtTitle->setEnabled(false);
if (!url.isEmpty()) {
m_ui->m_txtUrl->lineEdit()->setText(url);
}
else if (Application::clipboard()->mimeData()->hasText()) {
m_ui->m_txtUrl->lineEdit()->setText(Application::clipboard()->text());
}
loadCategories(m_root->getSubTreeCategories(), m_root);
loadFeed(NULL);
m_ui->m_txtUrl->lineEdit()->setFocus();
return QDialog::exec();
}
void FormEditOwnCloudFeed::onAuthenticationSwitched() {
onUsernameChanged(m_ui->m_txtUsername->lineEdit()->text());
onPasswordChanged(m_ui->m_txtPassword->lineEdit()->text());
}
void FormEditOwnCloudFeed::onAutoUpdateTypeChanged(int new_index) {
const Feed::AutoUpdateType auto_update_type = static_cast<Feed::AutoUpdateType>(m_ui->m_cmbAutoUpdateType->itemData(new_index).toInt());
switch (auto_update_type) {
case Feed::DontAutoUpdate:
case Feed::DefaultAutoUpdate:
m_ui->m_spinAutoUpdateInterval->setEnabled(false);
break;
case Feed::SpecificAutoUpdate:
default:
m_ui->m_spinAutoUpdateInterval->setEnabled(true);
}
}
void FormEditOwnCloudFeed::performAction() {
if (m_loadedFeed != NULL) {
saveFeed();
}
else {
addNewFeed();
}
accept();
}
void FormEditOwnCloudFeed::onUrlChanged(const QString &new_url) {
if (QRegExp(URL_REGEXP).exactMatch(new_url)) {
// New url is well-formed.
m_ui->m_txtUrl->setStatus(LineEditWithStatus::Ok, tr("The URL is ok."));
}
else if (!new_url.isEmpty()) {
// New url is not well-formed but is not empty on the other hand.
m_ui->m_txtUrl->setStatus(LineEditWithStatus::Warning, tr("The URL does not meet standard pattern. Does your URL start with \"http://\" or \"https://\" prefix."));
}
else {
// New url is empty.
m_ui->m_txtUrl->setStatus(LineEditWithStatus::Error, tr("The URL is empty."));
}
}
void FormEditOwnCloudFeed::onUsernameChanged(const QString &new_username) {
const bool is_username_ok = !m_ui->m_gbAuthentication->isChecked() || !new_username.isEmpty();
m_ui->m_txtUsername->setStatus(is_username_ok ?
LineEditWithStatus::Ok :
LineEditWithStatus::Warning,
is_username_ok ?
tr("Username is ok or it is not needed.") :
tr("Username is empty."));
}
void FormEditOwnCloudFeed::onPasswordChanged(const QString &new_password) {
const bool is_password_ok = !m_ui->m_gbAuthentication->isChecked() || !new_password.isEmpty();
m_ui->m_txtPassword->setStatus(is_password_ok ?
LineEditWithStatus::Ok :
LineEditWithStatus::Warning,
is_password_ok ?
tr("Password is ok or it is not needed.") :
tr("Password is empty."));
}
void FormEditOwnCloudFeed::onTitleChanged(const QString &title) {
m_ui->m_txtTitle->setStatus(title.isEmpty() ? WidgetWithStatus::Error : WidgetWithStatus::Ok,
title.isEmpty() ? tr("Title is empty.") : tr("Title looks okay."));
}
void FormEditOwnCloudFeed::initialize() {
setWindowIcon(qApp->icons()->fromTheme(QSL("application-rss+xml")));
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint);
// Setup auto-update options.
m_ui->m_spinAutoUpdateInterval->setValue(DEFAULT_AUTO_UPDATE_INTERVAL);
m_ui->m_cmbAutoUpdateType->addItem(tr("Auto-update using global interval"), QVariant::fromValue((int) Feed::DefaultAutoUpdate));
m_ui->m_cmbAutoUpdateType->addItem(tr("Auto-update every"), QVariant::fromValue((int) Feed::SpecificAutoUpdate));
m_ui->m_cmbAutoUpdateType->addItem(tr("Do not auto-update at all"), QVariant::fromValue((int) Feed::DontAutoUpdate));
setTabOrder(m_ui->m_cmbParentCategory, m_ui->m_txtTitle->lineEdit());
setTabOrder(m_ui->m_txtTitle->lineEdit(), m_ui->m_txtUrl->lineEdit());
setTabOrder(m_ui->m_txtUrl->lineEdit(), m_ui->m_cmbAutoUpdateType);
setTabOrder(m_ui->m_cmbAutoUpdateType, m_ui->m_spinAutoUpdateInterval);
setTabOrder(m_ui->m_spinAutoUpdateInterval, m_ui->m_gbAuthentication);
setTabOrder(m_ui->m_gbAuthentication, m_ui->m_txtUsername->lineEdit());
setTabOrder(m_ui->m_txtUsername->lineEdit(), m_ui->m_txtPassword->lineEdit());
setTabOrder(m_ui->m_txtPassword->lineEdit(), m_ui->m_buttonBox);
m_ui->m_txtUrl->lineEdit()->setPlaceholderText(tr("Full feed url including scheme"));
m_ui->m_txtUsername->lineEdit()->setPlaceholderText(tr("Username"));
m_ui->m_txtPassword->lineEdit()->setPlaceholderText(tr("Password"));
onAuthenticationSwitched();
}
void FormEditOwnCloudFeed::loadFeed(OwnCloudFeed *input_feed) {
m_loadedFeed = input_feed;
if (input_feed != NULL) {
setWindowTitle(tr("Edit existing feed"));
// Tiny Tiny RSS does not support editing of these features.
// User can edit only individual auto-update statuses.
m_ui->m_gbAuthentication->setEnabled(false);
m_ui->m_txtUrl->setEnabled(false);
m_ui->m_lblUrl->setEnabled(false);
m_ui->m_lblParentCategory->setEnabled(false);
m_ui->m_cmbParentCategory->setEnabled(false);
m_ui->m_txtTitle->setEnabled(true);
m_ui->m_cmbParentCategory->setCurrentIndex(m_ui->m_cmbParentCategory->findData(QVariant::fromValue((void*) input_feed->parent())));
m_ui->m_cmbAutoUpdateType->setCurrentIndex(m_ui->m_cmbAutoUpdateType->findData(QVariant::fromValue((int) input_feed->autoUpdateType())));
m_ui->m_spinAutoUpdateInterval->setValue(input_feed->autoUpdateInitialInterval());
m_ui->m_txtTitle->lineEdit()->setText(input_feed->title());
}
else {
setWindowTitle(tr("Add new feed"));
// Tiny Tiny RSS does not support editing of these features.
// User can edit only individual auto-update statuses.
m_ui->m_gbAuthentication->setEnabled(true);
m_ui->m_txtUrl->setEnabled(true);
m_ui->m_lblUrl->setEnabled(true);
m_ui->m_lblParentCategory->setEnabled(true);
m_ui->m_cmbParentCategory->setEnabled(true);
}
}
void FormEditOwnCloudFeed::saveFeed() {
bool renamed = false;
if (m_ui->m_txtTitle->lineEdit()->text() != m_loadedFeed->title()) {
if (!m_root->network()->renameFeed(m_ui->m_txtTitle->lineEdit()->text(), m_loadedFeed->customId())) {
qWarning("ownCloud: Došlo k problému při prejmenování kanálu s ownCloud ID '%d'.", m_loadedFeed->customId());
}
else {
renamed = true;
}
}
// User edited auto-update status. Save it.
OwnCloudFeed *new_feed_data = new OwnCloudFeed();
new_feed_data->setAutoUpdateType(static_cast<Feed::AutoUpdateType>(m_ui->m_cmbAutoUpdateType->itemData(m_ui->m_cmbAutoUpdateType->currentIndex()).toInt()));
new_feed_data->setAutoUpdateInitialInterval(m_ui->m_spinAutoUpdateInterval->value());
m_loadedFeed->editItself(new_feed_data);
delete new_feed_data;
if (renamed) {
QTimer::singleShot(200, m_root, SLOT(syncIn()));
}
}
void FormEditOwnCloudFeed::addNewFeed() {
const RootItem *parent = static_cast<RootItem*>(m_ui->m_cmbParentCategory->itemData(m_ui->m_cmbParentCategory->currentIndex()).value<void*>());
const int category_id = parent->kind() == RootItemKind::ServiceRoot ? 0 : parent->customId();
const bool response = m_root->network()->createFeed(m_ui->m_txtUrl->lineEdit()->text(), category_id);
if (response) {
// Feed was added online.
accept();
qApp->showGuiMessage(tr("Feed added"), tr("Feed was added, triggering sync in now."), QSystemTrayIcon::Information);
QTimer::singleShot(100, m_root, SLOT(syncIn()));
}
else {
reject();
qApp->showGuiMessage(tr("Cannot add feed"),
tr("Feed was not added due to error."),
QSystemTrayIcon::Critical, qApp->mainForm(), true);
}
}
void FormEditOwnCloudFeed::loadCategories(const QList<Category*> categories, RootItem *root_item) {
m_ui->m_cmbParentCategory->addItem(root_item->icon(),
root_item->title(),
QVariant::fromValue((void*) root_item));
foreach (Category *category, categories) {
m_ui->m_cmbParentCategory->addItem(category->icon(),
category->title(),
QVariant::fromValue((void*) category));
}
}

View File

@ -1,66 +0,0 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2016 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 FORMEDITOWNCLOUDFEED_H
#define FORMEDITOWNCLOUDFEED_H
#include <QDialog>
#include "ui_formeditowncloudfeed.h"
namespace Ui {
class FormEditOwnCloudFeed;
}
class OwnCloudServiceRoot;
class OwnCloudFeed;
class Category;
class RootItem;
class FormEditOwnCloudFeed : public QDialog {
Q_OBJECT
public:
explicit FormEditOwnCloudFeed(OwnCloudServiceRoot *root, QWidget *parent = 0);
virtual ~FormEditOwnCloudFeed();
int execForEdit(OwnCloudFeed *input_feed);
int execForAdd(const QString &url);
private slots:
void performAction();
void onAuthenticationSwitched();
void onAutoUpdateTypeChanged(int new_index);
void onUrlChanged(const QString &new_url);
void onUsernameChanged(const QString &new_username);
void onPasswordChanged(const QString &new_password);
void onTitleChanged(const QString &title);
private:
void initialize();
void loadFeed(OwnCloudFeed *input_feed);
void saveFeed();
void addNewFeed();
void loadCategories(const QList<Category*> categories, RootItem *root_item);
QScopedPointer<Ui::FormEditOwnCloudFeed> m_ui;
OwnCloudServiceRoot *m_root;
OwnCloudFeed *m_loadedFeed;
};
#endif // FORMEDITOWNCLOUDFEED_H

View File

@ -1,192 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FormEditOwnCloudFeed</class>
<widget class="QDialog" name="FormEditOwnCloudFeed">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>598</width>
<height>266</height>
</rect>
</property>
<property name="windowTitle">
<string>Edit feed</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="m_lblParentCategory">
<property name="text">
<string>Parent category</string>
</property>
<property name="buddy">
<cstring>m_cmbParentCategory</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="m_cmbParentCategory">
<property name="toolTip">
<string>Select parent item for your feed.</string>
</property>
<property name="iconSize">
<size>
<width>12</width>
<height>12</height>
</size>
</property>
<property name="frame">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="m_lblUrl">
<property name="text">
<string>URL</string>
</property>
<property name="buddy">
<cstring>m_txtUrl</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="LineEditWithStatus" name="m_txtUrl" native="true"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Auto-update</string>
</property>
<property name="buddy">
<cstring>m_cmbAutoUpdateType</cstring>
</property>
</widget>
</item>
<item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QComboBox" name="m_cmbAutoUpdateType">
<property name="toolTip">
<string>Select the auto-update strategy for this feed. Default auto-update strategy means that the feed will be update in time intervals set in application settings.</string>
</property>
</widget>
</item>
<item>
<widget class="TimeSpinBox" name="m_spinAutoUpdateInterval">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="4" column="0" colspan="2">
<widget class="QGroupBox" name="m_gbAuthentication">
<property name="toolTip">
<string>Some feeds require authentication, including GMail feeds. BASIC, NTLM-2 and DIGEST-MD5 authentication schemes are supported.</string>
</property>
<property name="title">
<string>Requires authentication</string>
</property>
<property name="flat">
<bool>false</bool>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Username</string>
</property>
<property name="buddy">
<cstring>m_txtUsername</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="LineEditWithStatus" name="m_txtUsername" native="true"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Password</string>
</property>
<property name="buddy">
<cstring>m_txtPassword</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="LineEditWithStatus" name="m_txtPassword" native="true"/>
</item>
</layout>
</widget>
</item>
<item row="1" column="1">
<widget class="LineEditWithStatus" name="m_txtTitle" native="true"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Title</string>
</property>
<property name="buddy">
<cstring>m_txtTitle</cstring>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="m_buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>LineEditWithStatus</class>
<extends>QWidget</extends>
<header>lineeditwithstatus.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>TimeSpinBox</class>
<extends>QDoubleSpinBox</extends>
<header>timespinbox.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>m_buttonBox</sender>
<signal>rejected()</signal>
<receiver>FormEditOwnCloudFeed</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>234</x>
<y>78</y>
</hint>
<hint type="destinationlabel">
<x>234</x>
<y>49</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -0,0 +1,96 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2016 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 "services/owncloud/gui/formowncloudfeeddetails.h"
#include "services/owncloud/owncloudfeed.h"
#include "services/owncloud/owncloudserviceroot.h"
#include "services/owncloud/network/owncloudnetworkfactory.h"
#include "miscellaneous/application.h"
#include "gui/dialogs/formmain.h"
#include <QTimer>
FormOwnCloudFeedDetails::FormOwnCloudFeedDetails(ServiceRoot *service_root, QWidget *parent)
: FormFeedDetails(service_root, parent) {
m_ui->m_cmbAutoUpdateType->setEnabled(false);
m_ui->m_spinAutoUpdateInterval->setEnabled(false);
m_ui->m_cmbType->setEnabled(false);
m_ui->m_cmbEncoding->setEnabled(false);
m_ui->m_btnFetchMetadata->setEnabled(false);
m_ui->m_btnIcon->setEnabled(false);
m_ui->m_txtTitle->setEnabled(false);
m_ui->m_txtUrl->setEnabled(true);
m_ui->m_txtDescription->setEnabled(false);
}
void FormOwnCloudFeedDetails::apply() {
if (m_editableFeed != NULL) {
bool renamed = false;
if (m_ui->m_txtTitle->lineEdit()->text() != m_editableFeed->title()) {
if (!qobject_cast<OwnCloudServiceRoot*>(m_serviceRoot)->network()->renameFeed(m_ui->m_txtTitle->lineEdit()->text(), m_editableFeed->customId())) {
qWarning("ownCloud: Došlo k problému při prejmenování kanálu s ownCloud ID '%d'.", m_editableFeed->customId());
}
else {
renamed = true;
}
}
// User edited auto-update status. Save it.
OwnCloudFeed *new_feed_data = new OwnCloudFeed();
new_feed_data->setAutoUpdateType(static_cast<Feed::AutoUpdateType>(m_ui->m_cmbAutoUpdateType->itemData(m_ui->m_cmbAutoUpdateType->currentIndex()).toInt()));
new_feed_data->setAutoUpdateInitialInterval(m_ui->m_spinAutoUpdateInterval->value());
qobject_cast<OwnCloudFeed*>(m_editableFeed)->editItself(new_feed_data);
delete new_feed_data;
if (renamed) {
QTimer::singleShot(200, m_serviceRoot, SLOT(syncIn()));
}
}
else {
const RootItem *parent = static_cast<RootItem*>(m_ui->m_cmbParentCategory->itemData(m_ui->m_cmbParentCategory->currentIndex()).value<void*>());
const int category_id = parent->kind() == RootItemKind::ServiceRoot ? 0 : parent->customId();
const bool response = qobject_cast<OwnCloudServiceRoot*>(m_serviceRoot)->network()->createFeed(m_ui->m_txtUrl->lineEdit()->text(), category_id);
if (response) {
// Feed was added online.
accept();
qApp->showGuiMessage(tr("Feed added"), tr("Feed was added, triggering sync in now."), QSystemTrayIcon::Information);
QTimer::singleShot(100, m_serviceRoot, SLOT(syncIn()));
}
else {
reject();
qApp->showGuiMessage(tr("Cannot add feed"),
tr("Feed was not added due to error."),
QSystemTrayIcon::Critical, qApp->mainForm(), true);
}
}
accept();
}
void FormOwnCloudFeedDetails::setEditableFeed(Feed *editable_feed) {
FormFeedDetails::setEditableFeed(editable_feed);
m_ui->m_txtTitle->setEnabled(true);
m_ui->m_txtUrl->setEnabled(false);
}

View File

@ -0,0 +1,35 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2016 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 FORMOWNCLOUDFEEDDETAILS_H
#define FORMOWNCLOUDFEEDDETAILS_H
#include "services/abstract/gui/formfeeddetails.h"
class FormOwnCloudFeedDetails : public FormFeedDetails {
public:
explicit FormOwnCloudFeedDetails(ServiceRoot *service_root, QWidget *parent = 0);
protected slots:
void apply();
protected:
void setEditableFeed(Feed *editable_feed);
};
#endif // FORMOWNCLOUDFEEDDETAILS_H

View File

@ -21,7 +21,7 @@
#include "miscellaneous/databasequeries.h"
#include "services/owncloud/owncloudserviceroot.h"
#include "services/owncloud/network/owncloudnetworkfactory.h"
#include "services/owncloud/gui/formeditowncloudfeed.h"
#include "services/owncloud/gui/formowncloudfeeddetails.h"
#include "gui/dialogs/formmain.h"
#include <QPointer>
@ -47,9 +47,9 @@ bool OwnCloudFeed::canBeEdited() const {
}
bool OwnCloudFeed::editViaGui() {
QPointer<FormEditOwnCloudFeed> form_pointer = new FormEditOwnCloudFeed(serviceRoot(), qApp->mainForm());
QPointer<FormOwnCloudFeedDetails> form_pointer = new FormOwnCloudFeedDetails(serviceRoot(), qApp->mainForm());
form_pointer.data()->execForEdit(this);
form_pointer.data()->exec(this, NULL);
delete form_pointer.data();
return false;
}

View File

@ -30,7 +30,7 @@
#include "services/owncloud/owncloudcategory.h"
#include "services/owncloud/network/owncloudnetworkfactory.h"
#include "services/owncloud/gui/formeditowncloudaccount.h"
#include "services/owncloud/gui/formeditowncloudfeed.h"
#include "services/owncloud/gui/formowncloudfeeddetails.h"
OwnCloudServiceRoot::OwnCloudServiceRoot(RootItem *parent)
@ -208,9 +208,9 @@ void OwnCloudServiceRoot::addNewFeed(const QString &url) {
return;
}
QScopedPointer<FormEditOwnCloudFeed> form_pointer(new FormEditOwnCloudFeed(this, qApp->mainForm()));
QScopedPointer<FormOwnCloudFeedDetails> form_pointer(new FormOwnCloudFeedDetails(this, qApp->mainForm()));
form_pointer.data()->execForAdd(url);
form_pointer.data()->exec(NULL, this, url);
qApp->feedUpdateLock()->unlock();
}

View File

@ -17,208 +17,13 @@
#include "services/standard/gui/formstandardfeeddetails.h"
#include "definitions/definitions.h"
#include "core/feedsmodel.h"
#include "services/abstract/rootitem.h"
#include "services/abstract/category.h"
#include "services/standard/standardserviceroot.h"
#include "services/standard/standardfeed.h"
#include "miscellaneous/textfactory.h"
#include "miscellaneous/iconfactory.h"
#include "network-web/networkfactory.h"
#include "gui/baselineedit.h"
#include "gui/messagebox.h"
#include "gui/systemtrayicon.h"
#include <QPushButton>
#include <QTextCodec>
#include <QFileDialog>
#include <QMenu>
#include <QPair>
#include <QNetworkReply>
#include <QClipboard>
#include <QMimeData>
#include "services/abstract/serviceroot.h"
#include "miscellaneous/application.h"
FormStandardFeedDetails::FormStandardFeedDetails(StandardServiceRoot *service_root, QWidget *parent)
: QDialog(parent),
m_editableFeed(NULL),
m_serviceRoot(service_root) {
initialize();
createConnections();
// Initialize that shit.
onTitleChanged(QString());
onDescriptionChanged(QString());
onUrlChanged(QString());
onUsernameChanged(QString());
onPasswordChanged(QString());
}
FormStandardFeedDetails::~FormStandardFeedDetails() {
}
int FormStandardFeedDetails::exec(StandardFeed *input_feed, RootItem *parent_to_select, const QString &url) {
// Load categories.
loadCategories(m_serviceRoot->getSubTreeCategories(), m_serviceRoot);
if (input_feed == NULL) {
// User is adding new category.
setWindowTitle(tr("Add new feed"));
// Make sure that "default" icon is used as the default option for new
// feed.
m_actionUseDefaultIcon->trigger();
int default_encoding_index = m_ui->m_cmbEncoding->findText(DEFAULT_FEED_ENCODING);
if (default_encoding_index >= 0) {
m_ui->m_cmbEncoding->setCurrentIndex(default_encoding_index);
}
if (parent_to_select != NULL) {
if (parent_to_select->kind() == RootItemKind::Category) {
m_ui->m_cmbParentCategory->setCurrentIndex(m_ui->m_cmbParentCategory->findData(QVariant::fromValue((void*) parent_to_select)));
}
else if (parent_to_select->kind() == RootItemKind::Feed) {
int target_item = m_ui->m_cmbParentCategory->findData(QVariant::fromValue((void*) parent_to_select->parent()));
if (target_item >= 0) {
m_ui->m_cmbParentCategory->setCurrentIndex(target_item);
}
}
}
if (!url.isEmpty()) {
m_ui->m_txtUrl->lineEdit()->setText(url);
}
else if (Application::clipboard()->mimeData()->hasText()) {
m_ui->m_txtUrl->lineEdit()->setText(Application::clipboard()->text());
}
}
else {
// User is editing existing category.
setWindowTitle(tr("Edit existing feed"));
setEditableFeed(input_feed);
}
// Run the dialog.
return QDialog::exec();
}
void FormStandardFeedDetails::onTitleChanged(const QString &new_title){
if (new_title.simplified().size() >= MIN_CATEGORY_NAME_LENGTH) {
m_ui->m_txtTitle->setStatus(LineEditWithStatus::Ok, tr("Feed name is ok."));
}
else {
m_ui->m_txtTitle->setStatus(LineEditWithStatus::Error, tr("Feed name is too short."));
}
checkOkButtonEnabled();
}
void FormStandardFeedDetails::onDescriptionChanged(const QString &new_description) {
if (new_description.simplified().isEmpty()) {
m_ui->m_txtDescription->setStatus(LineEditWithStatus::Warning, tr("Description is empty."));
}
else {
m_ui->m_txtDescription->setStatus(LineEditWithStatus::Ok, tr("The description is ok."));
}
}
void FormStandardFeedDetails::onUrlChanged(const QString &new_url) {
if (QRegExp(URL_REGEXP).exactMatch(new_url)) {
// New url is well-formed.
m_ui->m_txtUrl->setStatus(LineEditWithStatus::Ok, tr("The URL is ok."));
}
else if (!new_url.simplified().isEmpty()) {
// New url is not well-formed but is not empty on the other hand.
m_ui->m_txtUrl->setStatus(LineEditWithStatus::Warning, tr("The URL does not meet standard pattern. Does your URL start with \"http://\" or \"https://\" prefix."));
}
else {
// New url is empty.
m_ui->m_txtUrl->setStatus(LineEditWithStatus::Error, tr("The URL is empty."));
}
checkOkButtonEnabled();
}
void FormStandardFeedDetails::onUsernameChanged(const QString &new_username) {
bool is_username_ok = !m_ui->m_gbAuthentication->isChecked() || !new_username.simplified().isEmpty();
m_ui->m_txtUsername->setStatus(is_username_ok ?
LineEditWithStatus::Ok :
LineEditWithStatus::Warning,
is_username_ok ?
tr("Username is ok or it is not needed.") :
tr("Username is empty."));
}
void FormStandardFeedDetails::onPasswordChanged(const QString &new_password) {
bool is_password_ok = !m_ui->m_gbAuthentication->isChecked() || !new_password.simplified().isEmpty();
m_ui->m_txtPassword->setStatus(is_password_ok ?
LineEditWithStatus::Ok :
LineEditWithStatus::Warning,
is_password_ok ?
tr("Password is ok or it is not needed.") :
tr("Password is empty."));
}
void FormStandardFeedDetails::onAuthenticationSwitched() {
onUsernameChanged(m_ui->m_txtUsername->lineEdit()->text());
onPasswordChanged(m_ui->m_txtPassword->lineEdit()->text());
}
void FormStandardFeedDetails::onAutoUpdateTypeChanged(int new_index) {
Feed::AutoUpdateType auto_update_type = static_cast<Feed::AutoUpdateType>(m_ui->m_cmbAutoUpdateType->itemData(new_index).toInt());
switch (auto_update_type) {
case Feed::DontAutoUpdate:
case Feed::DefaultAutoUpdate:
m_ui->m_spinAutoUpdateInterval->setEnabled(false);
break;
case Feed::SpecificAutoUpdate:
default:
m_ui->m_spinAutoUpdateInterval->setEnabled(true);
}
}
void FormStandardFeedDetails::checkOkButtonEnabled() {
LineEditWithStatus::StatusType title_status = m_ui->m_txtTitle->status();
LineEditWithStatus::StatusType url_status = m_ui->m_txtUrl->status();
m_ui->m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(title_status == LineEditWithStatus::Ok &&
(url_status == LineEditWithStatus::Ok ||
url_status == LineEditWithStatus::Warning));
}
void FormStandardFeedDetails::onNoIconSelected() {
m_ui->m_btnIcon->setIcon(QIcon());
}
void FormStandardFeedDetails::onLoadIconFromFile() {
QFileDialog dialog(this, tr("Select icon file for the feed"),
qApp->homeFolderPath(), tr("Images (*.bmp *.jpg *.jpeg *.png *.svg *.tga)"));
dialog.setFileMode(QFileDialog::ExistingFile);
dialog.setWindowIcon(qApp->icons()->fromTheme(QSL("image-x-generic")));
dialog.setOptions(QFileDialog::DontUseNativeDialog | QFileDialog::ReadOnly);
dialog.setViewMode(QFileDialog::Detail);
dialog.setLabelText(QFileDialog::Accept, tr("Select icon"));
dialog.setLabelText(QFileDialog::Reject, tr("Cancel"));
//: Label for field with icon file name textbox for selection dialog.
dialog.setLabelText(QFileDialog::LookIn, tr("Look in:"));
dialog.setLabelText(QFileDialog::FileName, tr("Icon name:"));
dialog.setLabelText(QFileDialog::FileType, tr("Icon type:"));
if (dialog.exec() == QDialog::Accepted) {
m_ui->m_btnIcon->setIcon(QIcon(dialog.selectedFiles().value(0)));
}
}
void FormStandardFeedDetails::onUseDefaultIcon() {
m_ui->m_btnIcon->setIcon(qApp->icons()->fromTheme(QSL("application-rss+xml")));
FormStandardFeedDetails::FormStandardFeedDetails(ServiceRoot *service_root, QWidget *parent)
: FormFeedDetails(service_root, parent) {
}
void FormStandardFeedDetails::apply() {
@ -257,7 +62,7 @@ void FormStandardFeedDetails::apply() {
new_feed->setParent(parent);
// Edit the feed.
bool edited = m_editableFeed->editItself(new_feed);
bool edited = qobject_cast<StandardFeed*>(m_editableFeed)->editItself(new_feed);
if (edited) {
m_serviceRoot->requestItemReassignment(m_editableFeed, new_feed->parent());
@ -273,223 +78,14 @@ void FormStandardFeedDetails::apply() {
}
}
void FormStandardFeedDetails::guessFeed() {
QPair<StandardFeed*, QNetworkReply::NetworkError> result = StandardFeed::guessFeed(m_ui->m_txtUrl->lineEdit()->text(),
m_ui->m_txtUsername->lineEdit()->text(),
m_ui->m_txtPassword->lineEdit()->text());
void FormStandardFeedDetails::setEditableFeed(Feed *editable_feed) {
FormFeedDetails::setEditableFeed(editable_feed);
if (result.first != NULL) {
// Icon or whole feed was guessed.
m_ui->m_btnIcon->setIcon(result.first->icon());
m_ui->m_txtTitle->lineEdit()->setText(result.first->title());
m_ui->m_txtDescription->lineEdit()->setText(result.first->description());
m_ui->m_cmbType->setCurrentIndex(m_ui->m_cmbType->findData(QVariant::fromValue((int) result.first->type())));
StandardFeed *feed = qobject_cast<StandardFeed*>(editable_feed);
int encoding_index = m_ui->m_cmbEncoding->findText(result.first->encoding(), Qt::MatchFixedString);
if (encoding_index >= 0) {
m_ui->m_cmbEncoding->setCurrentIndex(encoding_index);
}
else {
m_ui->m_cmbEncoding->setCurrentIndex(m_ui->m_cmbEncoding->findText(DEFAULT_FEED_ENCODING,
Qt::MatchFixedString));
}
if (result.second == QNetworkReply::NoError) {
m_ui->m_lblFetchMetadata->setStatus(WidgetWithStatus::Ok,
tr("All metadata fetched successfully."),
tr("Feed and icon metadata fetched."));
}
else {
m_ui->m_lblFetchMetadata->setStatus(WidgetWithStatus::Warning,
tr("Result: %1.").arg(NetworkFactory::networkErrorText(result.second)),
tr("Feed or icon metadata not fetched."));
}
// Remove temporary feed object.
delete result.first;
}
else {
// No feed guessed, even no icon available.
m_ui->m_lblFetchMetadata->setStatus(WidgetWithStatus::Error,
tr("Error: %1.").arg(NetworkFactory::networkErrorText(result.second)),
tr("No metadata fetched."));
}
}
void FormStandardFeedDetails::guessIconOnly() {
QPair<StandardFeed*, QNetworkReply::NetworkError> result = StandardFeed::guessFeed(m_ui->m_txtUrl->lineEdit()->text(),
m_ui->m_txtUsername->lineEdit()->text(),
m_ui->m_txtPassword->lineEdit()->text());
if (result.first != NULL) {
// Icon or whole feed was guessed.
m_ui->m_btnIcon->setIcon(result.first->icon());
if (result.second == QNetworkReply::NoError) {
m_ui->m_lblFetchMetadata->setStatus(WidgetWithStatus::Ok,
tr("Icon fetched successfully."),
tr("Icon metadata fetched."));
}
else {
m_ui->m_lblFetchMetadata->setStatus(WidgetWithStatus::Warning,
tr("Result: %1.").arg(NetworkFactory::networkErrorText(result.second)),
tr("Icon metadata not fetched."));
}
// Remove temporary feed object.
delete result.first;
}
else {
// No feed guessed, even no icon available.
m_ui->m_lblFetchMetadata->setStatus(WidgetWithStatus::Error,
tr("Error: %1.").arg(NetworkFactory::networkErrorText(result.second)),
tr("No icon fetched."));
}
}
void FormStandardFeedDetails::createConnections() {
// General connections.
connect(m_ui->m_buttonBox, SIGNAL(accepted()), this, SLOT(apply()));
connect(m_ui->m_txtTitle->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(onTitleChanged(QString)));
connect(m_ui->m_txtDescription->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(onDescriptionChanged(QString)));
connect(m_ui->m_txtUrl->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(onUrlChanged(QString)));
connect(m_ui->m_txtUsername->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(onUsernameChanged(QString)));
connect(m_ui->m_txtPassword->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(onPasswordChanged(QString)));
connect(m_ui->m_gbAuthentication, SIGNAL(toggled(bool)), this, SLOT(onAuthenticationSwitched()));
connect(m_ui->m_cmbAutoUpdateType, SIGNAL(currentIndexChanged(int)), this, SLOT(onAutoUpdateTypeChanged(int)));
connect(m_ui->m_btnFetchMetadata, SIGNAL(clicked()), this, SLOT(guessFeed()));
// Icon connections.
connect(m_actionFetchIcon, SIGNAL(triggered()), this, SLOT(guessIconOnly()));
connect(m_actionLoadIconFromFile, SIGNAL(triggered()), this, SLOT(onLoadIconFromFile()));
connect(m_actionNoIcon, SIGNAL(triggered()), this, SLOT(onNoIconSelected()));
connect(m_actionUseDefaultIcon, SIGNAL(triggered()), this, SLOT(onUseDefaultIcon()));
}
void FormStandardFeedDetails::setEditableFeed(StandardFeed *editable_feed) {
m_editableFeed = editable_feed;
m_ui->m_cmbParentCategory->setCurrentIndex(m_ui->m_cmbParentCategory->findData(QVariant::fromValue((void*) editable_feed->parent())));
m_ui->m_txtTitle->lineEdit()->setText(editable_feed->title());
m_ui->m_txtDescription->lineEdit()->setText(editable_feed->description());
m_ui->m_btnIcon->setIcon(editable_feed->icon());
m_ui->m_cmbType->setCurrentIndex(m_ui->m_cmbType->findData(QVariant::fromValue((int) editable_feed->type())));
m_ui->m_cmbEncoding->setCurrentIndex(m_ui->m_cmbEncoding->findData(editable_feed->encoding(), Qt::DisplayRole, Qt::MatchFixedString));
m_ui->m_gbAuthentication->setChecked(editable_feed->passwordProtected());
m_ui->m_txtUsername->lineEdit()->setText(editable_feed->username());
m_ui->m_txtPassword->lineEdit()->setText(editable_feed->password());
m_ui->m_txtUrl->lineEdit()->setText(editable_feed->url());
m_ui->m_cmbAutoUpdateType->setCurrentIndex(m_ui->m_cmbAutoUpdateType->findData(QVariant::fromValue((int) editable_feed->autoUpdateType())));
m_ui->m_spinAutoUpdateInterval->setValue(editable_feed->autoUpdateInitialInterval());
}
void FormStandardFeedDetails::initialize() {
m_ui.reset(new Ui::FormStandardFeedDetails());
m_ui->setupUi(this);
// Set flags and attributes.
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint);
setWindowIcon(qApp->icons()->fromTheme(QSL("application-rss+xml")));
// Setup button box.
m_ui->m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
// Set text boxes.
m_ui->m_txtTitle->lineEdit()->setPlaceholderText(tr("Feed title"));
m_ui->m_txtTitle->lineEdit()->setToolTip(tr("Set title for your feed."));
m_ui->m_txtDescription->lineEdit()->setPlaceholderText(tr("Feed description"));
m_ui->m_txtDescription->lineEdit()->setToolTip(tr("Set description for your feed."));
m_ui->m_txtUrl->lineEdit()->setPlaceholderText(tr("Full feed url including scheme"));
m_ui->m_txtUrl->lineEdit()->setToolTip(tr("Set url for your feed."));
m_ui->m_txtUsername->lineEdit()->setPlaceholderText(tr("Username"));
m_ui->m_txtUsername->lineEdit()->setToolTip(tr("Set username to access the feed."));
m_ui->m_txtPassword->lineEdit()->setPlaceholderText(tr("Password"));
m_ui->m_txtPassword->lineEdit()->setToolTip(tr("Set password to access the feed."));
// Add standard feed types.
m_ui->m_cmbType->addItem(StandardFeed::typeToString(StandardFeed::Atom10), QVariant::fromValue((int) StandardFeed::Atom10));
m_ui->m_cmbType->addItem(StandardFeed::typeToString(StandardFeed::Rdf), QVariant::fromValue((int) StandardFeed::Rdf));
m_ui->m_cmbType->addItem(StandardFeed::typeToString(StandardFeed::Rss0X), QVariant::fromValue((int) StandardFeed::Rss0X));
m_ui->m_cmbType->addItem(StandardFeed::typeToString(StandardFeed::Rss2X), QVariant::fromValue((int) StandardFeed::Rss2X));
// Load available encodings.
const QList<QByteArray> encodings = QTextCodec::availableCodecs();
QStringList encoded_encodings;
foreach (const QByteArray &encoding, encodings) {
encoded_encodings.append(encoding);
}
// Sort encodings and add them.
qSort(encoded_encodings.begin(), encoded_encodings.end(), TextFactory::isCaseInsensitiveLessThan);
m_ui->m_cmbEncoding->addItems(encoded_encodings);
// Setup menu & actions for icon selection.
m_iconMenu = new QMenu(tr("Icon selection"), this);
m_actionLoadIconFromFile = new QAction(qApp->icons()->fromTheme(QSL("image-x-generic")),
tr("Load icon from file..."),
this);
m_actionNoIcon = new QAction(qApp->icons()->fromTheme(QSL("dialog-error")),
tr("Do not use icon"),
this);
m_actionUseDefaultIcon = new QAction(qApp->icons()->fromTheme(QSL("application-rss+xml")),
tr("Use default icon"),
this);
m_actionFetchIcon = new QAction(qApp->icons()->fromTheme(QSL("emblem-downloads")),
tr("Fetch icon from feed"),
this);
m_iconMenu->addAction(m_actionFetchIcon);
m_iconMenu->addAction(m_actionLoadIconFromFile);
m_iconMenu->addAction(m_actionUseDefaultIcon);
m_iconMenu->addAction(m_actionNoIcon);
m_ui->m_btnIcon->setMenu(m_iconMenu);
// Set feed metadata fetch label.
m_ui->m_lblFetchMetadata->setStatus(WidgetWithStatus::Information,
tr("No metadata fetched so far."),
tr("No metadata fetched so far."));
// Setup auto-update options.
m_ui->m_spinAutoUpdateInterval->setValue(DEFAULT_AUTO_UPDATE_INTERVAL);
m_ui->m_cmbAutoUpdateType->addItem(tr("Auto-update using global interval"), QVariant::fromValue((int) Feed::DefaultAutoUpdate));
m_ui->m_cmbAutoUpdateType->addItem(tr("Auto-update every"), QVariant::fromValue((int) Feed::SpecificAutoUpdate));
m_ui->m_cmbAutoUpdateType->addItem(tr("Do not auto-update at all"), QVariant::fromValue((int) Feed::DontAutoUpdate));
// Set tab order.
setTabOrder(m_ui->m_cmbParentCategory, m_ui->m_cmbType);
setTabOrder(m_ui->m_cmbType, m_ui->m_cmbEncoding);
setTabOrder(m_ui->m_cmbEncoding, m_ui->m_cmbAutoUpdateType);
setTabOrder(m_ui->m_cmbAutoUpdateType, m_ui->m_spinAutoUpdateInterval);
setTabOrder(m_ui->m_spinAutoUpdateInterval, m_ui->m_txtTitle->lineEdit());
setTabOrder(m_ui->m_txtTitle->lineEdit(), m_ui->m_txtDescription->lineEdit());
setTabOrder(m_ui->m_txtDescription->lineEdit(), m_ui->m_txtUrl->lineEdit());
setTabOrder(m_ui->m_txtUrl->lineEdit(), m_ui->m_btnFetchMetadata);
setTabOrder(m_ui->m_btnFetchMetadata, m_ui->m_btnIcon);
setTabOrder(m_ui->m_btnIcon, m_ui->m_gbAuthentication);
setTabOrder(m_ui->m_gbAuthentication, m_ui->m_txtUsername->lineEdit());
setTabOrder(m_ui->m_txtUsername->lineEdit(), m_ui->m_txtPassword->lineEdit());
m_ui->m_txtUrl->lineEdit()->setFocus(Qt::TabFocusReason);
}
void FormStandardFeedDetails::loadCategories(const QList<Category*> categories, RootItem *root_item) {
m_ui->m_cmbParentCategory->addItem(root_item->icon(),
root_item->title(),
QVariant::fromValue((void*) root_item));
foreach (Category *category, categories) {
m_ui->m_cmbParentCategory->addItem(category->icon(),
category->title(),
QVariant::fromValue((void*) category));
}
m_ui->m_cmbType->setCurrentIndex(m_ui->m_cmbType->findData(QVariant::fromValue((int) feed->type())));
m_ui->m_cmbEncoding->setCurrentIndex(m_ui->m_cmbEncoding->findData(feed->encoding(), Qt::DisplayRole, Qt::MatchFixedString));
m_ui->m_gbAuthentication->setChecked(feed->passwordProtected());
m_ui->m_txtUsername->lineEdit()->setText(feed->username());
m_ui->m_txtPassword->lineEdit()->setText(feed->password());
}

View File

@ -15,81 +15,23 @@
// 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 FORMSTANDARDFEEDDETAILS_H
#define FORMSTANDARDFEEDDETAILS_H
#ifndef FORMSSFEEDDETAILS_H
#define FORMSSFEEDDETAILS_H
#include <QDialog>
#include "ui_formstandardfeeddetails.h"
#include "services/abstract/gui/formfeeddetails.h"
namespace Ui {
class FormStandardFeedDetails;
}
class StandardServiceRoot;
class StandardFeed;
class Category;
class RootItem;
class FormStandardFeedDetails : public QDialog {
class FormStandardFeedDetails : public FormFeedDetails {
Q_OBJECT
public:
// Constructors and destructors.
explicit FormStandardFeedDetails(StandardServiceRoot *service_root, QWidget *parent = 0);
virtual ~FormStandardFeedDetails();
public slots:
// Executes add/edit standard feed dialog.
int exec(StandardFeed *input_feed, RootItem *parent_to_select, const QString &url = QString());
explicit FormStandardFeedDetails(ServiceRoot *service_root, QWidget *parent = 0);
protected slots:
// Applies changes.
void apply();
void guessFeed();
void guessIconOnly();
// Trigerred when title/description/url/username/password changes.
void onTitleChanged(const QString &new_title);
void onDescriptionChanged(const QString &new_description);
void onUrlChanged(const QString &new_url);
void onUsernameChanged(const QString &new_username);
void onPasswordChanged(const QString &new_password);
void onAuthenticationSwitched();
void onAutoUpdateTypeChanged(int new_index);
// Check if "OK" button can be enabled or not.
void checkOkButtonEnabled();
// Icon selectors.
void onNoIconSelected();
void onLoadIconFromFile();
void onUseDefaultIcon();
protected:
// Creates needed connections.
void createConnections();
// Sets the feed which will be edited.
void setEditableFeed(StandardFeed *editable_feed);
// Initializes the dialog.
void initialize();
// Loads categories into the dialog from the model.
void loadCategories(const QList<Category*> categories, RootItem *root_item);
private:
QScopedPointer<Ui::FormStandardFeedDetails> m_ui;
StandardFeed *m_editableFeed;
StandardServiceRoot *m_serviceRoot;
QMenu *m_iconMenu;
QAction *m_actionLoadIconFromFile;
QAction *m_actionUseDefaultIcon;
QAction *m_actionFetchIcon;
QAction *m_actionNoIcon;
void setEditableFeed(Feed *editable_feed);
};
#endif // FORMSTANDARDFEEDDETAILS_H
#endif // FORMSSFEEDDETAILS_H

View File

@ -30,8 +30,8 @@
#include "gui/feedmessageviewer.h"
#include "gui/feedsview.h"
#include "services/abstract/recyclebin.h"
#include "services/standard/standardserviceroot.h"
#include "services/standard/gui/formstandardfeeddetails.h"
#include "services/standard/standardserviceroot.h"
#include <QVariant>
#include <QTextCodec>
@ -94,7 +94,6 @@ StandardServiceRoot *StandardFeed::serviceRoot() const {
bool StandardFeed::editViaGui() {
QScopedPointer<FormStandardFeedDetails> form_pointer(new FormStandardFeedDetails(serviceRoot(), qApp->mainForm()));
form_pointer.data()->exec(this, NULL);
return false;
}

View File

@ -1,245 +0,0 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2016 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 "services/tt-rss/gui/formeditfeed.h"
#include "services/abstract/category.h"
#include "services/tt-rss/definitions.h"
#include "services/tt-rss/ttrssfeed.h"
#include "services/tt-rss/ttrsscategory.h"
#include "services/tt-rss/ttrssserviceroot.h"
#include "services/tt-rss/network/ttrssnetworkfactory.h"
#include "gui/dialogs/formmain.h"
#include "miscellaneous/iconfactory.h"
#include "miscellaneous/application.h"
#include <QClipboard>
#include <QMimeData>
#include <QTimer>
FormEditFeed::FormEditFeed(TtRssServiceRoot *root, QWidget *parent)
: QDialog(parent), m_ui(new Ui::FormEditFeed), m_root(root), m_loadedFeed(NULL) {
m_ui->setupUi(this);
initialize();
connect(m_ui->m_txtUrl->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(onUrlChanged(QString)));
connect(m_ui->m_gbAuthentication, SIGNAL(toggled(bool)), this, SLOT(onAuthenticationSwitched()));
connect(m_ui->m_cmbAutoUpdateType, SIGNAL(currentIndexChanged(int)), this, SLOT(onAutoUpdateTypeChanged(int)));
connect(m_ui->m_buttonBox, SIGNAL(accepted()), this, SLOT(performAction()));
}
FormEditFeed::~FormEditFeed() {
}
int FormEditFeed::execForEdit(TtRssFeed *input_feed) {
loadCategories(m_root->getSubTreeCategories(), m_root);
loadFeed(input_feed);
m_ui->m_txtUrl->lineEdit()->setFocus();
return QDialog::exec();
}
int FormEditFeed::execForAdd(const QString &url) {
if (!url.isEmpty()) {
m_ui->m_txtUrl->lineEdit()->setText(url);
}
else if (Application::clipboard()->mimeData()->hasText()) {
m_ui->m_txtUrl->lineEdit()->setText(Application::clipboard()->text());
}
loadCategories(m_root->getSubTreeCategories(), m_root);
loadFeed(NULL);
m_ui->m_txtUrl->lineEdit()->setFocus();
return QDialog::exec();
}
void FormEditFeed::onAuthenticationSwitched() {
onUsernameChanged(m_ui->m_txtUsername->lineEdit()->text());
onPasswordChanged(m_ui->m_txtPassword->lineEdit()->text());
}
void FormEditFeed::onAutoUpdateTypeChanged(int new_index) {
const Feed::AutoUpdateType auto_update_type = static_cast<Feed::AutoUpdateType>(m_ui->m_cmbAutoUpdateType->itemData(new_index).toInt());
switch (auto_update_type) {
case Feed::DontAutoUpdate:
case Feed::DefaultAutoUpdate:
m_ui->m_spinAutoUpdateInterval->setEnabled(false);
break;
case Feed::SpecificAutoUpdate:
default:
m_ui->m_spinAutoUpdateInterval->setEnabled(true);
}
}
void FormEditFeed::performAction() {
if (m_loadedFeed != NULL) {
// Edit given feed.
saveFeed();
}
else {
addNewFeed();
}
accept();
}
void FormEditFeed::onUrlChanged(const QString &new_url) {
if (QRegExp(URL_REGEXP).exactMatch(new_url)) {
// New url is well-formed.
m_ui->m_txtUrl->setStatus(LineEditWithStatus::Ok, tr("The URL is ok."));
}
else if (!new_url.isEmpty()) {
// New url is not well-formed but is not empty on the other hand.
m_ui->m_txtUrl->setStatus(LineEditWithStatus::Warning, tr("The URL does not meet standard pattern. Does your URL start with \"http://\" or \"https://\" prefix."));
}
else {
// New url is empty.
m_ui->m_txtUrl->setStatus(LineEditWithStatus::Error, tr("The URL is empty."));
}
}
void FormEditFeed::onUsernameChanged(const QString &new_username) {
const bool is_username_ok = !m_ui->m_gbAuthentication->isChecked() || !new_username.isEmpty();
m_ui->m_txtUsername->setStatus(is_username_ok ?
LineEditWithStatus::Ok :
LineEditWithStatus::Warning,
is_username_ok ?
tr("Username is ok or it is not needed.") :
tr("Username is empty."));
}
void FormEditFeed::onPasswordChanged(const QString &new_password) {
const bool is_password_ok = !m_ui->m_gbAuthentication->isChecked() || !new_password.isEmpty();
m_ui->m_txtPassword->setStatus(is_password_ok ?
LineEditWithStatus::Ok :
LineEditWithStatus::Warning,
is_password_ok ?
tr("Password is ok or it is not needed.") :
tr("Password is empty."));
}
void FormEditFeed::initialize() {
setWindowIcon(qApp->icons()->fromTheme(QSL("application-rss+xml")));
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint);
// Setup auto-update options.
m_ui->m_spinAutoUpdateInterval->setValue(DEFAULT_AUTO_UPDATE_INTERVAL);
m_ui->m_cmbAutoUpdateType->addItem(tr("Auto-update using global interval"), QVariant::fromValue((int) Feed::DefaultAutoUpdate));
m_ui->m_cmbAutoUpdateType->addItem(tr("Auto-update every"), QVariant::fromValue((int) Feed::SpecificAutoUpdate));
m_ui->m_cmbAutoUpdateType->addItem(tr("Do not auto-update at all"), QVariant::fromValue((int) Feed::DontAutoUpdate));
setTabOrder(m_ui->m_txtUrl->lineEdit(), m_ui->m_cmbAutoUpdateType);
setTabOrder(m_ui->m_cmbAutoUpdateType, m_ui->m_spinAutoUpdateInterval);
setTabOrder(m_ui->m_spinAutoUpdateInterval, m_ui->m_gbAuthentication);
setTabOrder(m_ui->m_gbAuthentication, m_ui->m_txtUsername->lineEdit());
setTabOrder(m_ui->m_txtUsername->lineEdit(), m_ui->m_txtPassword->lineEdit());
setTabOrder(m_ui->m_txtPassword->lineEdit(), m_ui->m_buttonBox);
m_ui->m_txtUrl->lineEdit()->setPlaceholderText(tr("Full feed url including scheme"));
m_ui->m_txtUsername->lineEdit()->setPlaceholderText(tr("Username"));
m_ui->m_txtPassword->lineEdit()->setPlaceholderText(tr("Password"));
onAuthenticationSwitched();
}
void FormEditFeed::loadFeed(TtRssFeed *input_feed) {
m_loadedFeed = input_feed;
if (input_feed != NULL) {
setWindowTitle(tr("Edit existing feed"));
// Tiny Tiny RSS does not support editing of these features.
// User can edit only individual auto-update statuses.
m_ui->m_gbAuthentication->setEnabled(false);
m_ui->m_txtUrl->setEnabled(false);
m_ui->m_lblUrl->setEnabled(false);
m_ui->m_lblParentCategory->setEnabled(false);
m_ui->m_cmbParentCategory->setEnabled(false);
m_ui->m_cmbParentCategory->setCurrentIndex(m_ui->m_cmbParentCategory->findData(QVariant::fromValue((void*) input_feed->parent())));
m_ui->m_cmbAutoUpdateType->setCurrentIndex(m_ui->m_cmbAutoUpdateType->findData(QVariant::fromValue((int) input_feed->autoUpdateType())));
m_ui->m_spinAutoUpdateInterval->setValue(input_feed->autoUpdateInitialInterval());
}
else {
setWindowTitle(tr("Add new feed"));
// Tiny Tiny RSS does not support editing of these features.
// User can edit only individual auto-update statuses.
m_ui->m_gbAuthentication->setEnabled(true);
m_ui->m_txtUrl->setEnabled(true);
m_ui->m_lblUrl->setEnabled(true);
m_ui->m_lblParentCategory->setEnabled(true);
m_ui->m_cmbParentCategory->setEnabled(true);
}
}
void FormEditFeed::saveFeed() {
// User edited auto-update status. Save it.
TtRssFeed *new_feed_data = new TtRssFeed();
new_feed_data->setAutoUpdateType(static_cast<Feed::AutoUpdateType>(m_ui->m_cmbAutoUpdateType->itemData(m_ui->m_cmbAutoUpdateType->currentIndex()).toInt()));
new_feed_data->setAutoUpdateInitialInterval(m_ui->m_spinAutoUpdateInterval->value());
m_loadedFeed->editItself(new_feed_data);
delete new_feed_data;
}
void FormEditFeed::addNewFeed() {
RootItem *parent = static_cast<RootItem*>(m_ui->m_cmbParentCategory->itemData(m_ui->m_cmbParentCategory->currentIndex()).value<void*>());
TtRssServiceRoot *root = parent->kind() == RootItemKind::Category ?
qobject_cast<TtRssCategory*>(parent)->serviceRoot() :
qobject_cast<TtRssServiceRoot*>(parent);
const int category_id = parent->kind() == RootItemKind::ServiceRoot ?
0 :
qobject_cast<TtRssCategory*>(parent)->customId();
const TtRssSubscribeToFeedResponse response = root->network()->subscribeToFeed(m_ui->m_txtUrl->lineEdit()->text(),
category_id,
m_ui->m_gbAuthentication->isChecked(),
m_ui->m_txtUsername->lineEdit()->text(),
m_ui->m_txtPassword->lineEdit()->text());
if (response.code() == STF_INSERTED) {
// Feed was added online.
accept();
qApp->showGuiMessage(tr("Feed added"), tr("Feed was added, triggering sync in now."), QSystemTrayIcon::Information);
QTimer::singleShot(100, root, SLOT(syncIn()));
}
else {
reject();
qApp->showGuiMessage(tr("Cannot add feed"),
tr("Feed was not added due to error."),
QSystemTrayIcon::Critical, qApp->mainForm(), true);
}
}
void FormEditFeed::loadCategories(const QList<Category*> categories, RootItem *root_item) {
m_ui->m_cmbParentCategory->addItem(root_item->icon(),
root_item->title(),
QVariant::fromValue((void*) root_item));
foreach (Category *category, categories) {
m_ui->m_cmbParentCategory->addItem(category->icon(),
category->title(),
QVariant::fromValue((void*) category));
}
}

View File

@ -1,65 +0,0 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2016 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 FORMEDITFEED_H
#define FORMEDITFEED_H
#include <QDialog>
#include "ui_formeditfeed.h"
namespace Ui {
class FormEditFeed;
}
class TtRssServiceRoot;
class TtRssFeed;
class Category;
class RootItem;
class FormEditFeed : public QDialog {
Q_OBJECT
public:
explicit FormEditFeed(TtRssServiceRoot *root, QWidget *parent = 0);
virtual ~FormEditFeed();
int execForEdit(TtRssFeed *input_feed);
int execForAdd(const QString &url);
private slots:
void performAction();
void onAuthenticationSwitched();
void onAutoUpdateTypeChanged(int new_index);
void onUrlChanged(const QString &new_url);
void onUsernameChanged(const QString &new_username);
void onPasswordChanged(const QString &new_password);
private:
void initialize();
void loadFeed(TtRssFeed *input_feed);
void saveFeed();
void addNewFeed();
void loadCategories(const QList<Category*> categories, RootItem *root_item);
QScopedPointer<Ui::FormEditFeed> m_ui;
TtRssServiceRoot *m_root;
TtRssFeed *m_loadedFeed;
};
#endif // FORMEDITFEED_H

View File

@ -1,179 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FormEditFeed</class>
<widget class="QDialog" name="FormEditFeed">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>598</width>
<height>263</height>
</rect>
</property>
<property name="windowTitle">
<string>Edit feed</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="m_lblParentCategory">
<property name="text">
<string>Parent category</string>
</property>
<property name="buddy">
<cstring>m_cmbParentCategory</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="m_cmbParentCategory">
<property name="toolTip">
<string>Select parent item for your feed.</string>
</property>
<property name="iconSize">
<size>
<width>12</width>
<height>12</height>
</size>
</property>
<property name="frame">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="m_lblUrl">
<property name="text">
<string>URL</string>
</property>
<property name="buddy">
<cstring>m_txtUrl</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="LineEditWithStatus" name="m_txtUrl" native="true"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Auto-update</string>
</property>
<property name="buddy">
<cstring>m_cmbAutoUpdateType</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QComboBox" name="m_cmbAutoUpdateType">
<property name="toolTip">
<string>Select the auto-update strategy for this feed. Default auto-update strategy means that the feed will be update in time intervals set in application settings.</string>
</property>
</widget>
</item>
<item>
<widget class="TimeSpinBox" name="m_spinAutoUpdateInterval">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="0" colspan="2">
<widget class="QGroupBox" name="m_gbAuthentication">
<property name="toolTip">
<string>Some feeds require authentication, including GMail feeds. BASIC, NTLM-2 and DIGEST-MD5 authentication schemes are supported.</string>
</property>
<property name="title">
<string>Requires authentication</string>
</property>
<property name="flat">
<bool>false</bool>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Username</string>
</property>
<property name="buddy">
<cstring>m_txtUsername</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="LineEditWithStatus" name="m_txtUsername" native="true"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Password</string>
</property>
<property name="buddy">
<cstring>m_txtPassword</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="LineEditWithStatus" name="m_txtPassword" native="true"/>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="m_buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>LineEditWithStatus</class>
<extends>QWidget</extends>
<header>lineeditwithstatus.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>TimeSpinBox</class>
<extends>QDoubleSpinBox</extends>
<header>timespinbox.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>m_buttonBox</sender>
<signal>rejected()</signal>
<receiver>FormEditFeed</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>234</x>
<y>78</y>
</hint>
<hint type="destinationlabel">
<x>234</x>
<y>49</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -0,0 +1,96 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2016 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 "services/tt-rss/gui/formttrssfeeddetails.h"
#include "services/tt-rss/definitions.h"
#include "services/tt-rss/ttrssserviceroot.h"
#include "services/tt-rss/ttrsscategory.h"
#include "services/tt-rss/network/ttrssnetworkfactory.h"
#include "miscellaneous/application.h"
#include "gui/dialogs/formmain.h"
#include <QTimer>
FormTtRssFeedDetails::FormTtRssFeedDetails(ServiceRoot *service_root, QWidget *parent)
: FormFeedDetails(service_root, parent) {
m_ui->m_cmbAutoUpdateType->setEnabled(false);
m_ui->m_spinAutoUpdateInterval->setEnabled(false);
m_ui->m_cmbType->setEnabled(false);
m_ui->m_cmbEncoding->setEnabled(false);
m_ui->m_btnFetchMetadata->setEnabled(false);
m_ui->m_btnIcon->setEnabled(false);
m_ui->m_txtTitle->setEnabled(false);
m_ui->m_txtDescription->setEnabled(false);
}
void FormTtRssFeedDetails::apply() {
if (m_editableFeed != NULL) {
// No action to perform.
}
else {
RootItem *parent = static_cast<RootItem*>(m_ui->m_cmbParentCategory->itemData(m_ui->m_cmbParentCategory->currentIndex()).value<void*>());
TtRssServiceRoot *root = parent->kind() == RootItemKind::Category ?
qobject_cast<TtRssCategory*>(parent)->serviceRoot() :
qobject_cast<TtRssServiceRoot*>(parent);
const int category_id = parent->kind() == RootItemKind::ServiceRoot ?
0 :
qobject_cast<TtRssCategory*>(parent)->customId();
const TtRssSubscribeToFeedResponse response = root->network()->subscribeToFeed(m_ui->m_txtUrl->lineEdit()->text(),
category_id,
m_ui->m_gbAuthentication->isChecked(),
m_ui->m_txtUsername->lineEdit()->text(),
m_ui->m_txtPassword->lineEdit()->text());
if (response.code() == STF_INSERTED) {
// Feed was added online.
accept();
qApp->showGuiMessage(tr("Feed added"), tr("Feed was added, triggering sync in now."), QSystemTrayIcon::Information);
QTimer::singleShot(100, root, SLOT(syncIn()));
}
else {
reject();
qApp->showGuiMessage(tr("Cannot add feed"),
tr("Feed was not added due to error."),
QSystemTrayIcon::Critical, qApp->mainForm(), true);
}
}
accept();
}
void FormTtRssFeedDetails::setEditableFeed(Feed *editable_feed) {
FormFeedDetails::setEditableFeed(editable_feed);
if (editable_feed != NULL) {
// Tiny Tiny RSS does not support editing of these features.
// User can edit only individual auto-update statuses.
m_ui->m_gbAuthentication->setEnabled(false);
m_ui->m_txtUrl->setEnabled(false);
m_ui->m_lblParentCategory->setEnabled(false);
m_ui->m_cmbParentCategory->setEnabled(false);
}
else {
// Tiny Tiny RSS does not support editing of these features.
// User can edit only individual auto-update statuses.
m_ui->m_gbAuthentication->setEnabled(true);
m_ui->m_txtUrl->setEnabled(true);
m_ui->m_lblParentCategory->setEnabled(true);
m_ui->m_cmbParentCategory->setEnabled(true);
}
}

View File

@ -0,0 +1,38 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2016 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 FORMTTRSSFEEDDETAILS_H
#define FORMTTRSSFEEDDETAILS_H
#include "services/abstract/gui/formfeeddetails.h"
class FormTtRssFeedDetails : public FormFeedDetails {
Q_OBJECT
public:
explicit FormTtRssFeedDetails(ServiceRoot *service_root, QWidget *parent = 0);
// FormFeedDetails interface
protected slots:
void apply();
protected:
void setEditableFeed(Feed *editable_feed);
};
#endif // FORMTTRSSFEEDDETAILS_H

View File

@ -26,7 +26,6 @@
#include "services/tt-rss/definitions.h"
#include "services/tt-rss/ttrssserviceroot.h"
#include "services/tt-rss/ttrsscategory.h"
#include "services/tt-rss/gui/formeditfeed.h"
#include "services/tt-rss/network/ttrssnetworkfactory.h"
#include <QPointer>
@ -96,14 +95,10 @@ QVariant TtRssFeed::data(int column, int role) const {
}
bool TtRssFeed::canBeEdited() const {
return true;
return false;
}
bool TtRssFeed::editViaGui() {
QPointer<FormEditFeed> form_pointer = new FormEditFeed(serviceRoot(), qApp->mainForm());
form_pointer.data()->execForEdit(this);
delete form_pointer.data();
return false;
}

View File

@ -31,7 +31,7 @@
#include "services/tt-rss/definitions.h"
#include "services/tt-rss/network/ttrssnetworkfactory.h"
#include "services/tt-rss/gui/formeditaccount.h"
#include "services/tt-rss/gui/formeditfeed.h"
#include "services/tt-rss/gui/formttrssfeeddetails.h"
#include <QSqlTableModel>
#include <QPair>
@ -122,9 +122,9 @@ void TtRssServiceRoot::addNewFeed(const QString &url) {
return;
}
QScopedPointer<FormEditFeed> form_pointer(new FormEditFeed(this, qApp->mainForm()));
QScopedPointer<FormTtRssFeedDetails> form_pointer(new FormTtRssFeedDetails(this, qApp->mainForm()));
form_pointer.data()->execForAdd(url);
form_pointer.data()->exec(NULL, this, url);
qApp->feedUpdateLock()->unlock();
}