Manager: Update machine configuration on change

(signaled by the VM or upon closing the standalone settings dialog)
This commit is contained in:
Alexander Babikov
2025-08-02 00:34:53 +05:00
parent a828626177
commit 4827da23f4
18 changed files with 80 additions and 19 deletions

View File

@@ -814,6 +814,7 @@ main(int argc, char *argv[])
emit main_window->close(); emit main_window->close();
}); });
QObject::connect(main_window, &MainWindow::vmmRunningStateChanged, &manager_socket, &VMManagerClientSocket::clientRunningStateChanged); QObject::connect(main_window, &MainWindow::vmmRunningStateChanged, &manager_socket, &VMManagerClientSocket::clientRunningStateChanged);
QObject::connect(main_window, &MainWindow::vmmConfigurationChanged, &manager_socket, &VMManagerClientSocket::configurationChanged);
main_window->installEventFilter(&manager_socket); main_window->installEventFilter(&manager_socket);
manager_socket.sendWinIdMessage(main_window->winId()); manager_socket.sendWinIdMessage(main_window->winId());

View File

@@ -1129,7 +1129,8 @@ MainWindow::on_actionSettings_triggered()
case QDialog::Accepted: case QDialog::Accepted:
settings.save(); settings.save();
config_changed = 2; config_changed = 2;
updateShortcuts(); updateShortcuts();
emit vmmConfigurationChanged();
pc_reset_hard(); pc_reset_hard();
break; break;
case QDialog::Rejected: case QDialog::Rejected:

View File

@@ -67,6 +67,7 @@ signals:
void getTitleForNonQtThread(wchar_t *title); void getTitleForNonQtThread(wchar_t *title);
void vmmRunningStateChanged(VMManagerProtocol::RunningState state); void vmmRunningStateChanged(VMManagerProtocol::RunningState state);
void vmmConfigurationChanged();
public slots: public slots:
void showSettings(); void showSettings();
void hardReset(); void hardReset();

View File

@@ -247,3 +247,9 @@ VMManagerClientSocket::clientRunningStateChanged(VMManagerProtocol::RunningState
extra_object["status"] = static_cast<int>(state); extra_object["status"] = static_cast<int>(state);
sendMessageWithObject(VMManagerProtocol::ClientMessage::RunningStateChanged, extra_object); sendMessageWithObject(VMManagerProtocol::ClientMessage::RunningStateChanged, extra_object);
} }
void
VMManagerClientSocket::configurationChanged() const
{
sendMessage(VMManagerProtocol::ClientMessage::ConfigurationChanged);
}

View File

@@ -44,6 +44,7 @@ signals:
public slots: public slots:
void clientRunningStateChanged(VMManagerProtocol::RunningState state) const; void clientRunningStateChanged(VMManagerProtocol::RunningState state) const;
void configurationChanged() const;
private: private:
QString server_name; QString server_name;

View File

