mirror of
https://github.com/PurpleI2P/i2pd
synced 2024-11-10 08:00:38 +03:00
Merge pull request #1491 from nonlinear-chaos-order-etc-etal/openssl
qt: delayed save in background. should be better ui experience
This commit is contained in:
commit
82bdcfbbcb
8
.gitignore
vendored
8
.gitignore
vendored
@ -258,9 +258,15 @@ build/Makefile
|
||||
|
||||
# qt
|
||||
|
||||
qt/i2pd_qt/*.ui.autosave
|
||||
qt/i2pd_qt/*.autosave
|
||||
qt/i2pd_qt/*.ui.bk*
|
||||
qt/i2pd_qt/*.ui_*
|
||||
|
||||
#unknown android stuff
|
||||
android/libs/
|
||||
|
||||
#various logs
|
||||
*LOGS/
|
||||
|
||||
qt/build-*.sh*
|
||||
|
||||
|
@ -89,7 +89,7 @@ namespace http
|
||||
void ShowTransports (std::stringstream& s);
|
||||
void ShowSAMSessions (std::stringstream& s);
|
||||
void ShowI2PTunnels (std::stringstream& s);
|
||||
void ShowLocalDestination (std::stringstream& s, const std::string& b32);
|
||||
void ShowLocalDestination (std::stringstream& s, const std::string& b32, uint32_t token);
|
||||
} // http
|
||||
} // i2p
|
||||
|
||||
|
3
qt/i2pd_qt/DelayedSaveManager.cpp
Normal file
3
qt/i2pd_qt/DelayedSaveManager.cpp
Normal file
@ -0,0 +1,3 @@
|
||||
#include "DelayedSaveManager.h"
|
||||
|
||||
DelayedSaveManager::DelayedSaveManager(){}
|
24
qt/i2pd_qt/DelayedSaveManager.h
Normal file
24
qt/i2pd_qt/DelayedSaveManager.h
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef DELAYEDSAVEMANAGER_H
|
||||
#define DELAYEDSAVEMANAGER_H
|
||||
|
||||
#include "Saver.h"
|
||||
|
||||
class DelayedSaveManager
|
||||
{
|
||||
public:
|
||||
DelayedSaveManager();
|
||||
|
||||
virtual void setSaver(Saver* saver)=0;
|
||||
|
||||
typedef unsigned int DATA_SERIAL_TYPE;
|
||||
|
||||
virtual void delayedSave(DATA_SERIAL_TYPE dataSerial, bool needsTunnelFocus, std::string tunnelNameToFocus)=0;
|
||||
|
||||
//returns false iff save failed
|
||||
virtual bool appExiting()=0;
|
||||
|
||||
virtual bool needsFocusOnTunnel()=0;
|
||||
virtual std::string& getTunnelNameToFocus()=0;
|
||||
};
|
||||
|
||||
#endif // DELAYEDSAVEMANAGER_H
|
140
qt/i2pd_qt/DelayedSaveManagerImpl.cpp
Normal file
140
qt/i2pd_qt/DelayedSaveManagerImpl.cpp
Normal file
@ -0,0 +1,140 @@
|
||||
#include "DelayedSaveManagerImpl.h"
|
||||
|
||||
DelayedSaveManagerImpl::DelayedSaveManagerImpl() :
|
||||
saver(nullptr),
|
||||
lastDataSerialSeen(DelayedSaveManagerImpl::INITIAL_DATA_SERIAL),
|
||||
lastSaveStartedTimestamp(A_VERY_OBSOLETE_TIMESTAMP),
|
||||
exiting(false),
|
||||
thread(new DelayedSaveThread(this))
|
||||
{
|
||||
}
|
||||
|
||||
void DelayedSaveManagerImpl::setSaver(Saver* saver) {
|
||||
this->saver = saver;
|
||||
}
|
||||
|
||||
void DelayedSaveManagerImpl::start() {
|
||||
thread->start();
|
||||
}
|
||||
|
||||
bool DelayedSaveManagerImpl::isSaverValid() {
|
||||
return saver != nullptr;
|
||||
}
|
||||
|
||||
void DelayedSaveManagerImpl::delayedSave(DATA_SERIAL_TYPE dataSerial, bool focusOnTunnel, std::string tunnelNameToFocus_) {
|
||||
if(lastDataSerialSeen==dataSerial)return;
|
||||
this->focusOnTunnel = focusOnTunnel;
|
||||
tunnelNameToFocus = tunnelNameToFocus_;
|
||||
lastDataSerialSeen=dataSerial;
|
||||
assert(isSaverValid());
|
||||
TIMESTAMP_TYPE now = getTime();
|
||||
TIMESTAMP_TYPE wakeTime = lastSaveStartedTimestamp + DelayedSaveThread::WAIT_TIME_MILLIS;
|
||||
if(now < wakeTime) {
|
||||
//defer save until lastSaveStartedTimestamp + DelayedSaveThread::WAIT_TIME_MILLIS
|
||||
thread->deferSaveUntil(wakeTime);
|
||||
return;
|
||||
}
|
||||
lastSaveStartedTimestamp = now;
|
||||
thread->startSavingNow();
|
||||
}
|
||||
|
||||
bool DelayedSaveManagerImpl::appExiting() {
|
||||
exiting=true;
|
||||
thread->wakeThreadAndJoinThread();
|
||||
assert(isSaverValid());
|
||||
saver->save(false, "");
|
||||
return true;
|
||||
}
|
||||
|
||||
DelayedSaveThread::DelayedSaveThread(DelayedSaveManagerImpl* delayedSaveManagerImpl_):
|
||||
delayedSaveManagerImpl(delayedSaveManagerImpl_),
|
||||
mutex(new QMutex()),
|
||||
waitCondition(new QWaitCondition()),
|
||||
saveNow(false),
|
||||
defer(false)
|
||||
{
|
||||
mutex->lock();
|
||||
}
|
||||
|
||||
DelayedSaveThread::~DelayedSaveThread(){
|
||||
mutex->unlock();
|
||||
delete mutex;
|
||||
delete waitCondition;
|
||||
}
|
||||
|
||||
void DelayedSaveThread::run() {
|
||||
forever {
|
||||
if(delayedSaveManagerImpl->isExiting())return;
|
||||
waitCondition->wait(mutex, WAIT_TIME_MILLIS);
|
||||
if(delayedSaveManagerImpl->isExiting())return;
|
||||
Saver* saver = delayedSaveManagerImpl->getSaver();
|
||||
assert(saver!=nullptr);
|
||||
if(saveNow) {
|
||||
saveNow = false;
|
||||
const bool focusOnTunnel = delayedSaveManagerImpl->needsFocusOnTunnel();
|
||||
const std::string tunnelNameToFocus = delayedSaveManagerImpl->getTunnelNameToFocus();
|
||||
saver->save(focusOnTunnel, tunnelNameToFocus);
|
||||
continue;
|
||||
}
|
||||
if(defer) {
|
||||
defer=false;
|
||||
#define max(a,b) (((a)>(b))?(a):(b))
|
||||
forever {
|
||||
TIMESTAMP_TYPE now = DelayedSaveManagerImpl::getTime();
|
||||
TIMESTAMP_TYPE millisToWait = max(wakeTime-now, 0);
|
||||
if(millisToWait>0) {
|
||||
waitCondition->wait(mutex, millisToWait);
|
||||
if(delayedSaveManagerImpl->isExiting())return;
|
||||
continue;
|
||||
}
|
||||
const bool focusOnTunnel = delayedSaveManagerImpl->needsFocusOnTunnel();
|
||||
const std::string tunnelNameToFocus = delayedSaveManagerImpl->getTunnelNameToFocus();
|
||||
saver->save(focusOnTunnel, tunnelNameToFocus);
|
||||
break; //break inner loop
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DelayedSaveThread::wakeThreadAndJoinThread() {
|
||||
waitCondition->wakeAll();
|
||||
quit();
|
||||
wait();//join //"similar to the POSIX pthread_join()"
|
||||
}
|
||||
|
||||
DelayedSaveManagerImpl::TIMESTAMP_TYPE DelayedSaveManagerImpl::getTime() {
|
||||
return QDateTime::currentMSecsSinceEpoch();
|
||||
}
|
||||
|
||||
void DelayedSaveThread::deferSaveUntil(TIMESTAMP_TYPE wakeTime_) {
|
||||
wakeTime = wakeTime_;
|
||||
defer = true;
|
||||
waitCondition->wakeAll();
|
||||
}
|
||||
|
||||
void DelayedSaveThread::startSavingNow() {
|
||||
//mutex->lock();
|
||||
saveNow=true;
|
||||
waitCondition->wakeAll();
|
||||
//mutex->unlock();
|
||||
}
|
||||
|
||||
DelayedSaveManagerImpl::~DelayedSaveManagerImpl() {
|
||||
thread->wakeThreadAndJoinThread();
|
||||
delete thread;
|
||||
}
|
||||
|
||||
bool DelayedSaveManagerImpl::isExiting() {
|
||||
return exiting;
|
||||
}
|
||||
Saver* DelayedSaveManagerImpl::getSaver() {
|
||||
return saver;
|
||||
}
|
||||
|
||||
bool DelayedSaveManagerImpl::needsFocusOnTunnel() {
|
||||
return focusOnTunnel;
|
||||
}
|
||||
|
||||
std::string& DelayedSaveManagerImpl::getTunnelNameToFocus() {
|
||||
return tunnelNameToFocus;
|
||||
}
|
82
qt/i2pd_qt/DelayedSaveManagerImpl.h
Normal file
82
qt/i2pd_qt/DelayedSaveManagerImpl.h
Normal file
@ -0,0 +1,82 @@
|
||||
#ifndef DELAYEDSAVEMANAGERIMPL_H
|
||||
#define DELAYEDSAVEMANAGERIMPL_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QThread>
|
||||
#include <QWaitCondition>
|
||||
#include <QMutex>
|
||||
#include <QDateTime>
|
||||
|
||||
#include "mainwindow.h"
|
||||
#include "DelayedSaveManager.h"
|
||||
#include "Saver.h"
|
||||
|
||||
class DelayedSaveManagerImpl;
|
||||
|
||||
class DelayedSaveThread : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static constexpr unsigned long WAIT_TIME_MILLIS = 1000L;
|
||||
|
||||
typedef qint64 TIMESTAMP_TYPE;
|
||||
static constexpr TIMESTAMP_TYPE A_VERY_OBSOLETE_TIMESTAMP=0;
|
||||
|
||||
DelayedSaveThread(DelayedSaveManagerImpl* delayedSaveManagerImpl);
|
||||
virtual ~DelayedSaveThread();
|
||||
|
||||
void run() override;
|
||||
|
||||
void deferSaveUntil(TIMESTAMP_TYPE wakeTime);
|
||||
void startSavingNow();
|
||||
|
||||
void wakeThreadAndJoinThread();
|
||||
|
||||
private:
|
||||
DelayedSaveManagerImpl* delayedSaveManagerImpl;
|
||||
QMutex* mutex;
|
||||
QWaitCondition* waitCondition;
|
||||
volatile bool saveNow;
|
||||
volatile bool defer;
|
||||
volatile TIMESTAMP_TYPE wakeTime;
|
||||
};
|
||||
|
||||
class DelayedSaveManagerImpl : public DelayedSaveManager
|
||||
{
|
||||
public:
|
||||
DelayedSaveManagerImpl();
|
||||
virtual ~DelayedSaveManagerImpl();
|
||||
virtual void setSaver(Saver* saver);
|
||||
virtual void start();
|
||||
virtual void delayedSave(DATA_SERIAL_TYPE dataSerial, bool focusOnTunnel, std::string tunnelNameToFocus);
|
||||
virtual bool appExiting();
|
||||
|
||||
typedef DelayedSaveThread::TIMESTAMP_TYPE TIMESTAMP_TYPE;
|
||||
|
||||
static constexpr DATA_SERIAL_TYPE INITIAL_DATA_SERIAL=0;
|
||||
bool isExiting();
|
||||
Saver* getSaver();
|
||||
static TIMESTAMP_TYPE getTime();
|
||||
|
||||
bool needsFocusOnTunnel();
|
||||
std::string& getTunnelNameToFocus();
|
||||
|
||||
private:
|
||||
Saver* saver;
|
||||
bool isSaverValid();
|
||||
|
||||
DATA_SERIAL_TYPE lastDataSerialSeen;
|
||||
|
||||
static constexpr TIMESTAMP_TYPE A_VERY_OBSOLETE_TIMESTAMP=DelayedSaveThread::A_VERY_OBSOLETE_TIMESTAMP;
|
||||
TIMESTAMP_TYPE lastSaveStartedTimestamp;
|
||||
|
||||
bool exiting;
|
||||
DelayedSaveThread* thread;
|
||||
void wakeThreadAndJoinThread();
|
||||
|
||||
bool focusOnTunnel;
|
||||
std::string tunnelNameToFocus;
|
||||
};
|
||||
|
||||
#endif // DELAYEDSAVEMANAGERIMPL_H
|
6
qt/i2pd_qt/Saver.cpp
Normal file
6
qt/i2pd_qt/Saver.cpp
Normal file
@ -0,0 +1,6 @@
|
||||
#include "Saver.h"
|
||||
|
||||
Saver::Saver()
|
||||
{
|
||||
|
||||
}
|
22
qt/i2pd_qt/Saver.h
Normal file
22
qt/i2pd_qt/Saver.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef SAVER_H
|
||||
#define SAVER_H
|
||||
|
||||
#include <string>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
class Saver : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Saver();
|
||||
//false iff failures
|
||||
virtual bool save(const bool focusOnTunnel, const std::string& tunnelNameToFocus)=0;
|
||||
|
||||
signals:
|
||||
void reloadTunnelsConfigAndUISignal(const QString);
|
||||
|
||||
};
|
||||
|
||||
#endif // SAVER_H
|
79
qt/i2pd_qt/SaverImpl.cpp
Normal file
79
qt/i2pd_qt/SaverImpl.cpp
Normal file
@ -0,0 +1,79 @@
|
||||
#include "SaverImpl.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <assert.h>
|
||||
#include <sstream>
|
||||
|
||||
#include "QList"
|
||||
#include "QString"
|
||||
|
||||
#include "mainwindow.h"
|
||||
|
||||
SaverImpl::SaverImpl(MainWindow *mainWindowPtr_, QList<MainWindowItem*> * configItems_, std::map<std::string,TunnelConfig*>* tunnelConfigs_) :
|
||||
configItems(configItems_), tunnelConfigs(tunnelConfigs_), confpath(), tunconfpath(), mainWindowPtr(mainWindowPtr_)
|
||||
{}
|
||||
|
||||
SaverImpl::~SaverImpl() {}
|
||||
|
||||
bool SaverImpl::save(const bool focusOnTunnel, const std::string& tunnelNameToFocus) {
|
||||
//save main config
|
||||
{
|
||||
std::stringstream out;
|
||||
for(QList<MainWindowItem*>::iterator it = configItems->begin(); it!= configItems->end(); ++it) {
|
||||
MainWindowItem* item = *it;
|
||||
item->saveToStringStream(out);
|
||||
}
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
QString backup=confpath+"~";
|
||||
if(QFile::exists(backup)) QFile::remove(backup);//TODO handle errors
|
||||
if(QFile::exists(confpath)) QFile::rename(confpath, backup);//TODO handle errors
|
||||
ofstream outfile;
|
||||
outfile.open(confpath.toStdString());//TODO handle errors
|
||||
outfile << out.str().c_str();
|
||||
outfile.close();
|
||||
}
|
||||
|
||||
//save tunnels config
|
||||
{
|
||||
std::stringstream out;
|
||||
|
||||
for (std::map<std::string,TunnelConfig*>::iterator it=tunnelConfigs->begin(); it!=tunnelConfigs->end(); ++it) {
|
||||
//const std::string& name = it->first;
|
||||
TunnelConfig* tunconf = it->second;
|
||||
tunconf->saveHeaderToStringStream(out);
|
||||
tunconf->saveToStringStream(out);
|
||||
tunconf->saveI2CPParametersToStringStream(out);
|
||||
}
|
||||
|
||||
using namespace std;
|
||||
|
||||
QString backup=tunconfpath+"~";
|
||||
if(QFile::exists(backup)) QFile::remove(backup);//TODO handle errors
|
||||
if(QFile::exists(tunconfpath)) QFile::rename(tunconfpath, backup);//TODO handle errors
|
||||
ofstream outfile;
|
||||
outfile.open(tunconfpath.toStdString());//TODO handle errors
|
||||
outfile << out.str().c_str();
|
||||
outfile.close();
|
||||
}
|
||||
|
||||
//reload saved configs
|
||||
#if 0
|
||||
i2p::client::context.ReloadConfig();
|
||||
#endif
|
||||
|
||||
if(focusOnTunnel) emit reloadTunnelsConfigAndUISignal(QString::fromStdString(tunnelNameToFocus));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SaverImpl::setConfPath(QString& confpath_) { confpath = confpath_; }
|
||||
|
||||
void SaverImpl::setTunnelsConfPath(QString& tunconfpath_) { tunconfpath = tunconfpath_; }
|
||||
|
||||
/*void SaverImpl::setTunnelFocus(bool focusOnTunnel, std::string tunnelNameToFocus) {
|
||||
this->focusOnTunnel=focusOnTunnel;
|
||||
this->tunnelNameToFocus=tunnelNameToFocus;
|
||||
}*/
|
33
qt/i2pd_qt/SaverImpl.h
Normal file
33
qt/i2pd_qt/SaverImpl.h
Normal file
@ -0,0 +1,33 @@
|
||||
#ifndef SAVERIMPL_H
|
||||
#define SAVERIMPL_H
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include <QObject>
|
||||
#include "QList"
|
||||
|
||||
#include "mainwindow.h"
|
||||
#include "TunnelConfig.h"
|
||||
#include "Saver.h"
|
||||
|
||||
class MainWindowItem;
|
||||
class TunnelConfig;
|
||||
|
||||
class SaverImpl : public Saver
|
||||
{
|
||||
public:
|
||||
SaverImpl(MainWindow *mainWindowPtr_, QList<MainWindowItem*> * configItems_, std::map<std::string,TunnelConfig*>* tunnelConfigs_);
|
||||
virtual ~SaverImpl();
|
||||
virtual bool save(const bool focusOnTunnel, const std::string& tunnelNameToFocus);
|
||||
void setConfPath(QString& confpath_);
|
||||
void setTunnelsConfPath(QString& tunconfpath_);
|
||||
private:
|
||||
QList<MainWindowItem*> * configItems;
|
||||
std::map<std::string,TunnelConfig*>* tunnelConfigs;
|
||||
QString confpath;
|
||||
QString tunconfpath;
|
||||
MainWindow* mainWindowPtr;
|
||||
};
|
||||
|
||||
#endif // SAVERIMPL_H
|
@ -40,6 +40,9 @@ public:
|
||||
|
||||
class ClientTunnelConfig;
|
||||
class ServerTunnelConfig;
|
||||
|
||||
class TunnelPane;
|
||||
|
||||
class TunnelConfig {
|
||||
/*
|
||||
const char I2P_TUNNELS_SECTION_TYPE_CLIENT[] = "client";
|
||||
@ -54,6 +57,7 @@ class TunnelConfig {
|
||||
*/
|
||||
QString type;
|
||||
std::string name;
|
||||
TunnelPane* tunnelPane;
|
||||
public:
|
||||
TunnelConfig(std::string name_, QString& type_, I2CPParameters& i2cpParameters_):
|
||||
type(type_), name(name_), i2cpParameters(i2cpParameters_) {}
|
||||
@ -68,7 +72,8 @@ public:
|
||||
virtual void saveToStringStream(std::stringstream& out)=0;
|
||||
virtual ClientTunnelConfig* asClientTunnelConfig()=0;
|
||||
virtual ServerTunnelConfig* asServerTunnelConfig()=0;
|
||||
|
||||
void setTunnelPane(TunnelPane* tp){this->tunnelPane = tp;}
|
||||
TunnelPane* getTunnelPane() {return tunnelPane;}
|
||||
private:
|
||||
I2CPParameters i2cpParameters;
|
||||
};
|
||||
|
@ -64,7 +64,7 @@ void TunnelPane::setupTunnelPane(
|
||||
|
||||
//type
|
||||
{
|
||||
const QString& type = tunnelConfig->getType();
|
||||
//const QString& type = tunnelConfig->getType();
|
||||
QHBoxLayout * horizontalLayout_ = new QHBoxLayout();
|
||||
horizontalLayout_->setObjectName(QStringLiteral("horizontalLayout_"));
|
||||
typeLabel = new QLabel(gridLayoutWidget_2);
|
||||
@ -83,6 +83,11 @@ void TunnelPane::setupTunnelPane(
|
||||
retranslateTunnelForm(*this);
|
||||
}
|
||||
|
||||
void TunnelPane::deleteWidget() {
|
||||
//gridLayoutWidget_2->deleteLater();
|
||||
tunnelGroupBox->deleteLater();
|
||||
}
|
||||
|
||||
void TunnelPane::appendControlsForI2CPParameters(I2CPParameters& i2cpParameters, int& gridIndex) {
|
||||
{
|
||||
//number of hops of an inbound tunnel
|
||||
|
@ -41,6 +41,8 @@ public:
|
||||
virtual ServerTunnelPane* asServerTunnelPane()=0;
|
||||
virtual ClientTunnelPane* asClientTunnelPane()=0;
|
||||
|
||||
void deleteWidget();
|
||||
|
||||
protected:
|
||||
MainWindow* mainWindow;
|
||||
QWidget * wrongInputPane;
|
||||
|
@ -91,7 +91,11 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \
|
||||
pagewithbackbutton.cpp \
|
||||
widgetlock.cpp \
|
||||
widgetlockregistry.cpp \
|
||||
logviewermanager.cpp
|
||||
logviewermanager.cpp \
|
||||
DelayedSaveManager.cpp \
|
||||
Saver.cpp \
|
||||
DelayedSaveManagerImpl.cpp \
|
||||
SaverImpl.cpp
|
||||
|
||||
HEADERS += DaemonQT.h mainwindow.h \
|
||||
../../libi2pd/api.h \
|
||||
@ -179,7 +183,11 @@ HEADERS += DaemonQT.h mainwindow.h \
|
||||
widgetlock.h \
|
||||
widgetlockregistry.h \
|
||||
i2pd.rc \
|
||||
logviewermanager.h
|
||||
logviewermanager.h \
|
||||
DelayedSaveManager.h \
|
||||
Saver.h \
|
||||
DelayedSaveManagerImpl.h \
|
||||
SaverImpl.h
|
||||
|
||||
INCLUDEPATH += ../../libi2pd
|
||||
INCLUDEPATH += ../../libi2pd_client
|
||||
|
@ -1,11 +1,8 @@
|
||||
#include <fstream>
|
||||
#include <assert.h>
|
||||
#include "mainwindow.h"
|
||||
#include "ui_mainwindow.h"
|
||||
#include "ui_statusbuttons.h"
|
||||
#include "ui_routercommandswidget.h"
|
||||
#include "ui_generalsettingswidget.h"
|
||||
#include <sstream>
|
||||
#include <QScrollBar>
|
||||
#include <QMessageBox>
|
||||
#include <QTimer>
|
||||
@ -29,17 +26,22 @@
|
||||
|
||||
#include "logviewermanager.h"
|
||||
|
||||
#include "DelayedSaveManagerImpl.h"
|
||||
#include "SaverImpl.h"
|
||||
|
||||
std::string programOptionsWriterCurrentSection;
|
||||
|
||||
MainWindow::MainWindow(std::shared_ptr<std::iostream> logStream_, QWidget *parent) :
|
||||
QMainWindow(parent)
|
||||
,logStream(logStream_)
|
||||
#ifndef ANDROID
|
||||
,quitting(false)
|
||||
#endif
|
||||
,delayedSaveManagerPtr(new DelayedSaveManagerImpl())
|
||||
,dataSerial(DelayedSaveManagerImpl::INITIAL_DATA_SERIAL)
|
||||
,wasSelectingAtStatusMainPage(false)
|
||||
,showHiddenInfoStatusMainPage(false)
|
||||
,logViewerManagerPtr(nullptr)
|
||||
#ifndef ANDROID
|
||||
,quitting(false)
|
||||
#endif
|
||||
,ui(new Ui::MainWindow)
|
||||
,statusButtonsUI(new Ui::StatusButtonsForm)
|
||||
,routerCommandsUI(new Ui::routerCommandsWidget)
|
||||
@ -51,9 +53,14 @@ MainWindow::MainWindow(std::shared_ptr<std::iostream> logStream_, QWidget *paren
|
||||
,datadir()
|
||||
,confpath()
|
||||
,tunconfpath()
|
||||
,tunnelConfigs()
|
||||
,tunnelsPageUpdateListener(this)
|
||||
,saverPtr(new SaverImpl(this, &configItems, &tunnelConfigs))
|
||||
|
||||
{
|
||||
assert(delayedSaveManagerPtr!=nullptr);
|
||||
assert(saverPtr!=nullptr);
|
||||
|
||||
ui->setupUi(this);
|
||||
statusButtonsUI->setupUi(ui->statusButtonsPane);
|
||||
routerCommandsUI->setupUi(routerCommandsParent);
|
||||
@ -75,7 +82,7 @@ MainWindow::MainWindow(std::shared_ptr<std::iostream> logStream_, QWidget *paren
|
||||
|
||||
ui->stackedWidget->setCurrentIndex(0);
|
||||
ui->settingsScrollArea->resize(uiSettings->settingsContentsGridLayout->sizeHint().width()+10,380);
|
||||
QScrollBar* const barSett = ui->settingsScrollArea->verticalScrollBar();
|
||||
//QScrollBar* const barSett = ui->settingsScrollArea->verticalScrollBar();
|
||||
int w = 683;
|
||||
int h = 3060;
|
||||
ui->settingsContents->setFixedSize(w, h);
|
||||
@ -270,7 +277,13 @@ MainWindow::MainWindow(std::shared_ptr<std::iostream> logStream_, QWidget *paren
|
||||
widgetlocks.add(new widgetlock(uiSettings->comboBox_httpPorxySignatureType,uiSettings->httpProxySignTypeComboEditPushButton));
|
||||
widgetlocks.add(new widgetlock(uiSettings->comboBox_socksProxySignatureType,uiSettings->socksProxySignTypeComboEditPushButton));
|
||||
|
||||
loadAllConfigs();
|
||||
loadAllConfigs(saverPtr);
|
||||
|
||||
QObject::connect(saverPtr, SIGNAL(reloadTunnelsConfigAndUISignal(const QString)),
|
||||
this, SLOT(reloadTunnelsConfigAndUI_QString(const QString)));
|
||||
|
||||
delayedSaveManagerPtr->setSaver(saverPtr);
|
||||
delayedSaveManagerPtr->start();
|
||||
|
||||
QObject::connect(uiSettings->logDestinationComboBox, SIGNAL(currentIndexChanged(const QString &)),
|
||||
this, SLOT(logDestinationComboBoxValueChanged(const QString &)));
|
||||
@ -292,7 +305,6 @@ MainWindow::MainWindow(std::shared_ptr<std::iostream> logStream_, QWidget *paren
|
||||
|
||||
QObject::connect(uiSettings->tunnelsConfigFileLineEdit, SIGNAL(textChanged(const QString &)),
|
||||
this, SLOT(reloadTunnelsConfigAndUI()));
|
||||
|
||||
QObject::connect(ui->addServerTunnelPushButton, SIGNAL(released()), this, SLOT(addServerTunnelPushButtonReleased()));
|
||||
QObject::connect(ui->addClientTunnelPushButton, SIGNAL(released()), this, SLOT(addClientTunnelPushButtonReleased()));
|
||||
|
||||
@ -307,7 +319,7 @@ MainWindow::MainWindow(std::shared_ptr<std::iostream> logStream_, QWidget *paren
|
||||
|
||||
logViewerManagerPtr=new LogViewerManager(logStream_,ui->logViewerTextEdit,this);
|
||||
assert(logViewerManagerPtr!=nullptr);
|
||||
onLoggingOptionsChange();
|
||||
//onLoggingOptionsChange();
|
||||
//QMetaObject::connectSlotsByName(this);
|
||||
}
|
||||
|
||||
@ -500,6 +512,8 @@ void MainWindow::handleQuitButton() {
|
||||
quitting=true;
|
||||
#endif
|
||||
close();
|
||||
delayedSaveManagerPtr->appExiting();
|
||||
qDebug("Performing quit");
|
||||
QApplication::instance()->quit();
|
||||
}
|
||||
|
||||
@ -526,6 +540,7 @@ void MainWindow::handleGracefulQuitTimerEvent() {
|
||||
quitting=true;
|
||||
#endif
|
||||
close();
|
||||
delayedSaveManagerPtr->appExiting();
|
||||
qDebug("Performing quit");
|
||||
QApplication::instance()->quit();
|
||||
}
|
||||
@ -534,6 +549,8 @@ MainWindow::~MainWindow()
|
||||
{
|
||||
qDebug("Destroying main window");
|
||||
delete statusPageUpdateTimer;
|
||||
delete delayedSaveManagerPtr;
|
||||
delete saverPtr;
|
||||
for(QList<MainWindowItem*>::iterator it = configItems.begin(); it!= configItems.end(); ++it) {
|
||||
MainWindowItem* item = *it;
|
||||
item->deleteLater();
|
||||
@ -594,7 +611,7 @@ NonGUIOptionItem* MainWindow::initNonGUIOption(ConfigOption option) {
|
||||
return retValue;
|
||||
}
|
||||
|
||||
void MainWindow::loadAllConfigs(){
|
||||
void MainWindow::loadAllConfigs(SaverImpl* saverPtr){
|
||||
|
||||
//BORROWED FROM ??? //TODO move this code into single location
|
||||
std::string config; i2p::config::GetOption("conf", config);
|
||||
@ -635,6 +652,9 @@ void MainWindow::loadAllConfigs(){
|
||||
this->datadir = datadir.c_str();
|
||||
this->tunconfpath = tunConf.c_str();
|
||||
|
||||
saverPtr->setConfPath(this->confpath);
|
||||
saverPtr->setTunnelsConfPath(this->tunconfpath);
|
||||
|
||||
for(QList<MainWindowItem*>::iterator it = configItems.begin(); it!= configItems.end(); ++it) {
|
||||
MainWindowItem* item = *it;
|
||||
item->loadFromConfigOption();
|
||||
@ -642,10 +662,40 @@ void MainWindow::loadAllConfigs(){
|
||||
|
||||
ReadTunnelsConfig();
|
||||
|
||||
onLoggingOptionsChange();
|
||||
//onLoggingOptionsChange();
|
||||
}
|
||||
|
||||
void MainWindow::layoutTunnels() {
|
||||
|
||||
int height=0;
|
||||
ui->tunnelsScrollAreaWidgetContents->setGeometry(0,0,0,0);
|
||||
for(std::map<std::string, TunnelConfig*>::iterator it = tunnelConfigs.begin(); it != tunnelConfigs.end(); ++it) {
|
||||
const std::string& name=it->first;
|
||||
TunnelConfig* tunconf = it->second;
|
||||
TunnelPane * tunnelPane=tunconf->getTunnelPane();
|
||||
if(!tunnelPane)continue;
|
||||
int h=tunnelPane->height();
|
||||
height+=h;
|
||||
//qDebug() << "tun.height:" << height << "sz:" << tunnelPanes.size();
|
||||
//int h=tunnelPane->appendClientTunnelForm(ctc, ui->tunnelsScrollAreaWidgetContents, tunnelPanes.size(), height);
|
||||
}
|
||||
//qDebug() << "tun.setting height:" << height;
|
||||
ui->tunnelsScrollAreaWidgetContents->setGeometry(QRect(0, 0, 621, height));
|
||||
/*QList<QWidget*> childWidgets = ui->tunnelsScrollAreaWidgetContents->findChildren<QWidget*>();
|
||||
foreach(QWidget* widget, childWidgets)
|
||||
widget->show();*/
|
||||
}
|
||||
|
||||
void MainWindow::deleteTunnelFromUI(std::string tunnelName, TunnelConfig* cnf) {
|
||||
TunnelPane* tp = cnf->getTunnelPane();
|
||||
if(!tp)return;
|
||||
tunnelPanes.remove(tp);
|
||||
tp->deleteWidget();
|
||||
layoutTunnels();
|
||||
}
|
||||
|
||||
/** returns false iff not valid items present and save was aborted */
|
||||
bool MainWindow::saveAllConfigs(){
|
||||
bool MainWindow::saveAllConfigs(bool focusOnTunnel, std::string tunnelNameToFocus){
|
||||
QString cannotSaveSettings = QApplication::tr("Cannot save settings.");
|
||||
programOptionsWriterCurrentSection="";
|
||||
/*if(!logFileNameOption->lineEdit->text().trimmed().isEmpty())logOption->optionValue=boost::any(std::string("file"));
|
||||
@ -653,7 +703,6 @@ bool MainWindow::saveAllConfigs(){
|
||||
daemonOption->optionValue=boost::any(false);
|
||||
serviceOption->optionValue=boost::any(false);
|
||||
|
||||
std::stringstream out;
|
||||
for(QList<MainWindowItem*>::iterator it = configItems.begin(); it!= configItems.end(); ++it) {
|
||||
MainWindowItem* item = *it;
|
||||
if(!item->isValid()){
|
||||
@ -661,27 +710,9 @@ bool MainWindow::saveAllConfigs(){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
delayedSaveManagerPtr->delayedSave(++dataSerial, focusOnTunnel, tunnelNameToFocus);
|
||||
|
||||
for(QList<MainWindowItem*>::iterator it = configItems.begin(); it!= configItems.end(); ++it) {
|
||||
MainWindowItem* item = *it;
|
||||
item->saveToStringStream(out);
|
||||
}
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
QString backup=confpath+"~";
|
||||
if(QFile::exists(backup)) QFile::remove(backup);//TODO handle errors
|
||||
if(QFile::exists(confpath)) QFile::rename(confpath, backup);//TODO handle errors
|
||||
ofstream outfile;
|
||||
outfile.open(confpath.toStdString());//TODO handle errors
|
||||
outfile << out.str().c_str();
|
||||
outfile.close();
|
||||
|
||||
SaveTunnelsConfig();
|
||||
|
||||
onLoggingOptionsChange();
|
||||
|
||||
//onLoggingOptionsChange();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -711,7 +742,7 @@ void MainWindow::updated() {
|
||||
adjustSizesAccordingToWrongLabel();
|
||||
|
||||
applyTunnelsUiToConfigs();
|
||||
saveAllConfigs();
|
||||
saveAllConfigs(false);
|
||||
}
|
||||
|
||||
void MainWindowItem::installListeners(MainWindow *mainWindow) {}
|
||||
@ -725,6 +756,7 @@ void MainWindow::appendTunnelForms(std::string tunnelNameToFocus) {
|
||||
ServerTunnelConfig* stc = tunconf->asServerTunnelConfig();
|
||||
if(stc){
|
||||
ServerTunnelPane * tunnelPane=new ServerTunnelPane(&tunnelsPageUpdateListener, stc, ui->wrongInputLabel, ui->wrongInputLabel, this);
|
||||
tunconf->setTunnelPane(tunnelPane);
|
||||
int h=tunnelPane->appendServerTunnelForm(stc, ui->tunnelsScrollAreaWidgetContents, tunnelPanes.size(), height);
|
||||
height+=h;
|
||||
//qDebug() << "tun.height:" << height << "sz:" << tunnelPanes.size();
|
||||
@ -738,6 +770,7 @@ void MainWindow::appendTunnelForms(std::string tunnelNameToFocus) {
|
||||
ClientTunnelConfig* ctc = tunconf->asClientTunnelConfig();
|
||||
if(ctc){
|
||||
ClientTunnelPane * tunnelPane=new ClientTunnelPane(&tunnelsPageUpdateListener, ctc, ui->wrongInputLabel, ui->wrongInputLabel, this);
|
||||
tunconf->setTunnelPane(tunnelPane);
|
||||
int h=tunnelPane->appendClientTunnelForm(ctc, ui->tunnelsScrollAreaWidgetContents, tunnelPanes.size(), height);
|
||||
height+=h;
|
||||
//qDebug() << "tun.height:" << height << "sz:" << tunnelPanes.size();
|
||||
@ -784,6 +817,10 @@ bool MainWindow::applyTunnelsUiToConfigs() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void MainWindow::reloadTunnelsConfigAndUI_QString(const QString tunnelNameToFocus) {
|
||||
reloadTunnelsConfigAndUI(tunnelNameToFocus.toStdString());
|
||||
}
|
||||
|
||||
void MainWindow::reloadTunnelsConfigAndUI(std::string tunnelNameToFocus) {
|
||||
deleteTunnelForms();
|
||||
for (std::map<std::string,TunnelConfig*>::iterator it=tunnelConfigs.begin(); it!=tunnelConfigs.end(); ++it) {
|
||||
@ -795,31 +832,6 @@ void MainWindow::reloadTunnelsConfigAndUI(std::string tunnelNameToFocus) {
|
||||
appendTunnelForms(tunnelNameToFocus);
|
||||
}
|
||||
|
||||
void MainWindow::SaveTunnelsConfig() {
|
||||
std::stringstream out;
|
||||
|
||||
for (std::map<std::string,TunnelConfig*>::iterator it=tunnelConfigs.begin(); it!=tunnelConfigs.end(); ++it) {
|
||||
const std::string& name = it->first;
|
||||
TunnelConfig* tunconf = it->second;
|
||||
tunconf->saveHeaderToStringStream(out);
|
||||
tunconf->saveToStringStream(out);
|
||||
tunconf->saveI2CPParametersToStringStream(out);
|
||||
}
|
||||
|
||||
using namespace std;
|
||||
|
||||
QString backup=tunconfpath+"~";
|
||||
if(QFile::exists(backup)) QFile::remove(backup);//TODO handle errors
|
||||
if(QFile::exists(tunconfpath)) QFile::rename(tunconfpath, backup);//TODO handle errors
|
||||
ofstream outfile;
|
||||
outfile.open(tunconfpath.toStdString());//TODO handle errors
|
||||
outfile << out.str().c_str();
|
||||
outfile.close();
|
||||
|
||||
i2p::client::context.ReloadConfig();
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::TunnelsPageUpdateListenerMainWindowImpl::updated(std::string oldName, TunnelConfig* tunConf) {
|
||||
if(oldName!=tunConf->getName()) {
|
||||
//name has changed
|
||||
@ -827,7 +839,7 @@ void MainWindow::TunnelsPageUpdateListenerMainWindowImpl::updated(std::string ol
|
||||
if(it!=mainWindow->tunnelConfigs.end())mainWindow->tunnelConfigs.erase(it);
|
||||
mainWindow->tunnelConfigs[tunConf->getName()]=tunConf;
|
||||
}
|
||||
mainWindow->saveAllConfigs();
|
||||
mainWindow->saveAllConfigs(true, tunConf->getName());
|
||||
}
|
||||
|
||||
void MainWindow::TunnelsPageUpdateListenerMainWindowImpl::needsDeleting(std::string oldName){
|
||||
@ -875,7 +887,8 @@ void MainWindow::anchorClickedHandler(const QUrl & link) {
|
||||
pageWithBackButton->show();
|
||||
textBrowser->hide();
|
||||
std::stringstream s;
|
||||
i2p::http::ShowLocalDestination(s,str.toStdString());
|
||||
std::string strstd = str.toStdString();
|
||||
i2p::http::ShowLocalDestination(s,strstd,0);
|
||||
childTextBrowser->setHtml(QString::fromStdString(s.str()));
|
||||
}
|
||||
}
|
||||
|
@ -62,6 +62,12 @@
|
||||
#include "widgetlockregistry.h"
|
||||
#include "widgetlock.h"
|
||||
|
||||
#include "DelayedSaveManager.h"
|
||||
#include "DelayedSaveManagerImpl.h"
|
||||
#include "SaverImpl.h"
|
||||
|
||||
class SaverImpl;
|
||||
|
||||
class LogViewerManager;
|
||||
|
||||
template<typename ValueType>
|
||||
@ -373,10 +379,14 @@ using namespace i2p::qt;
|
||||
|
||||
class Controller;
|
||||
|
||||
class DelayedSaveManagerImpl;
|
||||
|
||||
class MainWindow : public QMainWindow {
|
||||
Q_OBJECT
|
||||
private:
|
||||
std::shared_ptr<std::iostream> logStream;
|
||||
DelayedSaveManagerImpl* delayedSaveManagerPtr;
|
||||
DelayedSaveManager::DATA_SERIAL_TYPE dataSerial;
|
||||
public:
|
||||
explicit MainWindow(std::shared_ptr<std::iostream> logStream_, QWidget *parent=nullptr);
|
||||
~MainWindow();
|
||||
@ -502,16 +512,17 @@ protected:
|
||||
void initStringBox(ConfigOption option, QLineEdit* lineEdit);
|
||||
NonGUIOptionItem* initNonGUIOption(ConfigOption option);
|
||||
|
||||
void loadAllConfigs();
|
||||
void loadAllConfigs(SaverImpl* saverPtr);
|
||||
void layoutTunnels();
|
||||
|
||||
public slots:
|
||||
/** returns false iff not valid items present and save was aborted */
|
||||
bool saveAllConfigs();
|
||||
void SaveTunnelsConfig();
|
||||
bool saveAllConfigs(bool focusOnTunnel, std::string tunnelNameToFocus="");
|
||||
void reloadTunnelsConfigAndUI(std::string tunnelNameToFocus);
|
||||
|
||||
//focus none
|
||||
void reloadTunnelsConfigAndUI() { reloadTunnelsConfigAndUI(""); }
|
||||
void reloadTunnelsConfigAndUI_QString(const QString tunnelNameToFocus);
|
||||
void addServerTunnelPushButtonReleased();
|
||||
void addClientTunnelPushButtonReleased();
|
||||
|
||||
@ -530,6 +541,7 @@ private:
|
||||
|
||||
void appendTunnelForms(std::string tunnelNameToFocus);
|
||||
void deleteTunnelForms();
|
||||
void deleteTunnelFromUI(std::string tunnelName, TunnelConfig* cnf);
|
||||
|
||||
template<typename Section, typename Type>
|
||||
std::string GetI2CPOption (const Section& section, const std::string& name, const Type& value) const
|
||||
@ -575,11 +587,11 @@ private:
|
||||
std::map<std::string,TunnelConfig*>::const_iterator it=tunnelConfigs.find(name);
|
||||
if(it!=tunnelConfigs.end()){
|
||||
TunnelConfig* tc=it->second;
|
||||
deleteTunnelFromUI(name, tc);
|
||||
tunnelConfigs.erase(it);
|
||||
delete tc;
|
||||
}
|
||||
saveAllConfigs();
|
||||
reloadTunnelsConfigAndUI("");
|
||||
saveAllConfigs(false);
|
||||
}
|
||||
|
||||
std::string GenerateNewTunnelName() {
|
||||
@ -614,8 +626,7 @@ private:
|
||||
destinationPort,
|
||||
sigType);
|
||||
|
||||
saveAllConfigs();
|
||||
reloadTunnelsConfigAndUI(name);
|
||||
saveAllConfigs(true, name);
|
||||
}
|
||||
|
||||
void CreateDefaultServerTunnel() {//TODO dedup default values with ReadTunnelsConfig() and with ClientContext.cpp::ReadTunnels ()
|
||||
@ -651,8 +662,7 @@ private:
|
||||
isUniqueLocal);
|
||||
|
||||
|
||||
saveAllConfigs();
|
||||
reloadTunnelsConfigAndUI(name);
|
||||
saveAllConfigs(true, name);
|
||||
}
|
||||
|
||||
void ReadTunnelsConfig() //TODO deduplicate the code with ClientContext.cpp::ReadTunnels ()
|
||||
@ -793,7 +803,9 @@ private:
|
||||
|
||||
TunnelsPageUpdateListenerMainWindowImpl tunnelsPageUpdateListener;
|
||||
|
||||
void onLoggingOptionsChange() {}
|
||||
//void onLoggingOptionsChange() {}
|
||||
|
||||
SaverImpl* saverPtr;
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
Loading…
Reference in New Issue
Block a user