File indexing completed on 2024-05-12 04:52:11

0001 /*
0002  * dvbconfigdialog.cpp
0003  *
0004  * Copyright (C) 2007-2011 Christoph Pfister <christophpfister@gmail.com>
0005  *
0006  * This program is free software; you can redistribute it and/or modify
0007  * it under the terms of the GNU General Public License as published by
0008  * the Free Software Foundation; either version 2 of the License, or
0009  * (at your option) any later version.
0010  *
0011  * This program is distributed in the hope that it will be useful,
0012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0014  * GNU General Public License for more details.
0015  *
0016  * You should have received a copy of the GNU General Public License along
0017  * with this program; if not, write to the Free Software Foundation, Inc.,
0018  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
0019  */
0020 
0021 #include "../log.h"
0022 
0023 #include <KLocalizedString>
0024 
0025 #include <KConfigGroup>
0026 #include <KIO/Job>
0027 #include <QBoxLayout>
0028 #include <QButtonGroup>
0029 #include <QCheckBox>
0030 #include <QComboBox>
0031 #include <QDesktopServices>
0032 #include <QDialogButtonBox>
0033 #include <QFileDialog>
0034 #include <QLabel>
0035 #include <QLineEdit>
0036 #include <QLocale>
0037 #include <QProgressBar>
0038 #include <QPushButton>
0039 #include <QRadioButton>
0040 #include <QStyle>
0041 #include <QStyleOptionTab>
0042 #include <QSpinBox>
0043 #include <QStandardPaths>
0044 #include <QTabWidget>
0045 #include <QToolButton>
0046 #include <QTreeWidget>
0047 #include <QVBoxLayout>
0048 #include <QWidgetAction>
0049 
0050 #include "dvbconfig.h"
0051 #include "dvbconfigdialog.h"
0052 #include "dvbdevice.h"
0053 #include "dvbmanager.h"
0054 #include "dvbrecording.h"
0055 
0056 DvbConfigDialog::DvbConfigDialog(DvbManager *manager_, QWidget *parent) : QDialog(parent),
0057     manager(manager_)
0058 {
0059     setWindowTitle(i18nc("@title:window", "Configure Television"));
0060 
0061     tabWidget = new QTabWidget(this);
0062     QVBoxLayout *mainLayout = new QVBoxLayout;
0063     setLayout(mainLayout);
0064     mainLayout->addWidget(tabWidget);
0065 
0066     QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
0067     connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
0068     connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
0069 
0070     QWidget *widget = new QWidget(tabWidget);
0071     mainLayout->addWidget(widget);
0072     QBoxLayout *boxLayout = new QVBoxLayout(widget);
0073 
0074     int line = 0;
0075 
0076     QGridLayout *gridLayout = new QGridLayout();
0077     gridLayout->addWidget(new QLabel(i18n("Recording folder:")), line, 0);
0078 
0079     recordingFolderEdit = new QLineEdit(widget);
0080     recordingFolderEdit->setText(manager->getRecordingFolder());
0081     gridLayout->addWidget(recordingFolderEdit, line, 1);
0082 
0083     QToolButton *toolButton = new QToolButton(widget);
0084     toolButton->setIcon(QIcon::fromTheme(QLatin1String("document-open-folder"), QIcon(":document-open-folder")));
0085     toolButton->setToolTip(i18n("Select Folder"));
0086     connect(toolButton, SIGNAL(clicked()), this, SLOT(changeRecordingFolder()));
0087     gridLayout->addWidget(toolButton, line++, 2);
0088 
0089     gridLayout->addWidget(new QLabel(i18n("Time shift folder:")), line, 0);
0090 
0091     timeShiftFolderEdit = new QLineEdit(widget);
0092     timeShiftFolderEdit->setText(manager->getTimeShiftFolder());
0093     gridLayout->addWidget(timeShiftFolderEdit, line, 1);
0094 
0095     toolButton = new QToolButton(widget);
0096     toolButton->setIcon(QIcon::fromTheme(QLatin1String("document-open-folder"), QIcon(":document-open-folder")));
0097     toolButton->setToolTip(i18n("Select Folder"));
0098     connect(toolButton, SIGNAL(clicked()), this, SLOT(changeTimeShiftFolder()));
0099     gridLayout->addWidget(toolButton, line++, 2);
0100 
0101     gridLayout->addWidget(new QLabel(i18n("xmltv file name (optional):")), line, 0);
0102 
0103     xmltvFileNameEdit = new QLineEdit(widget);
0104     xmltvFileNameEdit->setText(manager->getXmltvFileName());
0105     gridLayout->addWidget(xmltvFileNameEdit, line, 1);
0106 
0107     toolButton = new QToolButton(widget);
0108     toolButton->setIcon(QIcon::fromTheme(QLatin1String("document-open-folder"), QIcon(":document-open-folder")));
0109     toolButton->setToolTip(i18n("Add optional file to allow reading EPG data from xmltv files"));
0110     connect(toolButton, SIGNAL(clicked()), this, SLOT(changeXmltvFileName()));
0111     gridLayout->addWidget(toolButton, line++, 2);
0112 
0113     gridLayout->addWidget(new QLabel(i18n("Disable parsing EPG data from MPEG-TS tables:")),
0114         line, 0);
0115     toolButton->setToolTip(i18n("Use this if your TV provider doesn't broadcast reliable EPG data"));
0116     disableEpgBox = new QCheckBox(widget);
0117     disableEpgBox->setChecked(manager->disableEpg());
0118     gridLayout->addWidget(disableEpgBox, line++, 1);
0119 
0120     boxLayout->addLayout(gridLayout);
0121 
0122     gridLayout = new QGridLayout();
0123     gridLayout->addWidget(new QLabel(i18n("Begin margin (minutes):")), line, 0);
0124 
0125     beginMarginBox = new QSpinBox(widget);
0126     beginMarginBox->setRange(0, 99);
0127     beginMarginBox->setValue(manager->getBeginMargin() / 60);
0128     gridLayout->addWidget(beginMarginBox, line++, 1);
0129 
0130     gridLayout->addWidget(new QLabel(i18n("End margin (minutes):")), line, 0);
0131 
0132     endMarginBox = new QSpinBox(widget);
0133     endMarginBox->setRange(0, 99);
0134     endMarginBox->setValue(manager->getEndMargin() / 60);
0135     gridLayout->addWidget(endMarginBox, line++, 1);
0136 
0137     gridLayout->addWidget(new QLabel(i18n("Naming style for recordings:")), line, 0);
0138 
0139     namingFormat = new QLineEdit(widget);
0140     namingFormat->setText(manager->getNamingFormat());
0141     namingFormat->setToolTip(i18n("The following substitutions work: \"%year\" for year (YYYY) and the following: %month, %day, %hour, %min, %sec, %channel and %title"));
0142     connect(namingFormat, SIGNAL(textChanged(QString)), this, SLOT(namingFormatChanged(QString)));
0143 
0144     gridLayout->addWidget(namingFormat, line, 1);
0145 
0146     validPixmap = QIcon::fromTheme(QLatin1String("dialog-ok-apply"), QIcon(":dialog-ok-apply")).pixmap(22);
0147     invalidPixmap = QIcon::fromTheme(QLatin1String("dialog-cancel"), QIcon(":dialog-cancel")).pixmap(22);
0148 
0149     namingFormatValidLabel = new QLabel(widget);
0150     namingFormatValidLabel->setPixmap(validPixmap);
0151     gridLayout->addWidget(namingFormatValidLabel, line++,2);
0152 
0153     gridLayout->addWidget(new QLabel(i18n("Action after recording finishes:")), line, 0);
0154 
0155     actionAfterRecordingLineEdit = new QLineEdit(widget);
0156     actionAfterRecordingLineEdit->setText(manager->getActionAfterRecording());
0157     actionAfterRecordingLineEdit->setToolTip(i18n("Leave empty for no command."));
0158     gridLayout->addWidget(actionAfterRecordingLineEdit, line++, 1);
0159 
0160     boxLayout->addLayout(gridLayout);
0161 
0162     gridLayout = new QGridLayout();
0163     gridLayout->addWidget(new QLabel(i18n("Use ISO 8859-1 charset instead of ISO 6937:")),
0164         1, 0);
0165 
0166     override6937CharsetBox = new QCheckBox(widget);
0167     override6937CharsetBox->setChecked(manager->override6937Charset());
0168     gridLayout->addWidget(override6937CharsetBox, 1, 1);
0169 
0170     gridLayout->addWidget(new QLabel(i18n("Create info files to accompany EPG recordings:")),
0171         2, 0);
0172     createInfoFileBox = new QCheckBox(widget);
0173     createInfoFileBox->setChecked(manager->createInfoFile());
0174     gridLayout->addWidget(createInfoFileBox, 2, 1);
0175 
0176 #if 0
0177     // FIXME: this functionality is not working. Comment it out
0178 
0179     gridLayout->addWidget(new QLabel(i18n("Scan channels when idle to fetch fresh EPG data:")),
0180         3, 0);
0181     scanWhenIdleBox = new QCheckBox(widget);
0182     scanWhenIdleBox->setChecked(manager->isScanWhenIdle());
0183     gridLayout->addWidget(scanWhenIdleBox, 3, 1);
0184 #endif
0185 
0186     QFrame *frame = new QFrame(widget);
0187     frame->setFrameShape(QFrame::HLine);
0188     boxLayout->addWidget(frame);
0189 
0190     boxLayout->addWidget(new QLabel(i18n("Scan data last updated on %1",
0191         QLocale().toString(manager->getScanDataDate(), QLocale::ShortFormat))));
0192 
0193     QPushButton *pushButton = new QPushButton(i18n("Update Scan Data over Internet"), widget);
0194     connect(pushButton, SIGNAL(clicked()), this, SLOT(updateScanFile()));
0195     boxLayout->addWidget(pushButton);
0196 
0197     QPushButton *openScanFileButton = new QPushButton(i18n("Edit Scanfile"), widget);
0198     connect(openScanFileButton, SIGNAL(clicked()), this, SLOT(openScanFile()));
0199     boxLayout->addWidget(openScanFileButton);
0200     openScanFileButton->setToolTip(i18n("You can add channels manually to this file before scanning for them."));
0201 
0202     frame = new QFrame(widget);
0203     frame->setFrameShape(QFrame::HLine);
0204     boxLayout->addWidget(frame);
0205 
0206     boxLayout->addLayout(gridLayout);
0207 
0208     QStyleOptionTab option;
0209     option.initFrom(tabWidget);
0210     int metric = style()->pixelMetric(QStyle::PM_SmallIconSize, &option, tabWidget);
0211 
0212     validPixmap = QIcon::fromTheme(QLatin1String("dialog-ok-apply"), QIcon(":dialog-ok-apply")).pixmap(metric);
0213     invalidPixmap = QIcon::fromTheme(QLatin1String("dialog-cancel"), QIcon(":dialog-cancel")).pixmap(metric);
0214 
0215     boxLayout->addStretch();
0216 
0217     tabWidget->addTab(widget, QIcon::fromTheme(QLatin1String("configure"), QIcon(":configure")), i18n("General Options"));
0218 
0219     QWidget *widgetAutomaticRecording = new QWidget(tabWidget);
0220     QBoxLayout *boxLayoutAutomaticRecording = new QVBoxLayout(widgetAutomaticRecording);
0221 
0222 
0223     QGridLayout *buttonGrid = new QGridLayout();
0224     initRegexButtons(buttonGrid);
0225 
0226     regexGrid = new QGridLayout();
0227     int j = 0;
0228     foreach (const QString regex, manager->getRecordingRegexList()) {
0229         RegexInputLine *inputLine = new RegexInputLine();
0230         inputLine->lineEdit = new QLineEdit(widget);
0231         inputLine->lineEdit->setText(regex);
0232         regexGrid->addWidget(inputLine->lineEdit, j, 0);
0233         inputLine->checkBox = new QCheckBox(widget);
0234         inputLine->checkBox->setChecked(false);
0235         regexGrid->addWidget(inputLine->checkBox, j, 2);
0236         inputLine->spinBox = new QSpinBox();
0237         inputLine->spinBox->setValue(manager->getRecordingRegexPriorityList().value(j));
0238         regexGrid->addWidget(inputLine->spinBox, j, 1);
0239 
0240         inputLine->index = j;
0241 
0242         regexInputList.append(inputLine);
0243 
0244         j = j + 1;
0245     }
0246 
0247     boxLayoutAutomaticRecording->addLayout(buttonGrid);
0248     boxLayoutAutomaticRecording->addLayout(regexGrid);
0249 
0250     tabWidget->addTab(widgetAutomaticRecording, QIcon::fromTheme(QLatin1String("configure"), QIcon(":configure")),
0251             i18n("Automatic Recording"));
0252     //
0253 
0254     int i = 1;
0255 
0256     foreach (const DvbDeviceConfig &deviceConfig, manager->getDeviceConfigs()) {
0257         DvbConfigPage *configPage = new DvbConfigPage(tabWidget, manager, &deviceConfig);
0258         connect(configPage, SIGNAL(moveLeft(DvbConfigPage*)),
0259             this, SLOT(moveLeft(DvbConfigPage*)));
0260         connect(configPage, SIGNAL(moveRight(DvbConfigPage*)),
0261             this, SLOT(moveRight(DvbConfigPage*)));
0262         connect(configPage, SIGNAL(remove(DvbConfigPage*)),
0263             this, SLOT(remove(DvbConfigPage*)));
0264         tabWidget->addTab(configPage, QIcon::fromTheme(QLatin1String("video-television"), QIcon(":video-television")), i18n("Device %1", i));
0265         configPages.append(configPage);
0266         ++i;
0267     }
0268 
0269     // Use a size that would allow show multiple devices
0270     resize(100 * fontMetrics().averageCharWidth(), 28 * fontMetrics().height());
0271 
0272     if (!configPages.isEmpty()) {
0273         configPages.at(0)->setMoveLeftEnabled(false);
0274         configPages.at(configPages.size() - 1)->setMoveRightEnabled(false);
0275     }
0276 
0277     mainLayout->addWidget(buttonBox);
0278 }
0279 
0280 DvbConfigDialog::~DvbConfigDialog()
0281 {
0282 }
0283 
0284 void DvbConfigDialog::changeRecordingFolder()
0285 {
0286     QString path = QFileDialog::getExistingDirectory(this, QString(), recordingFolderEdit->text());
0287 
0288     if (path.isEmpty()) {
0289         return;
0290     }
0291 
0292     recordingFolderEdit->setText(path);
0293 }
0294 
0295 void DvbConfigDialog::changeTimeShiftFolder()
0296 {
0297     QString path = QFileDialog::getExistingDirectory(this, QString(), timeShiftFolderEdit->text());
0298 
0299     if (path.isEmpty()) {
0300         return;
0301     }
0302 
0303     timeShiftFolderEdit->setText(path);
0304 }
0305 
0306 void DvbConfigDialog::changeXmltvFileName()
0307 {
0308     QString path = QFileDialog::getOpenFileName(this, QString(), xmltvFileNameEdit->text());
0309 
0310     if (path.isEmpty()) {
0311         return;
0312     }
0313 
0314     xmltvFileNameEdit->setText(path);
0315 }
0316 
0317 void DvbConfigDialog::updateScanFile()
0318 {
0319     QDialog *dialog = new DvbScanFileDownloadDialog(manager, this);
0320     dialog->setAttribute(Qt::WA_DeleteOnClose, true);
0321     dialog->setModal(true);
0322     dialog->show();
0323 }
0324 
0325 void DvbConfigDialog::newRegex()
0326 {
0327     RegexInputLine *inputLine = new RegexInputLine();
0328 
0329     inputLine->lineEdit = new QLineEdit(tabWidget);
0330     inputLine->lineEdit->setText("");
0331     regexGrid->addWidget(inputLine->lineEdit, regexInputList.size(), 0);
0332 
0333     inputLine->checkBox = new QCheckBox(tabWidget);
0334     inputLine->checkBox->setChecked(false);
0335     regexGrid->addWidget(inputLine->checkBox, regexInputList.size(), 2);
0336 
0337     inputLine->spinBox = new QSpinBox(tabWidget);
0338     inputLine->spinBox->setRange(0, 99);
0339     inputLine->spinBox->setValue(5);
0340     regexGrid->addWidget(inputLine->spinBox, regexInputList.size(), 1);
0341 
0342     regexInputList.append(inputLine);
0343 }
0344 
0345 
0346 
0347 /**
0348  * Helper function. Deletes all child widgets of the given layout @a item.
0349  */
0350 void deleteChildWidgets(QLayoutItem *item) {
0351     if (item->layout()) {
0352     // Process all child items recursively.
0353     for (int i = 0; i < item->layout()->count(); i++) {
0354         deleteChildWidgets(item->layout()->itemAt(i));
0355     }
0356     }
0357     delete item->widget();
0358 }
0359 
0360 
0361 /**
0362  * Helper function. Removes all layout items within the given @a layout
0363  * which either span the given @a row or @a column. If @a deleteWidgets
0364  * is true, all concerned child widgets become not only removed from the
0365  * layout, but also deleted.
0366  */
0367 void DvbConfigDialog::removeWidgets(QGridLayout *layout, int row, int column, bool deleteWidgets) {
0368     // We avoid usage of QGridLayout::itemAtPosition() here to improve performance.
0369     for (int i = layout->count() - 1; i >= 0; i--) {
0370     int r, c, rs, cs;
0371     layout->getItemPosition(i, &r, &c, &rs, &cs);
0372     if ((r <= row && r + rs - 1 >= row) || (c <= column && c + cs - 1 >= column)) {
0373         // This layout item is subject to deletion.
0374         QLayoutItem *item = layout->takeAt(i);
0375         if (deleteWidgets) {
0376         deleteChildWidgets(item);
0377         }
0378         delete item;
0379     }
0380     }
0381 }
0382 
0383 void DvbConfigDialog::initRegexButtons(QGridLayout *buttonGrid)
0384 {
0385     QWidgetAction *action = new QWidgetAction(tabWidget);
0386     action->setIcon(QIcon::fromTheme(QLatin1String("list-add"), QIcon(":list-add")));
0387     action->setText(i18nc("@action", "Add new Regex"));
0388 
0389     connect(action, SIGNAL(triggered()), this, SLOT(newRegex()));
0390     tabWidget->addAction(action);
0391     QPushButton *pushButtonAdd = new QPushButton(action->icon(), action->text(), tabWidget);
0392     connect(pushButtonAdd, SIGNAL(clicked()), this, SLOT(newRegex()));
0393     buttonGrid->addWidget(pushButtonAdd, 0, 0);
0394     pushButtonAdd->setToolTip(i18n("Add another regular expression."));
0395 
0396     action = new QWidgetAction(tabWidget);
0397     action->setIcon(QIcon::fromTheme(QLatin1String("edit-delete"), QIcon(":edit-delete")));
0398     action->setText(i18nc("@action", "Remove Regex"));
0399     connect(action, SIGNAL(triggered()), this, SLOT(removeRegex()));
0400     tabWidget->addAction(action);
0401     QPushButton *pushButtonRemove = new QPushButton(action->icon(), action->text(), tabWidget);
0402     connect(pushButtonRemove, SIGNAL(clicked()), this, SLOT(removeRegex()));
0403     buttonGrid->addWidget(pushButtonRemove, 0, 1);
0404     pushButtonRemove->setToolTip(i18n("Remove checked regular expressions."));
0405 }
0406 
0407 void DvbConfigDialog::removeRegex()
0408 {
0409     //regexGrid = new QGridLayout(tabWidget);
0410     //regexBoxMap = QMap<QCheckBox *, QLineEdit *>();
0411     QList<RegexInputLine *> copyList = QList<RegexInputLine *>();
0412     foreach(RegexInputLine *inputLine, regexInputList)
0413     {
0414         copyList.append(inputLine);
0415     }
0416     foreach(RegexInputLine *inputLine, copyList)
0417     {
0418         qCDebug(logDvb, "list:");
0419         if (inputLine->checkBox->isChecked()){
0420             qCDebug(logDvb, "checked:");
0421             if (regexInputList.removeOne(inputLine)) {
0422                 qCDebug(logDvb, "removed:");
0423             }
0424         }
0425     }
0426 
0427     QWidget *widgetAutomaticRecording = new QWidget(tabWidget);
0428     QBoxLayout *boxLayoutAutomaticRecording = new QVBoxLayout(widgetAutomaticRecording);
0429 
0430     QGridLayout *buttonGrid = new QGridLayout();
0431     regexGrid = new QGridLayout();
0432 
0433     initRegexButtons(buttonGrid);
0434 
0435     int j = 0;
0436     foreach (RegexInputLine *oldLine, regexInputList) {
0437         RegexInputLine *inputLine = new RegexInputLine();
0438         inputLine->lineEdit = new QLineEdit();
0439         inputLine->lineEdit->setText(oldLine->lineEdit->text());
0440         regexGrid->addWidget(inputLine->lineEdit, j, 0);
0441         inputLine->checkBox = new QCheckBox();
0442         inputLine->checkBox->setChecked(false);
0443         regexGrid->addWidget(inputLine->checkBox, j, 2);
0444         inputLine->spinBox = new QSpinBox();
0445         inputLine->spinBox->setValue(oldLine->spinBox->value());
0446         regexGrid->addWidget(inputLine->spinBox, j, 1);
0447 
0448         inputLine->index = j;
0449 
0450         j = j + 1;
0451     }
0452 
0453     boxLayoutAutomaticRecording->addLayout(buttonGrid);
0454     boxLayoutAutomaticRecording->addLayout(regexGrid);
0455     tabWidget->removeTab(1);
0456     tabWidget->addTab(widgetAutomaticRecording, QIcon::fromTheme(QLatin1String("configure"), QIcon(":configure")), i18n("Automatic Recording"));
0457     tabWidget->move(tabWidget->count()-1, 1);
0458     tabWidget->setCurrentIndex(1);
0459 }
0460 
0461 void DvbConfigDialog::openScanFile()
0462 {
0463     QString file(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QLatin1String("/scanfile.dvb"));
0464     QDesktopServices::openUrl(QUrl(file));
0465 }
0466 
0467 void DvbConfigDialog::namingFormatChanged(QString text)
0468 {
0469     QString temp = text.replace("%year", " ");
0470     temp = temp.replace("%month", " ");
0471     temp = temp.replace("%day", " ");
0472     temp = temp.replace("%hour", " ");
0473     temp = temp.replace("%min", " ");
0474     temp = temp.replace("%sec"," ");
0475     temp = temp.replace("%channel", " ");
0476     temp = temp.replace("%title", " ");
0477 
0478     if (!temp.contains("%")) {
0479         namingFormatValidLabel->setPixmap(validPixmap);
0480     } else {
0481         namingFormatValidLabel->setPixmap(invalidPixmap);
0482     }
0483 }
0484 
0485 void DvbConfigDialog::moveLeft(DvbConfigPage *configPage)
0486 {
0487     int index = configPages.indexOf(configPage);
0488 
0489     if (index <= 0) {
0490         return;
0491     }
0492 
0493 #if QT_VERSION < 0x050c00
0494     configPages.swap(index, index - 1);
0495 #else
0496     configPages.swapItemsAt(index, index - 1);
0497 #endif
0498 
0499     if (index == 1) {
0500         configPages.at(0)->setMoveLeftEnabled(false);
0501         configPages.at(1)->setMoveLeftEnabled(true);
0502     }
0503 
0504     if (index == (configPages.size() - 1)) {
0505         configPages.at(index)->setMoveRightEnabled(false);
0506         configPages.at(index - 1)->setMoveRightEnabled(true);
0507     }
0508 
0509     // configPages and tabWidget indexes differ by two
0510     tabWidget->insertTab(index + 1, configPages.at(index - 1), QIcon::fromTheme(QLatin1String("video-television"), QIcon(":video-television")),
0511         i18n("Device %1", index));
0512     tabWidget->setTabText(index + 2, i18n("Device %1", index + 1));
0513     tabWidget->setCurrentIndex(index + 1);
0514 }
0515 
0516 void DvbConfigDialog::moveRight(DvbConfigPage *configPage)
0517 {
0518     int index = configPages.indexOf(configPage) + 1;
0519 
0520     if ((index <= 0) || (index == configPages.size())) {
0521         return;
0522     }
0523 
0524 #if QT_VERSION < 0x050c00
0525     configPages.swap(index, index - 1);
0526 #else
0527     configPages.swapItemsAt(index, index - 1);
0528 #endif
0529 
0530     if (index == 1) {
0531         configPages.at(0)->setMoveLeftEnabled(false);
0532         configPages.at(1)->setMoveLeftEnabled(true);
0533     }
0534 
0535     if (index == (configPages.size() - 1)) {
0536         configPages.at(index)->setMoveRightEnabled(false);
0537         configPages.at(index - 1)->setMoveRightEnabled(true);
0538     }
0539 
0540     // configPages and tabWidget indexes differ by two
0541     tabWidget->insertTab(index + 1, configPages.at(index - 1), QIcon::fromTheme(QLatin1String("video-television"), QIcon(":video-television")),
0542         i18n("Device %1", index));
0543     tabWidget->setTabText(index + 2, i18n("Device %1", index + 1));
0544     tabWidget->setCurrentIndex(index + 2);
0545 }
0546 
0547 void DvbConfigDialog::remove(DvbConfigPage *configPage)
0548 {
0549     int index = configPages.indexOf(configPage);
0550 
0551     if (index < 0) {
0552         return;
0553     }
0554 
0555     delete configPages.takeAt(index);
0556 
0557     if ((index == 0) && !configPages.isEmpty()) {
0558         configPages.at(0)->setMoveLeftEnabled(false);
0559     }
0560 
0561     if ((index > 0) && (index == configPages.size())) {
0562         configPages.at(index - 1)->setMoveRightEnabled(false);
0563     }
0564 
0565     for (; index < configPages.size(); ++index) {
0566         // configPages and tabWidget indexes differ by two
0567         tabWidget->setTabText(index + 2, i18n("Device %1", index + 1));
0568     }
0569 }
0570 
0571 void DvbConfigDialog::accept()
0572 {
0573     manager->setRecordingFolder(recordingFolderEdit->text());
0574     manager->setTimeShiftFolder(timeShiftFolderEdit->text());
0575     manager->setXmltvFileName(xmltvFileNameEdit->text());
0576     manager->setNamingFormat(namingFormat->text());
0577     manager->setActionAfterRecording(actionAfterRecordingLineEdit->text());
0578     manager->setBeginMargin(beginMarginBox->value() * 60);
0579     manager->setEndMargin(endMarginBox->value() * 60);
0580     manager->setOverride6937Charset(override6937CharsetBox->isChecked());
0581     manager->setCreateInfoFile(createInfoFileBox->isChecked());
0582     manager->setDisableEpg(disableEpgBox->isChecked());
0583 #if 0
0584     manager->setScanWhenIdle(scanWhenIdleBox->isChecked());
0585 #endif
0586     manager->setRecordingRegexList(QStringList());
0587     manager->setRecordingRegexPriorityList(QList<int>());
0588 
0589     foreach (RegexInputLine *regexInputLine, regexInputList)
0590     {
0591         manager->addRecordingRegex(regexInputLine->lineEdit->text());
0592         qCDebug(logDvb, "saved regex: %s", qPrintable(regexInputLine->lineEdit->text()));
0593         manager->addRecordingRegexPriority(regexInputLine->spinBox->value());
0594         qCDebug(logDvb, "saved priority: %i", regexInputLine->spinBox->value());
0595     }
0596 
0597     QList<DvbDeviceConfigUpdate> configUpdates;
0598 
0599     foreach (DvbConfigPage *configPage, configPages) {
0600         DvbDeviceConfigUpdate configUpdate(configPage->getDeviceConfig());
0601         configUpdate.configs = configPage->getConfigs();
0602         configUpdates.append(configUpdate);
0603     }
0604 
0605     manager->updateDeviceConfigs(configUpdates);
0606     manager->getRecordingModel()->findNewRecordings();
0607     manager->getRecordingModel()->removeDuplicates();
0608     manager->getRecordingModel()->disableConflicts();
0609     //manager->getRecordingModel()->scanChannels();
0610     manager->writeDeviceConfigs();
0611 
0612     QDialog::accept();
0613 }
0614 
0615 DvbScanFileDownloadDialog::DvbScanFileDownloadDialog(DvbManager *manager_, QWidget *parent) :
0616     QDialog(parent), manager(manager_)
0617 {
0618     setWindowTitle(i18n("Update Scan Data"));
0619 
0620     QWidget *mainWidget = new QWidget(this);
0621     mainLayout = new QVBoxLayout;
0622     setLayout(mainLayout);
0623     mainLayout->addWidget(mainWidget);
0624 
0625     errorMsg = "Scan data update aborted.";
0626 
0627     buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
0628     buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
0629     connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
0630     connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
0631 
0632     QWidget *widget = new QWidget(this);
0633     mainLayout->addWidget(widget);
0634 
0635     mainLayout->addWidget(widget);
0636 
0637     label = new QLabel(i18n("Downloading scan data"), widget);
0638     mainLayout->addWidget(label);
0639 
0640     progressBar = new QProgressBar(widget);
0641     mainLayout->addWidget(progressBar);
0642     progressBar->setRange(0, 100);
0643 
0644     mainLayout->addWidget(buttonBox);
0645 
0646     job = KIO::get(QUrl("https://autoconfig.kde.org/kaffeine/scantable.dvb.qz"), KIO::NoReload,
0647                KIO::HideProgressInfo); // FIXME NoReload or Reload?
0648     job->setAutoDelete(false);
0649     connect(job, SIGNAL(percent(KJob*,ulong)),
0650         this, SLOT(progressChanged(KJob*,ulong)));
0651     connect(job, SIGNAL(data(KIO::Job*,QByteArray)),
0652         this, SLOT(dataArrived(KIO::Job*,QByteArray)));
0653     connect(job, SIGNAL(result(KJob*)), this, SLOT(jobFinished()));
0654 }
0655 
0656 DvbScanFileDownloadDialog::~DvbScanFileDownloadDialog()
0657 {
0658     delete job;
0659 }
0660 
0661 void DvbScanFileDownloadDialog::progressChanged(KJob *, unsigned long percent)
0662 {
0663     progressBar->setValue(int(percent));
0664 }
0665 
0666 void DvbScanFileDownloadDialog::dataArrived(KIO::Job *, const QByteArray &data)
0667 {
0668     scanData.append(data);
0669 
0670     /*
0671      * Current size in April, 2021 is 104KB.
0672      * Add an upper size limit here (1 MB), just in case, in order to
0673      * prevent potential issues.
0674      */
0675     int maxLimit = 1024 * 1024;
0676 
0677     if (scanData.size() > maxLimit) {
0678         errorMsg = i18n("Scan file is becoming bigger than %1 KB.\n"
0679                 "Aborting, as something might be wrong...\n",
0680                 QString::number(maxLimit / 1024., 'f', 2));
0681                job->kill(KJob::EmitResult);
0682     }
0683 }
0684 
0685 void DvbScanFileDownloadDialog::jobFinished()
0686 {
0687     progressBar->setValue(100);
0688 
0689     if (job->error() != 0) {
0690         if (job->error() == KJob::KilledJobError) {
0691             label->setText(errorMsg);
0692         } else {
0693             label->setText(job->errorString());
0694         }
0695 
0696         return;
0697     }
0698 
0699     if (manager->updateScanData(scanData)) {
0700         buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
0701         label->setText(i18n("Scan data successfully updated. %1 KB received.\n"
0702                     "Changes take effect after you have closed\n"
0703                     "the configuration dialog.",
0704                         QString::number(scanData.size() / 1024., 'f', 2)));
0705     } else {
0706         label->setText(i18n("Scan data update failed."));
0707     }
0708 }
0709 
0710 DvbConfigPage::DvbConfigPage(QWidget *parent, DvbManager *manager,
0711     const DvbDeviceConfig *deviceConfig_) : QWidget(parent), deviceConfig(deviceConfig_),
0712     dvbSObject(NULL)
0713 {
0714     boxLayout = new QVBoxLayout(this);
0715     boxLayout->addWidget(new QLabel(i18n("Name: %1", deviceConfig->frontendName)));
0716 
0717     QBoxLayout *horizontalLayout = new QHBoxLayout();
0718     moveLeftButton = new QPushButton(QIcon::fromTheme(QLatin1String("arrow-left"), QIcon(":arrow-left")), i18n("Move Left"), this);
0719     connect(moveLeftButton, SIGNAL(clicked()), this, SLOT(moveLeft()));
0720     horizontalLayout->addWidget(moveLeftButton);
0721 
0722     if (deviceConfig->device != NULL) {
0723         QPushButton *pushButton = new QPushButton(QIcon::fromTheme(QLatin1String("edit-undo"), QIcon(":edit-undo")), i18n("Reset"), this);
0724         connect(pushButton, SIGNAL(clicked()), this, SIGNAL(resetConfig()));
0725         horizontalLayout->addWidget(pushButton);
0726     } else {
0727         QPushButton *pushButton =
0728             new QPushButton(QIcon::fromTheme(QLatin1String("edit-delete"), QIcon(":edit-delete")), i18nc("@action", "Remove"), this);
0729         connect(pushButton, SIGNAL(clicked()), this, SLOT(removeConfig()));
0730         horizontalLayout->addWidget(pushButton);
0731     }
0732 
0733     moveRightButton = new QPushButton(QIcon::fromTheme(QLatin1String("arrow-right"), QIcon(":arrow-right")), i18n("Move Right"), this);
0734     connect(moveRightButton, SIGNAL(clicked()), this, SLOT(moveRight()));
0735     horizontalLayout->addWidget(moveRightButton);
0736     boxLayout->addLayout(horizontalLayout);
0737 
0738     if (deviceConfig->device == NULL) {
0739         addHSeparator(i18n("Device not connected."));
0740         boxLayout->addStretch();
0741         configs = deviceConfig->configs;
0742         return;
0743     }
0744 
0745     DvbDevice::TransmissionTypes transmissionTypes =
0746         deviceConfig->device->getTransmissionTypes();
0747 
0748     DvbConfig dvbCConfig;
0749     QList<DvbConfig> dvbSConfigs;
0750     DvbConfig dvbTConfig;
0751     DvbConfig atscConfig;
0752     DvbConfig isdbTConfig;
0753 
0754     foreach (const DvbConfig &config, deviceConfig->configs) {
0755         switch (config->getTransmissionType()) {
0756         case DvbConfigBase::DvbC:
0757             dvbCConfig = config;
0758             break;
0759         case DvbConfigBase::DvbS:
0760             dvbSConfigs.append(config);
0761             break;
0762         case DvbConfigBase::DvbT:
0763             dvbTConfig = config;
0764             break;
0765         case DvbConfigBase::Atsc:
0766             atscConfig = config;
0767             break;
0768         case DvbConfigBase::IsdbT:
0769             isdbTConfig = config;
0770             break;
0771         }
0772     }
0773 
0774     if ((transmissionTypes & DvbDevice::DvbC) != 0) {
0775         addHSeparator(i18n("DVB-C"));
0776 
0777         if (dvbCConfig.constData() == NULL) {
0778             DvbConfigBase *config = new DvbConfigBase(DvbConfigBase::DvbC);
0779             config->timeout = 1500;
0780             dvbCConfig = DvbConfig(config);
0781         }
0782 
0783         new DvbConfigObject(this, boxLayout, manager, dvbCConfig.data(), false);
0784         configs.append(dvbCConfig);
0785     }
0786 
0787     if ((transmissionTypes & (DvbDevice::DvbS | DvbDevice::DvbS2)) != 0) {
0788         bool dvbS2 = ((transmissionTypes & DvbDevice::DvbS2) != 0);
0789 
0790         if (dvbS2) {
0791             addHSeparator(i18n("DVB-S2"));
0792         } else {
0793             addHSeparator(i18n("DVB-S"));
0794         }
0795 
0796         dvbSObject = new DvbSConfigObject(this, boxLayout, manager, dvbSConfigs, deviceConfig->device, dvbS2);
0797     }
0798 
0799     if ((transmissionTypes & DvbDevice::DvbT) != 0) {
0800         bool dvbT2 = ((transmissionTypes & DvbDevice::DvbT2) != 0);
0801 
0802         if (dvbT2) {
0803             addHSeparator(i18n("DVB-T2"));
0804         } else {
0805             addHSeparator(i18n("DVB-T"));
0806         }
0807 
0808         if (dvbTConfig.constData() == NULL) {
0809             DvbConfigBase *config = new DvbConfigBase(DvbConfigBase::DvbT);
0810             config->timeout = 1500;
0811             dvbTConfig = DvbConfig(config);
0812         }
0813 
0814         new DvbConfigObject(this, boxLayout, manager, dvbTConfig.data(), dvbT2);
0815         configs.append(dvbTConfig);
0816     }
0817 
0818     if ((transmissionTypes & DvbDevice::Atsc) != 0) {
0819         addHSeparator(i18n("ATSC"));
0820 
0821         if (atscConfig.constData() == NULL) {
0822             DvbConfigBase *config = new DvbConfigBase(DvbConfigBase::Atsc);
0823             config->timeout = 1500;
0824             atscConfig = DvbConfig(config);
0825         }
0826 
0827         new DvbConfigObject(this, boxLayout, manager, atscConfig.data(), false);
0828         configs.append(atscConfig);
0829     }
0830 
0831     if ((transmissionTypes & DvbDevice::IsdbT) != 0) {
0832         addHSeparator(i18n("ISDB-T"));
0833 
0834         if (isdbTConfig.constData() == NULL) {
0835             DvbConfigBase *config = new DvbConfigBase(DvbConfigBase::IsdbT);
0836             config->timeout = 1500;
0837             isdbTConfig = DvbConfig(config);
0838         }
0839 
0840         new DvbConfigObject(this, boxLayout, manager, isdbTConfig.data(), false);
0841         configs.append(isdbTConfig);
0842     }
0843 
0844     boxLayout->addStretch();
0845 }
0846 
0847 DvbConfigPage::~DvbConfigPage()
0848 {
0849 }
0850 
0851 void DvbConfigPage::setMoveLeftEnabled(bool enabled)
0852 {
0853     moveLeftButton->setEnabled(enabled);
0854 }
0855 
0856 void DvbConfigPage::setMoveRightEnabled(bool enabled)
0857 {
0858     moveRightButton->setEnabled(enabled);
0859 }
0860 
0861 const DvbDeviceConfig *DvbConfigPage::getDeviceConfig() const
0862 {
0863     return deviceConfig;
0864 }
0865 
0866 QList<DvbConfig> DvbConfigPage::getConfigs()
0867 {
0868     if (dvbSObject != NULL) {
0869         dvbSObject->appendConfigs(configs);
0870     }
0871 
0872     for (int i = 0; i < configs.count(); ++i) {
0873         const DvbConfig &config = configs.at(i);
0874 
0875         if (config->name.isEmpty() || config->scanSource.isEmpty()) {
0876             configs.removeAt(i);
0877             --i;
0878         }
0879     }
0880 
0881     return configs;
0882 }
0883 
0884 void DvbConfigPage::moveLeft()
0885 {
0886     emit moveLeft(this);
0887 }
0888 
0889 void DvbConfigPage::moveRight()
0890 {
0891     emit moveRight(this);
0892 }
0893 
0894 void DvbConfigPage::removeConfig()
0895 {
0896     emit remove(this);
0897 }
0898 
0899 void DvbConfigPage::addHSeparator(const QString &title)
0900 {
0901     QFrame *frame = new QFrame(this);
0902     frame->setFrameShape(QFrame::HLine);
0903     boxLayout->addWidget(frame);
0904     boxLayout->addWidget(new QLabel(title, this));
0905 }
0906 
0907 DvbConfigObject::DvbConfigObject(QWidget *parent, QBoxLayout *layout, DvbManager *manager,
0908     DvbConfigBase *config_, bool isGen2_) : QObject(parent), config(config_)
0909 {
0910     QStringList sources;
0911     int sourceIndex = -1;
0912 
0913     isGen2 = isGen2_;
0914 
0915     switch (config->getTransmissionType()) {
0916     case DvbConfigBase::DvbC:
0917         defaultName = i18n("Cable");
0918         sources = manager->getScanSources(DvbManager::DvbC);
0919         sourceIndex = sources.indexOf(config->scanSource);
0920         break;
0921     case DvbConfigBase::DvbS:
0922         // handled separately
0923         break;
0924     case DvbConfigBase::DvbT:
0925         if (isGen2) {
0926             defaultName = i18n("Terrestrial (T2)");
0927             sources.append(QLatin1String("AUTO-T2-Normal"));
0928             sources.append(QLatin1String("AUTO-T2-Offsets"));
0929             sources.append(QLatin1String("AUTO-T2-Australia"));
0930             sources.append(QLatin1String("AUTO-T2-Italy"));
0931             sources.append(QLatin1String("AUTO-T2-Taiwan"));
0932             sources += manager->getScanSources(DvbManager::DvbT2);
0933         } else {
0934             defaultName = i18n("Terrestrial");
0935             sources.append(QLatin1String("AUTO-T-Normal"));
0936             sources.append(QLatin1String("AUTO-T-Offsets"));
0937             sources.append(QLatin1String("AUTO-T-Australia"));
0938             sources.append(QLatin1String("AUTO-T-Italy"));
0939             sources.append(QLatin1String("AUTO-T-Taiwan"));
0940             sources += manager->getScanSources(DvbManager::DvbT);
0941         }
0942         sourceIndex = sources.indexOf(config->scanSource);
0943         sources.replace(0, i18n("Autoscan"));
0944         sources.replace(1, i18n("Autoscan with 167 kHz Offsets"));
0945         sources.replace(2, i18n("Autoscan Australia"));
0946         sources.replace(3, i18n("Autoscan Italy"));
0947         sources.replace(4, i18n("Autoscan Taiwan"));
0948         break;
0949     case DvbConfigBase::Atsc:
0950         defaultName = i18n("Atsc");
0951         sources = manager->getScanSources(DvbManager::Atsc);
0952         sourceIndex = sources.indexOf(config->scanSource);
0953         break;
0954     case DvbConfigBase::IsdbT:
0955         defaultName = i18n("ISDB-T");
0956         sources.append(QLatin1String("AUTO-UHF-6MHz"));
0957         sources.replace(0, i18n("Autoscan"));
0958         sources += manager->getScanSources(DvbManager::IsdbT);
0959         sourceIndex = sources.indexOf(config->scanSource);
0960         break;
0961     }
0962 
0963     QGridLayout *gridLayout = new QGridLayout();
0964     layout->addLayout(gridLayout);
0965 
0966     gridLayout->addWidget(new QLabel(i18n("Tuner timeout (ms):")), 0, 0);
0967 
0968     timeoutBox = new QSpinBox(parent);
0969     timeoutBox->setRange(100, 5000);
0970     timeoutBox->setSingleStep(100);
0971     timeoutBox->setValue(config->timeout);
0972     connect(timeoutBox, SIGNAL(valueChanged(int)), this, SLOT(timeoutChanged(int)));
0973     gridLayout->addWidget(timeoutBox, 0, 1);
0974 
0975     gridLayout->addWidget(new QLabel(i18n("Source:")), 1, 0);
0976 
0977     sourceBox = new QComboBox(parent);
0978     sourceBox->addItem(i18n("No Source"));
0979     sourceBox->addItems(sources);
0980     sourceBox->setCurrentIndex(sourceIndex + 1);
0981     connect(sourceBox, SIGNAL(currentIndexChanged(int)), this, SLOT(sourceChanged(int)));
0982     gridLayout->addWidget(sourceBox, 1, 1);
0983 
0984     gridLayout->addWidget(new QLabel(i18n("Name:")), 2, 0);
0985 
0986     nameEdit = new QLineEdit(parent);
0987     nameEdit->setText(config->name);
0988     connect(nameEdit, SIGNAL(editingFinished()), this, SLOT(nameChanged()));
0989     gridLayout->addWidget(nameEdit, 2, 1);
0990 
0991     timeoutChanged(timeoutBox->value());
0992     sourceChanged(sourceBox->currentIndex());
0993     nameChanged();
0994     connect(parent, SIGNAL(resetConfig()), this, SLOT(resetConfig()));
0995 }
0996 
0997 DvbConfigObject::~DvbConfigObject()
0998 {
0999 }
1000 
1001 void DvbConfigObject::timeoutChanged(int timeout)
1002 {
1003     config->timeout = timeout;
1004 }
1005 
1006 void DvbConfigObject::sourceChanged(int index)
1007 {
1008     if (index <= 0) {
1009         // no source selected
1010         nameEdit->setEnabled(false);
1011         config->scanSource.clear();
1012     } else if ((index <= 5) && (config->getTransmissionType() == DvbConfigBase::DvbT)) {
1013         nameEdit->setEnabled(true);
1014 
1015         if (isGen2) {
1016             switch (index - 1) {
1017             case 0:
1018                 config->scanSource = QLatin1String("AUTO-T2-Normal");
1019                 break;
1020             case 1:
1021                 config->scanSource = QLatin1String("AUTO-T2-Offsets");
1022                 break;
1023             case 2:
1024                 config->scanSource = QLatin1String("AUTO-T2-Australia");
1025                 break;
1026             case 3:
1027                 config->scanSource = QLatin1String("AUTO-T2-Italy");
1028                 break;
1029             case 4:
1030                 config->scanSource = QLatin1String("AUTO-T2-Taiwan");
1031                 break;
1032             }
1033         } else {
1034             switch (index - 1) {
1035             case 0:
1036                 config->scanSource = QLatin1String("AUTO-T-Normal");
1037                 break;
1038             case 1:
1039                 config->scanSource = QLatin1String("AUTO-T-Offsets");
1040                 break;
1041             case 2:
1042                 config->scanSource = QLatin1String("AUTO-T-Australia");
1043                 break;
1044             case 3:
1045                 config->scanSource = QLatin1String("AUTO-T-Italy");
1046                 break;
1047             case 4:
1048                 config->scanSource = QLatin1String("AUTO-T-Taiwan");
1049                 break;
1050             }
1051         }
1052     } else {
1053         nameEdit->setEnabled(true);
1054         config->scanSource = sourceBox->currentText();
1055     }
1056 }
1057 
1058 void DvbConfigObject::nameChanged()
1059 {
1060     QString name = nameEdit->text();
1061 
1062     if (name.isEmpty()) {
1063         nameEdit->setText(defaultName);
1064         config->name = defaultName;
1065     } else {
1066         config->name = name;
1067     }
1068 }
1069 
1070 void DvbConfigObject::resetConfig()
1071 {
1072     timeoutBox->setValue(1500); // FIXME hardcoded
1073     sourceBox->setCurrentIndex(0);
1074     nameEdit->setText(defaultName);
1075 }
1076 
1077 DvbSConfigObject::DvbSConfigObject(QWidget *parent_, QBoxLayout *boxLayout, DvbManager *manager,
1078     const QList<DvbConfig> &configs, DvbDevice *device_, bool dvbS2) : QObject(parent_), parent(parent_), device(device_)
1079 {
1080     if (!configs.isEmpty()) {
1081         lnbConfig = new DvbConfigBase(*configs.at(0));
1082     } else {
1083         lnbConfig = createConfig(0);
1084     }
1085 
1086     if (dvbS2) {
1087         sources = manager->getScanSources(DvbManager::DvbS2);
1088     } else {
1089         sources = manager->getScanSources(DvbManager::DvbS);
1090     }
1091 
1092     layout = new QGridLayout();
1093     boxLayout->addLayout(layout);
1094 
1095     layout->addWidget(new QLabel(i18n("Tuner timeout (ms):")), 0, 0);
1096 
1097     timeoutBox = new QSpinBox(parent);
1098     timeoutBox->setRange(100, 5000);
1099     timeoutBox->setSingleStep(100);
1100     timeoutBox->setValue(lnbConfig->timeout);
1101     layout->addWidget(timeoutBox, 0, 1);
1102 
1103     layout->addWidget(new QLabel(i18n("Use Higher LNBf voltage:")),
1104         1, 0);
1105 
1106     higherVoltageBox = new QCheckBox(parent);
1107     higherVoltageBox->setTristate(true);
1108     higherVoltageBox->setCheckState((Qt::CheckState)lnbConfig->higherVoltage);
1109     higherVoltageBox->setToolTip(i18n("On some DVB devices, there's an extra control that allows to increase the \n"
1110         "voltage sent to LNBf, in order to compensate for cabling loss. This tri-state\n"
1111         "button defaults to not use it. It may be set to:\n"
1112         "- normal mode (unchecked);\n"
1113         "- higher voltage mode (checked);\n"
1114         "- tristate (don't send the control)."));
1115     layout->addWidget(higherVoltageBox, 1, 1);
1116 
1117     layout->addWidget(new QLabel(i18n("Configuration:")), 2, 0);
1118 
1119     configBox = new QComboBox(parent);
1120     configBox->addItem(i18n("DiSEqC Switch"));
1121     configBox->addItem(i18n("USALS Rotor"));
1122     configBox->addItem(i18n("Positions Rotor"));
1123     configBox->addItem(i18n("Disable DiSEqC"));
1124     configBox->setCurrentIndex(lnbConfig->configuration);
1125     connect(configBox, SIGNAL(currentIndexChanged(int)), this, SLOT(configChanged(int)));
1126     layout->addWidget(configBox, 2, 1);
1127 
1128     // Diseqc switch
1129 
1130     for (int lnbNumber = 0; lnbNumber < 4; ++lnbNumber) {
1131         DvbConfigBase *config;
1132 
1133         if (((lnbConfig->configuration == DvbConfigBase::DiseqcSwitch) ||
1134              (lnbConfig->configuration == DvbConfigBase::NoDiseqc)) &&
1135             (lnbNumber < configs.size())) {
1136             config = new DvbConfigBase(*configs.at(lnbNumber));
1137         } else {
1138             config = createConfig(lnbNumber);
1139         }
1140 
1141         QPushButton *pushButton = new QPushButton(i18n("LNB %1 Settings", lnbNumber + 1),
1142                               parent);
1143         if (lnbNumber > 0)
1144             connect(this, &DvbSConfigObject::setDiseqcVisible,
1145                 pushButton, &QPushButton::setVisible);
1146         else
1147             connect(this, &DvbSConfigObject::setFirstLnbVisible,
1148                 pushButton, &QPushButton::setVisible);
1149         layout->addWidget(pushButton, lnbNumber + 3, 0);
1150 
1151         QComboBox *comboBox = new QComboBox(parent);
1152         comboBox->addItem(i18n("No Source"));
1153         comboBox->addItems(sources);
1154         comboBox->setCurrentIndex(sources.indexOf(config->scanSource) + 1);
1155         if (lnbNumber > 0)
1156             connect(this, &DvbSConfigObject::setDiseqcVisible,
1157                 comboBox, &QComboBox::setVisible);
1158         else
1159             connect(this, &DvbSConfigObject::setFirstLnbVisible,
1160                 comboBox, &QComboBox::setVisible);
1161         layout->addWidget(comboBox, lnbNumber + 3, 1);
1162 
1163         diseqcConfigs.append(DvbConfig(config));
1164         lnbConfigs.append(new DvbSLnbConfigObject(timeoutBox, higherVoltageBox, comboBox, pushButton,
1165             config, device));
1166     }
1167 
1168     // USALS rotor / Positions rotor
1169 
1170     QPushButton *pushButton = new QPushButton(i18n("LNB Settings"), parent);
1171 
1172     connect(this, &DvbSConfigObject::setRotorVisible, pushButton,
1173         &QPushButton::setVisible);
1174     layout->addWidget(pushButton, 7, 0);
1175 
1176     lnbConfigs.append(new DvbSLnbConfigObject(timeoutBox, higherVoltageBox, NULL, pushButton, lnbConfig, device));
1177 
1178     sourceBox = new QComboBox(parent);
1179     sourceBox->addItems(sources);
1180     connect(this, &DvbSConfigObject::setRotorVisible, sourceBox,
1181         &QComboBox::setVisible);
1182     layout->addWidget(sourceBox, 7, 1);
1183 
1184     satelliteView = new QTreeWidget(parent);
1185 
1186     // Usals rotor
1187 
1188     pushButton = new QPushButton(i18n("Add Satellite"), parent);
1189     connect(this, &DvbSConfigObject::setUsalsVisible, pushButton,
1190         &QPushButton::setVisible);
1191     connect(pushButton, SIGNAL(clicked()), this, SLOT(addSatellite()));
1192     layout->addWidget(pushButton, 8, 0, 1, 2);
1193 
1194     // Positions rotor
1195 
1196     rotorSpinBox = new QSpinBox(parent);
1197     rotorSpinBox->setRange(0, 255);
1198     connect(this, &DvbSConfigObject::setPositionsVisible, rotorSpinBox,
1199         &QSpinBox::setVisible);
1200     layout->addWidget(rotorSpinBox, 9, 0);
1201 
1202     pushButton = new QPushButton(i18n("Add Satellite"), parent);
1203     connect(this, &DvbSConfigObject::setPositionsVisible, pushButton,
1204         &QPushButton::setVisible);
1205     connect(pushButton, SIGNAL(clicked()), this, SLOT(addSatellite()));
1206     layout->addWidget(pushButton, 9, 1);
1207 
1208     // USALS rotor / Positions rotor
1209 
1210     satelliteView->setColumnCount(2);
1211     satelliteView->setHeaderLabels(QStringList() << i18n("Satellite") << i18n("Position"));
1212     satelliteView->setMinimumHeight(100);
1213     satelliteView->setRootIsDecorated(false);
1214     satelliteView->sortByColumn(0, Qt::AscendingOrder);
1215     satelliteView->setSortingEnabled(true);
1216     connect(this, SIGNAL(setRotorVisible(bool)), satelliteView, SLOT(setVisible(bool)));
1217     layout->addWidget(satelliteView, 10, 0, 1, 2);
1218 
1219     if ((lnbConfig->configuration == DvbConfigBase::UsalsRotor) ||
1220         (lnbConfig->configuration == DvbConfigBase::PositionsRotor)) {
1221         foreach (const DvbConfig &config, configs) {
1222             QStringList stringList;
1223             stringList << config->scanSource << QString::number(config->lnbNumber);
1224             satelliteView->addTopLevelItem(new QTreeWidgetItem(stringList));
1225         }
1226     }
1227 
1228     pushButton = new QPushButton(i18n("Remove Satellite"), parent);
1229     connect(this, &DvbSConfigObject::setRotorVisible, pushButton,
1230         &QPushButton::setVisible);
1231     connect(pushButton, SIGNAL(clicked()), this, SLOT(removeSatellite()));
1232     layout->addWidget(pushButton, 11, 0, 1, 2);
1233 
1234     // Latitude/Longitude for USALS rotor
1235 
1236     layout = new QGridLayout();
1237 
1238     validPixmap = QIcon::fromTheme(QLatin1String("dialog-ok-apply")).pixmap(22);
1239     invalidPixmap = QIcon::fromTheme(QLatin1String("dialog-cancel")).pixmap(22);
1240 
1241     QLabel *label = new QLabel(i18n("Your position:"));
1242     layout->addWidget(label);
1243     connect(this, &DvbSConfigObject::setUsalsVisible, label,
1244         &QLabel::setVisible);
1245 
1246     label = new QLabel(i18n("Latitude:"));
1247     layout->addWidget(label, 1, 0);
1248     connect(this, &DvbSConfigObject::setUsalsVisible, label,
1249         &QLabel::setVisible);
1250 
1251     label = new QLabel(i18n("[S -90 ... 90 N]"));
1252     layout->addWidget(label, 1, 1);
1253     connect(this, &DvbSConfigObject::setUsalsVisible, label,
1254         &QLabel::setVisible);
1255 
1256     latitudeEdit = new QLineEdit(parent);
1257     latitudeEdit->setText(QString::number(lnbConfig->latitude, 'g', 10));
1258     connect(latitudeEdit, SIGNAL(textChanged(QString)), this, SLOT(latitudeChanged(QString)));
1259     layout->addWidget(latitudeEdit, 1, 2);
1260     connect(this, &DvbSConfigObject::setUsalsVisible, latitudeEdit,
1261         &QLineEdit::setVisible);
1262 
1263     latitudeValidLabel = new QLabel(parent);
1264     latitudeValidLabel->setPixmap(validPixmap);
1265     layout->addWidget(latitudeValidLabel, 1, 3);
1266     connect(this, &DvbSConfigObject::setUsalsVisible, latitudeValidLabel,
1267         &QLineEdit::setVisible);
1268 
1269     label = new QLabel(i18n("Longitude:"));
1270     layout->addWidget(label, 2, 0);
1271     connect(this, &DvbSConfigObject::setUsalsVisible, label,
1272         &QLabel::setVisible);
1273 
1274     label = new QLabel(i18n("[W -180 ... 180 E]"));
1275     layout->addWidget(label, 2, 1);
1276     connect(this, &DvbSConfigObject::setUsalsVisible, label,
1277         &QLabel::setVisible);
1278 
1279     longitudeEdit = new QLineEdit(parent);
1280     longitudeEdit->setText(QString::number(lnbConfig->longitude, 'g', 10));
1281     connect(this, SIGNAL(setUsalsVisible(bool)), longitudeEdit, SLOT(setVisible(bool)));
1282     connect(this, &DvbSConfigObject::setUsalsVisible, longitudeEdit,
1283         &QLineEdit::setVisible);
1284     layout->addWidget(longitudeEdit, 2, 2);
1285 
1286     longitudeValidLabel = new QLabel(parent);
1287     longitudeValidLabel->setPixmap(validPixmap);
1288     layout->addWidget(longitudeValidLabel, 2, 3);
1289     boxLayout->addLayout(layout);
1290     connect(this, &DvbSConfigObject::setUsalsVisible, longitudeValidLabel,
1291         &QLineEdit::setVisible);
1292 
1293     configChanged(configBox->currentIndex());
1294     connect(parent, SIGNAL(resetConfig()), this, SLOT(resetConfig()));
1295 }
1296 
1297 DvbSConfigObject::~DvbSConfigObject()
1298 {
1299     delete lnbConfig;
1300 }
1301 
1302 
1303 void DvbSConfigObject::latitudeChanged(const QString &text)
1304 {
1305     bool ok;
1306     toLatitude(text, &ok);
1307 
1308     if (ok) {
1309         latitudeValidLabel->setPixmap(validPixmap);
1310     } else {
1311         latitudeValidLabel->setPixmap(invalidPixmap);
1312     }
1313 }
1314 
1315 void DvbSConfigObject::longitudeChanged(const QString &text)
1316 {
1317     bool ok;
1318     toLongitude(text, &ok);
1319 
1320     if (ok) {
1321         longitudeValidLabel->setPixmap(validPixmap);
1322     } else {
1323         longitudeValidLabel->setPixmap(invalidPixmap);
1324     }
1325 }
1326 
1327 
1328 double DvbSConfigObject::toLatitude(const QString &text, bool *ok)
1329 {
1330     if (text.isEmpty()) {
1331         *ok = true;
1332         return 0;
1333     }
1334 
1335     double value = text.toDouble(ok);
1336 
1337     if (qAbs(value) > 90) {
1338         *ok = false;
1339     }
1340 
1341     return value;
1342 }
1343 
1344 double DvbSConfigObject::toLongitude(const QString &text, bool *ok)
1345 {
1346     if (text.isEmpty()) {
1347         *ok = true;
1348         return 0;
1349     }
1350 
1351     double value = text.toDouble(ok);
1352 
1353     if (qAbs(value) > 180) {
1354         *ok = false;
1355     }
1356 
1357     return value;
1358 }
1359 
1360 void DvbSConfigObject::appendConfigs(QList<DvbConfig> &list)
1361 {
1362     int index = configBox->currentIndex();
1363 
1364     if (index == 0 || index == 3) {
1365         // Diseqc switch or No Diseqc
1366 
1367         if (index == 3)
1368             diseqcConfigs[0]->configuration = DvbConfigBase::NoDiseqc;
1369         else
1370             diseqcConfigs[0]->configuration = DvbConfigBase::DiseqcSwitch;
1371 
1372         list += diseqcConfigs;
1373     } else if ((index == 1) || (index == 2)) {
1374         // Usals rotor / Positions rotor
1375 
1376         for (int i = 0;; ++i) {
1377             QTreeWidgetItem *item = satelliteView->topLevelItem(i);
1378 
1379             if (item == NULL) {
1380                 break;
1381             }
1382 
1383             QString satellite = item->text(0);
1384 
1385             DvbConfigBase *config = new DvbConfigBase(*lnbConfig);
1386             config->name = satellite;
1387             config->scanSource = satellite;
1388 
1389             if (index == 1) {
1390                 // USALS rotor
1391                 config->configuration = DvbConfigBase::UsalsRotor;
1392 
1393                 bool latitudeOk;
1394                 bool longitudeOk;
1395 
1396                 double latitude = toLatitude(latitudeEdit->text(), &latitudeOk);
1397                 double longitude = toLongitude(longitudeEdit->text(), &longitudeOk);
1398 
1399                 if (latitudeOk && longitudeOk) {
1400                     config->latitude = latitude;
1401                     config->longitude = longitude;
1402                 }
1403             } else {
1404                 // Positions rotor
1405                 config->configuration = DvbConfigBase::PositionsRotor;
1406                 config->lnbNumber = item->text(1).toInt();
1407             }
1408 
1409             list.append(DvbConfig(config));
1410         }
1411     }
1412 }
1413 
1414 void DvbSConfigObject::configChanged(int index)
1415 {
1416     if (index == 0) {
1417         // Diseqc switch
1418 
1419         emit setDiseqcVisible(true);
1420         emit setFirstLnbVisible(true);
1421         emit setRotorVisible(false);
1422         emit setUsalsVisible(false);
1423         emit setPositionsVisible(false);
1424     } else if (index == 1) {
1425         // Usals rotor
1426 
1427         satelliteView->hideColumn(1);
1428 
1429         emit setDiseqcVisible(false);
1430         emit setFirstLnbVisible(false);
1431         emit setRotorVisible(true);
1432         emit setUsalsVisible(true);
1433         emit setPositionsVisible(false);
1434     } else if (index == 2) {
1435         // Positions rotor
1436 
1437         if (satelliteView->isColumnHidden(1)) {
1438             int width = satelliteView->columnWidth(0);
1439             satelliteView->showColumn(1);
1440             satelliteView->setColumnWidth(0, width / 2);
1441         }
1442 
1443         emit setDiseqcVisible(false);
1444         emit setFirstLnbVisible(false);
1445         emit setRotorVisible(true);
1446         emit setUsalsVisible(false);
1447         emit setPositionsVisible(true);
1448     } else if (index == 3) {
1449         // No Diseqc switch
1450 
1451         emit setDiseqcVisible(false);
1452         emit setFirstLnbVisible(true);
1453         emit setRotorVisible(false);
1454         emit setUsalsVisible(false);
1455         emit setPositionsVisible(false);
1456     }
1457 }
1458 
1459 void DvbSConfigObject::addSatellite()
1460 {
1461     QString satellite = sourceBox->currentText();
1462     QString index = rotorSpinBox->text();
1463     QStringList stringList = QStringList() << satellite << index;
1464 
1465     if (configBox->currentIndex() == 1) {
1466         // USALS rotor
1467 
1468         if (satelliteView->findItems(satellite, Qt::MatchExactly).isEmpty()) {
1469             satelliteView->addTopLevelItem(new QTreeWidgetItem(stringList));
1470         }
1471     } else {
1472         // Positions rotor
1473 
1474         QList<QTreeWidgetItem *> items =
1475             satelliteView->findItems(index, Qt::MatchExactly, 1);
1476 
1477         if (!items.isEmpty()) {
1478             items.at(0)->setText(0, sourceBox->currentText());
1479         } else {
1480             satelliteView->addTopLevelItem(new QTreeWidgetItem(stringList));
1481         }
1482     }
1483 }
1484 
1485 void DvbSConfigObject::removeSatellite()
1486 {
1487     qDeleteAll(satelliteView->selectedItems());
1488 }
1489 
1490 void DvbSConfigObject::resetConfig()
1491 {
1492     timeoutBox->setValue(1500);
1493     higherVoltageBox->setChecked(Qt::PartiallyChecked);
1494     configBox->setCurrentIndex(0);
1495 
1496     for (int i = 0; i < lnbConfigs.size(); ++i) {
1497         lnbConfigs[i]->resetConfig();
1498     }
1499 
1500     satelliteView->clear();
1501 }
1502 
1503 DvbConfigBase *DvbSConfigObject::createConfig(int lnbNumber)
1504 {
1505     DvbConfigBase *config = new DvbConfigBase(DvbConfigBase::DvbS);
1506     config->timeout = 1500;
1507     config->higherVoltage = Qt::PartiallyChecked;
1508     config->configuration = DvbConfigBase::DiseqcSwitch;
1509     config->lnbNumber = lnbNumber;
1510     config->currentLnb = device->getLnbSatModels().at(0);
1511     config->bpf = 0;
1512     return config;
1513 }
1514 
1515 DvbSLnbConfigObject::DvbSLnbConfigObject(QSpinBox *timeoutSpinBox,
1516                      QCheckBox *higherVoltageBox,
1517                      QComboBox *sourceBox_,
1518     QPushButton *configureButton_, DvbConfigBase *config_, DvbDevice *device_) : QObject(timeoutSpinBox),
1519     sourceBox(sourceBox_), configureButton(configureButton_), config(config_), device(device_)
1520 {
1521     connect(timeoutSpinBox, SIGNAL(valueChanged(int)), this, SLOT(timeoutChanged(int)));
1522     connect(higherVoltageBox, SIGNAL(stateChanged(int)), this, SLOT(higherVoltageChanged(int)));
1523     connect(configureButton, SIGNAL(clicked()), this, SLOT(configure()));
1524 
1525     if (sourceBox != NULL) {
1526         connect(sourceBox, SIGNAL(currentIndexChanged(int)),
1527             this, SLOT(sourceChanged(int)));
1528         sourceChanged(sourceBox->currentIndex());
1529     }
1530 
1531     timeoutChanged(timeoutSpinBox->value());
1532 }
1533 
1534 DvbSLnbConfigObject::~DvbSLnbConfigObject()
1535 {
1536 }
1537 
1538 void DvbSLnbConfigObject::resetConfig()
1539 {
1540     config->currentLnb = device->getLnbSatModels().at(0);
1541     config->bpf = 0;
1542 
1543     if (sourceBox != NULL) {
1544         sourceBox->setCurrentIndex(0);
1545     }
1546 }
1547 
1548 void DvbSLnbConfigObject::timeoutChanged(int value)
1549 {
1550     config->timeout = value;
1551 }
1552 
1553 void DvbSLnbConfigObject::higherVoltageChanged(int value)
1554 {
1555     config->higherVoltage = value;
1556 }
1557 
1558 void DvbSLnbConfigObject::sourceChanged(int index)
1559 {
1560     if (index <= 0) {
1561         // no source selected
1562         configureButton->setEnabled(false);
1563         config->name.clear();
1564         config->scanSource.clear();
1565     } else {
1566         configureButton->setEnabled(true);
1567         config->name = sourceBox->currentText();
1568         config->scanSource = config->name;
1569     }
1570 }
1571 
1572 void DvbSLnbConfigObject::configure()
1573 {
1574     QVBoxLayout *mainLayout = new QVBoxLayout();
1575 
1576     dialog = new QDialog(configureButton);
1577     dialog->setAttribute(Qt::WA_DeleteOnClose);
1578     dialog->setWindowTitle(i18n("LNB Settings"));
1579     dialog->setLayout(mainLayout);
1580 
1581     QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
1582     connect(buttonBox, &QDialogButtonBox::accepted, this, &DvbSLnbConfigObject::dialogAccepted);
1583     connect(buttonBox, &QDialogButtonBox::rejected, dialog, &QDialog::reject);
1584 
1585     QWidget *mainWidget = new QWidget(dialog);
1586     QGridLayout *gridLayout = new QGridLayout(mainWidget);
1587     mainLayout->addWidget(mainWidget);
1588 
1589     lnbSelectionGroup = new QButtonGroup(mainWidget);
1590     lnbSelectionGroup->setExclusive(true);
1591     connect(lnbSelectionGroup, SIGNAL(buttonClicked(int)), this, SLOT(selectType(int)));
1592 
1593     int i, size = device->getLnbSatModels().size();
1594 
1595     currentType = -1;
1596 
1597     for (i = 0; i < size; i++) {
1598         struct lnbSat lnb = device->getLnbSatModels().at(i);
1599         QRadioButton *radioButton = new QRadioButton(i18nd("libdvbv5", lnb.name.toLocal8Bit().constData()), mainWidget);
1600         mainLayout->addWidget(radioButton);
1601         lnbSelectionGroup->addButton(radioButton, i + 1);
1602         gridLayout->addWidget(radioButton, i % ((size + 1) / 2), i / ((size + 1) / 2));
1603 
1604         if (config->currentLnb.alias.isEmpty() || config->currentLnb.alias == lnb.alias) {
1605             radioButton->setChecked(true);
1606             config->currentLnb = lnb;
1607             currentType = i + 1;
1608         }
1609     }
1610 
1611     // shouldn't happen, except if the config file has an invalid LNBf
1612     if (currentType < 0) {
1613         config->currentLnb = device->getLnbSatModels().at(0);
1614         currentType = 1;
1615     }
1616 
1617     QFrame *frame = new QFrame(mainWidget);
1618     frame->setFrameShape(QFrame::VLine);
1619     gridLayout->addWidget(frame, 0, 3, 6, 1);
1620 
1621     // FIXME: Those are actually the IF frequencies
1622 
1623     lowBandLabel = new QLabel(i18n("Low frequency (KHz)"), mainWidget);
1624     gridLayout->addWidget(lowBandLabel, 0, 4);
1625     lowBandSpinBox = new QSpinBox(mainWidget);
1626     gridLayout->addWidget(lowBandSpinBox, 0, 5);
1627     lowBandSpinBox->setRange(0, 15000);
1628     lowBandSpinBox->setValue(config->currentLnb.lowFreq);
1629     lowBandSpinBox->setEnabled(false);
1630 
1631     highBandLabel = new QLabel(i18n("High frequency (MHz)"), mainWidget);
1632     gridLayout->addWidget(highBandLabel, 1, 4);
1633     highBandSpinBox = new QSpinBox(mainWidget);
1634     gridLayout->addWidget(highBandSpinBox, 1, 5);
1635     highBandSpinBox->setRange(0, 15000);
1636     highBandSpinBox->setValue(config->currentLnb.highFreq);
1637     highBandSpinBox->setEnabled(false);
1638 
1639     switchLabel = new QLabel(i18n("Switch frequency (MHz)"), mainWidget);
1640     gridLayout->addWidget(switchLabel, 2, 4);
1641     switchSpinBox = new QSpinBox(mainWidget);
1642     gridLayout->addWidget(switchSpinBox, 2, 5);
1643     switchSpinBox->setRange(0, 15000);
1644     switchSpinBox->setValue(config->currentLnb.rangeSwitch);
1645     switchSpinBox->setEnabled(false);
1646 
1647     lowRangeLabel = new QLabel(i18n("Low range: %1 MHz to %2 MHz", config->currentLnb.freqRange[0].low, config->currentLnb.freqRange[0].high), mainWidget);
1648     gridLayout->addWidget(lowRangeLabel, 3, 4, 1, 2);
1649 
1650     highRangeLabel = new QLabel(mainWidget);
1651     gridLayout->addWidget(highRangeLabel, 4, 4, 1, 2);
1652 
1653     selectType(currentType);
1654 
1655     mainLayout->addWidget(buttonBox);
1656 
1657     dialog->setModal(true);
1658     dialog->show();
1659 
1660 }
1661 
1662 void DvbSLnbConfigObject::selectType(int type)
1663 {
1664     struct lnbSat lnb = device->getLnbSatModels().at(type - 1);
1665 
1666 
1667     lowBandSpinBox->setValue(lnb.lowFreq);
1668     if (!lnb.lowFreq) {
1669         lowBandLabel->hide();
1670         lowBandSpinBox->hide();
1671     } else {
1672         lowBandLabel->show();
1673         lowBandSpinBox->show();
1674     }
1675 
1676     highBandSpinBox->setValue(lnb.highFreq);
1677     if (!lnb.highFreq) {
1678         highBandLabel->hide();
1679         highBandSpinBox->hide();
1680     } else {
1681         highBandLabel->show();
1682         highBandSpinBox->show();
1683     }
1684 
1685     switchSpinBox->setValue(lnb.rangeSwitch);
1686     if (!lnb.rangeSwitch) {
1687         switchLabel->hide();
1688         switchSpinBox->hide();
1689     } else {
1690         switchLabel->show();
1691         switchSpinBox->show();
1692     }
1693 
1694     lowRangeLabel->setText(i18n("Low range: %1 MHz to %2 MHz", lnb.freqRange[0].low, lnb.freqRange[0].high));
1695 
1696     if (!lnb.freqRange[1].high) {
1697         if (!lnb.highFreq) {
1698             highRangeLabel->hide();
1699         } else {
1700             highRangeLabel->setText(i18n("Bandstacked"));
1701             highRangeLabel->show();
1702         }
1703     } else {
1704         highRangeLabel->setText(i18n("High range: %1 MHz to %2 MHz", lnb.freqRange[1].low, lnb.freqRange[1].high));
1705         highRangeLabel->show();
1706     }
1707 
1708     currentType = type;
1709 }
1710 
1711 void DvbSLnbConfigObject::dialogAccepted()
1712 {
1713     config->currentLnb = device->getLnbSatModels().at(currentType - 1);
1714     qCDebug(logDvb) << "Selected LNBf:" << config->currentLnb.alias;
1715 
1716     dialog->accept();
1717 }
1718 
1719 #include "moc_dvbconfigdialog.cpp"