@@ -198,6 +198,30 @@ VMManagerDetails::updateData(VMManagerSystem *passed_sysconfig) {
startPauseButton->setEnabled(true); startPauseButton->setEnabled(true);
configureButton->setEnabled(true); configureButton->setEnabled(true);
updateConfig(passed_sysconfig);
updateScreenshots(passed_sysconfig);
ui->systemLabel->setText(passed_sysconfig->displayName);
ui->statusLabel->setText(sysconfig->process->processId() == 0 ?
tr("Not running") :
QString("%1: PID %2").arg(tr("Running"), QString::number(sysconfig->process->processId())));
ui->notesTextEdit->setPlainText(passed_sysconfig->notes);
ui->notesTextEdit->setEnabled(true);
disconnect(sysconfig->process, &QProcess::stateChanged, this, &VMManagerDetails::updateProcessStatus);
connect(sysconfig->process, &QProcess::stateChanged, this, &VMManagerDetails::updateProcessStatus);
disconnect(sysconfig, &VMManagerSystem::windowStatusChanged, this, &VMManagerDetails::updateWindowStatus);
connect(sysconfig, &VMManagerSystem::windowStatusChanged, this, &VMManagerDetails::updateWindowStatus);
disconnect(sysconfig, &VMManagerSystem::clientProcessStatusChanged, this, &VMManagerDetails::updateProcessStatus);
connect(sysconfig, &VMManagerSystem::clientProcessStatusChanged, this, &VMManagerDetails::updateProcessStatus);
updateProcessStatus();
}
void
VMManagerDetails::updateConfig(VMManagerSystem *passed_sysconfig) {
// Each detail section here has its own VMManagerDetailSection. // Each detail section here has its own VMManagerDetailSection.
// When a system is selected in the list view it is updated here, through this object: // When a system is selected in the list view it is updated here, through this object:
// * First you clear it with VMManagerDetailSection::clear() // * First you clear it with VMManagerDetailSection::clear()
@@ -242,6 +266,10 @@ VMManagerDetails::updateData(VMManagerSystem *passed_sysconfig) {
portsSection->addSection(tr("Serial Ports"), passed_sysconfig->getDisplayValue(Display::Name::Serial)); portsSection->addSection(tr("Serial Ports"), passed_sysconfig->getDisplayValue(Display::Name::Serial));
portsSection->addSection(tr("Parallel Ports"), passed_sysconfig->getDisplayValue(Display::Name::Parallel)); portsSection->addSection(tr("Parallel Ports"), passed_sysconfig->getDisplayValue(Display::Name::Parallel));
}
void
VMManagerDetails::updateScreenshots(VMManagerSystem *passed_sysconfig) {
// Disable screenshot navigation buttons by default // Disable screenshot navigation buttons by default
ui->screenshotNext->setEnabled(false); ui->screenshotNext->setEnabled(false);
ui->screenshotPrevious->setEnabled(false); ui->screenshotPrevious->setEnabled(false);
@@ -286,24 +314,6 @@ VMManagerDetails::updateData(VMManagerSystem *passed_sysconfig) {
} }
#endif #endif
} }
ui->systemLabel->setText(passed_sysconfig->displayName);
ui->statusLabel->setText(sysconfig->process->processId() == 0 ?
tr("Not running") :
QString("%1: PID %2").arg(tr("Running"), QString::number(sysconfig->process->processId())));
ui->notesTextEdit->setPlainText(passed_sysconfig->notes);
ui->notesTextEdit->setEnabled(true);
disconnect(sysconfig->process, &QProcess::stateChanged, this, &VMManagerDetails::updateProcessStatus);
connect(sysconfig->process, &QProcess::stateChanged, this, &VMManagerDetails::updateProcessStatus);
disconnect(sysconfig, &VMManagerSystem::windowStatusChanged, this, &VMManagerDetails::updateWindowStatus);
connect(sysconfig, &VMManagerSystem::windowStatusChanged, this, &VMManagerDetails::updateWindowStatus);
disconnect(sysconfig, &VMManagerSystem::clientProcessStatusChanged, this, &VMManagerDetails::updateProcessStatus);
connect(sysconfig, &VMManagerSystem::clientProcessStatusChanged, this, &VMManagerDetails::updateProcessStatus);
updateProcessStatus();
} }
void void

View File

@@ -67,6 +67,8 @@ private:
QToolButton *configureButton; QToolButton *configureButton;
QToolButton *cadButton; QToolButton *cadButton;
void updateConfig(VMManagerSystem *passed_sysconfig);
void updateScreenshots(VMManagerSystem *passed_sysconfig);
static QWidget* createHorizontalLine(int leftSpacing = 25, int rightSpacing = 25); static QWidget* createHorizontalLine(int leftSpacing = 25, int rightSpacing = 25);
// QVBoxLayout *detailsLayout; // QVBoxLayout *detailsLayout;
private slots: private slots:

View File

@@ -181,9 +181,11 @@ VMManagerMain::currentSelectionChanged(const QModelIndex &current,
return; return;
} }
disconnect(selected_sysconfig, &VMManagerSystem::configurationChanged, this, &VMManagerMain::onConfigUpdated);
const auto mapped_index = proxy_model->mapToSource(current); const auto mapped_index = proxy_model->mapToSource(current);
selected_sysconfig = vm_model->getConfigObjectForIndex(mapped_index); selected_sysconfig = vm_model->getConfigObjectForIndex(mapped_index);
vm_details->updateData(selected_sysconfig); vm_details->updateData(selected_sysconfig);
connect(selected_sysconfig, &VMManagerSystem::configurationChanged, this, &VMManagerMain::onConfigUpdated);
// Emit that the selection changed, include with the process state // Emit that the selection changed, include with the process state
emit selectionChanged(current, selected_sysconfig->process->state()); emit selectionChanged(current, selected_sysconfig->process->state());
@@ -309,6 +311,12 @@ VMManagerMain::currentSelectionIsValid() const
return ui->listView->currentIndex().isValid() && selected_sysconfig->isValid(); return ui->listView->currentIndex().isValid() && selected_sysconfig->isValid();
} }
void
VMManagerMain::onConfigUpdated(const QString &uuid)
{
if (selected_sysconfig->uuid == uuid)
vm_details->updateData(selected_sysconfig);
}
// Used from MainWindow during app exit to obtain and persist the current selection // Used from MainWindow during app exit to obtain and persist the current selection
QString QString
VMManagerMain::getCurrentSelection() const VMManagerMain::getCurrentSelection() const

