00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "stationlistmodel.h"
00022 #include "settings_general.h"
00023 #include <QFile>
00024 #include <KProgressDialog>
00025 #include <KLocale>
00026 #define AND &&
00027 #define OR ||
00028 #define NOT !
00029 #define EQUAL ==
00030
00031 stationlistModel::stationlistModel(const QPointer<QObject> parent,
00032 const QPointer<QWidget> mainWidget)
00033 : QAbstractTableModel(parent)
00034 {
00035
00036
00037
00038 QStringList m_stringList;
00039 int i;
00040
00041
00042 m_mainWidget = mainWidget;
00043
00044
00045 m_stringList = settings_general::streamConfigFiles();
00046 for (i = 0; i < m_stringList.size(); ++i) {
00047 m_stationlist.append(new radioStation(this, m_mainWidget, m_stringList.at(i), i));
00048 helper_connectSignalsAndSlots(m_stationlist.last());
00049 };
00050 helper_writeStationListToGeneralSettings();
00051
00052
00053
00054
00055 recalculate_numberOfActiveStreams_and_bandwidth();
00056 m_listOfStreamsOfWhichTheUserWantsThatTheyRip = 0;
00057 }
00058
00059 stationlistModel::~stationlistModel()
00060 {
00061 delete m_listOfStreamsOfWhichTheUserWantsThatTheyRip;
00062 }
00063
00064 void stationlistModel::helper_connectSignalsAndSlots(QPointer<radioStation> m_stream)
00065 {
00066 connect(m_stream, SIGNAL(streamNameChanged(qlonglong, PropertyValue)),
00067 this, SLOT(reloadStreamName(qlonglong)));
00068 connect(m_stream, SIGNAL(statusChanged(qlonglong, PropertyValue)),
00069 this, SLOT(reloadStatus(qlonglong)));
00070 connect(m_stream, SIGNAL(errorChanged(qlonglong, PropertyValue)),
00071 this, SLOT(reloadStatus(qlonglong)));
00072 connect(m_stream, SIGNAL(songChanged(qlonglong, PropertyValue)),
00073 this, SLOT(reloadSong(qlonglong)));
00074 connect(m_stream, SIGNAL(dataSizeChanged(qlonglong, PropertyValue)),
00075 this, SLOT(reloadDataSize(qlonglong)));
00076 connect(m_stream, SIGNAL(bitrateChanged(qlonglong, PropertyValue)),
00077 this, SLOT(reloadBitrate(qlonglong)));
00078 connect(m_stream, SIGNAL(bitrateChanged(qlonglong, PropertyValue)),
00079 this, SLOT(recalculate_numberOfActiveStreams_and_bandwidth()));
00080 connect(m_stream, SIGNAL(metaIntervalChanged(qlonglong, PropertyValue)),
00081 this, SLOT(reloadMetaInterval(qlonglong)));
00082 connect(m_stream, SIGNAL(serverNameChanged(qlonglong, PropertyValue)),
00083 this, SLOT(reloadServerName(qlonglong)));
00084 connect(m_stream, SIGNAL(relayPortChanged(qlonglong, PropertyValue)),
00085 this, SLOT(reloadRelayPort(qlonglong)));
00086 connect(m_stream, SIGNAL(running()),
00087 this, SLOT(recalculate_numberOfActiveStreams_and_bandwidth()));
00088 connect(m_stream, SIGNAL(not_running()),
00089 this, SLOT(recalculate_numberOfActiveStreams_and_bandwidth()));
00090 }
00091
00092 int stationlistModel::rowCount (const QModelIndex & parent) const
00093 {
00094 return m_stationlist.size();
00095 }
00096
00097 int stationlistModel::columnCount (const QModelIndex & parent) const
00098 {
00099 return 8;
00100 }
00101
00102 QVariant stationlistModel::columnInfo(const columnInfoType type,
00103 const int column,
00104 const qint64 row,
00105 const quint64 value) const
00106 {
00107 switch (type) {
00108 case columnHeaderTitle:
00109 case columnHeaderToolTip:
00110 case columnHeaderWhatsThis:
00111 case columnWidth:
00112 case setColumnWidth:
00113 case columnVisibility:
00114 case setColumnVisibility:
00115 break;
00116 default:
00117 if ((row >= rowCount()) OR (row < 0)) {
00118 return QVariant();
00119 };
00120 }
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136 switch (column) {
00137
00138 case 0:
00139 {
00140 switch (type) {
00141 case columnHeaderTitle:
00142 return i18nc("@title:column", "stream name");
00143 case columnHeaderToolTip:
00144 case columnHeaderWhatsThis:
00145 return QVariant();
00146 case columnWidth:
00147 return settings_general::columnWidth_streamName();
00148 case setColumnWidth:
00149 settings_general::setColumnWidth_streamName(value);
00150 settings_general::self()->writeConfig();
00151 return QVariant();
00152 case columnVisibility:
00153 return settings_general::columnVisibility_streamName();
00154 case setColumnVisibility:
00155 settings_general::setColumnVisibility_streamName(value);
00156 settings_general::self()->writeConfig();
00157 return QVariant();
00158 case columnData:
00159 return m_stationlist.at(row)->streamName().formatedValue;
00160 case columnDataToolTip:
00161 return m_stationlist.at(row)->streamName().toolTip;
00162 case columnDataWhatsThis:
00163 return m_stationlist.at(row)->streamName().whatsThis;
00164 };
00165 break;
00166 }
00167
00168 case 1:
00169 {
00170 switch (type) {
00171 case columnHeaderTitle:
00172 return i18nc("@title:column", "status");
00173 case columnHeaderToolTip:
00174 case columnHeaderWhatsThis:
00175 return QVariant();
00176 case columnWidth:
00177 return settings_general::columnWidth_statusAndError();
00178 case setColumnWidth:
00179 settings_general::setColumnWidth_statusAndError(value);
00180 settings_general::self()->writeConfig();
00181 return QVariant();
00182 case columnVisibility:
00183 return settings_general::columnVisibility_statusAndError();
00184 case setColumnVisibility:
00185 settings_general::setColumnVisibility_statusAndError(value);
00186 settings_general::self()->writeConfig();
00187 return QVariant();
00188 case columnData:
00189 if (m_stationlist.at(row)->status().formatedValue.isEmpty()) {
00190 return m_stationlist.at(row)->error().formatedValue;
00191 }
00192 else if (m_stationlist.at(row)->error().formatedValue.isEmpty()) {
00193 return m_stationlist.at(row)->status().formatedValue;
00194 } else {
00195 return QString(i18nc("@item:intable This produces the status message from the "
00196 "actual status (%1) and the error message (%3). "
00197 "Both of them are guaranteed to "
00198 "be not empty. %2 is replayed by an en-dash (Unicode "
00199 "U+2013). Use it or replace it by something what looks "
00200 "nicer in your language.",
00201 "%1 %2 %3",
00202 m_stationlist.at(row)->status().formatedValue,
00203 QString(QChar(0x2013)),
00204 m_stationlist.at(row)->error().formatedValue));
00205 };
00206 case columnDataToolTip:
00207 case columnDataWhatsThis:
00208 return QVariant();
00209 };
00210 break;
00211 }
00212
00213 case 2:
00214 {
00215 switch (type) {
00216 case columnHeaderTitle:
00217 return i18nc("@title:column header of the column with the name of the actual track",
00218 "track");
00219 case columnHeaderToolTip:
00220 case columnHeaderWhatsThis:
00221 return QVariant();
00222 case columnWidth:
00223 return settings_general::columnWidth_song();
00224 case setColumnWidth:
00225 settings_general::setColumnWidth_song(value);
00226 settings_general::self()->writeConfig();
00227 return QVariant();
00228 case columnVisibility:
00229 return settings_general::columnVisibility_song();
00230 case setColumnVisibility:
00231 settings_general::setColumnVisibility_song(value);
00232 settings_general::self()->writeConfig();
00233 return QVariant();
00234 case columnData:
00235 return m_stationlist.at(row)->song().formatedValue;
00236 case columnDataToolTip:
00237 return m_stationlist.at(row)->song().toolTip;
00238 case columnDataWhatsThis:
00239 return m_stationlist.at(row)->song().whatsThis;
00240 };
00241 break;
00242 }
00243
00244 case 3:
00245 {
00246 switch (type) {
00247 case columnHeaderTitle:
00248 return i18nc("@title:column", "track size");
00249 case columnHeaderToolTip:
00250 case columnHeaderWhatsThis:
00251 return QVariant();
00252 case columnWidth:
00253 return settings_general::columnWidth_dataSize();
00254 case setColumnWidth:
00255 settings_general::setColumnWidth_dataSize(value);
00256 settings_general::self()->writeConfig();
00257 return QVariant();
00258 case columnVisibility:
00259 return settings_general::columnVisibility_dataSize();
00260 case setColumnVisibility:
00261 settings_general::setColumnVisibility_dataSize(value);
00262 settings_general::self()->writeConfig();
00263 return QVariant();
00264 case columnData:
00265 return m_stationlist.at(row)->dataSize().formatedValue;
00266 case columnDataToolTip:
00267 return m_stationlist.at(row)->dataSize().toolTip;
00268 case columnDataWhatsThis:
00269 return m_stationlist.at(row)->dataSize().whatsThis;
00270 };
00271 break;
00272 }
00273
00274 case 4:
00275 {
00276 switch (type) {
00277 case columnHeaderTitle:
00278 return i18nc("@title:column", "bit rate");
00279 case columnHeaderToolTip:
00280 case columnHeaderWhatsThis:
00281 return QVariant();
00282 case columnWidth:
00283 return settings_general::columnWidth_bitrate();
00284 case setColumnWidth:
00285 settings_general::setColumnWidth_bitrate(value);
00286 settings_general::self()->writeConfig();
00287 return QVariant();
00288 case columnVisibility:
00289 return settings_general::columnVisibility_bitrate();
00290 case setColumnVisibility:
00291 settings_general::setColumnVisibility_bitrate(value);
00292 settings_general::self()->writeConfig();
00293 return QVariant();
00294 case columnData:
00295 return m_stationlist.at(row)->bitrate().formatedValue;
00296 case columnDataToolTip:
00297 return m_stationlist.at(row)->bitrate().toolTip;
00298 case columnDataWhatsThis:
00299 return m_stationlist.at(row)->bitrate().whatsThis;
00300 };
00301 break;
00302 }
00303
00304 case 5:
00305 {
00306 switch (type) {
00307 case columnHeaderTitle:
00308 return i18nc("@title:column", "meta data interval");
00309 case columnHeaderToolTip:
00310 return i18nc("@info:tooltip", "interval of meta data");
00311 case columnHeaderWhatsThis:
00312 return QVariant();
00313 case columnWidth:
00314 return settings_general::columnWidth_metaInterval();
00315 case setColumnWidth:
00316 settings_general::setColumnWidth_metaInterval(value);
00317 settings_general::self()->writeConfig();
00318 return QVariant();
00319 case columnVisibility:
00320 return settings_general::columnVisibility_metaInterval();
00321 case setColumnVisibility:
00322 settings_general::setColumnVisibility_metaInterval(value);
00323 settings_general::self()->writeConfig();
00324 return QVariant();
00325 case columnData:
00326 return m_stationlist.at(row)->metaInterval().formatedValue;
00327 case columnDataToolTip:
00328 return m_stationlist.at(row)->metaInterval().toolTip;
00329 case columnDataWhatsThis:
00330 return m_stationlist.at(row)->metaInterval().whatsThis;
00331 };
00332 break;
00333 }
00334
00335 case 6:
00336 {
00337 switch (type) {
00338 case columnHeaderTitle:
00339 return i18nc("@title:column", "server name");
00340 case columnHeaderToolTip:
00341 case columnHeaderWhatsThis:
00342 return QVariant();
00343 case columnWidth:
00344 return settings_general::columnWidth_serverName();
00345 case setColumnWidth:
00346 settings_general::setColumnWidth_serverName(value);
00347 settings_general::self()->writeConfig();
00348 return QVariant();
00349 case columnVisibility:
00350 return settings_general::columnVisibility_serverName();
00351 case setColumnVisibility:
00352 settings_general::setColumnVisibility_serverName(value);
00353 settings_general::self()->writeConfig();
00354 return QVariant();
00355 case columnData:
00356 return m_stationlist.at(row)->serverName().formatedValue;
00357 case columnDataToolTip:
00358 return m_stationlist.at(row)->serverName().toolTip;
00359 case columnDataWhatsThis:
00360 return m_stationlist.at(row)->serverName().whatsThis;
00361 };
00362 break;
00363 }
00364
00365 case 7:
00366 {
00367 switch (type) {
00368 case columnHeaderTitle:
00369 return i18nc("@title:column 'relay port' means 'the port that the relay server uses'",
00370 "relay port");
00371 case columnHeaderToolTip:
00372 return i18nc("@info:tooltip", "port of the relay server");
00373 case columnHeaderWhatsThis:
00374 return QVariant();
00375 case columnWidth:
00376 return settings_general::columnWidth_relayPort();
00377 case setColumnWidth:
00378 settings_general::setColumnWidth_relayPort(value);
00379 settings_general::self()->writeConfig();
00380 return QVariant();
00381 case columnVisibility:
00382 return settings_general::columnVisibility_relayPort();
00383 case setColumnVisibility:
00384 settings_general::setColumnVisibility_relayPort(value);
00385 settings_general::self()->writeConfig();
00386 return QVariant();
00387 case columnData:
00388 return m_stationlist.at(row)->relayPort().formatedValue;
00389 case columnDataToolTip:
00390 return m_stationlist.at(row)->relayPort().toolTip;
00391 case columnDataWhatsThis:
00392 return m_stationlist.at(row)->relayPort().whatsThis;
00393 };
00394 break;
00395 }
00396
00397
00398
00399
00400 };
00401 return QVariant();
00402 }
00403
00404 void stationlistModel::recalculate_numberOfActiveStreams_and_bandwidth()
00405 {
00406
00407 int i;
00408 int temp_numberOfActiveStreams = 0;
00409 quint64 temp_bandwidth = 0;
00410
00411
00412
00413
00414 for (i=0; i < m_stationlist.size(); ++i) {
00415 if (m_stationlist.at(i)->status().internalValue.value<ripping::statusType>() != ripping::idle) {
00416 temp_numberOfActiveStreams++;
00417 if (m_stationlist.at(i)->bitrate().type == PropertyValue::value) {
00418 temp_bandwidth = temp_bandwidth +
00419 m_stationlist.at(i)->bitrate().internalValue.toULongLong();
00420 };
00421 };
00422 };
00423
00424
00425 if (internal_numberOfActiveStreams != temp_numberOfActiveStreams) {
00426 internal_numberOfActiveStreams = temp_numberOfActiveStreams;
00427 emit numberOfActiveStreamsChanged();
00428 if (internal_numberOfActiveStreams == 0) {
00429 emit numberOfActiveStreamsIsZero();
00430 };
00431 };
00432 if (internal_bandwidth != temp_bandwidth) {
00433 internal_bandwidth = temp_bandwidth;
00434 emit bandwidthChanged();
00435 };
00436 }
00437
00438 void stationlistModel::reloadStreamName(const qlonglong stationIndex)
00439 {
00440 emit dataChanged(index(stationIndex, 0), index(stationIndex, 0));
00441 }
00442
00443 void stationlistModel::reloadStatus(const qlonglong stationIndex)
00444 {
00445 emit dataChanged(index(stationIndex, 1), index(stationIndex, 1));
00446 }
00447
00448 void stationlistModel::reloadSong(const qlonglong stationIndex)
00449 {
00450 emit dataChanged(index(stationIndex, 2), index(stationIndex, 2));
00451 }
00452
00453 void stationlistModel::reloadDataSize(const qlonglong stationIndex)
00454 {
00455 emit dataChanged(index(stationIndex, 3), index(stationIndex, 3));
00456 }
00457
00458 void stationlistModel::reloadBitrate(const qlonglong stationIndex)
00459 {
00460 emit dataChanged(index(stationIndex, 4), index(stationIndex, 4));
00461 }
00462
00463 void stationlistModel::reloadMetaInterval(const qlonglong stationIndex)
00464 {
00465 emit dataChanged(index(stationIndex, 5), index(stationIndex, 5));
00466 }
00467
00468 void stationlistModel::reloadServerName(const qlonglong stationIndex)
00469 {
00470 emit dataChanged(index(stationIndex, 6), index(stationIndex, 6));
00471 }
00472
00473 void stationlistModel::reloadRelayPort(const qlonglong stationIndex)
00474 {
00475 emit dataChanged(index(stationIndex, 7), index(stationIndex, 7));
00476 }
00477
00478 QVariant stationlistModel::headerData(int section, Qt::Orientation orientation, int role) const
00479 {
00480 if (orientation EQUAL Qt::Vertical) {
00481 if (role == Qt::DisplayRole) {
00482 return (int(section+1));
00483 } else {
00484 return QVariant();
00485 };
00486 } else {
00487 switch (role) {
00488 case Qt::DisplayRole:
00489 return columnInfo(columnHeaderTitle, section);
00490 case Qt::ToolTipRole:
00491 return columnInfo(columnHeaderToolTip, section);
00492 case Qt::WhatsThisRole:
00493 return columnInfo(columnHeaderWhatsThis, section);
00494 default:
00495 return QVariant();
00496 };
00497 };
00498 return QVariant();
00499
00500
00501 }
00502
00503 QVariant stationlistModel::data(const QModelIndex &index, int role) const
00504 {
00505
00506 QVariant returnValue;
00507
00508
00509 if (index.model() EQUAL this) {
00510 switch (role) {
00511 case Qt::DisplayRole:
00512 returnValue = columnInfo(columnData, index.column(), index.row());
00513 break;
00514 case Qt::ToolTipRole:
00515 returnValue = columnInfo(columnDataToolTip, index.column(), index.row());
00516 break;
00517 case Qt::WhatsThisRole:
00518 returnValue = columnInfo(columnDataWhatsThis, index.column(), index.row());
00519 break;
00520 default:
00521 returnValue = QVariant();
00522 break;
00523 };
00524 }
00525
00526
00527 return returnValue;
00528 }
00529
00530 void stationlistModel::sort (int column, Qt::SortOrder order)
00531 {
00532
00533 }
00534
00535 void stationlistModel::addNewStation()
00536 {
00537
00538 const int size_of_list = m_stationlist.size();
00539
00540
00541 QPointer<radioStation> m_newStation;
00542 int exitCode;
00543 QString m_fileName;
00544
00545
00546 m_newStation = new radioStation(this, m_mainWidget, QString(), size_of_list);
00547 exitCode = m_newStation->execSettingsDialog();
00548 if (exitCode == QDialog::Accepted) {
00549 beginInsertRows(QModelIndex(), size_of_list, size_of_list);
00550 m_stationlist.append(m_newStation);
00551 helper_connectSignalsAndSlots(m_stationlist.last());
00552 helper_writeStationListToGeneralSettings();
00553 endInsertRows();
00554 } else {
00555 m_fileName = m_newStation->configFileName();
00556 delete m_newStation;
00557
00558
00559 QFile theFile(m_fileName);
00560 theFile.remove();
00561 };
00562 }
00563
00564 void stationlistModel::deleteStation(const int index)
00565 {
00566
00567 if ((index >= 0) AND (index < m_stationlist.size())) {
00568
00569 QString filename;
00570 int i;
00571 QFile the_file;
00572
00573
00574
00575 filename = m_stationlist.at(index)->configFileName();
00576
00577 beginRemoveRows(QModelIndex(), index, index);
00578
00579 delete m_stationlist.at(index);
00580
00581
00582 m_stationlist.removeAt(index);
00583
00584 helper_writeStationListToGeneralSettings();
00585
00586 for (i=index; i<m_stationlist.size(); ++i) {
00587 m_stationlist.at(i)->setIndex(i);
00588 };
00589
00590 endRemoveRows();
00591
00592
00593 the_file.setFileName(filename);
00594 the_file.remove();
00595
00596 };
00597 }
00598
00599 inline void stationlistModel::helper_writeStationListToGeneralSettings()
00600 {
00601
00602 int i;
00603 QStringList helper_stringlist;
00604
00605
00606 for (i = 0; i < m_stationlist.size(); ++i) {
00607 helper_stringlist.append(m_stationlist.at(i)->configFileName());
00608 };
00609 settings_general::setStreamConfigFiles(helper_stringlist);
00610 settings_general::self()->writeConfig();
00611 }
00612
00613 void stationlistModel::record(const int index)
00614 {
00615
00616 if ((index >= 0) AND (index < m_stationlist.size())) {
00617 m_stationlist.at(index)->startStreamripper();
00618 };
00619 }
00620
00621 void stationlistModel::stopRecording(const int index)
00622 {
00623
00624 if ((index >= 0) AND (index < m_stationlist.size())) {
00625 m_stationlist.at(index)->shutDown();
00626 };
00627 }
00628
00629 void stationlistModel::showConfigDialog(const int index)
00630 {
00631
00632 if ((index >= 0) AND (index < m_stationlist.size())) {
00633 m_stationlist.at(index)->showSettingsDialog();
00634 };
00635 }
00636
00637 quint64 stationlistModel::bandwidth() const
00638 {
00639 return internal_bandwidth;
00640 }
00641
00642 int stationlistModel::numberOfActiveStreams() const
00643 {
00644 return internal_numberOfActiveStreams;
00645 }
00646
00647 void stationlistModel::rememberListOfStreamsWhichTheUserWantsToRip_ifNotYetDone()
00648 {
00649
00650 int i;
00651 QStringList temp_stringList;
00652
00653
00654 if (m_listOfStreamsOfWhichTheUserWantsThatTheyRip == 0) {
00655 for (i=0; i < rowCount(); i++) {
00656 if (m_stationlist.at(i)->doesTheUserWantsThatTheStreamIsRipping()) {
00657 temp_stringList.append(m_stationlist.at(i)->configFileName());
00658 };
00659 };
00660 m_listOfStreamsOfWhichTheUserWantsThatTheyRip = new QStringList(temp_stringList);
00661 };
00662 }
00663
00664 bool stationlistModel::queryClose()
00665 {
00666
00667 int i;
00668
00669
00670
00671 rememberListOfStreamsWhichTheUserWantsToRip_ifNotYetDone();
00672
00673
00674 if (numberOfActiveStreams() > 0) {
00675 for (i = 0; i < m_stationlist.size(); ++i) {
00676 m_stationlist.at(i)->shutDown();
00677 };
00678 };
00679
00680
00681
00682
00683 if (numberOfActiveStreams() > 0) {
00684 QPointer<KProgressDialog> m_dialog = new KProgressDialog(m_mainWidget,
00685 i18nc("@title:window", "Saving files..."),
00686 i18nc("@label", "Please wait while last files are saved..."));
00687 connect(this, SIGNAL(numberOfActiveStreamsIsZero()), m_dialog, SLOT(reject()));
00688
00689 m_dialog->progressBar()->setMinimum(0);
00690 m_dialog->progressBar()->setMaximum(0);
00691 m_dialog->setModal(true);
00692 m_dialog->setAutoClose(false);
00693 m_dialog->setMinimumDuration(0);
00694
00695
00696 m_dialog->setButtonText(i18nc("@action:button", "Quit without saving"));
00697 m_dialog->exec();
00698 delete m_dialog;
00699 };
00700
00701 return true;
00702 }
00703
00704 void stationlistModel::saveProperties(KConfigGroup & m_configGroup)
00705 {
00706 rememberListOfStreamsWhichTheUserWantsToRip_ifNotYetDone();
00707 m_configGroup.writePathEntry("streamsToResume",
00708 * m_listOfStreamsOfWhichTheUserWantsThatTheyRip);
00709
00710 }
00711
00712 void stationlistModel::readProperties(const KConfigGroup & m_configGroup)
00713 {
00714
00715 QStringList temp_stringList;
00716 int i;
00717
00718
00719 temp_stringList = m_configGroup.readPathEntry("streamsToResume", temp_stringList);
00720 for (i = 0; i < rowCount(); i++) {
00721 if (temp_stringList.contains(m_stationlist.at(i)->configFileName())) {
00722 m_stationlist.at(i)->startStreamripper();
00723 };
00724 };
00725 }