/*
Copyright © 2015 Gluzskiy Alexandr (sss)
This file is part of Unknown Download Manager (UDM).
UDM 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 2 of the License, or
(at your option) any later version.
UDM 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 UDM. If not, see .
*/
#include "udm_main.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "connect_widget.h"
#include "client_session.h"
#include "downloads_model.h"
#include "filters_model.h"
#include "download_add_widget.h"
udm_main::udm_main(QWidget *parent)
: QMainWindow(parent)
{
io_service_ = nullptr;
thread_client_session = nullptr;
//session = nullptr;
auto menu_main = this->menuBar()->addMenu(tr("Main"));
auto action_connect = menu_main->addAction(tr("Connect"));
connect(action_connect, SIGNAL(triggered()), this, SLOT(show_connect_widget()));
auto action_exit = menu_main->addAction(tr("Exit"));
connect(action_exit, SIGNAL(triggered(bool)), this, SLOT(close())); //TODO: something better
lbl_state = new QLabel;
lbl_state->setText(tr("State") + ": " + tr("Offline"));
this->statusBar()->addPermanentWidget(lbl_state);
tbl_downloads = new QTableView;
tbl_downloads->setShowGrid(false);
tbl_downloads->setUpdatesEnabled(true);
mdl_downloads = new downloads_model(downloads);
tbl_downloads->setModel(mdl_downloads);
tbl_downloads->setSelectionBehavior(QAbstractItemView::SelectRows);
tbl_downloads->setSortingEnabled(true);
tbl_downloads->horizontalHeader()->setHighlightSections(false);
tbl_downloads->horizontalHeader()->setMovable(true);
tbl_downloads->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
tbl_downloads->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
tree_filters = new QTreeView;
mdl_filters = new filters_model;
tree_filters->setModel(mdl_filters);
tree_filters->header()->hide();
tree_filters->setSelectionMode(QAbstractItemView::ExtendedSelection);
tree_filters->setSelectionBehavior(QAbstractItemView::SelectRows);
tree_filters->setIndentation(10);
spl_hor = new QSplitter(Qt::Horizontal);
spl_hor->addWidget(tree_filters);
spl_hor->addWidget(tbl_downloads);
spl_hor->setStretchFactor(0, 2);
spl_hor->setStretchFactor(1, 10);
tabs_info = new QTabWidget;
spl_vert = new QSplitter(Qt::Vertical);
spl_vert->addWidget(spl_hor);
spl_vert->addWidget(tabs_info);
spl_vert->setStretchFactor(0, 3);
spl_vert->setStretchFactor(1, 1);
setCentralWidget(spl_vert);
create_buttons();
}
udm_main::~udm_main()
{
if(thread_client_session)
{
thread_client_session->quit();
thread_client_session->deleteLater();
//delete thread_client_session;
}
//TODO: clear all remaining data
}
void udm_main::show_connect_widget()
{
connect_widget *w = new connect_widget;
connect(w, SIGNAL(client_connect(QString&,QString&,int)), this, SLOT(client_connect(QString&,QString&,int)));
//TODO: make connection to other slots related to connection
//TODO: destroy widget on close
w->show();
}
void udm_main::client_pre_connect_init()
{
if(thread_client_session)
{
thread_client_session->quit();
delete thread_client_session;
thread_client_session = nullptr;
}
thread_client_session = new QThread(this);
if(io_service_)
{
delete io_service_;
io_service_ = nullptr;
}
io_service_ = new boost::asio::io_service;
/* if(session) //crashing
{
delete session;
session = nullptr;
} */
session = new client_session(0, io_service_); //parent must be 0 here
connect(session, SIGNAL(server_message_received(server_msg)), this, SLOT(server_message_received(server_msg)));
connect(session, SIGNAL(client_connected(bool,QString)), this, SLOT(client_connected(bool,QString)));
connect(session, SIGNAL(client_disconnected()), this, SLOT(client_disconnected()));
connect(session, SIGNAL(terminate_thread()), thread_client_session, SLOT(quit()));
}
void udm_main::client_connect_finalize()
{
session->moveToThread(thread_client_session);
thread_client_session->start();
}
void udm_main::client_connect(QString &host, QString &password, int port)
{
client_pre_connect_init();
connect(this, SIGNAL(connect_signal(QString,QString,int)), session, SLOT(client_connect(QString,QString,int)));
client_connect_finalize();
emit connect_signal(host, password, port);
}
void udm_main::client_connect_ssl(QString &host, QString &password, int port, QString &ssl_ca, QString &ssl_crt, QString &ssl_key)
{
client_pre_connect_init();
connect(this, SIGNAL(connect_signal(QString,QString,int,QString,QString)), session, SLOT(client_connect(QString,QString,int,QString,QString)));
client_connect_finalize();
emit connect_signal_ssl(host, password, port, ssl_ca, ssl_crt, ssl_key);
}
void udm_main::server_message_received(server_msg msg)
{
switch(msg.type())
{
case SERVER_MSG_TYPE::SERVER_AUTH_REPLY:
{
if(msg.auth_reply().status())
{
auth_token = msg.auth_reply().auth_token();
btn_add->setEnabled(true); //we can add downloads now
lbl_state->setText(tr("State") + ": " + tr("Connected") + ", " + tr("Authenticated"));
//request modules and settings here
{
client_msg msg;
msg.set_type(CLIENT_MSG_TYPE::CLIENT_CORE_INFO_REQUEST);
msg.set_auth_token(auth_token);
session->send_message(msg);
}
{
client_msg msg;
msg.set_type(CLIENT_MSG_TYPE::CLIENT_MODULES_REQUEST);
msg.set_auth_token(auth_token);
session->send_message(msg);
}
{
client_msg msg;
msg.set_type(CLIENT_MSG_TYPE::CLIENT_DOWNLOADS_LIST_REQUEST);
msg.set_auth_token(auth_token);
session->send_message(msg);
}
}
else
{
QMessageBox msg_box;
msg_box.setText(tr("Authentication failed with error:") + "\n" + msg.auth_reply().error_description().c_str());
msg_box.exec();
lbl_state->setText(tr("State") + ": " + tr("auth error"));
}
}
break;
case SERVER_MSG_TYPE::SERVER_CORE_INFO_REPLY:
server_info = msg.server_core_info_reply();
break;
case SERVER_MSG_TYPE::SERVER_MODULES_REPLY:
{
modules.clear(); //TODO: something better
for(auto i : msg.server_modules_reply())
modules.push_back(i);
}
break;
case SERVER_MSG_TYPE::SERVER_DOWNLOADS_LIST_REPLY:
{
if(!downloads.empty())
{
mdl_downloads->removeRows(0, downloads.size());
downloads.clear(); //TODO: something better
}
for(auto i : msg.downloads())
downloads.push_back(i.download());
mdl_downloads->insertRows(0, downloads.size());
mdl_downloads->refresh();
}
break;
case SERVER_MSG_TYPE::SERVER_DOWNLOAD_INFO_REPLY:
{
bool found = false;
for(auto i : downloads)
{
if(i.id() == msg.download().download().id())
{
//TODO: merge download, not replace
i = msg.download().download();
found = true;
break;
}
}
if(!found)
downloads.push_back(msg.download().download());
mdl_downloads->insertRows(downloads.size(), 1);
mdl_downloads->refresh();
}
break;
default:
break;
}
}
void udm_main::create_buttons()
{
btn_start = new QPushButton(this);
btn_start->setEnabled(false);
connect(btn_start, SIGNAL(clicked(bool)), this, SLOT(btn_start_clicked()));
btn_stop = new QPushButton(this);
btn_stop->setEnabled(false);
connect(btn_stop, SIGNAL(clicked(bool)), this, SLOT(btn_stop_clicked()));
btn_del = new QPushButton(this);
btn_del->setEnabled(false);
connect(btn_del, SIGNAL(clicked(bool)), this, SLOT(btn_del_clicked()));
btn_add = new QPushButton(this);
btn_add->setEnabled(false);
connect(btn_add, SIGNAL(clicked(bool)), this, SLOT(btn_add_clicked()));
button_bar = new QToolBar(this);
button_bar->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
//TODO: support dynamic action buttons for modules
button_bar->addWidget(btn_start);
button_bar->addWidget(btn_stop);
button_bar->addSeparator();
button_bar->addWidget(btn_del);
button_bar->addWidget(btn_add);
btn_start->setText(tr("Start"));
btn_start->setToolTip(tr("Start download"));
btn_start->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
btn_stop->setText(tr("Stop"));
btn_stop->setToolTip(tr("Stop download"));
btn_stop->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
btn_del->setText(tr("Delete"));
btn_del->setToolTip(tr("Delete download"));
btn_del->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
btn_add->setText(tr("Add"));
btn_add->setToolTip(tr("Add download"));
btn_add->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
this->addToolBar(button_bar);
}
void udm_main::btn_start_clicked()
{
}
void udm_main::btn_stop_clicked()
{
}
void udm_main::btn_add_clicked()
{
download_add_widget *w = new download_add_widget(modules);
connect(w, SIGNAL(got_download_settings(std::string, std::map)), this, SLOT(got_download_settings(std::string, std::map)));
w->show();
}
void udm_main::got_download_settings(std::string module_name, std::map settings)
{
if(!settings.empty())
{
client_msg msg;
msg.set_auth_token(auth_token);
msg.set_type(CLIENT_MSG_TYPE::CLIENT_DOWNLOAD_ADD);
client_download_add_request *r = msg.mutable_download_add_request();
r->set_module_name(module_name);
for(auto i : settings)
{
int_string_pair *p = r->add_params();
p->set_id(i.first);
p->set_value(i.second);
}
session->send_message(msg);
}
}
void udm_main::btn_del_clicked()
{
}
void udm_main::client_connected(bool success, QString error_text)
{
if(!success)
{
QMessageBox msg;
msg.setText(tr("client connection error with error:") + error_text);
msg.exec();
lbl_state->setText(tr("State") + ": " + tr("Connection error"));
btn_add->setEnabled(false);
btn_del->setEnabled(false);
btn_start->setEnabled(false);
btn_stop->setEnabled(false);
}
else
{
lbl_state->setText(tr("State") + ": " + tr("Connected"));
}
/* QMessageBox msg;
msg.setText(success?"client connected with message:":"client connection error with error:" + error_text);
msg.exec(); */
}
void udm_main::client_disconnected()
{
btn_add->setEnabled(false);
btn_del->setEnabled(false);
btn_start->setEnabled(false);
btn_stop->setEnabled(false);
lbl_state->setText(tr("State") + ": " + tr("Disconnected"));
}