View File

@@ -78,6 +78,7 @@ public slots:
#endif #endif
void modelDataChange(); void modelDataChange();
void onPreferencesUpdated(); void onPreferencesUpdated();
void onConfigUpdated(const QString &uuid);
int getActiveMachineCount(); int getActiveMachineCount();
private: private:

View File

@@ -128,6 +128,8 @@ VMManagerMainWindow::vmmSelectionChanged(const QModelIndex &currentSelection, co
ui->actionStartPause->setIcon(QIcon(":/menuicons/qt/icons/pause.ico")); ui->actionStartPause->setIcon(QIcon(":/menuicons/qt/icons/pause.ico"));
ui->actionStartPause->setText(tr("Pause")); ui->actionStartPause->setText(tr("Pause"));
ui->actionStartPause->setToolTip(tr("Pause")); ui->actionStartPause->setToolTip(tr("Pause"));
disconnect(ui->actionStartPause, &QAction::triggered, vmm, &VMManagerMain::startButtonPressed);
connect(ui->actionStartPause, &QAction::triggered, vmm, &VMManagerMain::pauseButtonPressed);
ui->actionHard_Reset->setEnabled(true); ui->actionHard_Reset->setEnabled(true);
ui->actionForce_Shutdown->setEnabled(true); ui->actionForce_Shutdown->setEnabled(true);
ui->actionCtrl_Alt_Del->setEnabled(true); ui->actionCtrl_Alt_Del->setEnabled(true);
@@ -136,6 +138,8 @@ VMManagerMainWindow::vmmSelectionChanged(const QModelIndex &currentSelection, co
ui->actionStartPause->setIcon(QIcon(":/menuicons/qt/icons/run.ico")); ui->actionStartPause->setIcon(QIcon(":/menuicons/qt/icons/run.ico"));
ui->actionStartPause->setText(tr("Start")); ui->actionStartPause->setText(tr("Start"));
ui->actionStartPause->setToolTip(tr("Start")); ui->actionStartPause->setToolTip(tr("Start"));
disconnect(ui->actionStartPause, &QAction::triggered, vmm, &VMManagerMain::pauseButtonPressed);
connect(ui->actionStartPause, &QAction::triggered, vmm, &VMManagerMain::startButtonPressed);
ui->actionHard_Reset->setEnabled(false); ui->actionHard_Reset->setEnabled(false);
ui->actionForce_Shutdown->setEnabled(false); ui->actionForce_Shutdown->setEnabled(false);
ui->actionCtrl_Alt_Del->setEnabled(false); ui->actionCtrl_Alt_Del->setEnabled(false);

View File

@@ -113,6 +113,12 @@ VMManagerModel::reload(QWidget* parent)
// TODO: Remove missing configs // TODO: Remove missing configs
} }
void
VMManagerModel::refreshConfigs() {
for ( const auto& each_config : machines)
each_config->reloadConfig();
}
QModelIndex QModelIndex
VMManagerModel::getIndexForConfigFile(const QFileInfo& config_file) VMManagerModel::getIndexForConfigFile(const QFileInfo& config_file)
{ {

View File

@@ -58,6 +58,7 @@ public:
void updateDisplayName(const QModelIndex &index, const QString &newDisplayName); void updateDisplayName(const QModelIndex &index, const QString &newDisplayName);
QHash <QString, int> getProcessStats(); QHash <QString, int> getProcessStats();
int getActiveMachineCount(); int getActiveMachineCount();
void refreshConfigs();
signals: signals:
void systemDataChanged(); void systemDataChanged();

View File

@@ -91,6 +91,8 @@ VMManagerProtocol::getClientMessageType(const QJsonObject &json_document)
return VMManagerProtocol::ClientMessage::WindowUnblocked; return VMManagerProtocol::ClientMessage::WindowUnblocked;
} else if (message_type == "RunningStateChanged") { } else if (message_type == "RunningStateChanged") {
return VMManagerProtocol::ClientMessage::RunningStateChanged; return VMManagerProtocol::ClientMessage::RunningStateChanged;
} else if (message_type == "ConfigurationChanged") {
return VMManagerProtocol::ClientMessage::ConfigurationChanged;
} else if (message_type == "WinIdMessage") { } else if (message_type == "WinIdMessage") {
return VMManagerProtocol::ClientMessage::WinIdMessage; return VMManagerProtocol::ClientMessage::WinIdMessage;
} }

