You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Labcontrol/src/mainwindow.cpp

1024 lines
36 KiB
C++

/*
* Copyright 2014-2020 Markus Prasser
*
* This file is part of Labcontrol.
*
* Labcontrol 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.
*
* Labcontrol 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 Labcontrol. If not, see <http://www.gnu.org/licenses/>.
*/
#include <memory>
#include "Lib/settings.h"
#include "localzleafstarter.h"
#include "mainwindow.h"
#include "manualprintingsetup.h"
#include <QButtonGroup>
#include <QDebug>
#include <QInputDialog>
#include <QtGlobal>
extern std::unique_ptr<lc::Settings> settings;
lc::MainWindow::MainWindow(QWidget *argParent)
: QMainWindow{argParent},
icons(static_cast<int>(icons_t::ICON_QUANTITY)), ui{new Ui::MainWindow} {
ui->setupUi(this);
lablib = new Lablib{this};
LoadIconPixmaps();
SetupWidgets();
if (valid_items) {
gui_update_timer = new QTimer{this};
connect(gui_update_timer, &QTimer::timeout, this,
&MainWindow::UpdateClientsTableView);
gui_update_timer->start(500);
}
/* session actions */
// Add z-Tree versions to the corresponding combo box
ui->CBzTreeVersion->addItem(tr("Please choose a version:"));
ui->CBzTreeVersion->addItems(settings->installedZTreeVersions);
// Add default path to the corresponding combo box
ui->CBDataTargetPath->addItem(tr("Set a new path HERE"));
ui->CBDataTargetPath->addItem(QDir::homePath());
ui->CBDataTargetPath->addItem(QDir::homePath() + "/zTreeData");
ui->CBDataTargetPath->setCurrentIndex(2);
connect(this, &MainWindow::RequestNewDataTargetPath, this,
&MainWindow::GetNewDataTargetPath);
if (settings->dvipsCmd.isEmpty() || settings->latexCmd.isEmpty() ||
settings->lcDataDir.isEmpty() || settings->lprCmd.isEmpty() ||
settings->postscriptViewer.isEmpty() || settings->ps2pdfCmd.isEmpty() ||
settings->rmCmd.isEmpty() || settings->vncViewer.isEmpty()) {
QMessageBox::information(
this, tr("Receipts printing will not work"),
tr("Some component essential for receipts creation and"
" printing is missing. No receipts will be created or"
" printed."),
QMessageBox::Ok);
} else {
ui->CBReceiptsHeader->addItems(settings->installedLaTeXHeaders);
if (settings->defaultReceiptIndex &&
settings->defaultReceiptIndex < ui->CBReceiptsHeader->count()) {
ui->CBReceiptsHeader->setCurrentIndex(settings->defaultReceiptIndex);
}
}
}
lc::MainWindow::~MainWindow() {
delete ui;
delete valid_items;
}
bool lc::MainWindow::CheckIfUserIsAdmin() {
if (settings->localUserName.isEmpty()) {
QMessageBox messageBox{
QMessageBox::Warning, tr("User not detectable"),
tr("Your user name could not be queryed. The admin tab will be"
" disabled. You won't be able to perform administrative"
" actions but can conduct experiments normally."),
QMessageBox::Ok};
messageBox.exec();
return false;
}
qDebug() << "The user's name is:" << settings->localUserName;
return lablib->CheckIfUserIsAdmin();
}
void lc::MainWindow::DisableDisfunctionalWidgets() {
const QStringList &zTreeEntries = settings->installedZTreeVersions;
if (zTreeEntries.isEmpty()) {
ui->CBClientNames->setEnabled(false);
// ui->GBzTree->setEnabled( false );
ui->L_FakeName->setEnabled(false);
ui->PBRunzLeaf->setEnabled(false);
ui->PBStartLocalzLeaf->setEnabled(false);
ui->PBStartzLeaf->setEnabled(false);
}
// Disable all z-Leaf killing related buttons if the 'killall' command is not
// available
if (settings->killallCmd.isEmpty()) {
ui->PBKillLocalzLeaf->setEnabled(false);
ui->PBKillzLeaf->setEnabled(false);
}
// Disable all functions relying on the labcontrol installation directory if
// it is not available
if (settings->lcDataDir.isEmpty()) {
ui->CBClientNames->setEnabled(false);
ui->CBWebcamChooser->setEnabled(false);
ui->GBClientActions->setEnabled(false);
ui->LEFilePath->setEnabled(false);
ui->L_FakeName->setEnabled(false);
ui->L_WebcamChooser->setEnabled(false);
ui->PBBeamFile->setEnabled(false);
ui->PBChooseFile->setEnabled(false);
ui->PBKillLocalzLeaf->setEnabled(false);
ui->PBRunzLeaf->setEnabled(false);
ui->PBShowPreprints->setEnabled(false);
ui->PBStartLocalzLeaf->setEnabled(false);
}
// Disable 'PBShowPreprints', if 'file_manager' was not set
if (settings->fileMngr.isEmpty()) {
ui->PBShowPreprints->setEnabled(false);
}
// Disable 'PBBoot', if 'network_broadcast_address' was not set
if (settings->netwBrdAddr.isEmpty()) {
ui->PBBoot->setEnabled(false);
}
// Disable 'PBShowORSEE', if 'orsee_command' was not set
if (settings->browserCmd.isEmpty() || settings->orseeUrl.isEmpty()) {
ui->PBShowORSEE->setEnabled(false);
}
// Disable all widgets needless if 'public_key_path_user' or
// 'user_name_on_clients' was not set
if (settings->pkeyPathUser.isEmpty() ||
settings->userNameOnClients.isEmpty()) {
ui->CBClientNames->setEnabled(false);
ui->LEFilePath->setEnabled(false);
ui->L_FakeName->setEnabled(false);
ui->PBBeamFile->setEnabled(false);
ui->PBChooseFile->setEnabled(false);
ui->PBKillzLeaf->setEnabled(false);
ui->PBRunzLeaf->setEnabled(false);
ui->PBShutdown->setEnabled(false);
ui->PBStartzLeaf->setEnabled(false);
ui->RBUseUserRoot->click();
ui->RBUseLocalUser->setEnabled(false);
}
// Disable widgets needless if 'public_key_path_root' was not set
if (settings->pkeyPathRoot.isEmpty()) {
ui->RBUseUserRoot->setEnabled(false);
ui->RBUseLocalUser->click();
}
if (settings->pkeyPathRoot.isEmpty() && settings->pkeyPathUser.isEmpty()) {
ui->GBExecuteOnEveryClient->setEnabled(false);
ui->GBOptionsForAdminActions->setEnabled(false);
ui->PBOpenTerminal->setEnabled(false);
}
// Disable beam functionality if 'rcp_command' was not set
if (settings->scpCmd.isEmpty()) {
ui->LEFilePath->setEnabled(false);
ui->PBBeamFile->setEnabled(false);
ui->PBChooseFile->setEnabled(false);
}
// Disable 'PBRunzLeaf' and 'PBStartzLeaf' if 'server_ip' was not set
if (settings->serverIP.isEmpty()) {
ui->PBRunzLeaf->setEnabled(false);
ui->PBStartzLeaf->setEnabled(false);
}
// Disable any actions concerning the clients if 'ssh_command' was not set
if (settings->sshCmd.isEmpty()) {
ui->CBClientNames->setEnabled(false);
ui->GBClientActions->setEnabled(false);
ui->L_FakeName->setEnabled(false);
ui->LEFilePath->setEnabled(false);
ui->PBBeamFile->setEnabled(false);
ui->PBChooseFile->setEnabled(false);
ui->PBKillzLeaf->setEnabled(false);
ui->PBRunzLeaf->setEnabled(false);
ui->PBShutdown->setEnabled(false);
ui->PBStartzLeaf->setEnabled(false);
ui->TAdminActions->setEnabled(false);
}
if (settings->tasksetCmd.isEmpty()) {
ui->CBClientNames->setEnabled(false);
ui->L_FakeName->setEnabled(false);
ui->PBRunzLeaf->setEnabled(false);
ui->PBStartSession->setEnabled(false);
ui->PBStartLocalzLeaf->setEnabled(false);
ui->PBStartzLeaf->setEnabled(false);
}
// Disable 'PBOpenTerminal' if 'terminal_emulator_command' was not set
if (settings->termEmulCmd.isEmpty()) {
ui->GBExecuteOnEveryClient->setEnabled(false);
ui->PBOpenTerminal->setEnabled(false);
}
// Disable 'PBViewDesktop' if 'vnc_viewer' was not set
if (settings->vncViewer.isEmpty()) {
ui->PBViewDesktopViewOnly->setEnabled(false);
ui->PBViewDesktopFullControl->setEnabled(false);
}
// Disable 'PBBoot' if 'wakeonlan_command' was not set
if (settings->wakeonlanCmd.isEmpty()) {
ui->PBBoot->setEnabled(false);
}
// Deactivate the webcam choosing interface if no webcams are available or the
// viewer is missing
if (settings->webcamDisplayCmd.isEmpty() || settings->webcams.isEmpty()) {
ui->CBWebcamChooser->setEnabled(false);
ui->L_WebcamChooser->setEnabled(false);
}
if (settings->wineCmd.isEmpty()) {
ui->CBClientNames->setEnabled(false);
ui->L_FakeName->setEnabled(false);
ui->PBRunzLeaf->setEnabled(false);
// ui->PBStartSession->setEnabled( false );
ui->PBStartLocalzLeaf->setEnabled(false);
ui->PBStartzLeaf->setEnabled(false);
}
if (settings->zTreeInstDir.isEmpty()) {
ui->CBClientNames->setEnabled(false);
ui->L_FakeName->setEnabled(false);
ui->PBRunzLeaf->setEnabled(false);
ui->PBStartSession->setEnabled(false);
ui->PBStartLocalzLeaf->setEnabled(false);
ui->PBStartzLeaf->setEnabled(false);
}
}
void lc::MainWindow::LoadIconPixmaps() {
if (settings->lcDataDir.isEmpty()) {
return;
}
const QStringList iconNames{QStringList{} << "unknown.png"
<< "off.png"
<< "down.png"
<< "boot.png"
<< "on.png"
<< "zLeaf.png"};
for (int i = 0; i < (int)icons_t::ICON_QUANTITY; i++) {
if (!icons[i].load(settings->lcDataDir + "/icons/" + iconNames[i])) {
QMessageBox::information(
this, tr("Could not load icon '%1'").arg(iconNames[i]),
tr("The icon in '%1/icons/%2' could not be loaded.")
.arg(settings->lcDataDir)
.arg(iconNames[i]),
QMessageBox::Ok);
}
}
}
void lc::MainWindow::on_PBKillLocalzLeaf_clicked() {
QString program{settings->killallCmd};
QStringList arguments;
arguments << "-I"
<< "-q"
<< "zleaf.exe";
// Start the process
QProcess killLocalzLeafProc;
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
killLocalzLeafProc.setProcessEnvironment(env);
killLocalzLeafProc.startDetached(program, arguments);
localzLeavesAreRunning = false;
// Output message via the debug messages tab
qDebug() << program << arguments;
}
void lc::MainWindow::on_PBPrintPaymentFileManually_clicked() {
ManualPrintingSetup *manPrint = new ManualPrintingSetup{this};
manPrint->setWindowFlags(Qt::Window);
manPrint->show();
connect(manPrint, SIGNAL(destroyed(QObject *)), manPrint,
SLOT(deleteLater()));
connect(manPrint, &ManualPrintingSetup::RequestReceiptsHandler, this,
&MainWindow::StartReceiptsHandler);
}
void lc::MainWindow::on_PBRunzLeaf_clicked() {
// Check if more than one client is selected and issue a warning message if so
unsigned short int numberOfSelectedClients = 0;
QModelIndexList activatedItems =
ui->TVClients->selectionModel()->selectedIndexes();
for (QModelIndexList::ConstIterator it = activatedItems.cbegin();
it != activatedItems.cend(); ++it) {
if ((*it).data(Qt::DisplayRole).type() != 0) {
++numberOfSelectedClients;
}
}
qDebug() << numberOfSelectedClients << "clients are selected.";
if (numberOfSelectedClients > 1) {
QMessageBox messageBox{
QMessageBox::Information, tr("Too many clients selected"),
tr("There are too many clients selected in the table view on the left. "
"Please select only one."),
QMessageBox::Ok, this};
messageBox.exec();
} else {
const QString *const fakeName =
new QString{ui->CBClientNames->currentText()};
for (QModelIndexList::ConstIterator it = activatedItems.cbegin();
it != activatedItems.cend(); ++it) {
if ((*it).data(Qt::DisplayRole).type() != 0) {
Client *client =
static_cast<Client *>((*it).data(Qt::UserRole).value<void *>());
client->StartZLeaf(fakeName);
}
}
delete fakeName;
}
}
void lc::MainWindow::on_RBUseLocalUser_toggled(bool checked) {
if (checked) {
qDebug() << "'RBUseLocalUser' got toggled.";
}
}
void lc::MainWindow::SetupWidgets() {
// Fill the 'CBClientNames' with possible client names and the 'TVClients'
// with the clients
if (!settings->GetClients().isEmpty()) {
valid_items = new QVector<QStandardItem *>;
valid_items->reserve(settings->GetClients().size());
clients_view_model = new QStandardItemModel{this};
for (auto *s : settings->GetClients()) {
int temp_xpos = s->xPosition - 1, temp_ypos = s->yPosition - 1;
// Check if a client already exists at the given position and skip, if so
if (clients_view_model->item(temp_ypos, temp_xpos)) {
QMessageBox::information(this, tr("Double assignment to one position"),
tr("Two clients where set for the same "
"position, '%1' will be dropped.")
.arg(s->name));
continue;
}
// Work to be done for the 'CBClientNames'
ui->CBClientNames->addItem(s->name);
// Work to be done for the 'TVClients'
QStandardItem *item = new QStandardItem(s->name);
item->setBackground(QBrush(QColor(127, 255, 127, 255)));
QVariant v = qVariantFromValue(static_cast<void *>(s));
item->setData(v, Qt::UserRole);
item->setIcon(icons[(int)icons_t::UNKNOWN]);
clients_view_model->setItem(temp_ypos, temp_xpos, item);
valid_items->append(item);
}
ui->TVClients->setModel(clients_view_model);
valid_items->squeeze();
} else {
QMessageBox messageBox{
QMessageBox::Warning, tr("Could not construct clients view"),
tr("The creation of the clients view failed. Please check the file "
"'/etc/xdg/Labcontrol/Labcontrol.conf'."),
QMessageBox::Ok, this};
messageBox.exec();
ui->CBClientNames->setEnabled(false);
ui->GBClientActions->setEnabled(false);
ui->LEFilePath->setEnabled(false);
ui->L_FakeName->setEnabled(false);
ui->PBBeamFile->setEnabled(false);
ui->PBChooseFile->setEnabled(false);
ui->PBRunzLeaf->setEnabled(false);
ui->TAdminActions->setEnabled(false);
ui->TVClients->setEnabled(false);
}
// Fill the 'CBWebcamChooser' with all available network webcams
if (!settings->webcams.isEmpty()) {
for (const auto &s : settings->webcams_names)
ui->CBWebcamChooser->addItem(s);
}
// Disable the admin tab if the user has no administrative rights and set it
// up
if (CheckIfUserIsAdmin()) {
ui->TAdminActions->setEnabled(true);
ui->L_AdministrativeRights->setText(tr("You have administrative rights."));
} else {
ui->L_AdministrativeRights->setText(
tr("You don't have administrative rights."));
}
ui->L_UserName->setText(tr("You are user %1").arg(settings->localUserName));
if (!settings->userNameOnClients.isEmpty()) {
ui->RBUseLocalUser->setText(settings->userNameOnClients);
} else {
ui->RBUseUserRoot->click();
}
// Match the QRadioButtons correct groups
userChooseButtonGroup = new QButtonGroup{this};
userChooseButtonGroup->setExclusive(true);
userChooseButtonGroup->addButton(ui->RBUseLocalUser);
userChooseButtonGroup->addButton(ui->RBUseUserRoot);
ui->RBUseLocalUser->click();
// Fill the CBCommandToExecute QComboBox
if (!settings->userNameOnClients.isEmpty()) {
ui->CBCommandToExecute->addItems(
QStringList{} << ""
<< "apt update"
<< "apt full-upgrade -y"
<< "reboot"
<< "rm -rfv /home/" + settings->userNameOnClients +
"/.mozilla"
<< "uname -a");
} else {
ui->CBCommandToExecute->addItems(QStringList{} << ""
<< "apt update"
<< "apt full-upgrade -y"
<< "reboot"
<< "uname -a");
}
// Disable buttons which are not configured
// DisableDisfunctionalWidgets();
// Set the info text in LInfo on the TInfo tab
ui->LInfo->setText(
"This is Labcontrol version 2.1.6\n\n\n\n\n\n"
"Developers\n\n"
"0day-2016 Henning Prömpers\n"
"2014-2016 Markus Prasser\n"
"2016 - now WiwilabHiwiOrgaization\n\n\n"
"Copyright\n\n"
"Labcontrol is free software: you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
"the Free Software Foundation, either version 3 of the License, or\n"
"(at your option) any later version.\n\n"
"Labcontrol is distributed in the hope that it will be useful,\n"
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
"See the GNU General Public License for more details.\n\n"
"You should have received a copy of the GNU General Public License\n"
"along with Labcontrol. If not, see "
"<http://www.gnu.org/licenses/>.\n\n\n");
}
void lc::MainWindow::StartReceiptsHandler(
QString argzTreeDataTargetPath, bool argReceiptsForLocalClients,
QString argAnonymousReceiptsPlaceholder, QString argLatexHeaderName,
QString argDateString) {
ReceiptsHandler *recHand =
new ReceiptsHandler{argzTreeDataTargetPath,
argReceiptsForLocalClients,
argAnonymousReceiptsPlaceholder,
argLatexHeaderName,
argDateString,
this};
connect(recHand, &ReceiptsHandler::PrintingFinished, recHand,
&ReceiptsHandler::deleteLater);
}
void lc::MainWindow::UpdateClientsTableView() {
for (auto s : *valid_items) {
Client::State state =
static_cast<Client *>(s->data(Qt::UserRole).value<void *>())
->GetClientState();
switch (state) {
case Client::State::RESPONDING:
s->setBackground(QBrush(QColor(128, 255, 128, 255)));
s->setIcon(icons[(int)icons_t::ON]);
break;
case Client::State::NOT_RESPONDING:
s->setBackground(QBrush(QColor(255, 255, 128, 255)));
s->setIcon(icons[(int)icons_t::OFF]);
break;
case Client::State::BOOTING:
s->setBackground(QBrush(QColor(128, 128, 255, 255)));
s->setIcon(icons[(int)icons_t::BOOT]);
break;
case Client::State::SHUTTING_DOWN:
s->setBackground(QBrush(QColor(128, 128, 255, 255)));
s->setIcon(icons[(int)icons_t::DOWN]);
break;
case Client::State::ZLEAF_RUNNING:
s->setBackground(QBrush(QColor(0, 255, 0, 255)));
s->setIcon(icons[(int)icons_t::ZLEAF]);
break;
case Client::State::UNINITIALIZED:
case Client::State::ERROR:
s->setBackground(QBrush(QColor(255, 128, 128, 255)));
break;
}
}
}
/* Experiment tab functions */
void lc::MainWindow::on_PBBoot_clicked() {
QModelIndexList activatedItems =
ui->TVClients->selectionModel()->selectedIndexes();
for (QModelIndexList::ConstIterator it = activatedItems.cbegin();
it != activatedItems.cend(); ++it) {
if ((*it).data(Qt::DisplayRole).type() != 0) {
Client *client =
static_cast<Client *>((*it).data(Qt::UserRole).value<void *>());
client->Boot();
}
}
}
void lc::MainWindow::on_PBChooseFile_clicked() {
QFileDialog *file_dialog =
new QFileDialog{this, tr("Choose a file to beam"), QDir::homePath()};
file_dialog->setFileMode(QFileDialog::Directory);
file_dialog->setOption(QFileDialog::DontUseNativeDialog, true);
file_dialog->setOption(QFileDialog::ReadOnly, true);
file_dialog->setOption(QFileDialog::ShowDirsOnly, true);
if (file_dialog->exec()) {
ui->LEFilePath->setText(file_dialog->selectedFiles().at(0));
qDebug() << "Chose file" << ui->LEFilePath->text() << "for beaming.";
} else {
ui->LEFilePath->setText(tr("File choosing cancelled"));
qDebug() << "File choosing cancelled";
}
delete file_dialog;
}
void lc::MainWindow::on_PBBeamFile_clicked() {
QModelIndexList activatedItems =
ui->TVClients->selectionModel()->selectedIndexes();
const QString fileToBeam{ui->LEFilePath->text()};
if (fileToBeam == "") {
QMessageBox::information(this, "Upload failed",
"You didn't choose any folder to upload.");
} else {
// Iterate over the selected clients to upload the file
for (QModelIndexList::ConstIterator it = activatedItems.cbegin();
it != activatedItems.cend(); ++it) {
if ((*it).data(Qt::DisplayRole).type() != 0) {
Client *client =
static_cast<Client *>((*it).data(Qt::UserRole).value<void *>());
client->BeamFile(fileToBeam, &settings->pkeyPathUser,
&settings->userNameOnClients);
}
}
// Inform the user about the path
QMessageBox::information(
this, "Upload completed",
"The folder was copied to all selected clients.\nThe path on every "
"client is /home/ewfuser/media4ztree" +
fileToBeam.mid(fileToBeam.lastIndexOf('/')) +
".\nDon't forget to adjust the media path within zTree!");
}
}
void lc::MainWindow::on_PBShowORSEE_clicked() { lablib->ShowOrsee(); }
void lc::MainWindow::on_PBShowPreprints_clicked() { lablib->ShowPreprints(); }
void lc::MainWindow::on_PBShutdown_clicked() {
// Confirmation dialog
QMessageBox::StandardButton reply;
reply = QMessageBox::question(this, "Confirm",
"Really shutdown the selected clients?",
QMessageBox::Yes | QMessageBox::No);
if (reply == QMessageBox::Yes) {
QModelIndexList activatedItems =
ui->TVClients->selectionModel()->selectedIndexes();
for (QModelIndexList::ConstIterator it = activatedItems.cbegin();
it != activatedItems.cend(); ++it) {
if ((*it).data(Qt::DisplayRole).type() != 0) {
Client *client =
static_cast<Client *>((*it).data(Qt::UserRole).value<void *>());
// Do not shut down the server itself
if (client->name == "self") {
QMessageBox::information(NULL, "Shutdown canceled",
"It is not allowed to shutdown the server "
"itself via labcontrol!");
} else {
client->Shutdown();
}
}
}
} else {
qDebug() << "Canceled shutting down the selected clients";
}
}
void lc::MainWindow::on_CBWebcamChooser_activated(int argIndex) {
if (argIndex != 0) {
QString program{settings->webcamDisplayCmd};
QStringList arguments;
// Attention argIndex is NOT 0-based
arguments << settings->webcams[argIndex - 1];
qDebug() << "Webcam" << arguments << "will be opened";
QProcess showWebcamProcess;
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
showWebcamProcess.setProcessEnvironment(env);
showWebcamProcess.startDetached(program, arguments);
}
}
void lc::MainWindow::on_PBstartBrowser_clicked() {
QString argURL = ui->LEURL->text();
bool argFullscreen = ui->CBFullscreen->checkState();
QModelIndexList activated_items =
ui->TVClients->selectionModel()->selectedIndexes();
for (QModelIndexList::ConstIterator it = activated_items.cbegin();
it != activated_items.cend(); ++it) {
if ((*it).data(Qt::DisplayRole).type() != 0) {
Client *client =
static_cast<Client *>((*it).data(Qt::UserRole).value<void *>());
client->StartClientBrowser(&argURL, &argFullscreen);
}
}
}
void lc::MainWindow::on_PBstopBrowser_clicked() {
// Confirmation dialog
QMessageBox::StandardButton reply;
reply = QMessageBox::question(this, "Confirm",
"Really kill all selected browser instances?",
QMessageBox::Yes | QMessageBox::No);
if (reply == QMessageBox::Yes) {
QModelIndexList activated_items =
ui->TVClients->selectionModel()->selectedIndexes();
for (QModelIndexList::ConstIterator it = activated_items.cbegin();
it != activated_items.cend(); ++it) {
if ((*it).data(Qt::DisplayRole).type() != 0) {
Client *client =
static_cast<Client *>((*it).data(Qt::UserRole).value<void *>());
client->StopClientBrowser();
}
}
} else {
qDebug() << "Canceled stopping all selected browser processes";
}
}
// View only VNC button
void lc::MainWindow::on_PBViewDesktopViewOnly_clicked() {
QModelIndexList activatedItems =
ui->TVClients->selectionModel()->selectedIndexes();
for (QModelIndexList::ConstIterator it = activatedItems.cbegin();
it != activatedItems.cend(); ++it) {
if ((*it).data(Qt::DisplayRole).type() != 0) {
Client *client =
static_cast<Client *>((*it).data(Qt::UserRole).value<void *>());
client->ShowDesktopViewOnly();
}
}
}
// Full control VNC button
void lc::MainWindow::on_PBViewDesktopFullControl_clicked() {
QModelIndexList activatedItems =
ui->TVClients->selectionModel()->selectedIndexes();
for (QModelIndexList::ConstIterator it = activatedItems.cbegin();
it != activatedItems.cend(); ++it) {
if ((*it).data(Qt::DisplayRole).type() != 0) {
Client *client =
static_cast<Client *>((*it).data(Qt::UserRole).value<void *>());
client->ShowDesktopFullControl();
}
}
}
/* Session tab functions */
void lc::MainWindow::on_PBStartzLeaf_clicked() {
QModelIndexList activated_items =
ui->TVClients->selectionModel()->selectedIndexes();
for (QModelIndexList::ConstIterator it = activated_items.cbegin();
it != activated_items.cend(); ++it) {
if ((*it).data(Qt::DisplayRole).type() != 0) {
Client *client =
static_cast<Client *>((*it).data(Qt::UserRole).value<void *>());
client->StartZLeaf(nullptr, ui->LEzLeafCommandline->text());
}
}
}
void lc::MainWindow::on_PBStartLocalzLeaf_clicked() {
LocalzLeafStarter *localzLeafStarter = new LocalzLeafStarter{this};
localzLeafStarter->setWindowFlags(Qt::Window);
localzLeafStarter->show();
connect(localzLeafStarter, &LocalzLeafStarter::LocalzLeafRequested, this,
&MainWindow::StartLocalzLeaf);
connect(localzLeafStarter, &LocalzLeafStarter::LocalzLeafRequested,
localzLeafStarter, &LocalzLeafStarter::deleteLater);
}
void lc::MainWindow::StartLocalzLeaf(const QString &argzLeafName,
const QString &argzLeafVersion,
const quint16 argzTreePort) {
if (settings->tasksetCmd.isEmpty() || settings->wineCmd.isEmpty() ||
settings->zTreeInstDir.isEmpty()) {
return;
}
QProcess startProc;
startProc.setProcessEnvironment(QProcessEnvironment::systemEnvironment());
QStringList arguments;
arguments << "0x00000001" << settings->wineCmd
<< QString{settings->zTreeInstDir + "/zTree_" + argzLeafVersion +
"/zleaf.exe"}
<< "/server"
<< "127.0.0.1"
<< "/channel" << QString::number(argzTreePort - 7000) << "/name"
<< argzLeafName;
if (!settings->localzLeafSize.isEmpty()) {
arguments << "/size" << QString{settings->localzLeafSize};
}
qDebug() << "Start local zLeaf:" << arguments;
startProc.startDetached(settings->tasksetCmd, arguments);
}
void lc::MainWindow::on_PBStopZtree_clicked() {
QString program{settings->killallCmd};
QStringList arguments;
arguments << "-I"
<< "-q"
<< "ztree.exe";
// Confirmation dialog
QMessageBox::StandardButton reply;
reply = QMessageBox::question(this, "Confirm",
"Really kill all z-Tree instances?",
QMessageBox::Yes | QMessageBox::No);
if (reply == QMessageBox::Yes) {
// Kill all z-Tree processes
QProcess killLocalzLeafProc;
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
killLocalzLeafProc.setProcessEnvironment(env);
killLocalzLeafProc.startDetached(program, arguments);
// Output message via the debug messages tab
qDebug() << program << arguments;
} else {
qDebug() << "Canceled stopping all z-Tree processes";
}
}
void lc::MainWindow::on_PBRecoverCrashedSession_clicked() {
// TODO: Implement the functionality of the restore session script in here (no
// zenity script)
QProcess startProc;
startProc.setProcessEnvironment(QProcessEnvironment::systemEnvironment());
if (!settings->restartCrashedSessionScript.isEmpty()) {
startProc.startDetached(settings->restartCrashedSessionScript);
}
}
void lc::MainWindow::on_CBDataTargetPath_activated(int argIndex) {
if (!argIndex) {
emit RequestNewDataTargetPath();
}
ui->CBDataTargetPath->setStyleSheet("");
}
// Open a folder chooser dialog for zTree data path
void lc::MainWindow::GetNewDataTargetPath() {
QFileDialog fileDialog{this};
fileDialog.setFileMode(QFileDialog::Directory);
fileDialog.setDirectory(QDir::homePath());
fileDialog.setOption(QFileDialog::ShowDirsOnly, true);
fileDialog.setOption(QFileDialog::DontUseNativeDialog, true);
if (fileDialog.exec()) {
const QString fileName = fileDialog.selectedFiles().at(0);
ui->CBDataTargetPath->addItem(fileName);
ui->CBDataTargetPath->setCurrentText(fileName);
}
}
// Dummy function for enabling anonymous receipts section in UI
void lc::MainWindow::on_CBReceiptsHeader_activated(int argIndex) {
Q_UNUSED(argIndex);
ui->CBReceiptsHeader->setStyleSheet("");
}
// Anonymous receipients header check box
void lc::MainWindow::on_ChBPrintanonymousreceipts_clicked() {
ui->LReplaceParticipantNames->setEnabled(true);
ui->CBReplaceParticipantNames->setEnabled(true);
}
// Start session button actions
void lc::MainWindow::on_PBStartSession_clicked() {
if (ui->CBzTreeVersion->currentIndex() == 0) {
QMessageBox::information(
this, tr("No z-Tree version chosen"),
tr("A z-Tree version was not chosen, yet. This setting is"
" mandatory."),
QMessageBox::Ok);
return;
}
const QModelIndexList activatedItems =
ui->TVClients->selectionModel()->selectedIndexes();
if (!ui->ChBSessionWithoutAttachedClients->isChecked()) {
if (!activatedItems.length()) {
QMessageBox::information(
this, tr("Canceled, no clients were chosen"),
tr("The start of a new session was canceled.\n"
" Some clients have to be selected first or the"
" creation of sessions without clients must be"
" allowed with the checkbox."));
return;
}
}
QString anonymousReceiptsPlaceholder;
if (ui->ChBPrintAnonymousReceipts->isChecked()) {
anonymousReceiptsPlaceholder = ui->CBReplaceParticipantNames->currentText();
}
QVector<Client *> associatedClients;
for (auto cit = activatedItems.cbegin(); cit != activatedItems.cend();
++cit) {
if ((*cit).data(Qt::DisplayRole).type() != 0) {
Client *client =
static_cast<Client *>((*cit).data(Qt::UserRole).value<void *>());
client->SetSessionPort(ui->SBPort->value());
client->SetzLeafVersion(ui->CBzTreeVersion->currentText());
associatedClients.append(client);
}
}
this->lablib->StartNewSession(associatedClients, anonymousReceiptsPlaceholder,
ui->ChBReceiptsForLocalClients->isChecked(),
ui->CBReceiptsHeader->currentText(),
ui->CBDataTargetPath->currentText(),
static_cast<quint16>(ui->SBPort->value()),
ui->CBzTreeVersion->currentText());
// Display the command line
QString cmd =
this->lablib
->getzLeafArgs(ui->SBPort->value(), ui->CBzTreeVersion->currentText())
.join(" ");
ui->LEzLeafCommandline->setText(cmd);
// Start z-Leaf on selected clients if checkbox is activated
if (ui->ChBautoStartClientZleaf->isChecked()) {
for (auto cit = activatedItems.cbegin(); cit != activatedItems.cend();
++cit) {
if ((*cit).data(Qt::DisplayRole).type() != 0) {
Client *client =
static_cast<Client *>((*cit).data(Qt::UserRole).value<void *>());
client->StartZLeaf(nullptr, cmd);
}
}
}
// Set chosen Port
settings->SetChosenZTreePort(ui->SBPort->text().toInt());
// Increment port number
int newPort = ui->SBPort->text().toInt() + 1;
ui->SBPort->setValue(newPort);
}
void lc::MainWindow::on_PBKillzLeaf_clicked() {
QModelIndexList activated_items =
ui->TVClients->selectionModel()->selectedIndexes();
for (QModelIndexList::ConstIterator it = activated_items.cbegin();
it != activated_items.cend(); ++it) {
if ((*it).data(Qt::DisplayRole).type() != 0) {
Client *client =
static_cast<Client *>((*it).data(Qt::UserRole).value<void *>());
client->KillZLeaf();
}
}
}
/* Admin tab functions */
void lc::MainWindow::on_PBOpenFilesystem_clicked() {
// Determine the correct user to be used
QString *userToBeUsed = nullptr;
if (ui->RBUseUserRoot->isChecked()) {
userToBeUsed = new QString{"root"};
} else {
userToBeUsed = new QString{settings->userNameOnClients};
}
QModelIndexList activated_items =
ui->TVClients->selectionModel()->selectedIndexes();
for (QModelIndexList::ConstIterator it = activated_items.cbegin();
it != activated_items.cend(); ++it) {
if ((*it).data(Qt::DisplayRole).type() != 0) {
Client *client =
static_cast<Client *>((*it).data(Qt::UserRole).value<void *>());
client->OpenFilesystem(userToBeUsed);
}
}
delete userToBeUsed;
}
void lc::MainWindow::on_PBExecute_clicked() {
// Get the command to be executed ...
QString command = ui->CBCommandToExecute->currentText();
// Set the correct public key
QString pkeyPathUser;
if (ui->RBUseUserRoot->isChecked()) {
pkeyPathUser = settings->pkeyPathRoot;
} else {
pkeyPathUser = settings->pkeyPathUser;
}
qDebug() << "Executing command" << command << " on chosen clients.";
QModelIndexList activated_items =
ui->TVClients->selectionModel()->selectedIndexes();
for (QModelIndexList::ConstIterator it = activated_items.cbegin();
it != activated_items.cend(); ++it) {
if ((*it).data(Qt::DisplayRole).type() != 0) {
Client *client =
static_cast<Client *>((*it).data(Qt::UserRole).value<void *>());
client->OpenTerminal(command, ui->RBUseUserRoot->isChecked());
}
}
}
// Issue open terminal call
void lc::MainWindow::on_PBOpenTerminal_clicked() {
QString pkeyPathUser;
if (ui->RBUseUserRoot->isChecked()) {
pkeyPathUser = settings->pkeyPathRoot;
} else {
pkeyPathUser = settings->pkeyPathUser;
}
QModelIndexList activated_items =
ui->TVClients->selectionModel()->selectedIndexes();
for (QModelIndexList::ConstIterator it = activated_items.cbegin();
it != activated_items.cend(); ++it) {
if ((*it).data(Qt::DisplayRole).type() != 0) {
Client *client =
static_cast<Client *>((*it).data(Qt::UserRole).value<void *>());
client->OpenTerminal(QString{}, ui->RBUseUserRoot->isChecked());
}
}
}
// Enable RMB
void lc::MainWindow::on_PBEnableRMB_clicked() {
// Confirmation dialog
QMessageBox::StandardButton reply;
reply = QMessageBox::question(
this, "Confirm",
"Really enable the right mouse button on selected clients?",
QMessageBox::Yes | QMessageBox::No);
if (reply == QMessageBox::Yes) {
qDebug() << "Enabling RMB on chosen clients.";
QModelIndexList activated_items =
ui->TVClients->selectionModel()->selectedIndexes();
for (QModelIndexList::ConstIterator it = activated_items.cbegin();
it != activated_items.cend(); ++it) {
if ((*it).data(Qt::DisplayRole).type() != 0) {
Client *client =
static_cast<Client *>((*it).data(Qt::UserRole).value<void *>());
client->ControlRMB(true);
}
}
}
}
// Disable RMB
void lc::MainWindow::on_PBDisableRMB_clicked() {
// Confirmation dialog
QMessageBox::StandardButton reply;
reply = QMessageBox::question(
this, "Confirm",
"Really disable the right mouse button on selected clients?",
QMessageBox::Yes | QMessageBox::No);
if (reply == QMessageBox::Yes) {
qDebug() << "Disabling RMB on chosen clients.";
QModelIndexList activated_items =
ui->TVClients->selectionModel()->selectedIndexes();
for (QModelIndexList::ConstIterator it = activated_items.cbegin();
it != activated_items.cend(); ++it) {
if ((*it).data(Qt::DisplayRole).type() != 0) {
Client *client =
static_cast<Client *>((*it).data(Qt::UserRole).value<void *>());
client->ControlRMB(false);
}
}
}
}