/*************************************************************************** * Copyright (c) 2025 Kindred Systems * * * * This file is part of the FreeCAD CAx development system. * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * * * * This library 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 Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this library; see the file COPYING.LIB. If not, * * write to the Free Software Foundation, Inc., 59 Temple Place, * * Suite 330, Boston, MA 02111-1307, USA * * * ***************************************************************************/ #include "PreCompiled.h" #include #include #include #include #include "OriginManagerDialog.h" #include "OriginManager.h" #include "FileOrigin.h" #include "BitmapFactory.h" namespace Gui { OriginManagerDialog::OriginManagerDialog(QWidget* parent) : QDialog(parent) { setupUi(); populateOriginList(); updateButtonStates(); } OriginManagerDialog::~OriginManagerDialog() = default; void OriginManagerDialog::setupUi() { setWindowTitle(tr("Manage File Origins")); setMinimumSize(450, 350); auto* mainLayout = new QVBoxLayout(this); // Description auto* descLabel = new QLabel(tr("Configure file origins for storing and retrieving documents.")); descLabel->setWordWrap(true); mainLayout->addWidget(descLabel); // Origin list m_originList = new QListWidget(this); m_originList->setIconSize(QSize(24, 24)); m_originList->setSelectionMode(QAbstractItemView::SingleSelection); connect(m_originList, &QListWidget::itemSelectionChanged, this, &OriginManagerDialog::onOriginSelectionChanged); connect(m_originList, &QListWidget::itemDoubleClicked, this, &OriginManagerDialog::onOriginDoubleClicked); mainLayout->addWidget(m_originList); // Action buttons auto* actionLayout = new QHBoxLayout(); m_addButton = new QPushButton(tr("Add Silo...")); m_addButton->setIcon(BitmapFactory().iconFromTheme("list-add")); connect(m_addButton, &QPushButton::clicked, this, &OriginManagerDialog::onAddSilo); actionLayout->addWidget(m_addButton); m_editButton = new QPushButton(tr("Edit...")); m_editButton->setIcon(BitmapFactory().iconFromTheme("document-edit")); connect(m_editButton, &QPushButton::clicked, this, &OriginManagerDialog::onEditOrigin); actionLayout->addWidget(m_editButton); m_removeButton = new QPushButton(tr("Remove")); m_removeButton->setIcon(BitmapFactory().iconFromTheme("list-remove")); connect(m_removeButton, &QPushButton::clicked, this, &OriginManagerDialog::onRemoveOrigin); actionLayout->addWidget(m_removeButton); actionLayout->addStretch(); m_defaultButton = new QPushButton(tr("Set as Default")); connect(m_defaultButton, &QPushButton::clicked, this, &OriginManagerDialog::onSetDefault); actionLayout->addWidget(m_defaultButton); mainLayout->addLayout(actionLayout); // Dialog buttons m_buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); connect(m_buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); mainLayout->addWidget(m_buttonBox); } void OriginManagerDialog::populateOriginList() { m_originList->clear(); auto* mgr = OriginManager::instance(); std::string currentId = mgr->currentOriginId(); for (const std::string& originId : mgr->originIds()) { FileOrigin* origin = mgr->getOrigin(originId); if (!origin) { continue; } auto* item = new QListWidgetItem(m_originList); item->setIcon(origin->icon()); QString displayText = QString::fromStdString(origin->name()); // Add connection status for remote origins if (origin->requiresAuthentication()) { ConnectionState state = origin->connectionState(); switch (state) { case ConnectionState::Connected: displayText += tr(" [Connected]"); break; case ConnectionState::Connecting: displayText += tr(" [Connecting...]"); break; case ConnectionState::Disconnected: displayText += tr(" [Disconnected]"); break; case ConnectionState::Error: displayText += tr(" [Error]"); break; } } // Mark default origin if (originId == currentId) { displayText += tr(" (Default)"); QFont font = item->font(); font.setBold(true); item->setFont(font); } item->setText(displayText); item->setData(Qt::UserRole, QString::fromStdString(originId)); item->setToolTip(QString::fromStdString(origin->name())); } } void OriginManagerDialog::updateButtonStates() { FileOrigin* origin = selectedOrigin(); bool hasSelection = (origin != nullptr); bool isLocal = hasSelection && (origin->id() == "local"); bool isDefault = hasSelection && (origin->id() == OriginManager::instance()->currentOriginId()); // Can't edit or remove local origin m_editButton->setEnabled(hasSelection && !isLocal); m_removeButton->setEnabled(hasSelection && !isLocal); m_defaultButton->setEnabled(hasSelection && !isDefault); } FileOrigin* OriginManagerDialog::selectedOrigin() const { QListWidgetItem* item = m_originList->currentItem(); if (!item) { return nullptr; } std::string originId = item->data(Qt::UserRole).toString().toStdString(); return OriginManager::instance()->getOrigin(originId); } void OriginManagerDialog::onAddSilo() { // TODO: Open SiloConfigDialog for adding new instance QMessageBox::information(this, tr("Add Silo"), tr("Silo configuration dialog not yet implemented.\n\n" "To add a Silo instance, configure it in the Silo workbench preferences.")); } void OriginManagerDialog::onEditOrigin() { FileOrigin* origin = selectedOrigin(); if (!origin || origin->id() == "local") { return; } // TODO: Open SiloConfigDialog for editing QMessageBox::information(this, tr("Edit Origin"), tr("Origin editing not yet implemented.\n\n" "To edit this origin, modify settings in the Silo workbench preferences.")); } void OriginManagerDialog::onRemoveOrigin() { FileOrigin* origin = selectedOrigin(); if (!origin || origin->id() == "local") { return; } QString name = QString::fromStdString(origin->name()); QMessageBox::StandardButton reply = QMessageBox::question(this, tr("Remove Origin"), tr("Are you sure you want to remove '%1'?\n\n" "This will not delete any files, but you will need to reconfigure " "the connection to use this origin again.").arg(name), QMessageBox::Yes | QMessageBox::No, QMessageBox::No); if (reply == QMessageBox::Yes) { std::string originId = origin->id(); OriginManager::instance()->unregisterOrigin(originId); populateOriginList(); updateButtonStates(); } } void OriginManagerDialog::onSetDefault() { FileOrigin* origin = selectedOrigin(); if (!origin) { return; } OriginManager::instance()->setCurrentOrigin(origin->id()); populateOriginList(); updateButtonStates(); } void OriginManagerDialog::onOriginSelectionChanged() { updateButtonStates(); } void OriginManagerDialog::onOriginDoubleClicked(QListWidgetItem* item) { if (!item) { return; } std::string originId = item->data(Qt::UserRole).toString().toStdString(); if (originId != "local") { onEditOrigin(); } } } // namespace Gui