File indexing completed on 2024-04-28 16:31:59

0001 /***************************************************************************
0002     Copyright (C) 2006-2009 Robby Stephenson <robby@periapsis.org>
0003  ***************************************************************************/
0004 
0005 /***************************************************************************
0006  *                                                                         *
0007  *   This program is free software; you can redistribute it and/or         *
0008  *   modify it under the terms of the GNU General Public License as        *
0009  *   published by the Free Software Foundation; either version 2 of        *
0010  *   the License or (at your option) version 3 or any later version        *
0011  *   accepted by the membership of KDE e.V. (or its successor approved     *
0012  *   by the membership of KDE e.V.), which shall act as a proxy            *
0013  *   defined in Section 14 of version 3 of the license.                    *
0014  *                                                                         *
0015  *   This program is distributed in the hope that it will be useful,       *
0016  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0017  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0018  *   GNU General Public License for more details.                          *
0019  *                                                                         *
0020  *   You should have received a copy of the GNU General Public License     *
0021  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
0022  *                                                                         *
0023  ***************************************************************************/
0024 
0025 #include "fetcherconfigdialog.h"
0026 #include "fetch/fetchmanager.h"
0027 #include "gui/combobox.h"
0028 #include "utils/string_utils.h"
0029 #include "tellico_debug.h"
0030 
0031 #include <KLocalizedString>
0032 #include <KComboBox>
0033 #include <KIconLoader>
0034 #include <KHelpClient>
0035 
0036 #include <QLineEdit>
0037 #include <QLabel>
0038 #include <QLayout>
0039 #include <QStackedWidget>
0040 #include <QGroupBox>
0041 #include <QCheckBox>
0042 #include <QHBoxLayout>
0043 #include <QGridLayout>
0044 #include <QVBoxLayout>
0045 #include <QDialogButtonBox>
0046 #include <QPushButton>
0047 
0048 namespace {
0049   static const int FETCHER_CONFIG_MIN_WIDTH = 600;
0050 }
0051 
0052 using Tellico::FetcherConfigDialog;
0053 
0054 FetcherConfigDialog::FetcherConfigDialog(QWidget* parent_)
0055     : QDialog(parent_)
0056     , m_newSource(true)
0057     , m_useDefaultName(true)
0058     , m_configWidget(nullptr) {
0059   init(Fetch::Unknown);
0060 }
0061 
0062 FetcherConfigDialog::FetcherConfigDialog(const QString& sourceName_, Tellico::Fetch::Type type_, bool updateOverwrite_,
0063                                          Tellico::Fetch::ConfigWidget* configWidget_, QWidget* parent_)
0064     : QDialog(parent_)
0065     , m_newSource(false)
0066     , m_useDefaultName(false)
0067     , m_configWidget(configWidget_) {
0068   init(type_);
0069   m_nameEdit->setText(sourceName_);
0070   m_cbOverwrite->setChecked(updateOverwrite_);
0071 }
0072 
0073 void FetcherConfigDialog::init(Tellico::Fetch::Type type_) {
0074   setModal(true);
0075   setWindowTitle(i18n("Data Source Properties"));
0076 
0077   QVBoxLayout* mainLayout = new QVBoxLayout();
0078   setLayout(mainLayout);
0079 
0080   setMinimumWidth(FETCHER_CONFIG_MIN_WIDTH);
0081 
0082   QWidget* widget = new QWidget(this);
0083   QBoxLayout* topLayout = new QHBoxLayout(widget);
0084   widget->setLayout(topLayout);
0085 
0086   QBoxLayout* vlay1 = new QVBoxLayout();
0087   topLayout->addLayout(vlay1);
0088   m_iconLabel = new QLabel(widget);
0089   if(type_ == Fetch::Unknown) {
0090     m_iconLabel->setPixmap(KIconLoader::global()->loadIcon(QStringLiteral("network-wired"), KIconLoader::Panel, 64));
0091   } else {
0092     m_iconLabel->setPixmap(Fetch::Manager::self()->fetcherIcon(type_, KIconLoader::Panel, 64));
0093   }
0094   vlay1->addWidget(m_iconLabel);
0095   vlay1->addStretch(1);
0096 
0097   QBoxLayout* vlay2 = new QVBoxLayout();
0098   topLayout->addLayout(vlay2);
0099 
0100   QGridLayout* gl = new QGridLayout();
0101   vlay2->addLayout(gl);
0102   int row = -1;
0103 
0104   QLabel* label = new QLabel(i18n("&Source name: "), widget);
0105   gl->addWidget(label, ++row, 0);
0106   QString w = i18n("The name identifies the data source and should be unique and informative.");
0107   label->setWhatsThis(w);
0108 
0109   m_nameEdit = new QLineEdit(widget);
0110   gl->addWidget(m_nameEdit, row, 1);
0111   m_nameEdit->setFocus();
0112   m_nameEdit->setWhatsThis(w);
0113   label->setBuddy(m_nameEdit);
0114   connect(m_nameEdit, &QLineEdit::textChanged, this, &FetcherConfigDialog::slotNameChanged);
0115 
0116   if(m_newSource) {
0117     label = new QLabel(i18n("Source &type: "), widget);
0118   } else {
0119     // since the label doesn't have a buddy, we don't want an accel,
0120     // but also want to reuse string we already have
0121     label = new QLabel(KLocalizedString::removeAcceleratorMarker(i18n("Source &type: ")), widget);
0122   }
0123   gl->addWidget(label, ++row, 0);
0124   w = i18n("Tellico supports several different data sources.");
0125   label->setWhatsThis(w);
0126 
0127   if(m_newSource) {
0128     m_typeCombo = new GUI::ComboBox(widget);
0129     gl->addWidget(m_typeCombo, row, 1);
0130     m_typeCombo->setWhatsThis(w);
0131     label->setBuddy(m_typeCombo);
0132   } else {
0133     m_typeCombo = nullptr;
0134     QLabel* lab = new QLabel(Fetch::Manager::typeName(type_), widget);
0135     gl->addWidget(lab, row, 1);
0136     lab->setWhatsThis(w);
0137   }
0138   m_cbOverwrite = new QCheckBox(i18n("Updating from source should overwrite user data"), widget);
0139   ++row;
0140   gl->addWidget(m_cbOverwrite, row, 0, 1, 2);
0141   w = i18n("If checked, updating entries will overwrite any existing information.");
0142   m_cbOverwrite->setWhatsThis(w);
0143 
0144   if(m_newSource) {
0145     m_stack = new QStackedWidget(widget);
0146     vlay2->addWidget(m_stack);
0147     void (QComboBox::* activatedInt)(int) = &QComboBox::activated;
0148     connect(m_typeCombo, activatedInt, this, &FetcherConfigDialog::slotNewSourceSelected);
0149 
0150     int z3950_idx = 0;
0151     Fetch::NameTypeMap typeMap = Fetch::Manager::self()->nameTypeMap();
0152     // key is the fetcher name, value is the type
0153     for(Fetch::NameTypeMap::ConstIterator it = typeMap.constBegin(); it != typeMap.constEnd(); ++it) {
0154       m_typeCombo->addItem(Fetch::Manager::self()->fetcherIcon(it.value()), it.key(), it.value());
0155       if(it.value() == Fetch::Z3950) {
0156         z3950_idx = m_typeCombo->count()-1;
0157       }
0158     }
0159     // make sure first widget gets initialized
0160     // I'd like it to be the z39.50 widget
0161     m_typeCombo->setCurrentIndex(z3950_idx);
0162     slotNewSourceSelected(z3950_idx);
0163   } else {
0164     m_stack = nullptr;
0165     // just add config widget and reparent
0166     m_configWidget->setParent(widget);
0167     m_configWidget->show();
0168     vlay2->addWidget(m_configWidget);
0169     connect(m_configWidget, &Fetch::ConfigWidget::signalName, this, &FetcherConfigDialog::slotPossibleNewName);
0170   }
0171 
0172   mainLayout->addWidget(widget);
0173 
0174   QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|
0175                                                      QDialogButtonBox::Cancel|
0176                                                      QDialogButtonBox::Help);
0177   QPushButton* okButton = buttonBox->button(QDialogButtonBox::Ok);
0178   okButton->setDefault(true);
0179   okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
0180   connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
0181   connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
0182   connect(buttonBox, &QDialogButtonBox::helpRequested, this, &FetcherConfigDialog::slotHelp);
0183   mainLayout->addWidget(buttonBox);
0184 }
0185 
0186 QString FetcherConfigDialog::sourceName() const {
0187   return m_nameEdit->text();
0188 }
0189 
0190 bool FetcherConfigDialog::updateOverwrite() const {
0191   return m_cbOverwrite->isChecked();
0192 }
0193 
0194 Tellico::Fetch::ConfigWidget* FetcherConfigDialog::configWidget() const {
0195   if(m_newSource) {
0196     return dynamic_cast<Fetch::ConfigWidget*>(m_stack->currentWidget());
0197   }
0198   myWarning() << "called for modifying existing fetcher!";
0199   return m_configWidget;
0200 }
0201 
0202 Tellico::Fetch::Type FetcherConfigDialog::sourceType() const {
0203   if(!m_newSource || m_typeCombo->count() == 0) {
0204     myWarning() << "called for modifying existing fetcher!";
0205     return Fetch::Unknown;
0206   }
0207   return static_cast<Fetch::Type>(m_typeCombo->currentData().toInt());
0208 }
0209 
0210 void FetcherConfigDialog::slotNewSourceSelected(int idx_) {
0211   if(!m_newSource) {
0212     return;
0213   }
0214 
0215   // always change to default name
0216   m_useDefaultName = true;
0217 
0218   Fetch::ConfigWidget* cw = m_configWidgets[idx_];
0219   if(cw) {
0220     m_stack->setCurrentWidget(cw);
0221     slotPossibleNewName(cw->preferredName());
0222     return;
0223   }
0224 
0225   Fetch::Type type = sourceType();
0226   if(type == Fetch::Unknown) {
0227     myWarning() << "unknown source type";
0228     return;
0229   }
0230   m_iconLabel->setPixmap(Fetch::Manager::self()->fetcherIcon(type, KIconLoader::Panel, 64));
0231   cw = Fetch::Manager::self()->configWidget(m_stack, type, m_typeCombo->currentText());
0232   if(!cw) {
0233     // bad bad bad!
0234     myWarning() << "no config widget found for type" << type;
0235     m_typeCombo->setCurrentIndex(0);
0236     slotNewSourceSelected(0);
0237     return;
0238   }
0239   connect(cw, &Fetch::ConfigWidget::signalName, this, &FetcherConfigDialog::slotPossibleNewName);
0240   m_configWidgets.insert(idx_, cw);
0241   m_stack->addWidget(cw);
0242   m_stack->setCurrentWidget(cw);
0243   slotPossibleNewName(cw->preferredName());
0244 }
0245 
0246 void FetcherConfigDialog::slotNameChanged(const QString&) {
0247   m_useDefaultName = false;
0248 }
0249 
0250 void FetcherConfigDialog::slotPossibleNewName(const QString& name_) {
0251   if(name_.isEmpty()) {
0252     return;
0253   }
0254   Fetch::ConfigWidget* cw = m_stack ? static_cast<Fetch::ConfigWidget*>(m_stack->currentWidget()) : m_configWidget;
0255   if(m_useDefaultName || (cw && m_nameEdit->text() == cw->preferredName())) {
0256     m_nameEdit->setText(name_);
0257     m_useDefaultName = true; // it gets reset in slotNameChanged()
0258   }
0259 }
0260 
0261 void FetcherConfigDialog::slotHelp() {
0262   KHelpClient::invokeHelp(QStringLiteral("data-sources-options"));
0263 }