File indexing completed on 2024-04-28 05:08:21
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 const QString labelText(i18n("Source &type: ")); 0117 if(m_newSource) { 0118 label = new QLabel(labelText, widget); 0119 } else { 0120 // since the label doesn't have a buddy, we don't want an accel, 0121 // but also want to reuse string we already have 0122 label = new QLabel(KLocalizedString::removeAcceleratorMarker(labelText), widget); 0123 } 0124 gl->addWidget(label, ++row, 0); 0125 w = i18n("Tellico supports several different data sources."); 0126 label->setWhatsThis(w); 0127 0128 if(m_newSource) { 0129 m_typeCombo = new GUI::ComboBox(widget); 0130 gl->addWidget(m_typeCombo, row, 1); 0131 m_typeCombo->setWhatsThis(w); 0132 label->setBuddy(m_typeCombo); 0133 } else { 0134 m_typeCombo = nullptr; 0135 QLabel* lab = new QLabel(Fetch::Manager::typeName(type_), widget); 0136 gl->addWidget(lab, row, 1); 0137 lab->setWhatsThis(w); 0138 } 0139 m_cbOverwrite = new QCheckBox(i18n("Updating from source should overwrite user data"), widget); 0140 ++row; 0141 gl->addWidget(m_cbOverwrite, row, 0, 1, 2); 0142 w = i18n("If checked, updating entries will overwrite any existing information."); 0143 m_cbOverwrite->setWhatsThis(w); 0144 0145 if(m_newSource) { 0146 m_stack = new QStackedWidget(widget); 0147 vlay2->addWidget(m_stack); 0148 void (QComboBox::* activatedInt)(int) = &QComboBox::activated; 0149 connect(m_typeCombo, activatedInt, this, &FetcherConfigDialog::slotNewSourceSelected); 0150 0151 int z3950_idx = 0; 0152 const auto typeByName = Fetch::Manager::self()->nameTypeHash(); 0153 auto typeKeys = typeByName.keys(); 0154 typeKeys.sort(Qt::CaseInsensitive); 0155 // key is the fetcher name, value is the fetcher type 0156 for(auto it = typeKeys.constBegin(); it != typeKeys.constEnd(); ++it) { 0157 const auto typeValue = typeByName.value(*it); 0158 m_typeCombo->addItem(Fetch::Manager::self()->fetcherIcon(typeValue), *it, typeValue); 0159 if(typeValue == Fetch::Z3950) { 0160 z3950_idx = m_typeCombo->count()-1; 0161 } 0162 } 0163 // make sure first widget gets initialized 0164 // I'd like it to be the z39.50 widget 0165 m_typeCombo->setCurrentIndex(z3950_idx); 0166 slotNewSourceSelected(z3950_idx); 0167 } else { 0168 m_stack = nullptr; 0169 // just add config widget and reparent 0170 m_configWidget->setParent(widget); 0171 m_configWidget->show(); 0172 vlay2->addWidget(m_configWidget); 0173 connect(m_configWidget, &Fetch::ConfigWidget::signalName, this, &FetcherConfigDialog::slotPossibleNewName); 0174 } 0175 0176 mainLayout->addWidget(widget); 0177 0178 QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok| 0179 QDialogButtonBox::Cancel| 0180 QDialogButtonBox::Help); 0181 QPushButton* okButton = buttonBox->button(QDialogButtonBox::Ok); 0182 okButton->setDefault(true); 0183 okButton->setShortcut(Qt::CTRL | Qt::Key_Return); 0184 connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); 0185 connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); 0186 connect(buttonBox, &QDialogButtonBox::helpRequested, this, &FetcherConfigDialog::slotHelp); 0187 mainLayout->addWidget(buttonBox); 0188 } 0189 0190 QString FetcherConfigDialog::sourceName() const { 0191 return m_nameEdit->text(); 0192 } 0193 0194 bool FetcherConfigDialog::updateOverwrite() const { 0195 return m_cbOverwrite->isChecked(); 0196 } 0197 0198 Tellico::Fetch::ConfigWidget* FetcherConfigDialog::configWidget() const { 0199 if(m_newSource) { 0200 return dynamic_cast<Fetch::ConfigWidget*>(m_stack->currentWidget()); 0201 } 0202 myWarning() << "called for modifying existing fetcher!"; 0203 return m_configWidget; 0204 } 0205 0206 Tellico::Fetch::Type FetcherConfigDialog::sourceType() const { 0207 if(!m_newSource || m_typeCombo->count() == 0) { 0208 myWarning() << "called for modifying existing fetcher!"; 0209 return Fetch::Unknown; 0210 } 0211 return static_cast<Fetch::Type>(m_typeCombo->currentData().toInt()); 0212 } 0213 0214 void FetcherConfigDialog::slotNewSourceSelected(int idx_) { 0215 if(!m_newSource) { 0216 return; 0217 } 0218 0219 // always change to default name 0220 m_useDefaultName = true; 0221 0222 Fetch::ConfigWidget* cw = m_configWidgets[idx_]; 0223 if(cw) { 0224 m_stack->setCurrentWidget(cw); 0225 slotPossibleNewName(cw->preferredName()); 0226 return; 0227 } 0228 0229 Fetch::Type type = sourceType(); 0230 if(type == Fetch::Unknown) { 0231 myWarning() << "unknown source type"; 0232 return; 0233 } 0234 m_iconLabel->setPixmap(Fetch::Manager::self()->fetcherIcon(type, KIconLoader::Panel, 64)); 0235 cw = Fetch::Manager::self()->configWidget(m_stack, type, m_typeCombo->currentText()); 0236 if(!cw) { 0237 // bad bad bad! 0238 myWarning() << "no config widget found for type" << type; 0239 m_typeCombo->setCurrentIndex(0); 0240 slotNewSourceSelected(0); 0241 return; 0242 } 0243 connect(cw, &Fetch::ConfigWidget::signalName, this, &FetcherConfigDialog::slotPossibleNewName); 0244 m_configWidgets.insert(idx_, cw); 0245 m_stack->addWidget(cw); 0246 m_stack->setCurrentWidget(cw); 0247 slotPossibleNewName(cw->preferredName()); 0248 } 0249 0250 void FetcherConfigDialog::slotNameChanged(const QString&) { 0251 m_useDefaultName = false; 0252 } 0253 0254 void FetcherConfigDialog::slotPossibleNewName(const QString& name_) { 0255 if(name_.isEmpty()) { 0256 return; 0257 } 0258 Fetch::ConfigWidget* cw = m_stack ? static_cast<Fetch::ConfigWidget*>(m_stack->currentWidget()) : m_configWidget; 0259 if(m_useDefaultName || (cw && m_nameEdit->text() == cw->preferredName())) { 0260 m_nameEdit->setText(name_); 0261 m_useDefaultName = true; // it gets reset in slotNameChanged() 0262 } 0263 } 0264 0265 void FetcherConfigDialog::slotHelp() { 0266 KHelpClient::invokeHelp(QStringLiteral("data-sources-options")); 0267 }