View File

@@ -54,6 +54,7 @@ public:
WindowBlocked, WindowBlocked,
WindowUnblocked, WindowUnblocked,
RunningStateChanged, RunningStateChanged,
ConfigurationChanged,
WinIdMessage, WinIdMessage,
UnknownMessage, UnknownMessage,
}; };

View File

@@ -185,6 +185,10 @@ VMManagerServerSocket::jsonReceived(const QJsonObject &json)
} }
} }
break; break;
case VMManagerProtocol::ClientMessage::ConfigurationChanged:
qDebug("Configuration change received from client");
emit configurationChanged();
break;
default: default:
qDebug("Unknown client message type received:"); qDebug("Unknown client message type received:");
qDebug() << json; qDebug() << json;

View File

@@ -75,6 +75,7 @@ signals:
void dataReceived(); void dataReceived();
void windowStatusChanged(int status); void windowStatusChanged(int status);
void runningStatusChanged(VMManagerProtocol::RunningState state); void runningStatusChanged(VMManagerProtocol::RunningState state);
void configurationChanged();
void winIdReceived(WId id); void winIdReceived(WId id);

View File

@@ -482,6 +482,8 @@ VMManagerSystem::launchSettings() {
qInfo().nospace().noquote() << "Abnormal program termination while launching settings: exit code " << exitCode << ", exit status " << exitStatus; qInfo().nospace().noquote() << "Abnormal program termination while launching settings: exit code " << exitCode << ", exit status " << exitStatus;
return; return;
} }
configurationChangeReceived();
}); });
} }
@@ -818,6 +820,7 @@ VMManagerSystem::startServer() {
connect(socket_server, &VMManagerServerSocket::dataReceived, this, &VMManagerSystem::dataReceived); connect(socket_server, &VMManagerServerSocket::dataReceived, this, &VMManagerSystem::dataReceived);
connect(socket_server, &VMManagerServerSocket::windowStatusChanged, this, &VMManagerSystem::windowStatusChangeReceived); connect(socket_server, &VMManagerServerSocket::windowStatusChanged, this, &VMManagerSystem::windowStatusChangeReceived);
connect(socket_server, &VMManagerServerSocket::runningStatusChanged, this, &VMManagerSystem::runningStatusChangeReceived); connect(socket_server, &VMManagerServerSocket::runningStatusChanged, this, &VMManagerSystem::runningStatusChangeReceived);
connect(socket_server, &VMManagerServerSocket::configurationChanged, this, &VMManagerSystem::configurationChangeReceived);
connect(socket_server, &VMManagerServerSocket::winIdReceived, this, [this] (WId id) { this->id = id; }); connect(socket_server, &VMManagerServerSocket::winIdReceived, this, [this] (WId id) { this->id = id; });
return true; return true;
} else { } else {
@@ -956,6 +959,12 @@ VMManagerSystem::runningStatusChangeReceived(VMManagerProtocol::RunningState sta
processStatusChanged(); processStatusChanged();
} }
void void
VMManagerSystem::configurationChangeReceived()
{
reloadConfig();
emit configurationChanged(this->uuid);
}
void
VMManagerSystem::reloadConfig() VMManagerSystem::reloadConfig()
{ {
loadSettings(); loadSettings();

View File

@@ -148,6 +148,7 @@ signals:
void windowStatusChanged(); void windowStatusChanged();
void itemDataChanged(); void itemDataChanged();
void clientProcessStatusChanged(); void clientProcessStatusChanged();
void configurationChanged(const QString &uuid);
private: private:
void loadSettings(); void loadSettings();
@@ -188,6 +189,7 @@ private:
void dataReceived(); void dataReceived();
void windowStatusChangeReceived(int status); void windowStatusChangeReceived(int status);
void runningStatusChangeReceived(VMManagerProtocol::RunningState state); void runningStatusChangeReceived(VMManagerProtocol::RunningState state);
void configurationChangeReceived();
void processStatusChanged(); void processStatusChanged();
void statusRefresh(); void statusRefresh();
}; };