File indexing completed on 2024-05-12 04:52:10
0001 /* 0002 * dvbchanneldialog.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 <KConfigGroup> 0024 #include <KMessageBox> 0025 #include <QAction> 0026 #include <QBoxLayout> 0027 #include <QCheckBox> 0028 #include <QComboBox> 0029 #include <QCoreApplication> 0030 #include <QGroupBox> 0031 #include <QHeaderView> 0032 #include <QLabel> 0033 #include <QLineEdit> 0034 #include <QMimeData> 0035 #include <QSpinBox> 0036 0037 #include "dvbchanneldialog.h" 0038 #include "dvbchanneldialog_p.h" 0039 #include "dvbsi.h" 0040 #include "../iso-codes.h" 0041 0042 bool DvbChannelLessThan::operator()(const DvbSharedChannel &x, const DvbSharedChannel &y) const 0043 { 0044 switch (sortOrder) { 0045 case ChannelNameAscending: 0046 if (x->name != y->name) { 0047 return (x->name.localeAwareCompare(y->name) < 0); 0048 } 0049 0050 break; 0051 case ChannelNameDescending: 0052 if (x->name != y->name) { 0053 return (x->name.localeAwareCompare(y->name) > 0); 0054 } 0055 0056 break; 0057 case ChannelNumberAscending: 0058 if (x->number != y->number) { 0059 return (x->number < y->number); 0060 } 0061 0062 break; 0063 case ChannelNumberDescending: 0064 if (x->number != y->number) { 0065 return (x->number > y->number); 0066 } 0067 0068 break; 0069 } 0070 0071 return (x < y); 0072 } 0073 0074 DvbChannelTableModel::DvbChannelTableModel(QObject *parent) : 0075 TableModel<DvbChannelTableModelHelper>(parent), channelModel(NULL), 0076 dndInsertBeforeNumber(-1), dndEventPosted(false) 0077 { 0078 } 0079 0080 DvbChannelTableModel::~DvbChannelTableModel() 0081 { 0082 } 0083 0084 void DvbChannelTableModel::setChannelModel(DvbChannelModel *channelModel_) 0085 { 0086 if (channelModel != NULL) { 0087 qCWarning(logDvb, "Channel model already set"); 0088 return; 0089 } 0090 0091 channelModel = channelModel_; 0092 connect(channelModel, SIGNAL(channelAdded(DvbSharedChannel)), 0093 this, SLOT(channelAdded(DvbSharedChannel))); 0094 connect(channelModel, SIGNAL(channelAboutToBeUpdated(DvbSharedChannel)), 0095 this, SLOT(channelAboutToBeUpdated(DvbSharedChannel))); 0096 connect(channelModel, SIGNAL(channelUpdated(DvbSharedChannel)), 0097 this, SLOT(channelUpdated(DvbSharedChannel))); 0098 connect(channelModel, SIGNAL(channelRemoved(DvbSharedChannel)), 0099 this, SLOT(channelRemoved(DvbSharedChannel))); 0100 reset(channelModel->getChannels()); 0101 } 0102 0103 QVariant DvbChannelTableModel::headerData(int section, Qt::Orientation orientation, int role) const 0104 { 0105 if ((orientation == Qt::Horizontal) && (role == Qt::DisplayRole)) { 0106 switch (section) { 0107 case 0: 0108 return i18nc("@title:column tv show", "Channel"); 0109 case 1: 0110 return i18nc("@title:column tv channel", "Number"); 0111 } 0112 } 0113 0114 return QVariant(); 0115 } 0116 0117 QVariant DvbChannelTableModel::data(const QModelIndex &index, int role) const 0118 { 0119 const DvbSharedChannel &channel = value(index); 0120 0121 if (channel.isValid()) { 0122 switch (role) { 0123 case Qt::DecorationRole: 0124 if (index.column() == 0) { 0125 if (channel->hasVideo) { 0126 if (!channel->isScrambled) { 0127 return QIcon::fromTheme(QLatin1String("video-television"), QIcon(":video-television")); 0128 } else { 0129 return QIcon::fromTheme(QLatin1String("video-television-encrypted"), QIcon(":video-television-encrypted")); 0130 } 0131 } else { 0132 if (!channel->isScrambled) { 0133 return QIcon::fromTheme(QLatin1String("text-speak"), QIcon(":text-speak")); 0134 } else { 0135 return QIcon::fromTheme(QLatin1String("audio-radio-encrypted"), QIcon(":audio-radio-encrypted")); 0136 } 0137 } 0138 } 0139 0140 break; 0141 case Qt::DisplayRole: 0142 switch (index.column()) { 0143 case 0: 0144 return channel->name; 0145 case 1: 0146 return channel->number; 0147 } 0148 0149 break; 0150 } 0151 } 0152 0153 return QVariant(); 0154 } 0155 0156 void DvbChannelTableModel::sort(int column, Qt::SortOrder order) 0157 { 0158 DvbChannelLessThan::SortOrder sortOrder; 0159 0160 if (order == Qt::AscendingOrder) { 0161 if (column == 0) { 0162 sortOrder = DvbChannelLessThan::ChannelNameAscending; 0163 } else { 0164 sortOrder = DvbChannelLessThan::ChannelNumberAscending; 0165 } 0166 } else { 0167 if (column == 0) { 0168 sortOrder = DvbChannelLessThan::ChannelNameDescending; 0169 } else { 0170 sortOrder = DvbChannelLessThan::ChannelNumberDescending; 0171 } 0172 } 0173 0174 internalSort(sortOrder); 0175 } 0176 0177 Qt::ItemFlags DvbChannelTableModel::flags(const QModelIndex &index) const 0178 { 0179 if (index.isValid()) { 0180 return (QAbstractTableModel::flags(index) | Qt::ItemIsDragEnabled); 0181 } else { 0182 return (QAbstractTableModel::flags(index) | Qt::ItemIsDropEnabled); 0183 } 0184 } 0185 0186 QMimeData *DvbChannelTableModel::mimeData(const QModelIndexList &indexes) const 0187 { 0188 QList<DvbSharedChannel> selectedChannels; 0189 0190 foreach (const QModelIndex &index, indexes) { 0191 if (index.column() == 0) { 0192 selectedChannels.append(value(index)); 0193 } 0194 } 0195 0196 QMimeData *mimeData = new QMimeData(); 0197 mimeData->setData(QLatin1String("application/x-org.kde.kaffeine-selectedchannels"), QByteArray()); 0198 // this way the list will be properly deleted once drag and drop ends 0199 mimeData->setProperty("SelectedChannels", QVariant::fromValue(selectedChannels)); 0200 return mimeData; 0201 } 0202 0203 QStringList DvbChannelTableModel::mimeTypes() const 0204 { 0205 return QStringList(QLatin1String("application/x-org.kde.kaffeine-selectedchannels")); 0206 } 0207 0208 Qt::DropActions DvbChannelTableModel::supportedDropActions() const 0209 { 0210 return Qt::MoveAction; 0211 } 0212 0213 bool DvbChannelTableModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, 0214 int column, const QModelIndex &parent) 0215 { 0216 Q_UNUSED(column) 0217 Q_UNUSED(parent) 0218 dndSelectedChannels.clear(); 0219 dndInsertBeforeNumber = -1; 0220 0221 if (action == Qt::MoveAction) { 0222 dndSelectedChannels = 0223 data->property("SelectedChannels").value<QList<DvbSharedChannel> >(); 0224 const DvbSharedChannel &dndInsertBeforeChannel = value(row); 0225 0226 if (dndInsertBeforeChannel.isValid()) { 0227 dndInsertBeforeNumber = dndInsertBeforeChannel->number; 0228 } 0229 0230 if (!dndSelectedChannels.isEmpty() && !dndEventPosted) { 0231 dndEventPosted = true; 0232 QCoreApplication::postEvent(this, new QEvent(QEvent::User)); 0233 } 0234 } 0235 0236 return false; 0237 } 0238 0239 void DvbChannelTableModel::setFilter(const QString &filter) 0240 { 0241 // Qt::CaseSensitive == no filtering 0242 helper.filter.setCaseSensitivity( 0243 filter.isEmpty() ? Qt::CaseSensitive : Qt::CaseInsensitive); 0244 helper.filter.setPattern(filter); 0245 reset(channelModel->getChannels()); 0246 } 0247 0248 void DvbChannelTableModel::channelAdded(const DvbSharedChannel &channel) 0249 { 0250 insert(channel); 0251 } 0252 0253 void DvbChannelTableModel::channelAboutToBeUpdated(const DvbSharedChannel &channel) 0254 { 0255 aboutToUpdate(channel); 0256 } 0257 0258 void DvbChannelTableModel::channelUpdated(const DvbSharedChannel &channel) 0259 { 0260 update(channel); 0261 } 0262 0263 void DvbChannelTableModel::channelRemoved(const DvbSharedChannel &channel) 0264 { 0265 remove(channel); 0266 } 0267 0268 void DvbChannelTableModel::customEvent(QEvent *event) 0269 { 0270 Q_UNUSED(event) 0271 bool ok = true; 0272 emit checkChannelDragAndDrop(&ok); 0273 0274 if (ok && !dndSelectedChannels.isEmpty()) { 0275 channelModel->dndMoveChannels(dndSelectedChannels, dndInsertBeforeNumber); 0276 } 0277 0278 dndSelectedChannels.clear(); 0279 dndEventPosted = false; 0280 } 0281 0282 DvbChannelView::DvbChannelView(QWidget *parent) : QTreeView(parent), tableModel(NULL) 0283 { 0284 } 0285 0286 DvbChannelView::~DvbChannelView() 0287 { 0288 } 0289 0290 QAction *DvbChannelView::addEditAction() 0291 { 0292 QAction *action = new QAction(QIcon::fromTheme(QLatin1String("configure"), QIcon(":configure")), i18nc("@action", "Edit"), this); 0293 connect(action, SIGNAL(triggered()), this, SLOT(editChannel())); 0294 addAction(action); 0295 return action; 0296 } 0297 0298 QAction *DvbChannelView::addRemoveAction() 0299 { 0300 QAction *action = new QAction(QIcon::fromTheme(QLatin1String("edit-delete"), QIcon(":edit-delete")), i18nc("@action", "Remove"), this); 0301 connect(action, SIGNAL(triggered()), this, SLOT(removeChannel())); 0302 addAction(action); 0303 return action; 0304 } 0305 0306 void DvbChannelView::setModel(DvbChannelTableModel *tableModel_) 0307 { 0308 tableModel = tableModel_; 0309 QTreeView::setModel(tableModel); 0310 } 0311 0312 void DvbChannelView::checkChannelDragAndDrop(bool *ok) 0313 { 0314 if ((*ok) && ((header()->sortIndicatorSection() != 1) || 0315 (header()->sortIndicatorOrder() != Qt::AscendingOrder))) { 0316 if (KMessageBox::warningContinueCancel(this, i18nc("@info", 0317 "The channels will be sorted by number to allow drag and drop.\n" 0318 "Do you want to continue?")) == KMessageBox::Continue) { 0319 sortByColumn(1, Qt::AscendingOrder); 0320 } else { 0321 *ok = false; 0322 } 0323 } 0324 } 0325 0326 void DvbChannelView::channelPidsChanged(const DvbSharedChannel &channel) 0327 { 0328 emit channelPidsUpdated(channel); 0329 } 0330 0331 void DvbChannelView::editChannel() 0332 { 0333 QModelIndex index = currentIndex(); 0334 0335 if (index.isValid()) { 0336 QDialog *dialog = new DvbChannelEditor(tableModel, tableModel->value(index), this); 0337 dialog->setAttribute(Qt::WA_DeleteOnClose, true); 0338 dialog->setModal(true); 0339 connect(dialog, SIGNAL(channelPidsChanged(DvbSharedChannel)), 0340 this, SLOT(channelPidsChanged(DvbSharedChannel))); 0341 dialog->show(); 0342 } 0343 } 0344 0345 void DvbChannelView::removeChannel() 0346 { 0347 QList<DvbSharedChannel> selectedChannels; 0348 0349 foreach (const QModelIndex &index, selectionModel()->selectedIndexes()) { 0350 if (index.column() == 0) { 0351 selectedChannels.append(tableModel->value(index)); 0352 } 0353 } 0354 0355 DvbChannelModel *channelModel = tableModel->getChannelModel(); 0356 0357 foreach (const DvbSharedChannel &channel, selectedChannels) { 0358 channelModel->removeChannel(channel); 0359 } 0360 } 0361 0362 void DvbChannelView::removeAllChannels() 0363 { 0364 DvbChannelModel *channelModel = tableModel->getChannelModel(); 0365 0366 foreach (const DvbSharedChannel &channel, channelModel->getChannels().values()) { 0367 channelModel->removeChannel(channel); 0368 } 0369 } 0370 0371 static QLatin1String enumToString(DvbTransponderBase::FecRate fecRate) 0372 { 0373 const char *text = ""; 0374 0375 switch (fecRate) { 0376 case DvbTransponderBase::FecNone: text = "NONE"; break; 0377 case DvbTransponderBase::Fec1_2: text = "1/2"; break; 0378 case DvbTransponderBase::Fec1_3: text = "1/3"; break; 0379 case DvbTransponderBase::Fec1_4: text = "1/4"; break; 0380 case DvbTransponderBase::Fec2_3: text = "2/3"; break; 0381 case DvbTransponderBase::Fec2_5: text = "2/5"; break; 0382 case DvbTransponderBase::Fec3_4: text = "3/4"; break; 0383 case DvbTransponderBase::Fec3_5: text = "3/5"; break; 0384 case DvbTransponderBase::Fec4_5: text = "4/5"; break; 0385 case DvbTransponderBase::Fec5_6: text = "5/6"; break; 0386 case DvbTransponderBase::Fec6_7: text = "6/7"; break; 0387 case DvbTransponderBase::Fec7_8: text = "7/8"; break; 0388 case DvbTransponderBase::Fec8_9: text = "8/9"; break; 0389 case DvbTransponderBase::Fec9_10: text = "9/10"; break; 0390 case DvbTransponderBase::FecAuto: text = "AUTO"; break; 0391 } 0392 0393 return QLatin1String(text); 0394 } 0395 0396 static QLatin1String enumToString(DvbCTransponder::Modulation modulation) 0397 { 0398 const char *text = ""; 0399 0400 switch (modulation) { 0401 case DvbCTransponder::Qam16: text = "16-QAM"; break; 0402 case DvbCTransponder::Qam32: text = "32-QAM"; break; 0403 case DvbCTransponder::Qam64: text = "64-QAM"; break; 0404 case DvbCTransponder::Qam128: text = "128-QAM"; break; 0405 case DvbCTransponder::Qam256: text = "256-QAM"; break; 0406 case DvbCTransponder::ModulationAuto: text = "AUTO"; break; 0407 } 0408 0409 return QLatin1String(text); 0410 } 0411 0412 static QString enumToString(DvbSTransponder::Polarization polarization) 0413 { 0414 switch (polarization) { 0415 case DvbSTransponder::Horizontal: return i18n("Horizontal"); 0416 case DvbSTransponder::Vertical: return i18n("Vertical"); 0417 case DvbSTransponder::CircularLeft: return i18n("Circular left"); 0418 case DvbSTransponder::CircularRight: return i18n("Circular right"); 0419 case DvbSTransponder::Off: return i18n("Off"); 0420 } 0421 0422 return QString(); 0423 } 0424 0425 static QLatin1String enumToString(DvbS2Transponder::Modulation modulation) 0426 { 0427 const char *text = ""; 0428 0429 switch (modulation) { 0430 case DvbS2Transponder::Qpsk: text = "QPSK"; break; 0431 case DvbS2Transponder::Psk8: text = "8-PSK"; break; 0432 case DvbS2Transponder::Apsk16: text = "16-APSK"; break; 0433 case DvbS2Transponder::Apsk32: text = "32-APSK"; break; 0434 case DvbS2Transponder::ModulationAuto: text = "AUTO"; break; 0435 } 0436 0437 return QLatin1String(text); 0438 } 0439 0440 static QLatin1String enumToString(DvbS2Transponder::RollOff rollOff) 0441 { 0442 const char *text = ""; 0443 0444 switch (rollOff) { 0445 case DvbS2Transponder::RollOff20: text = "0.20"; break; 0446 case DvbS2Transponder::RollOff25: text = "0.25"; break; 0447 case DvbS2Transponder::RollOff35: text = "0.35"; break; 0448 case DvbS2Transponder::RollOffAuto: text = "AUTO"; break; 0449 } 0450 0451 return QLatin1String(text); 0452 } 0453 0454 static QLatin1String enumToString(DvbTTransponder::Bandwidth bandwidth) 0455 { 0456 const char *text = ""; 0457 0458 switch (bandwidth) { 0459 case DvbTTransponder::Bandwidth5MHz: text = "5MHz"; break; 0460 case DvbTTransponder::Bandwidth6MHz: text = "6MHz"; break; 0461 case DvbTTransponder::Bandwidth7MHz: text = "7MHz"; break; 0462 case DvbTTransponder::Bandwidth8MHz: text = "8MHz"; break; 0463 case DvbTTransponder::BandwidthAuto: text = "AUTO"; break; 0464 } 0465 0466 return QLatin1String(text); 0467 } 0468 0469 static QLatin1String enumToString(DvbT2Transponder::Bandwidth bandwidth) 0470 { 0471 const char *text = ""; 0472 0473 switch (bandwidth) { 0474 case DvbT2Transponder::Bandwidth1_7MHz: text = "1.7MHz"; break; 0475 case DvbT2Transponder::Bandwidth5MHz: text = "5MHz"; break; 0476 case DvbT2Transponder::Bandwidth6MHz: text = "6MHz"; break; 0477 case DvbT2Transponder::Bandwidth7MHz: text = "7MHz"; break; 0478 case DvbT2Transponder::Bandwidth8MHz: text = "8MHz"; break; 0479 case DvbT2Transponder::Bandwidth10MHz: text = "10MHz"; break; 0480 case DvbT2Transponder::BandwidthAuto: text = "AUTO"; break; 0481 } 0482 0483 return QLatin1String(text); 0484 } 0485 static QLatin1String enumToString(DvbTTransponder::Modulation modulation) 0486 { 0487 const char *text = ""; 0488 0489 switch (modulation) { 0490 case DvbTTransponder::Qpsk: text = "QPSK"; break; 0491 case DvbTTransponder::Qam16: text = "16-QAM"; break; 0492 case DvbTTransponder::Qam64: text = "64-QAM"; break; 0493 case DvbTTransponder::ModulationAuto: text = "AUTO"; break; 0494 } 0495 0496 return QLatin1String(text); 0497 } 0498 0499 static QLatin1String enumToString(DvbT2Transponder::Modulation modulation) 0500 { 0501 const char *text = ""; 0502 0503 switch (modulation) { 0504 case DvbT2Transponder::Qpsk: text = "QPSK"; break; 0505 case DvbT2Transponder::Qam16: text = "16-QAM"; break; 0506 case DvbT2Transponder::Qam64: text = "64-QAM"; break; 0507 case DvbT2Transponder::Qam256: text = "256-QAM"; break; 0508 case DvbT2Transponder::ModulationAuto: text = "AUTO"; break; 0509 } 0510 0511 return QLatin1String(text); 0512 } 0513 0514 static QLatin1String enumToString(DvbTTransponder::TransmissionMode transmissionMode) 0515 { 0516 const char *text = ""; 0517 0518 switch (transmissionMode) { 0519 case DvbTTransponder::TransmissionMode2k: text = "2k"; break; 0520 case DvbTTransponder::TransmissionMode4k: text = "4k"; break; 0521 case DvbTTransponder::TransmissionMode8k: text = "8k"; break; 0522 case DvbTTransponder::TransmissionModeAuto: text = "AUTO"; break; 0523 } 0524 0525 return QLatin1String(text); 0526 } 0527 0528 static QLatin1String enumToString(DvbT2Transponder::TransmissionMode transmissionMode) 0529 { 0530 const char *text = ""; 0531 0532 switch (transmissionMode) { 0533 case DvbT2Transponder::TransmissionMode1k: text = "1k"; break; 0534 case DvbT2Transponder::TransmissionMode2k: text = "2k"; break; 0535 case DvbT2Transponder::TransmissionMode4k: text = "4k"; break; 0536 case DvbT2Transponder::TransmissionMode8k: text = "8k"; break; 0537 case DvbT2Transponder::TransmissionMode16k: text = "16k"; break; 0538 case DvbT2Transponder::TransmissionMode32k: text = "32k"; break; 0539 case DvbT2Transponder::TransmissionModeAuto: text = "AUTO"; break; 0540 } 0541 0542 return QLatin1String(text); 0543 } 0544 0545 static QLatin1String enumToString(IsdbTTransponder::TransmissionMode transmissionMode) 0546 { 0547 const char *text = ""; 0548 0549 switch (transmissionMode) { 0550 case IsdbTTransponder::TransmissionMode2k: text = "2k"; break; 0551 case IsdbTTransponder::TransmissionMode4k: text = "4k"; break; 0552 case IsdbTTransponder::TransmissionMode8k: text = "8k"; break; 0553 case IsdbTTransponder::TransmissionModeAuto: text = "AUTO"; break; 0554 } 0555 0556 return QLatin1String(text); 0557 } 0558 0559 static QLatin1String enumToString(DvbTTransponder::GuardInterval guardInterval) 0560 { 0561 const char *text = ""; 0562 0563 switch (guardInterval) { 0564 case DvbTTransponder::GuardInterval1_4: text = "1/4"; break; 0565 case DvbTTransponder::GuardInterval1_8: text = "1/8"; break; 0566 case DvbTTransponder::GuardInterval1_16: text = "1/16"; break; 0567 case DvbTTransponder::GuardInterval1_32: text = "1/32"; break; 0568 case DvbTTransponder::GuardIntervalAuto: text = "AUTO"; break; 0569 } 0570 0571 return QLatin1String(text); 0572 } 0573 0574 static QLatin1String enumToString(DvbT2Transponder::GuardInterval guardInterval) 0575 { 0576 const char *text = ""; 0577 0578 switch (guardInterval) { 0579 case DvbT2Transponder::GuardInterval1_4: text = "1/4"; break; 0580 case DvbT2Transponder::GuardInterval19_128: text = "19/128"; break; 0581 case DvbT2Transponder::GuardInterval1_8: text = "1/8"; break; 0582 case DvbT2Transponder::GuardInterval19_256: text = "19/256"; break; 0583 case DvbT2Transponder::GuardInterval1_16: text = "1/16"; break; 0584 case DvbT2Transponder::GuardInterval1_32: text = "1/32"; break; 0585 case DvbT2Transponder::GuardInterval1_128: text = "1/128"; break; 0586 case DvbT2Transponder::GuardIntervalAuto: text = "AUTO"; break; 0587 } 0588 0589 return QLatin1String(text); 0590 } 0591 0592 static QLatin1String enumToString(DvbTTransponder::Hierarchy hierarchy) 0593 { 0594 const char *text = ""; 0595 0596 switch (hierarchy) { 0597 case DvbTTransponder::HierarchyNone: text = "NONE"; break; 0598 case DvbTTransponder::Hierarchy1: text = "1"; break; 0599 case DvbTTransponder::Hierarchy2: text = "2"; break; 0600 case DvbTTransponder::Hierarchy4: text = "4"; break; 0601 case DvbTTransponder::HierarchyAuto: text = "AUTO"; break; 0602 } 0603 0604 return QLatin1String(text); 0605 } 0606 0607 static QLatin1String enumToString(DvbT2Transponder::Hierarchy hierarchy) 0608 { 0609 const char *text = ""; 0610 0611 switch (hierarchy) { 0612 case DvbT2Transponder::HierarchyNone: text = "NONE"; break; 0613 case DvbT2Transponder::Hierarchy1: text = "1"; break; 0614 case DvbT2Transponder::Hierarchy2: text = "2"; break; 0615 case DvbT2Transponder::Hierarchy4: text = "4"; break; 0616 case DvbT2Transponder::HierarchyAuto: text = "AUTO"; break; 0617 } 0618 0619 return QLatin1String(text); 0620 } 0621 0622 static QLatin1String enumToString(AtscTransponder::Modulation modulation) 0623 { 0624 const char *text = ""; 0625 0626 switch (modulation) { 0627 case AtscTransponder::Qam64: text = "64-QAM"; break; 0628 case AtscTransponder::Qam256: text = "256-QAM"; break; 0629 case AtscTransponder::Vsb8: text = "8-VSB"; break; 0630 case AtscTransponder::Vsb16: text = "16-VSB"; break; 0631 case AtscTransponder::ModulationAuto: text = "AUTO"; break; 0632 } 0633 0634 return QLatin1String(text); 0635 } 0636 0637 static QLatin1String enumToString(IsdbTTransponder::Bandwidth bandwidth) 0638 { 0639 const char *text = ""; 0640 0641 switch (bandwidth) { 0642 case IsdbTTransponder::Bandwidth6MHz: text = "6MHz"; break; 0643 case IsdbTTransponder::Bandwidth7MHz: text = "7MHz"; break; 0644 case IsdbTTransponder::Bandwidth8MHz: text = "8MHz"; break; 0645 } 0646 0647 return QLatin1String(text); 0648 } 0649 0650 static QLatin1String enumToString(IsdbTTransponder::Modulation modulation) 0651 { 0652 const char *text = ""; 0653 0654 switch (modulation) { 0655 case IsdbTTransponder::Dqpsk: text = "DQPSK"; break; 0656 case IsdbTTransponder::Qpsk: text = "QPSK"; break; 0657 case IsdbTTransponder::Qam16: text = "16-QAM"; break; 0658 case IsdbTTransponder::Qam64: text = "64-QAM"; break; 0659 case IsdbTTransponder::ModulationAuto: text = "AUTO"; break; 0660 } 0661 0662 return QLatin1String(text); 0663 } 0664 0665 static QLatin1String enumToString(IsdbTTransponder::GuardInterval guardInterval) 0666 { 0667 const char *text = ""; 0668 0669 switch (guardInterval) { 0670 case IsdbTTransponder::GuardInterval1_4: text = "1/4"; break; 0671 case IsdbTTransponder::GuardInterval1_8: text = "1/8"; break; 0672 case IsdbTTransponder::GuardInterval1_16: text = "1/16"; break; 0673 case IsdbTTransponder::GuardInterval1_32: text = "1/32"; break; 0674 case IsdbTTransponder::GuardIntervalAuto: text = "AUTO"; break; 0675 } 0676 0677 return QLatin1String(text); 0678 } 0679 0680 static QLatin1String enumToString(IsdbTTransponder::PartialReception partialReception) 0681 { 0682 const char *text = ""; 0683 0684 switch (partialReception) { 0685 case IsdbTTransponder::PR_disabled: text = "No"; break; 0686 case IsdbTTransponder::PR_enabled: text = "Yes"; break; 0687 case IsdbTTransponder::PR_AUTO: text = "AUTO"; break; 0688 } 0689 0690 return QLatin1String(text); 0691 } 0692 0693 static QLatin1String enumToString(IsdbTTransponder::SoundBroadcasting soundBroadcasting) 0694 { 0695 const char *text = ""; 0696 0697 switch (soundBroadcasting) { 0698 case IsdbTTransponder::SB_disabled: text = "No"; break; 0699 case IsdbTTransponder::SB_enabled: text = "Yes"; break; 0700 case IsdbTTransponder::SB_AUTO: text = "AUTO"; break; 0701 } 0702 0703 return QLatin1String(text); 0704 } 0705 0706 DvbChannelEditor::DvbChannelEditor(DvbChannelTableModel *model_, const DvbSharedChannel &channel_, 0707 QWidget *parent) : QDialog(parent), model(model_), channel(channel_) 0708 { 0709 setWindowTitle(i18nc("@title:window", "Edit Channel")); 0710 0711 QWidget *widget = new QWidget(this); 0712 QBoxLayout *mainLayout = new QVBoxLayout(widget); 0713 QGridLayout *gridLayout = new QGridLayout(); 0714 0715 audioStreamBox = NULL; 0716 0717 nameEdit = new QLineEdit(widget); 0718 nameEdit->setText(channel->name); 0719 gridLayout->addWidget(nameEdit, 0, 1); 0720 0721 QLabel *label = new QLabel(i18nc("@label tv channel", "Name:"), widget); 0722 label->setBuddy(nameEdit); 0723 gridLayout->addWidget(label, 0, 0); 0724 0725 numberBox = new QSpinBox(widget); 0726 numberBox->setRange(1, 99999); 0727 numberBox->setValue(channel->number); 0728 gridLayout->addWidget(numberBox, 0, 3); 0729 0730 label = new QLabel(i18nc("@label tv channel", "Number:"), widget); 0731 label->setBuddy(numberBox); 0732 gridLayout->addWidget(label, 0, 2); 0733 mainLayout->addLayout(gridLayout); 0734 0735 QBoxLayout *boxLayout = new QHBoxLayout(); 0736 0737 QGroupBox *groupBox = new QGroupBox(widget); 0738 gridLayout = new QGridLayout(groupBox); 0739 gridLayout->addWidget(new QLabel(i18nc("@label tv channel", "Source:")), 0, 0); 0740 gridLayout->addWidget(new QLabel(channel->source), 0, 1); 0741 0742 int row = 11; 0743 0744 switch (channel->transponder.getTransmissionType()) { 0745 case DvbTransponderBase::Invalid: 0746 break; 0747 case DvbTransponderBase::DvbC: { 0748 const DvbCTransponder *tp = channel->transponder.as<DvbCTransponder>(); 0749 gridLayout->addWidget(new QLabel(i18n("Frequency (MHz):")), 1, 0); 0750 gridLayout->addWidget( 0751 new QLabel(QString::number(tp->frequency / 1000000.0)), 1, 1); 0752 gridLayout->addWidget(new QLabel(i18n("Symbol rate (kS/s):")), 2, 0); 0753 gridLayout->addWidget(new QLabel(QString::number(tp->symbolRate / 1000.0)), 2, 1); 0754 gridLayout->addWidget(new QLabel(i18n("Modulation:")), 3, 0); 0755 gridLayout->addWidget(new QLabel(enumToString(tp->modulation)), 3, 1); 0756 gridLayout->addWidget(new QLabel(i18n("FEC rate:")), 4, 0); 0757 gridLayout->addWidget(new QLabel(enumToString(tp->fecRate)), 4, 1); 0758 break; 0759 } 0760 case DvbTransponderBase::DvbS: 0761 case DvbTransponderBase::DvbS2: { 0762 const DvbS2Transponder *tp2 = channel->transponder.as<DvbS2Transponder>(); 0763 const DvbSTransponder *tp = channel->transponder.as<DvbSTransponder>(); 0764 0765 if (tp == NULL) { 0766 tp = tp2; 0767 } 0768 0769 gridLayout->addWidget(new QLabel(i18n("Polarization:")), 1, 0); 0770 gridLayout->addWidget(new QLabel(enumToString(tp->polarization)), 1, 1); 0771 gridLayout->addWidget(new QLabel(i18n("Frequency (MHz):")), 2, 0); 0772 gridLayout->addWidget(new QLabel(QString::number(tp->frequency / 1000.0)), 2, 1); 0773 gridLayout->addWidget(new QLabel(i18n("Symbol rate (kS/s):")), 3, 0); 0774 gridLayout->addWidget(new QLabel(QString::number(tp->symbolRate / 1000.0)), 3, 1); 0775 gridLayout->addWidget(new QLabel(i18n("FEC rate:")), 4, 0); 0776 gridLayout->addWidget(new QLabel(enumToString(tp->fecRate)), 4, 1); 0777 0778 if (tp2 != NULL) { 0779 gridLayout->addWidget(new QLabel(i18n("Modulation:")), 5, 0); 0780 gridLayout->addWidget(new QLabel(enumToString(tp2->modulation)), 5, 1); 0781 gridLayout->addWidget(new QLabel(i18n("Roll-off:")), 6, 0); 0782 gridLayout->addWidget(new QLabel(enumToString(tp2->rollOff)), 6, 1); 0783 } 0784 0785 break; 0786 } 0787 case DvbTransponderBase::DvbT: { 0788 const DvbTTransponder *tp = channel->transponder.as<DvbTTransponder>(); 0789 gridLayout->addWidget(new QLabel(i18n("Frequency (MHz):")), 1, 0); 0790 gridLayout->addWidget( 0791 new QLabel(QString::number(tp->frequency / 1000000.0)), 1, 1); 0792 gridLayout->addWidget(new QLabel(i18n("Bandwidth:")), 2, 0); 0793 gridLayout->addWidget(new QLabel(enumToString(tp->bandwidth)), 2, 1); 0794 gridLayout->addWidget(new QLabel(i18n("Modulation:")), 3, 0); 0795 gridLayout->addWidget(new QLabel(enumToString(tp->modulation)), 3, 1); 0796 gridLayout->addWidget(new QLabel(i18n("FEC rate:")), 4, 0); 0797 gridLayout->addWidget(new QLabel(enumToString(tp->fecRateHigh)), 4, 1); 0798 gridLayout->addWidget(new QLabel(i18n("FEC rate LP:")), 5, 0); 0799 gridLayout->addWidget(new QLabel(enumToString(tp->fecRateLow)), 5, 1); 0800 gridLayout->addWidget(new QLabel(i18n("Transmission mode:")), 6, 0); 0801 gridLayout->addWidget(new QLabel(enumToString(tp->transmissionMode)), 6, 1); 0802 gridLayout->addWidget(new QLabel(i18n("Guard interval:")), 7, 0); 0803 gridLayout->addWidget(new QLabel(enumToString(tp->guardInterval)), 7, 1); 0804 gridLayout->addWidget(new QLabel(i18n("Hierarchy:")), 8, 0); 0805 gridLayout->addWidget(new QLabel(enumToString(tp->hierarchy)), 8, 1); 0806 break; 0807 } 0808 case DvbTransponderBase::DvbT2: { 0809 const DvbT2Transponder *tp = channel->transponder.as<DvbT2Transponder>(); 0810 gridLayout->addWidget(new QLabel(i18n("Frequency (MHz):")), 1, 0); 0811 gridLayout->addWidget( 0812 new QLabel(QString::number(tp->frequency / 1000000.0)), 1, 1); 0813 gridLayout->addWidget(new QLabel(i18n("Bandwidth:")), 2, 0); 0814 gridLayout->addWidget(new QLabel(enumToString(tp->bandwidth)), 2, 1); 0815 gridLayout->addWidget(new QLabel(i18n("Modulation:")), 3, 0); 0816 gridLayout->addWidget(new QLabel(enumToString(tp->modulation)), 3, 1); 0817 gridLayout->addWidget(new QLabel(i18n("FEC rate:")), 4, 0); 0818 gridLayout->addWidget(new QLabel(enumToString(tp->fecRateHigh)), 4, 1); 0819 gridLayout->addWidget(new QLabel(i18n("FEC rate LP:")), 5, 0); 0820 gridLayout->addWidget(new QLabel(enumToString(tp->fecRateLow)), 5, 1); 0821 gridLayout->addWidget(new QLabel(i18n("Transmission mode:")), 6, 0); 0822 gridLayout->addWidget(new QLabel(enumToString(tp->transmissionMode)), 6, 1); 0823 gridLayout->addWidget(new QLabel(i18n("Guard interval:")), 7, 0); 0824 gridLayout->addWidget(new QLabel(enumToString(tp->guardInterval)), 7, 1); 0825 gridLayout->addWidget(new QLabel(i18n("Hierarchy:")), 8, 0); 0826 gridLayout->addWidget(new QLabel(enumToString(tp->hierarchy)), 8, 1); 0827 gridLayout->addWidget(new QLabel(i18n("PLP (stream ID):")), 9, 0); 0828 gridLayout->addWidget( 0829 new QLabel(QString::number(tp->streamId)), 9, 1); 0830 break; 0831 } 0832 case DvbTransponderBase::IsdbT: { 0833 const IsdbTTransponder *tp = channel->transponder.as<IsdbTTransponder>(); 0834 row= 1; 0835 gridLayout->addWidget(new QLabel(i18n("Frequency (MHz):")), row, 0); 0836 gridLayout->addWidget( 0837 new QLabel(QString::number(tp->frequency / 1000000.0)), row++, 1); 0838 gridLayout->addWidget(new QLabel(i18n("Bandwidth:")), row, 0); 0839 gridLayout->addWidget(new QLabel(enumToString(tp->bandwidth)), row++, 1); 0840 gridLayout->addWidget(new QLabel(i18n("Transmission mode:")), row, 0); 0841 gridLayout->addWidget(new QLabel(enumToString(tp->transmissionMode)), row++, 1); 0842 gridLayout->addWidget(new QLabel(i18n("Guard interval:")), row, 0); 0843 gridLayout->addWidget(new QLabel(enumToString(tp->guardInterval)), row++, 1); 0844 0845 gridLayout->addWidget(new QLabel(i18n("Partial reception:")), row, 0); 0846 gridLayout->addWidget(new QLabel(enumToString(tp->partialReception)), row++, 1); 0847 gridLayout->addWidget(new QLabel(i18n("Sound broadcasting:")), row, 0); 0848 gridLayout->addWidget(new QLabel(enumToString(tp->soundBroadcasting)), row++, 1); 0849 0850 if (tp->soundBroadcasting == 1) { 0851 gridLayout->addWidget(new QLabel(i18n("SB channel ID:")), row, 0); 0852 gridLayout->addWidget(new QLabel(QString::number(tp->subChannelId)), row++, 1); 0853 gridLayout->addWidget(new QLabel(i18n("SB index:")), row, 0); 0854 gridLayout->addWidget(new QLabel(QString::number(tp->subChannelId)), row++, 1); 0855 gridLayout->addWidget(new QLabel(i18n("SB count:")), row, 0); 0856 gridLayout->addWidget(new QLabel(QString::number(tp->sbSegmentCount)), row++, 1); 0857 } 0858 0859 if (tp->layerEnabled[0]) { 0860 gridLayout->addWidget(new QLabel(i18n("Layer A Modulation:")), row, 0); 0861 gridLayout->addWidget(new QLabel(enumToString(tp->modulation[0])), row++, 1); 0862 gridLayout->addWidget(new QLabel(i18n("Layer A FEC rate:")), row, 0); 0863 gridLayout->addWidget(new QLabel(enumToString(tp->fecRate[0])), row++, 1); 0864 gridLayout->addWidget(new QLabel(i18n("Layer A segments:")), row, 0); 0865 gridLayout->addWidget(new QLabel(QString::number(tp->segmentCount[0])), row++, 1); 0866 gridLayout->addWidget(new QLabel(i18n("Layer A interleaving:")), row, 0); 0867 gridLayout->addWidget(new QLabel(QString::number(tp->interleaving[0])), row++, 1); 0868 } 0869 if (tp->layerEnabled[1]) { 0870 gridLayout->addWidget(new QLabel(i18n("Layer B Modulation:")), row, 0); 0871 gridLayout->addWidget(new QLabel(enumToString(tp->modulation[1])), row++, 1); 0872 gridLayout->addWidget(new QLabel(i18n("Layer B FEC rate:")), row, 0); 0873 gridLayout->addWidget(new QLabel(enumToString(tp->fecRate[1])), row++, 1); 0874 gridLayout->addWidget(new QLabel(i18n("Layer B segments:")), row, 0); 0875 gridLayout->addWidget(new QLabel(QString::number(tp->segmentCount[1])), row++, 1); 0876 gridLayout->addWidget(new QLabel(i18n("Layer B interleaving:")), row, 0); 0877 gridLayout->addWidget(new QLabel(QString::number(tp->interleaving[1])), row++, 1); 0878 } 0879 if (tp->layerEnabled[2]) { 0880 gridLayout->addWidget(new QLabel(i18n("Layer C Modulation:")), row, 0); 0881 gridLayout->addWidget(new QLabel(enumToString(tp->modulation[2])), row++, 1); 0882 gridLayout->addWidget(new QLabel(i18n("Layer C FEC rate:")), row, 0); 0883 gridLayout->addWidget(new QLabel(enumToString(tp->fecRate[2])), row++, 1); 0884 gridLayout->addWidget(new QLabel(i18n("Layer C segments:")), row, 0); 0885 gridLayout->addWidget(new QLabel(QString::number(tp->segmentCount[2])), row++, 1); 0886 gridLayout->addWidget(new QLabel(i18n("Layer C interleaving:")), row, 0); 0887 gridLayout->addWidget(new QLabel(QString::number(tp->interleaving[2])), row++, 1); 0888 } 0889 0890 break; 0891 } 0892 case DvbTransponderBase::Atsc: { 0893 const AtscTransponder *tp = channel->transponder.as<AtscTransponder>(); 0894 gridLayout->addWidget(new QLabel(i18n("Frequency (MHz):")), 1, 0); 0895 gridLayout->addWidget( 0896 new QLabel(QString::number(tp->frequency / 1000000.0)), 1, 1); 0897 gridLayout->addWidget(new QLabel(i18n("Modulation:")), 2, 0); 0898 gridLayout->addWidget(new QLabel(enumToString(tp->modulation)), 2, 1); 0899 break; 0900 } 0901 } 0902 0903 gridLayout->addWidget(new QLabel(), 10, 0, 1, 2); 0904 0905 gridLayout->addItem(new QSpacerItem(0, 0), row, 0, 1, 2); 0906 gridLayout->setRowStretch(row, 1); 0907 boxLayout->addWidget(groupBox); 0908 0909 groupBox = new QGroupBox(widget); 0910 gridLayout = new QGridLayout(groupBox); 0911 gridLayout->addWidget(new QLabel(i18n("Network ID:")), 0, 0); 0912 0913 row = 1; 0914 0915 networkIdBox = new QSpinBox(groupBox); 0916 networkIdBox->setRange(-1, (1 << 16) - 1); 0917 networkIdBox->setValue(channel->networkId); 0918 gridLayout->addWidget(networkIdBox, 0, 1); 0919 0920 gridLayout->addWidget(new QLabel(i18n("Transport stream ID:")), row, 0); 0921 0922 transportStreamIdBox = new QSpinBox(groupBox); 0923 transportStreamIdBox->setRange(0, (1 << 16) - 1); 0924 transportStreamIdBox->setValue(channel->transportStreamId); 0925 gridLayout->addWidget(transportStreamIdBox, row++, 1); 0926 0927 gridLayout->addWidget(new QLabel(i18n("Service ID:")), row, 0); 0928 0929 serviceIdBox = new QSpinBox(groupBox); 0930 serviceIdBox->setRange(0, (1 << 16) - 1); 0931 serviceIdBox->setValue(channel->serviceId); 0932 gridLayout->addWidget(serviceIdBox, row++, 1); 0933 0934 DvbPmtSection pmtSection(channel->pmtSectionData); 0935 DvbPmtParser pmtParser(pmtSection); 0936 0937 gridLayout->addWidget(new QLabel(i18n("Audio channel:")), row, 0); 0938 if (pmtParser.audioPids.count() > 1) { 0939 audioStreamBox = new QComboBox(groupBox); 0940 0941 for (int i = 0; i < pmtParser.audioPids.size(); ++i) { 0942 const QPair<int, QString> &it = pmtParser.audioPids.at(i); 0943 QString text = QString::number(it.first); 0944 0945 if (!it.second.isEmpty()) { 0946 QString languageString; 0947 0948 if (!IsoCodes::getLanguage(it.second, &languageString)) 0949 languageString = it.second; 0950 0951 text = text + QLatin1String(" (") + languageString + QLatin1Char(')'); 0952 } 0953 0954 audioStreamBox->addItem(text); 0955 audioPids.append(it.first); 0956 } 0957 audioStreamBox->setCurrentIndex(audioPids.indexOf(channel->audioPid)); 0958 gridLayout->addWidget(audioStreamBox, row++, 1); 0959 } else { 0960 const QPair<int, QString> &it = pmtParser.audioPids.at(0); 0961 QString text = QString::number(it.first); 0962 0963 if (!it.second.isEmpty()) { 0964 QString languageString; 0965 0966 if (!IsoCodes::getLanguage(it.second, &languageString)) 0967 languageString = it.second; 0968 0969 text = text + QLatin1String(" (") + languageString + QLatin1Char(')'); 0970 } 0971 gridLayout->addWidget(new QLabel(text), row++, 1); 0972 } 0973 0974 gridLayout->addWidget(new QLabel(i18n("Scrambled:")), row, 0); 0975 scrambledBox = new QCheckBox(groupBox); 0976 scrambledBox->setChecked(channel->isScrambled); 0977 gridLayout->addWidget(scrambledBox, row++, 1); 0978 0979 row++; 0980 0981 gridLayout->addWidget(new QLabel(i18n("PMT PID:")), row, 0); 0982 gridLayout->addWidget(new QLabel(QString::number(channel->pmtPid)), row++, 1); 0983 0984 if (pmtParser.videoPid >= 0) { 0985 gridLayout->addWidget(new QLabel(i18n("Video PID:")), row, 0); 0986 gridLayout->addWidget(new QLabel(QString::number(pmtParser.videoPid)), row++, 1); 0987 } 0988 0989 if (!pmtParser.subtitlePids.isEmpty()) { 0990 gridLayout->addWidget(new QLabel(i18n("Subtitle PID:")), row, 0); 0991 } 0992 0993 for (int i = 0; i < pmtParser.subtitlePids.size(); ++i) { 0994 const QPair<int, QString> &it = pmtParser.subtitlePids.at(i); 0995 QString languageString; 0996 0997 if (!IsoCodes::getLanguage(it.second, &languageString)) 0998 languageString = it.second; 0999 1000 1001 gridLayout->addWidget(new QLabel(QString(QLatin1String("%1 (%2)")).arg(it.first).arg(languageString)), 1002 row++, 1); 1003 } 1004 1005 if (pmtParser.teletextPid != -1) { 1006 gridLayout->addWidget(new QLabel(i18n("Teletext PID:")), row, 0); 1007 gridLayout->addWidget( 1008 new QLabel(QString::number(pmtParser.teletextPid)), row++, 1); 1009 } 1010 1011 gridLayout->addItem(new QSpacerItem(0, 0), 5, 0, 1, 2); 1012 gridLayout->setRowStretch(5, 1); 1013 boxLayout->addWidget(groupBox); 1014 mainLayout->addLayout(boxLayout); 1015 1016 mainLayout = new QVBoxLayout; 1017 setLayout(mainLayout); 1018 mainLayout->addWidget(widget); 1019 1020 QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); 1021 connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); 1022 connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); 1023 mainLayout->addWidget(buttonBox); 1024 1025 } 1026 1027 DvbChannelEditor::~DvbChannelEditor() 1028 { 1029 } 1030 1031 void DvbChannelEditor::accept() 1032 { 1033 DvbChannel updatedChannel = *channel; 1034 int oldAudioPid = channel->audioPid; 1035 1036 updatedChannel.name = nameEdit->text(); 1037 updatedChannel.number = numberBox->value(); 1038 updatedChannel.networkId = networkIdBox->value(); 1039 updatedChannel.transportStreamId = transportStreamIdBox->value(); 1040 updatedChannel.serviceId = serviceIdBox->value(); 1041 1042 if (audioStreamBox && audioStreamBox->currentIndex() != -1) { 1043 updatedChannel.audioPid = audioPids.at(audioStreamBox->currentIndex()); 1044 } 1045 1046 updatedChannel.isScrambled = scrambledBox->isChecked(); 1047 model->getChannelModel()->updateChannel(channel, updatedChannel); 1048 1049 /* 1050 * If a channel is being played, a change at a PID should 1051 * be reflected at the played channel. 1052 * 1053 * TODO: add support for videos with multiple PIDs 1054 */ 1055 if (updatedChannel.audioPid != oldAudioPid) 1056 emit channelPidsChanged(channel); 1057 1058 QDialog::accept(); 1059 } 1060 1061 #include "moc_dvbchanneldialog_p.cpp" 1062 #include "moc_dvbchanneldialog.cpp"