/* 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: { downloads.clear(); //TODO: something better for(auto i : msg.downloads()) downloads.push_back(i.download()); 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()) { i = msg.download().download(); found = true; break; } } if(!found) downloads.push_back(msg.download().download()); 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")); }