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 }