Commit 367a6cb1 authored by Linus Jahn's avatar Linus Jahn Committed by Jonah Brüchert

Add settings for JID/Password (#54)

Now Kaidan starts directly with opened roster, if you've typed in
your password once.

Add new global vars. for the organization name and domain:
ORGANIZATION_NAME:	"KaidanIM"
ORGANIZATION_DOMAIN:	"kaidanim.github.io"

Currently they are not used.

Closes #24.
parent f1d598c3
......@@ -10,6 +10,9 @@ set(APPLICATION_NAME "kaidan")
set(APPLICATION_DISPLAY_NAME "Kaidan")
set(APPLICATION_DESCRIPTION "Cross platform XMPP client")
set(ORGANIZAITON_NAME "KaidanIM")
set(ORGANIZATION_DOMAIN "kaidanim.github.io")
# Version
set(VERSION_MAJOR 0)
set(VERSION_MINOR 0)
......@@ -87,6 +90,8 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE
APPLICATION_NAME="${APPLICATION_NAME}"
APPLICATION_DISPLAY_NAME="${APPLICATION_DISPLAY_NAME}"
APPLICATION_DESCRIPTION="${APPLICATION_DESCRIPTION}"
ORGANIZAITON_NAME="${ORGANIZAITON_NAME}"
ORGANIZATION_DOMAIN="${ORGANIZATION_DOMAIN}"
VERSION_STRING="${VERSION_STRING}"
......
......@@ -22,9 +22,14 @@
#include "Kaidan.h"
#include <iostream>
// Qt
#include <QDebug>
#include <QSettings>
#include <QString>
// Boost
#include <boost/bind.hpp>
#include <boost/smart_ptr/make_shared.hpp>
// Kaidan
#include "EchoPayload.h"
#include "RosterController.h"
......@@ -33,6 +38,25 @@ Kaidan::Kaidan(NetworkFactories* networkFactories, QObject *parent) :
{
netFactories = networkFactories;
connected = false;
//
// Restore login data
//
// init settings (-> "kaidan/kaidan.conf")
settings = new QSettings(QString(APPLICATION_NAME), QString(APPLICATION_NAME));
if (settings->value("auth/jid").toString() != "")
{
// get JID from settings
jid = settings->value("auth/jid").toString();
if (settings->value("auth/password").toString() != "")
{
// get password from settings
password = settings->value("auth/password").toString();
}
}
}
Kaidan::~Kaidan()
......@@ -48,19 +72,27 @@ Kaidan::~Kaidan()
}
delete rosterController_;
delete settings;
}
void Kaidan::mainConnect(const QString &jid, const QString &pass){
client = new Swift::Client(jid.toStdString(), pass.toStdString(), netFactories);
void Kaidan::mainConnect()
{
// Create a new XMPP client
client = new Swift::Client(jid.toStdString(), password.toStdString(), netFactories);
// trust all certificates
client->setAlwaysTrustCertificates();
// event handling
client->onConnected.connect(boost::bind(&Kaidan::handleConnected, this));
client->onDisconnected.connect(boost::bind(&Kaidan::handleDisconnected, this));
client->onMessageReceived.connect(
boost::bind(&Kaidan::handleMessageReceived, this, _1));
client->onPresenceReceived.connect(
boost::bind(&Kaidan::handlePresenceReceived, this, _1));
client->onMessageReceived.connect(boost::bind(&Kaidan::handleMessageReceived, this, _1));
client->onPresenceReceived.connect(boost::bind(&Kaidan::handlePresenceReceived, this, _1));
// Create XML tracer (console output of xmpp data)
tracer = new Swift::ClientXMLTracer(client);
// share kaidan version
softwareVersionResponder = new Swift::SoftwareVersionResponder(client->getIQRouter());
softwareVersionResponder->setVersion(APPLICATION_DISPLAY_NAME, VERSION_STRING);
softwareVersionResponder->start();
......@@ -68,10 +100,11 @@ void Kaidan::mainConnect(const QString &jid, const QString &pass){
client->addPayloadParserFactory(&echoPayloadParserFactory);
client->addPayloadSerializer(&echoPayloadSerializer);
// .. and connect!
client->connect();
}
//we don't want to close client without disconnection
// we don't want to close client without disconnection
void Kaidan::mainDisconnect()
{
if (connectionState())
......@@ -80,20 +113,9 @@ void Kaidan::mainDisconnect()
}
}
void Kaidan::handlePresenceReceived(Presence::ref presence)
{
// Automatically approve subscription requests
if (presence->getType() == Swift::Presence::Subscribe)
{
Swift::Presence::ref response = Swift::Presence::create();
response->setTo(presence->getFrom());
response->setType(Swift::Presence::Subscribed);
client->sendPresence(response);
}
}
void Kaidan::handleConnected()
{
// emit connected signal
connected = true;
emit connectionStateConnected();
client->sendPresence(Presence::create("Send me a message"));
......@@ -108,6 +130,18 @@ void Kaidan::handleDisconnected()
emit connectionStateDisconnected();
}
void Kaidan::handlePresenceReceived(Presence::ref presence)
{
// Automatically approve subscription requests
if (presence->getType() == Swift::Presence::Subscribe)
{
Swift::Presence::ref response = Swift::Presence::create();
response->setTo(presence->getFrom());
response->setType(Swift::Presence::Subscribed);
client->sendPresence(response);
}
}
void Kaidan::handleMessageReceived(Message::ref message)
{
// Echo back the incoming message
......@@ -132,3 +166,37 @@ bool Kaidan::connectionState() const
{
return connected;
}
bool Kaidan::newLoginNeeded()
{
// if no jid or password, return true
return (jid == "") || (password == "");
}
QString Kaidan::getJid()
{
return jid;
}
QString Kaidan::getPassword()
{
return password;
}
void Kaidan::setJid(QString jid_)
{
// set new jid for mainConnect
jid = jid_;
// save to settings
settings->setValue("auth/jid", jid_);
}
void Kaidan::setPassword(QString password_)
{
// set new password for
password = password_;
// save to settings
settings->setValue("auth/password", password_);
}
......@@ -22,15 +22,17 @@
#ifndef KAIDAN_H
#define KAIDAN_H
// Qt
#include <QObject>
#include <QSettings>
#include <QString>
#include <QStringList>
// Swiften
#include <Swiften/Swiften.h>
// Kaidan
#include "EchoPayloadParserFactory.h"
#include "EchoPayloadSerializer.h"
class RosterController;
#include "RosterController.h"
class Kaidan : public QObject
{
......@@ -42,9 +44,17 @@ class Kaidan : public QObject
public:
Kaidan(Swift::NetworkFactories* networkFactories, QObject *parent = 0);
~Kaidan();
Q_INVOKABLE void mainDisconnect();
Q_INVOKABLE void mainConnect(const QString &jid, const QString &pass);
Q_INVOKABLE void mainConnect();
bool connectionState() const;
Q_INVOKABLE bool newLoginNeeded();
Q_INVOKABLE QString getJid();
Q_INVOKABLE QString getPassword();
Q_INVOKABLE void setJid(QString);
Q_INVOKABLE void setPassword(QString);
RosterController* getRosterController();
......@@ -68,6 +78,11 @@ private:
Swift::NetworkFactories *netFactories;
RosterController* rosterController_;
QSettings* settings;
QString jid;
QString password;
};
#endif
......@@ -20,11 +20,13 @@
#ifndef ROSTERCONTROLLER_H
#define ROSTERCONTROLLER_H
#include "RosterItem.h"
#include <Swiften/Swiften.h>
// Qt
#include <QObject>
#include <QQmlListProperty>
// Swiften
#include <Swiften/Swiften.h>
// Kaidan
#include "RosterItem.h"
class RosterController : public QObject
{
......
......@@ -74,6 +74,15 @@ int main(int argc, char *argv[])
qmlRegisterType<RosterController>(APPLICATION_ID, 1, 0, "RosterController");
qmlRegisterType<RosterItem>(APPLICATION_ID, 1, 0, "RosterItem");
//
// Kaidan back-end
//
QtEventLoop eventLoop;
BoostNetworkFactories networkFactories(&eventLoop);
Kaidan kaidan(&networkFactories);
//
// App
//
......@@ -85,6 +94,8 @@ int main(int argc, char *argv[])
QGuiApplication::setApplicationName(APPLICATION_NAME);
QGuiApplication::setApplicationDisplayName(APPLICATION_DISPLAY_NAME);
QGuiApplication::setApplicationVersion(VERSION_STRING);
QGuiApplication::setOrganizationName(ORGANIZAITON_NAME);
QGuiApplication::setOrganizationDomain(ORGANIZATION_DOMAIN);
// attributes
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
......@@ -129,17 +140,6 @@ int main(int argc, char *argv[])
break;
}
//
// Kaidan back-end
//
QtEventLoop eventLoop;
BoostNetworkFactories networkFactories(&eventLoop);
Kaidan kaidan(&networkFactories);
//
// QML-GUI
//
......
/*
* Kaidan - Cross platform XMPP client
*
* Copyright (C) 2016 LNJ <git@lnj.li>
* Copyright (C) 2016-2017 LNJ <git@lnj.li>
* Copyright (C) 2016 Marzanna
*
* Kaidan is free software: you can redistribute it and/or modify
......@@ -25,6 +25,8 @@ import org.kde.kirigami 1.0 as Kirigami
import harbour.kaidan 1.0
Kirigami.ScrollablePage {
property bool isRetry
title: "Login"
GridLayout {
......@@ -38,6 +40,7 @@ Kirigami.ScrollablePage {
}
Controls.TextField {
id: jidField
text: kaidan.getJid()
placeholderText: qsTr("user@example.org")
Layout.fillWidth: true
}
......@@ -48,6 +51,7 @@ Kirigami.ScrollablePage {
}
Controls.TextField {
id: passField
text: kaidan.getPassword()
placeholderText: qsTr("Password")
echoMode: TextInput.Password
Layout.fillWidth: true
......@@ -56,16 +60,18 @@ Kirigami.ScrollablePage {
// Connect button
Controls.Button {
id: connectButton
text: qsTr("Connect")
text: isRetry ? qsTr("Retry") : qsTr("Connect")
Layout.columnSpan: 2
Layout.alignment: Qt.AlignRight
onClicked: {
// disable the button
connectButton.enabled = false;
// connect to given account data
connectButton.text = "<i>" + qsTr("Connecting...") + "</i>"
connectButton.text = "<i>" + qsTr("Connecting...") + "</i>";
kaidan.mainConnect(jidField.text, passField.text);
kaidan.setJid(jidField.text);
kaidan.setPassword(passField.text);
kaidan.mainConnect();
}
}
}
......@@ -73,18 +79,19 @@ Kirigami.ScrollablePage {
Component.onCompleted: {
function goToRoster() {
// we need to disconnect enableConnectButton to prevent calling it on normal disconnection
kaidan.connectionStateDisconnected.disconnect(enableConnectButton)
kaidan.connectionStateDisconnected.disconnect(enableConnectButton);
// open the roster page
pageStack.replace(rosterPage)
pageStack.replace(rosterPage);
}
function enableConnectButton() {
connectButton.text = qsTr("Retry")
connectButton.enabled = true
isRetry = true;
connectButton.text = qsTr("Retry");
connectButton.enabled = true;
}
// connect functions to back-end events
kaidan.connectionStateConnected.connect(goToRoster)
kaidan.connectionStateDisconnected.connect(enableConnectButton)
kaidan.connectionStateConnected.connect(goToRoster);
kaidan.connectionStateDisconnected.connect(enableConnectButton);
}
}
/*
* Kaidan - Cross platform XMPP client
*
* Copyright (C) 2016 LNJ <git@lnj.li>
* Copyright (C) 2016-2017 LNJ <git@lnj.li>
* Copyright (C) 2016 Marzanna
*
* Kaidan is free software: you can redistribute it and/or modify
......@@ -24,16 +24,40 @@ import harbour.kaidan 1.0
Kirigami.ApplicationWindow {
id: root
visible: true
// first page: login, the roster page will be opened after it
pageStack.initialPage: loginPage
// load all pages
Component {id: chatPage; ChatPage {}}
Component {id: loginPage; LoginPage {}}
Component {id: rosterPage; RosterPage {}}
// diconnect from jabber server
onClosing: kaidan.mainDisconnect()
// when the window was closed, disconnect from jabber server
onClosing: {
kaidan.mainDisconnect()
}
Component.onCompleted: {
function openLoginPage() {
// disconnect this func; the login page will do that
kaidan.connectionStateDisconnected.disconnect(openLoginPage);
// open login page
pageStack.pop(); // pop all pages
pageStack.push(loginPage, {"isRetry": true});
}
if (kaidan.newLoginNeeded()) {
// open login page and get new data from user
pageStack.push(loginPage);
}
else {
// open client normally
// on connection failure, open login page
kaidan.connectionStateDisconnected.connect(openLoginPage);
// show roster and login with restored data
pageStack.push(rosterPage);
kaidan.mainConnect();
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment