Added gmail edit acc dialog.

This commit is contained in:
Martin Rotter 2017-10-17 14:00:30 +02:00
parent b72375e8e8
commit 29be179ea1
9 changed files with 469 additions and 6 deletions

View file

@ -504,7 +504,8 @@ equals(USE_WEBENGINE, true) {
src/services/gmail/gmailentrypoint.h \ src/services/gmail/gmailentrypoint.h \
src/services/gmail/gmailserviceroot.h \ src/services/gmail/gmailserviceroot.h \
src/services/gmail/gmailfeed.h \ src/services/gmail/gmailfeed.h \
src/services/gmail/network/gmailnetworkfactory.h src/services/gmail/network/gmailnetworkfactory.h \
src/services/gmail/gui/formeditgmailaccount.h
SOURCES += src/gui/locationlineedit.cpp \ SOURCES += src/gui/locationlineedit.cpp \
src/gui/webviewer.cpp \ src/gui/webviewer.cpp \
@ -523,7 +524,8 @@ equals(USE_WEBENGINE, true) {
src/services/gmail/gmailentrypoint.cpp \ src/services/gmail/gmailentrypoint.cpp \
src/services/gmail/gmailserviceroot.cpp \ src/services/gmail/gmailserviceroot.cpp \
src/services/gmail/gmailfeed.cpp \ src/services/gmail/gmailfeed.cpp \
src/services/gmail/network/gmailnetworkfactory.cpp src/services/gmail/network/gmailnetworkfactory.cpp \
src/services/gmail/gui/formeditgmailaccount.cpp
# Add AdBlock sources. # Add AdBlock sources.
HEADERS += src/network-web/adblock/adblockaddsubscriptiondialog.h \ HEADERS += src/network-web/adblock/adblockaddsubscriptiondialog.h \
@ -558,7 +560,8 @@ equals(USE_WEBENGINE, true) {
FORMS += src/network-web/adblock/adblockaddsubscriptiondialog.ui \ FORMS += src/network-web/adblock/adblockaddsubscriptiondialog.ui \
src/network-web/adblock/adblockdialog.ui \ src/network-web/adblock/adblockdialog.ui \
src/services/inoreader/gui/formeditinoreaderaccount.ui \ src/services/inoreader/gui/formeditinoreaderaccount.ui \
src/gui/dialogs/oauthlogin.ui src/gui/dialogs/oauthlogin.ui \
src/services/gmail/gui/formeditgmailaccount.ui
} }
else { else {
HEADERS += src/gui/messagepreviewer.h \ HEADERS += src/gui/messagepreviewer.h \

View file

@ -29,6 +29,7 @@
#define ARGUMENTS_LIST_SEPARATOR "\n" #define ARGUMENTS_LIST_SEPARATOR "\n"
#define LOCALHOST_ADDRESS "http://localhost"
#define ADBLOCK_ADBLOCKED_PAGE "adblockedpage" #define ADBLOCK_ADBLOCKED_PAGE "adblockedpage"
#define ADBLOCK_HOWTO_FILTERS "http://adblockplus.org/en/filters" #define ADBLOCK_HOWTO_FILTERS "http://adblockplus.org/en/filters"
#define ADBLOCK_UPDATE_DAYS_INTERVAL 5 #define ADBLOCK_UPDATE_DAYS_INTERVAL 5

View file

@ -55,7 +55,7 @@ OAuth2Service::OAuth2Service(QString authUrl, QString tokenUrl, QString clientId
QString clientSecret, QString scope, QObject* parent) QString clientSecret, QString scope, QObject* parent)
: QObject(parent), m_timerId(-1), m_tokensExpireIn(QDateTime()) { : QObject(parent), m_timerId(-1), m_tokensExpireIn(QDateTime()) {
m_redirectUrl = QSL(INOREADER_OAUTH_CLI_REDIRECT); m_redirectUrl = QSL(LOCALHOST_ADDRESS);
m_tokenGrantType = QSL("authorization_code"); m_tokenGrantType = QSL("authorization_code");
m_tokenUrl = QUrl(tokenUrl); m_tokenUrl = QUrl(tokenUrl);
m_authUrl = authUrl; m_authUrl = authUrl;

View file

@ -22,6 +22,9 @@
#define GMAIL_OAUTH_AUTH_URL "https://accounts.google.com/o/oauth2/auth" #define GMAIL_OAUTH_AUTH_URL "https://accounts.google.com/o/oauth2/auth"
#define GMAIL_OAUTH_TOKEN_URL "https://accounts.google.com/o/oauth2/token" #define GMAIL_OAUTH_TOKEN_URL "https://accounts.google.com/o/oauth2/token"
#define GMAIL_OAUTH_SCOPE "https://mail.google.com/" #define GMAIL_OAUTH_SCOPE "https://mail.google.com/"
#define GMAIL_DEFAULT_BATCH_SIZE 100 #define GMAIL_DEFAULT_BATCH_SIZE 100
#define GMAIL_MAX_BATCH_SIZE 999
#define GMAIL_MIN_BATCH_SIZE 20
#endif // GMAIL_DEFINITIONS_H #endif // GMAIL_DEFINITIONS_H

View file

@ -0,0 +1,204 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/gmail/gui/formeditgmailaccount.h"
#include "gui/guiutilities.h"
#include "miscellaneous/application.h"
#include "miscellaneous/iconfactory.h"
#include "network-web/oauth2service.h"
#include "services/gmail/definitions.h"
#include "services/gmail/gmailserviceroot.h"
FormEditGmailAccount::FormEditGmailAccount(QWidget* parent) : QDialog(parent),
m_oauth(new OAuth2Service(GMAIL_OAUTH_AUTH_URL, GMAIL_OAUTH_TOKEN_URL,
QString(), QString(), GMAIL_OAUTH_SCOPE)), m_editableRoot(nullptr) {
m_ui.setupUi(this);
GuiUtilities::setLabelAsNotice(*m_ui.m_lblAuthInfo, true);
GuiUtilities::applyDialogProperties(*this, qApp->icons()->miscIcon(QSL("gmail")));
m_ui.m_lblTestResult->setStatus(WidgetWithStatus::StatusType::Information,
tr("Not tested yet."),
tr("Not tested yet."));
m_ui.m_lblTestResult->label()->setWordWrap(true);
m_ui.m_txtUsername->lineEdit()->setPlaceholderText(tr("User-visible username"));
setTabOrder(m_ui.m_txtUsername->lineEdit(), m_ui.m_txtAppId);
setTabOrder(m_ui.m_txtAppId, m_ui.m_txtAppKey);
setTabOrder(m_ui.m_txtAppKey, m_ui.m_txtRedirectUrl);
setTabOrder(m_ui.m_txtRedirectUrl, m_ui.m_spinLimitMessages);
setTabOrder(m_ui.m_spinLimitMessages, m_ui.m_btnTestSetup);
setTabOrder(m_ui.m_btnTestSetup, m_ui.m_buttonBox);
connect(m_ui.m_txtAppId->lineEdit(), &BaseLineEdit::textChanged, this, &FormEditGmailAccount::checkOAuthValue);
connect(m_ui.m_txtAppKey->lineEdit(), &BaseLineEdit::textChanged, this, &FormEditGmailAccount::checkOAuthValue);
connect(m_ui.m_txtRedirectUrl->lineEdit(), &BaseLineEdit::textChanged, this, &FormEditGmailAccount::checkOAuthValue);
connect(m_ui.m_txtUsername->lineEdit(), &BaseLineEdit::textChanged, this, &FormEditGmailAccount::checkUsername);
connect(m_ui.m_btnTestSetup, &QPushButton::clicked, this, &FormEditGmailAccount::testSetup);
connect(m_ui.m_buttonBox, &QDialogButtonBox::accepted, this, &FormEditGmailAccount::onClickedOk);
connect(m_ui.m_buttonBox, &QDialogButtonBox::rejected, this, &FormEditGmailAccount::onClickedCancel);
m_ui.m_spinLimitMessages->setValue(GMAIL_DEFAULT_BATCH_SIZE);
m_ui.m_spinLimitMessages->setMinimum(GMAIL_MIN_BATCH_SIZE);
m_ui.m_spinLimitMessages->setMaximum(GMAIL_MAX_BATCH_SIZE);
checkUsername(m_ui.m_txtUsername->lineEdit()->text());
hookNetwork();
}
FormEditGmailAccount::~FormEditGmailAccount() {}
void FormEditGmailAccount::testSetup() {
if (m_oauth->clientId() != m_ui.m_txtAppId->lineEdit()->text() ||
m_oauth->clientSecret() != m_ui.m_txtAppKey->lineEdit()->text() ||
m_oauth->redirectUrl() != m_ui.m_txtRedirectUrl->lineEdit()->text()) {
// User changed some important settings. Log out.
m_oauth->logout();
}
m_oauth->setClientId(m_ui.m_txtAppId->lineEdit()->text());
m_oauth->setClientSecret(m_ui.m_txtAppKey->lineEdit()->text());
m_oauth->setRedirectUrl(m_ui.m_txtRedirectUrl->lineEdit()->text());
if (m_oauth->login()) {
m_ui.m_lblTestResult->setStatus(WidgetWithStatus::StatusType::Ok,
tr("You are already logged in."),
tr("Access granted. \
"));
}
}
void FormEditGmailAccount::onClickedOk() {
bool editing_account = true;
if (m_editableRoot == nullptr) {
// We want to confirm newly created account.
// So save new account into DB, setup its properties.
m_editableRoot = new GmailServiceRoot(nullptr);
editing_account = false;
}
// We copy credentials from testing OAuth to live OAuth.
m_editableRoot->network()->oauth()->setAccessToken(m_oauth->accessToken());
m_editableRoot->network()->oauth()->setRefreshToken(m_oauth->refreshToken());
m_editableRoot->network()->oauth()->setTokensExpireIn(m_oauth->tokensExpireIn());
m_editableRoot->network()->oauth()->setClientId(m_ui.m_txtAppId->lineEdit()->text());
m_editableRoot->network()->oauth()->setClientSecret(m_ui.m_txtAppKey->lineEdit()->text());
m_editableRoot->network()->oauth()->setRedirectUrl(m_ui.m_txtRedirectUrl->lineEdit()->text());
m_editableRoot->network()->setUsername(m_ui.m_txtUsername->lineEdit()->text());
m_editableRoot->network()->setBatchSize(m_ui.m_spinLimitMessages->value());
m_editableRoot->saveAccountDataToDatabase();
accept();
if (editing_account) {
m_editableRoot->completelyRemoveAllData();
m_editableRoot->syncIn();
}
}
void FormEditGmailAccount::onClickedCancel() {
reject();
}
void FormEditGmailAccount::checkUsername(const QString& username) {
if (username.isEmpty()) {
m_ui.m_txtUsername->setStatus(WidgetWithStatus::StatusType::Error, tr("No username entered. \
"));
}
else {
m_ui.m_txtUsername->setStatus(WidgetWithStatus::StatusType::Ok, tr("Some username entered. \
"));
}
}
void FormEditGmailAccount::onAuthFailed() {
m_ui.m_lblTestResult->setStatus(WidgetWithStatus::StatusType::Error,
tr("You did not grant access."),
tr("There was error during testing."));
}
void FormEditGmailAccount::onAuthError(const QString& error, const QString& detailed_description) {
Q_UNUSED(error)
m_ui.m_lblTestResult->setStatus(WidgetWithStatus::StatusType::Error,
tr("There is error. %1 ").arg(detailed_description),
tr("There was error during testing."));
}
void FormEditGmailAccount::onAuthGranted() {
m_ui.m_lblTestResult->setStatus(WidgetWithStatus::StatusType::Ok,
tr("Tested successfully.You may be prompted to login once more."),
tr("Your access was approved."));
}
void FormEditGmailAccount::hookNetwork() {
connect(m_oauth, &OAuth2Service::tokensReceived, this, &FormEditGmailAccount::onAuthGranted);
connect(m_oauth, &OAuth2Service::tokensRetrieveError, this, &FormEditGmailAccount::onAuthError);
connect(m_oauth, &OAuth2Service::authFailed, this, &FormEditGmailAccount::onAuthFailed);
}
GmailServiceRoot* FormEditGmailAccount::execForCreate() {
setWindowTitle(tr("Add new Gmail account"));
m_ui.m_txtAppId->lineEdit()->clear();
m_ui.m_txtAppKey->lineEdit()->clear();
m_ui.m_txtRedirectUrl->lineEdit()->setText(LOCALHOST_ADDRESS);
exec();
return m_editableRoot;
}
void FormEditGmailAccount::execForEdit(GmailServiceRoot* existing_root) {
setWindowTitle(tr("Edit existing Gmail account"));
m_editableRoot = existing_root;
// We copy settings from existing OAuth to our testing OAuth.
m_oauth->setClientId(existing_root->network()->oauth()->clientId());
m_oauth->setClientSecret(existing_root->network()->oauth()->clientSecret());
m_oauth->setRedirectUrl(existing_root->network()->oauth()->redirectUrl());
m_oauth->setRefreshToken(existing_root->network()->oauth()->refreshToken());
m_oauth->setAccessToken(existing_root->network()->oauth()->accessToken());
m_oauth->setTokensExpireIn(existing_root->network()->oauth()->tokensExpireIn());
// Setup the GUI.
m_ui.m_txtAppId->lineEdit()->setText(existing_root->network()->oauth()->clientId());
m_ui.m_txtAppKey->lineEdit()->setText(existing_root->network()->oauth()->clientSecret());
m_ui.m_txtRedirectUrl->lineEdit()->setText(existing_root->network()->oauth()->redirectUrl());
m_ui.m_txtUsername->lineEdit()->setText(existing_root->network()->userName());
m_ui.m_spinLimitMessages->setValue(existing_root->network()->batchSize());
exec();
}
void FormEditGmailAccount::checkOAuthValue(const QString& value) {
LineEditWithStatus* line_edit = qobject_cast<LineEditWithStatus*>(sender()->parent());
if (line_edit != nullptr) {
if (value.isEmpty()) {
line_edit->setStatus(WidgetWithStatus::Error, tr("Empty value is entered."));
}
else {
line_edit->setStatus(WidgetWithStatus::Ok, tr("Some value is entered."));
}
}
}

View file

@ -0,0 +1,63 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 FORMEDITINOREADERACCOUNT_H
#define FORMEDITINOREADERACCOUNT_H
#include <QDialog>
#include "ui_formeditgmailaccount.h"
#include "services/gmail/network/gmailnetworkfactory.h"
namespace Ui {
class FormEditGmailAccount;
}
class GmailServiceRoot;
class FormEditGmailAccount : public QDialog {
Q_OBJECT
public:
explicit FormEditGmailAccount(QWidget* parent = nullptr);
virtual ~FormEditGmailAccount();
GmailServiceRoot* execForCreate();
void execForEdit(GmailServiceRoot* existing_root);
private slots:
void testSetup();
void onClickedOk();
void onClickedCancel();
void checkOAuthValue(const QString& value);
void checkUsername(const QString& username);
void onAuthFailed();
void onAuthError(const QString& error, const QString& detailed_description);
void onAuthGranted();
private:
void hookNetwork();
Ui::FormEditGmailAccount m_ui;
OAuth2Service* m_oauth;
GmailServiceRoot* m_editableRoot;
};
#endif // FORMEDITINOREADERACCOUNT_H

View file

@ -0,0 +1,190 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FormEditGmailAccount</class>
<widget class="QDialog" name="FormEditGmailAccount">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>542</width>
<height>363</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="m_lblUsername">
<property name="text">
<string>Username</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="LineEditWithStatus" name="m_txtUsername" native="true"/>
</item>
<item row="1" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>OAuth 2.0 settings</string>
</property>
<layout class="QFormLayout" name="formLayout_4">
<item row="0" column="0">
<widget class="QLabel" name="m_lblUsername_2">
<property name="text">
<string>Application ID</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="LineEditWithStatus" name="m_txtAppId" native="true"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="m_lblUsername_3">
<property name="text">
<string>Application key</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="LineEditWithStatus" name="m_txtAppKey" native="true"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="m_lblUsername_4">
<property name="text">
<string>Redirect URL</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="LineEditWithStatus" name="m_txtRedirectUrl" native="true"/>
</item>
<item row="3" column="0" colspan="2">
<widget class="QLabel" name="m_lblAuthInfo">
<property name="text">
<string>Predefined settings DO NOT have to be changed from their default values. Change these values only of you are advanced user and you know what you are doing!</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0" colspan="2">
<layout class="QFormLayout" name="formLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Only download newest X messages per feed</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="m_spinLimitMessages">
<property name="maximumSize">
<size>
<width>140</width>
<height>16777215</height>
</size>
</property>
<property name="suffix">
<string> message(s)</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="0" colspan="2">
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QPushButton" name="m_btnTestSetup">
<property name="text">
<string>&amp;Login</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="LabelWithStatus" name="m_lblTestResult" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="layoutDirection">
<enum>Qt::RightToLeft</enum>
</property>
</widget>
</item>
</layout>
</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>LabelWithStatus</class>
<extends>QWidget</extends>
<header>labelwithstatus.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>m_spinLimitMessages</tabstop>
<tabstop>m_btnTestSetup</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>m_buttonBox</sender>
<signal>accepted()</signal>
<receiver>FormEditGmailAccount</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>m_buttonBox</sender>
<signal>rejected()</signal>
<receiver>FormEditGmailAccount</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View file

@ -23,7 +23,6 @@
#define INOREADER_OAUTH_TOKEN_URL "https://www.inoreader.com/oauth2/token" #define INOREADER_OAUTH_TOKEN_URL "https://www.inoreader.com/oauth2/token"
#define INOREADER_OAUTH_AUTH_URL "https://www.inoreader.com/oauth2/auth" #define INOREADER_OAUTH_AUTH_URL "https://www.inoreader.com/oauth2/auth"
#define INOREADER_OAUTH_CLI_REDIRECT "http://localhost"
#define INOREADER_OAUTH_CLI_ID "1000000604" #define INOREADER_OAUTH_CLI_ID "1000000604"
#define INOREADER_OAUTH_CLI_KEY "gsStoZ3aAoQJCgQxoFSuXkWI7Sly87yK" #define INOREADER_OAUTH_CLI_KEY "gsStoZ3aAoQJCgQxoFSuXkWI7Sly87yK"

View file

@ -157,7 +157,7 @@ InoreaderServiceRoot* FormEditInoreaderAccount::execForCreate() {
m_ui.m_txtAppId->lineEdit()->setText(INOREADER_OAUTH_CLI_ID); m_ui.m_txtAppId->lineEdit()->setText(INOREADER_OAUTH_CLI_ID);
m_ui.m_txtAppKey->lineEdit()->setText(INOREADER_OAUTH_CLI_KEY); m_ui.m_txtAppKey->lineEdit()->setText(INOREADER_OAUTH_CLI_KEY);
m_ui.m_txtRedirectUrl->lineEdit()->setText(INOREADER_OAUTH_CLI_REDIRECT); m_ui.m_txtRedirectUrl->lineEdit()->setText(LOCALHOST_ADDRESS);
exec(); exec();