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 "stationlistwidget.h"
00023 #include "settings_general.h"
00024 #include <QAbstractItemModel>
00025 #include <QApplication>
00026 #include <QClipboard>
00027 #include <QFile>
00028 #include <QItemSelection>
00029 #include <QMimeData>
00030 #include <KProgressDialog>
00031 #include <KLocale>
00032 #define AND &&
00033 #define OR ||
00034 #define NOT !
00035 #define EQUAL ==
00036
00037 stationlistModel::stationlistModel(stationlistWidget *parent,
00038 QWidget *mainWidget) : QAbstractTableModel(parent)
00039 {
00040
00041 QStringList m_stringList;
00042 int i;
00043
00044
00045 m_mainWidget = mainWidget;
00046 view = parent;
00047
00048
00049 m_stringList = settings_general::streamConfigFiles();
00050 for (i = 0; i < m_stringList.size(); ++i) {
00051 m_stationlist.append(new radioStation(this, m_mainWidget, m_stringList.at(i), i));
00052 helper_connectSignalsAndSlots(m_stationlist.last());
00053 };
00054 helper_writeStationListToGeneralSettings();
00055
00056
00057
00058
00059 recalculate_numberOfActiveStreams_and_bandwidth();
00060 connect(this, SIGNAL(rowsInserted(const QModelIndex &, int, int)),
00061 this, SLOT(recalculate_numberOfActiveStreams_and_bandwidth()));
00062 connect(this, SIGNAL(rowsRemoved(const QModelIndex &, int, int)),
00063 this, SLOT(recalculate_numberOfActiveStreams_and_bandwidth()));
00064 m_listOfStreamsOfWhichTheUserWantsThatTheyRip = 0;
00065 }
00066
00067 stationlistModel::~stationlistModel()
00068 {
00069 delete m_listOfStreamsOfWhichTheUserWantsThatTheyRip;
00070 }
00071
00072 void stationlistModel::helper_connectSignalsAndSlots(radioStation *m_stream)
00073 {
00074 connect(m_stream, SIGNAL(streamNameChanged(qlonglong, PropertyValue)),
00075 this, SLOT(reloadStreamName(qlonglong)));
00076 connect(m_stream, SIGNAL(uriChanged(qlonglong, PropertyValue)),
00077 this, SLOT(reloadUri(qlonglong)));
00078 connect(m_stream, SIGNAL(statusChanged(qlonglong, PropertyValue)),
00079 this, SLOT(reloadStatus(qlonglong)));
00080 connect(m_stream, SIGNAL(errorChanged(qlonglong, PropertyValue)),
00081 this, SLOT(reloadStatus(qlonglong)));
00082 connect(m_stream, SIGNAL(songChanged(qlonglong, PropertyValue)),
00083 this, SLOT(reloadSong(qlonglong)));
00084 connect(m_stream, SIGNAL(dataSizeChanged(qlonglong, PropertyValue)),
00085 this, SLOT(reloadDataSize(qlonglong)));
00086 connect(m_stream, SIGNAL(bitrateChanged(qlonglong, PropertyValue)),
00087 this, SLOT(reloadBitrate(qlonglong)));
00088 connect(m_stream, SIGNAL(bitrateChanged(qlonglong, PropertyValue)),
00089 this, SLOT(recalculate_numberOfActiveStreams_and_bandwidth()));
00090 connect(m_stream, SIGNAL(metaIntervalChanged(qlonglong, PropertyValue)),
00091 this, SLOT(reloadMetaInterval(qlonglong)));
00092 connect(m_stream, SIGNAL(metaInterval_milliSecondsChanged(qlonglong, PropertyValue)),
00093 this, SLOT(reloadMetaInterval_milliSeconds(qlonglong)));
00094 connect(m_stream, SIGNAL(serverNameChanged(qlonglong, PropertyValue)),
00095 this, SLOT(reloadServerName(qlonglong)));
00096 connect(m_stream, SIGNAL(relayPortChanged(qlonglong, PropertyValue)),
00097 this, SLOT(reloadRelayPort(qlonglong)));
00098 connect(m_stream, SIGNAL(running()),
00099 this, SLOT(recalculate_numberOfActiveStreams_and_bandwidth()));
00100 connect(m_stream, SIGNAL(not_running()),
00101 this, SLOT(recalculate_numberOfActiveStreams_and_bandwidth()));
00102 }
00103
00104 int stationlistModel::rowCount (const QModelIndex & parent) const
00105 {
00106 if (parent.isValid()) {
00107 return 0;
00108 } else {
00109 return m_stationlist.size();
00110 };
00111 }
00112
00113 int stationlistModel::columnCount (const QModelIndex & parent) const
00114 {
00115 if (parent.isValid()) {
00116 return 0;
00117 } else {
00118 return 10;
00119 };
00120 }
00121
00122 QVariant stationlistModel::columnInfo(const columnInfoType type,
00123 const int column,
00124 const qint64 row,
00125 const quint64 value,
00126 QList<radioStation *> listOfStations) const
00127 {
00128 QVariant temp;
00129
00130 if (listOfStations.isEmpty()) {
00131 listOfStations = m_stationlist;
00132 };
00133
00134 switch (type) {
00135 case columnHeaderTitle:
00136 case columnHeaderToolTip:
00137 case columnHeaderWhatsThis:
00138 case columnWidth:
00139 case setColumnWidth:
00140 case columnVisibility:
00141 case setColumnVisibility:
00142 break;
00143 default:
00144 if ((row >= listOfStations.size()) OR (row < 0)) {
00145 return QVariant();
00146 };
00147 }
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 switch (column) {
00164
00165 case 0:
00166 {
00167 switch (type) {
00168 case columnHeaderTitle:
00169 return i18nc("@title:column", "stream name");
00170 case columnHeaderToolTip:
00171 case columnHeaderWhatsThis:
00172 return QVariant();
00173 case columnWidth:
00174 return settings_general::columnWidth_streamName();
00175 case setColumnWidth:
00176 settings_general::setColumnWidth_streamName(value);
00177 settings_general::self()->writeConfig();
00178 return QVariant();
00179 case columnVisibility:
00180 return settings_general::columnVisibility_streamName();
00181 case setColumnVisibility:
00182 settings_general::setColumnVisibility_streamName(value);
00183 settings_general::self()->writeConfig();
00184 return QVariant();
00185 case columnData:
00186 temp.setValue<PropertyValue>(listOfStations.at(row)->streamName());
00187 return temp;
00188 };
00189 break;
00190 }
00191
00192 case 1:
00193 {
00194 switch (type) {
00195 case columnHeaderTitle:
00196 return i18nc("@title:column", "URL");
00197 case columnHeaderToolTip:
00198 case columnHeaderWhatsThis:
00199 return QVariant();
00200 case columnWidth:
00201 return settings_general::columnWidth_uri();
00202 case setColumnWidth:
00203 settings_general::setColumnWidth_uri(value);
00204 settings_general::self()->writeConfig();
00205 return QVariant();
00206 case columnVisibility:
00207 return settings_general::columnVisibility_uri();
00208 case setColumnVisibility:
00209 settings_general::setColumnVisibility_uri(value);
00210 settings_general::self()->writeConfig();
00211 return QVariant();
00212 case columnData:
00213 temp.setValue<PropertyValue>(listOfStations.at(row)->uri());
00214 return temp;
00215 };
00216 break;
00217 }
00218
00219 case 2:
00220 {
00221 switch (type) {
00222 case columnHeaderTitle:
00223 return i18nc("@title:column", "status");
00224 case columnHeaderToolTip:
00225 case columnHeaderWhatsThis:
00226 return QVariant();
00227 case columnWidth:
00228 return settings_general::columnWidth_statusAndError();
00229 case setColumnWidth:
00230 settings_general::setColumnWidth_statusAndError(value);
00231 settings_general::self()->writeConfig();
00232 return QVariant();
00233 case columnVisibility:
00234 return settings_general::columnVisibility_statusAndError();
00235 case setColumnVisibility:
00236 settings_general::setColumnVisibility_statusAndError(value);
00237 settings_general::self()->writeConfig();
00238 return QVariant();
00239 case columnData:
00240 PropertyValue my_statusAndError;
00241 if (listOfStations.at(row)->error().formatedValue.isEmpty()) {
00242 my_statusAndError.formatedValue = listOfStations.at(row)->status().formatedValue;
00243 my_statusAndError.toolTip = listOfStations.at(row)->status().toolTip;
00244 my_statusAndError.whatsThis = listOfStations.at(row)->status().whatsThis;
00245 } else {
00246 my_statusAndError.toolTip = listOfStations.at(row)->error().toolTip;
00247 my_statusAndError.whatsThis = listOfStations.at(row)->error().whatsThis;
00248 if (listOfStations.at(row)->status().formatedValue.isEmpty()) {
00249 my_statusAndError.formatedValue = listOfStations.at(row)->error().formatedValue;
00250 } else {
00251 my_statusAndError.formatedValue = QString(i18nc(
00252 "@item:intable This produces the status message from the actual status (%1) and "
00253 "the error message (%3). Both of them are guaranteed to be not empty. %2 is "
00254 "replaced by an en-dash (Unicode U+2013). Use it or replace it by something "
00255 "what looks nicer in your language.",
00256 "%1 %2 %3",
00257 listOfStations.at(row)->status().formatedValue,
00258 QString(QChar(0x2013)),
00259 listOfStations.at(row)->error().formatedValue));
00260 };
00261 };
00262 my_statusAndError.internalValue = listOfStations.at(row)->status().internalValue;
00263 if ((!(listOfStations.at(row)->error().type == PropertyValue::unset)) ||
00264 (listOfStations.at(row)->status().type == PropertyValue::error)) {
00265 my_statusAndError.type = PropertyValue::error;
00266 } else if (my_statusAndError.formatedValue.isEmpty()) {
00267 my_statusAndError.type = PropertyValue::unset;
00268 } else {
00269 my_statusAndError.type = PropertyValue::value;
00270 };
00271 temp.setValue<PropertyValue>(my_statusAndError);
00272 return temp;
00273 };
00274 break;
00275 }
00276
00277 case 3:
00278 {
00279 switch (type) {
00280 case columnHeaderTitle:
00281 return i18nc("@title:column header of the column with the name of the actual track",
00282 "track");
00283 case columnHeaderToolTip:
00284 case columnHeaderWhatsThis:
00285 return QVariant();
00286 case columnWidth:
00287 return settings_general::columnWidth_song();
00288 case setColumnWidth:
00289 settings_general::setColumnWidth_song(value);
00290 settings_general::self()->writeConfig();
00291 return QVariant();
00292 case columnVisibility:
00293 return settings_general::columnVisibility_song();
00294 case setColumnVisibility:
00295 settings_general::setColumnVisibility_song(value);
00296 settings_general::self()->writeConfig();
00297 return QVariant();
00298 case columnData:
00299 temp.setValue<PropertyValue>(listOfStations.at(row)->song());
00300 return temp;
00301 };
00302 break;
00303 }
00304
00305 case 4:
00306 {
00307 switch (type) {
00308 case columnHeaderTitle:
00309 return i18nc("@title:column", "track size");
00310 case columnHeaderToolTip:
00311 case columnHeaderWhatsThis:
00312 return QVariant();
00313 case columnWidth:
00314 return settings_general::columnWidth_dataSize();
00315 case setColumnWidth:
00316 settings_general::setColumnWidth_dataSize(value);
00317 settings_general::self()->writeConfig();
00318 return QVariant();
00319 case columnVisibility:
00320 return settings_general::columnVisibility_dataSize();
00321 case setColumnVisibility:
00322 settings_general::setColumnVisibility_dataSize(value);
00323 settings_general::self()->writeConfig();
00324 return QVariant();
00325 case columnData:
00326 temp.setValue<PropertyValue>(listOfStations.at(row)->dataSize());
00327 return temp;
00328 };
00329 break;
00330 }
00331
00332 case 5:
00333 {
00334 switch (type) {
00335 case columnHeaderTitle:
00336 return i18nc("@title:column", "bit rate");
00337 case columnHeaderToolTip:
00338 case columnHeaderWhatsThis:
00339 return QVariant();
00340 case columnWidth:
00341 return settings_general::columnWidth_bitrate();
00342 case setColumnWidth:
00343 settings_general::setColumnWidth_bitrate(value);
00344 settings_general::self()->writeConfig();
00345 return QVariant();
00346 case columnVisibility:
00347 return settings_general::columnVisibility_bitrate();
00348 case setColumnVisibility:
00349 settings_general::setColumnVisibility_bitrate(value);
00350 settings_general::self()->writeConfig();
00351 return QVariant();
00352 case columnData:
00353 temp.setValue<PropertyValue>(listOfStations.at(row)->bitrate());
00354 return temp;
00355 };
00356 break;
00357 }
00358
00359 case 6:
00360 {
00361 switch (type) {
00362 case columnHeaderTitle:
00363 return i18nc("@title:column The unit is KiB instead of kB. See "
00364 "http://en.wikipedia.org/wiki/Binary_prefix for details.",
00365 "meta data interval (KiB)");
00366 case columnHeaderToolTip:
00367 return i18nc("@info:tooltip", "interval of meta data in bytes");
00368 case columnHeaderWhatsThis:
00369 return QVariant();
00370 case columnWidth:
00371 return settings_general::columnWidth_metaInterval();
00372 case setColumnWidth:
00373 settings_general::setColumnWidth_metaInterval(value);
00374 settings_general::self()->writeConfig();
00375 return QVariant();
00376 case columnVisibility:
00377 return settings_general::columnVisibility_metaInterval();
00378 case setColumnVisibility:
00379 settings_general::setColumnVisibility_metaInterval(value);
00380 settings_general::self()->writeConfig();
00381 return QVariant();
00382 case columnData:
00383 temp.setValue<PropertyValue>(listOfStations.at(row)->metaInterval());
00384 return temp;
00385 };
00386 break;
00387 }
00388
00389 case 7:
00390 {
00391 switch (type) {
00392 case columnHeaderTitle:
00393 return i18nc("@title:column unit is millisecond", "meta data interval (ms)");
00394 case columnHeaderToolTip:
00395 return i18nc("@info:tooltip", "interval of meta data in milliseconds");
00396 case columnHeaderWhatsThis:
00397 return QVariant();
00398 case columnWidth:
00399 return settings_general::columnWidth_metaInterval_milliSeconds();
00400 case setColumnWidth:
00401 settings_general::setColumnWidth_metaInterval_milliSeconds(value);
00402 settings_general::self()->writeConfig();
00403 return QVariant();
00404 case columnVisibility:
00405 return settings_general::columnVisibility_metaInterval_milliSeconds();
00406 case setColumnVisibility:
00407 settings_general::setColumnVisibility_metaInterval_milliSeconds(value);
00408 settings_general::self()->writeConfig();
00409 return QVariant();
00410 case columnData:
00411 temp.setValue<PropertyValue>(listOfStations.at(row)->metaInterval_milliSeconds());
00412 return temp;
00413 };
00414 break;
00415 }
00416
00417 case 8:
00418 {
00419 switch (type) {
00420 case columnHeaderTitle:
00421 return i18nc("@title:column", "server name");
00422 case columnHeaderToolTip:
00423 case columnHeaderWhatsThis:
00424 return QVariant();
00425 case columnWidth:
00426 return settings_general::columnWidth_serverName();
00427 case setColumnWidth:
00428 settings_general::setColumnWidth_serverName(value);
00429 settings_general::self()->writeConfig();
00430 return QVariant();
00431 case columnVisibility:
00432 return settings_general::columnVisibility_serverName();
00433 case setColumnVisibility:
00434 settings_general::setColumnVisibility_serverName(value);
00435 settings_general::self()->writeConfig();
00436 return QVariant();
00437 case columnData:
00438 temp.setValue<PropertyValue>(listOfStations.at(row)->serverName());
00439 return temp;
00440 };
00441 break;
00442 }
00443
00444 case 9:
00445 {
00446 switch (type) {
00447 case columnHeaderTitle:
00448 return i18nc("@title:column 'relay port' means 'the port that the relay server uses'",
00449 "relay port");
00450 case columnHeaderToolTip:
00451 return i18nc("@info:tooltip", "port of the relay server");
00452 case columnHeaderWhatsThis:
00453 return QVariant();
00454 case columnWidth:
00455 return settings_general::columnWidth_relayPort();
00456 case setColumnWidth:
00457 settings_general::setColumnWidth_relayPort(value);
00458 settings_general::self()->writeConfig();
00459 return QVariant();
00460 case columnVisibility:
00461 return settings_general::columnVisibility_relayPort();
00462 case setColumnVisibility:
00463 settings_general::setColumnVisibility_relayPort(value);
00464 settings_general::self()->writeConfig();
00465 return QVariant();
00466 case columnData:
00467 temp.setValue<PropertyValue>(listOfStations.at(row)->relayPort());
00468 return temp;
00469 };
00470 break;
00471 }
00472
00473
00474
00475
00476 };
00477 return QVariant();
00478 }
00479
00480 void stationlistModel::recalculate_numberOfActiveStreams_and_bandwidth()
00481 {
00482
00483 int i;
00484 int temp_numberOfActiveStreams = 0;
00485 quint64 temp_bandwidth = 0;
00486
00487
00488
00489
00490 for (i=0; i < m_stationlist.size(); ++i) {
00491 if (m_stationlist.at(i)->status().internalValue.value<ripping::statusType>() != ripping::idle) {
00492 temp_numberOfActiveStreams++;
00493 if (m_stationlist.at(i)->bitrate().type == PropertyValue::value) {
00494 temp_bandwidth = temp_bandwidth +
00495 m_stationlist.at(i)->bitrate().internalValue.toULongLong();
00496 };
00497 };
00498 };
00499
00500
00501 if (internal_numberOfActiveStreams != temp_numberOfActiveStreams) {
00502 internal_numberOfActiveStreams = temp_numberOfActiveStreams;
00503 emit numberOfActiveStreamsChanged();
00504 if (internal_numberOfActiveStreams == 0) {
00505 emit numberOfActiveStreamsIsZero();
00506 };
00507 };
00508 if (internal_bandwidth != temp_bandwidth) {
00509 internal_bandwidth = temp_bandwidth;
00510 emit bandwidthChanged();
00511 };
00512 }
00513
00514 void stationlistModel::reloadStreamName(const qlonglong stationIndex)
00515 {
00516 emit dataChanged(index(stationIndex, 0), index(stationIndex, 0));
00517 }
00518
00519 void stationlistModel::reloadUri(const qlonglong stationIndex)
00520 {
00521 emit dataChanged(index(stationIndex, 1), index(stationIndex, 0));
00522 }
00523
00524 void stationlistModel::reloadStatus(const qlonglong stationIndex)
00525 {
00526 emit dataChanged(index(stationIndex, 2), index(stationIndex, 2));
00527 }
00528
00529 void stationlistModel::reloadSong(const qlonglong stationIndex)
00530 {
00531 emit dataChanged(index(stationIndex, 3), index(stationIndex, 3));
00532 }
00533
00534 void stationlistModel::reloadDataSize(const qlonglong stationIndex)
00535 {
00536 emit dataChanged(index(stationIndex, 4), index(stationIndex, 4));
00537 }
00538
00539 void stationlistModel::reloadBitrate(const qlonglong stationIndex)
00540 {
00541 emit dataChanged(index(stationIndex, 5), index(stationIndex, 5));
00542 }
00543
00544 void stationlistModel::reloadMetaInterval(const qlonglong stationIndex)
00545 {
00546 emit dataChanged(index(stationIndex, 6), index(stationIndex, 6));
00547 }
00548
00549 void stationlistModel::reloadMetaInterval_milliSeconds(const qlonglong stationIndex)
00550 {
00551 emit dataChanged(index(stationIndex, 7), index(stationIndex, 7));
00552 }
00553
00554 void stationlistModel::reloadServerName(const qlonglong stationIndex)
00555 {
00556 emit dataChanged(index(stationIndex, 8), index(stationIndex, 8));
00557 }
00558
00559 void stationlistModel::reloadRelayPort(const qlonglong stationIndex)
00560 {
00561 emit dataChanged(index(stationIndex, 9), index(stationIndex, 9));
00562 }
00563
00564 QVariant stationlistModel::headerData(int section, Qt::Orientation orientation, int role) const
00565 {
00566 if (orientation EQUAL Qt::Vertical) {
00567 if (role == Qt::DisplayRole) {
00568 return (int(section+1));
00569 } else {
00570 return QVariant();
00571 };
00572 } else {
00573 switch (role) {
00574 case Qt::DisplayRole:
00575 return columnInfo(columnHeaderTitle, section);
00576 case Qt::ToolTipRole:
00577 return columnInfo(columnHeaderToolTip, section);
00578 case Qt::WhatsThisRole:
00579 return columnInfo(columnHeaderWhatsThis, section);
00580 default:
00581 return QVariant();
00582 };
00583 };
00584 return QVariant();
00585
00586
00587 }
00588
00589 QVariant stationlistModel::data(const QModelIndex &index, int role) const
00590 {
00591
00592 QVariant returnValue;
00593
00594
00595 if ((index.model() EQUAL this) AND (!index.parent().isValid()) AND (index.isValid())) {
00596 switch (role) {
00597 case Qt::DisplayRole:
00598 returnValue =
00599 columnInfo(columnData, index.column(), index.row()).value<PropertyValue>().formatedValue;
00600 break;
00601 case Qt::ToolTipRole:
00602 returnValue =
00603 columnInfo(columnData, index.column(), index.row()).value<PropertyValue>().toolTip;
00604 break;
00605 case Qt::WhatsThisRole:
00606 returnValue =
00607 columnInfo(columnData, index.column(), index.row()).value<PropertyValue>().whatsThis;
00608 break;
00609 case Qt::TextAlignmentRole:
00610 returnValue = static_cast<int>(columnInfo(columnData, index.column(), index.row())
00611 .value<PropertyValue>().formatedValueAlignment);
00612 break;
00613 default:
00614 returnValue = QVariant();
00615 break;
00616 };
00617 }
00618
00619
00620 return returnValue;
00621 }
00622
00623 void stationlistModel::sort(int column, Qt::SortOrder order)
00624 {
00625 if (m_stationlist.isEmpty() || column < 0 || column >= columnCount()) {
00626 return;
00627 };
00628
00629
00630 int i;
00631 int j;
00632 bool abort;
00633 PropertyValue temp;
00634 QList<radioStation *> sorted_list;
00635 QModelIndexList temp_indexList;
00636 QStringList selection;
00637
00638
00639
00640
00641 temp_indexList = view->selectionModel()->selectedRows();
00642 foreach (const QModelIndex & tempModelIndex, temp_indexList) {
00643 selection.append(m_stationlist.at(tempModelIndex.row())->configFileName());
00644 };
00645
00646
00647 for (i = 0; i < m_stationlist.size(); ++i) {
00648 temp = columnInfo(columnData, column, i).value<PropertyValue>();
00649 j = 0;
00650 abort = (j >= sorted_list.size());
00651 while (!abort) {
00652 if (helper_firstIsAfterSecond(
00653 temp,
00654 columnInfo(columnData, column, j, -1, sorted_list).value<PropertyValue>(),
00655 order)) {
00656 ++j;
00657 abort = (j >= sorted_list.size());
00658 } else {
00659 abort = true;
00660 };
00661 };
00662 sorted_list.insert(j, m_stationlist.at(i));
00663 };
00664
00665
00666 m_stationlist = sorted_list;
00667
00668
00669 view->selectionModel()->clear();
00670 for (i = 0; i < m_stationlist.size(); ++i) {
00671 m_stationlist.at(i)->setIndex(i);
00672 if (selection.contains(m_stationlist.at(i)->configFileName())) {
00673 view->selectionModel()->select(
00674 index(i, 0),
00675 QItemSelectionModel::Select | QItemSelectionModel::Rows);
00676 };
00677 };
00678
00679
00680 settings_general::setSortingAscendingly(order == Qt::AscendingOrder);
00681 settings_general::setSortByColumn(column);
00682 settings_general::self()->writeConfig();
00683
00684
00685 emit dataChanged(index(0, 0),
00686 index(m_stationlist.size() - 1, columnCount() - 1));
00687
00688 }
00689
00690 bool stationlistModel::helper_isNumericValue(const QVariant & value)
00691 {
00692
00693 QMetaType::Type type;
00694
00695
00696 type = static_cast<QMetaType::Type>(value.type());
00697 return (type == QMetaType::Int ||
00698 type == QMetaType::UInt ||
00699 type == QMetaType::Double ||
00700 type == QMetaType::Long ||
00701 type == QMetaType::LongLong ||
00702 type == QMetaType::Short ||
00703 type == QMetaType::Char ||
00704 type == QMetaType::ULong ||
00705 type == QMetaType::ULongLong ||
00706 type == QMetaType::UShort ||
00707 type == QMetaType::UChar ||
00708 type == QMetaType::Float ||
00709
00710 value.typeName() == QString("ripping::statusType"));
00711 }
00712
00713 qlonglong stationlistModel::helper_toLongLong(const PropertyValue & value)
00714 {
00715
00716 if (value.internalValue.typeName() == QString("ripping::statusType")) {
00717 return value.internalValue.value<ripping::statusType>();
00718 } else {
00719 return value.internalValue.toLongLong();
00720 };
00721 }
00722
00723 bool stationlistModel::helper_firstIsAfterSecond(const PropertyValue & firstValue,
00724 const PropertyValue & secondValue,
00725 Qt::SortOrder order)
00726 {
00727
00728 if (order == Qt::AscendingOrder) {
00729 switch (firstValue.type) {
00730 case PropertyValue::unset:
00731 return (secondValue.type == PropertyValue::unset);
00732 case PropertyValue::value:
00733 if (secondValue.type == PropertyValue::unset) {
00734 return true;
00735 } else if (secondValue.type == PropertyValue::error) {
00736 return false;
00737 } else {
00738 if (helper_isNumericValue(firstValue.internalValue) &&
00739 helper_isNumericValue(secondValue.internalValue)) {
00740 return helper_toLongLong(firstValue) >= helper_toLongLong(secondValue);
00741 } else {
00742 return QString::localeAwareCompare(firstValue.formatedValue,
00743 secondValue.formatedValue) >= 0;
00744 };
00745 };
00746 case PropertyValue::error:
00747 if (secondValue.type == PropertyValue::error) {
00748 return QString::localeAwareCompare(firstValue.formatedValue,
00749 secondValue.formatedValue) >= 0;
00750 } else {
00751 return true;
00752 };
00753 };
00754 } else {
00755 switch (firstValue.type) {
00756 case PropertyValue::unset:
00757 return true;
00758 case PropertyValue::value:
00759 if (secondValue.type == PropertyValue::unset) {
00760 return false;
00761 } else if (secondValue.type == PropertyValue::error) {
00762 return true;
00763 } else {
00764 if (helper_isNumericValue(firstValue.internalValue) &&
00765 helper_isNumericValue(secondValue.internalValue)) {
00766 return helper_toLongLong(firstValue) <= helper_toLongLong(secondValue);
00767 } else {
00768 return QString::localeAwareCompare(firstValue.formatedValue,
00769 secondValue.formatedValue) <= 0;
00770 };
00771 };
00772 case PropertyValue::error:
00773 if (secondValue.type == PropertyValue::error) {
00774 return QString::localeAwareCompare(firstValue.formatedValue,
00775 secondValue.formatedValue) <= 0;
00776 } else {
00777 return false;
00778 };
00779 };
00780 };
00781 kDebug() << "Function hasn't calculated a return value. TRUE is returned to prevent a crash.";
00782 return true;
00783 }
00784
00785 QModelIndex stationlistModel::addNewStation()
00786 {
00787
00788 const int size_of_list = m_stationlist.size();
00789
00790
00791 QPointer<radioStation> m_newStation;
00792 int exitCode;
00793 QString m_fileName;
00794 QModelIndex returnValue;
00795
00796
00797 m_newStation = new radioStation(this, m_mainWidget, QString(), size_of_list);
00798 exitCode = m_newStation->execSettingsDialog();
00799 if (exitCode == QDialog::Accepted) {
00800 beginInsertRows(QModelIndex(), size_of_list, size_of_list);
00801 m_stationlist.append(m_newStation);
00802 helper_connectSignalsAndSlots(m_stationlist.last());
00803 helper_writeStationListToGeneralSettings();
00804 endInsertRows();
00805 returnValue = index(size_of_list, 0);
00806 } else {
00807 m_fileName = m_newStation->configFileName();
00808 delete m_newStation;
00809
00810
00811 QFile theFile(m_fileName);
00812 theFile.remove();
00813 };
00814 return returnValue;
00815 }
00816
00817 bool stationlistModel::removeRows(int row, int count, const QModelIndex & parent)
00818 {
00819
00820 int i;
00821 QString filename;
00822 QFile the_file;
00823
00824
00825 if (count == 0) {
00826 return true;
00827 };
00828
00829 if ((row >= 0) &&
00830 (count > 0) &&
00831 ((row + count - 1) < m_stationlist.size()) &&
00832 (!parent.isValid())) {
00833 beginRemoveRows(QModelIndex(), row, row + count - 1);
00834 for (i = row; i <= row+count-1; ++i) {
00835
00836 filename = m_stationlist.at(i)->configFileName();
00837 delete m_stationlist.at(i);
00838
00839 m_stationlist.removeAt(i);
00840
00841 the_file.setFileName(filename);
00842 the_file.remove();
00843 };
00844
00845 helper_writeStationListToGeneralSettings();
00846
00847 for (i = row; i < m_stationlist.size(); ++i) {
00848 m_stationlist.at(i)->setIndex(i);
00849 };
00850 endRemoveRows();
00851 return true;
00852 } else {
00853 return false;
00854 };
00855 }
00856
00857 inline void stationlistModel::helper_writeStationListToGeneralSettings()
00858 {
00859
00860 int i;
00861 QStringList helper_stringlist;
00862
00863
00864 for (i = 0; i < m_stationlist.size(); ++i) {
00865 helper_stringlist.append(m_stationlist.at(i)->configFileName());
00866 };
00867 settings_general::setStreamConfigFiles(helper_stringlist);
00868 settings_general::self()->writeConfig();
00869 }
00870
00871 void stationlistModel::record(const int index)
00872 {
00873
00874 if ((index >= 0) AND (index < m_stationlist.size())) {
00875 m_stationlist.at(index)->startStreamripper();
00876 };
00877 }
00878
00879 void stationlistModel::stopRecording(const int index)
00880 {
00881
00882 if ((index >= 0) AND (index < m_stationlist.size())) {
00883 m_stationlist.at(index)->shutDown();
00884 };
00885 }
00886
00887 void stationlistModel::showConfigDialog(const int index)
00888 {
00889
00890 if ((index >= 0) AND (index < m_stationlist.size())) {
00891 m_stationlist.at(index)->showSettingsDialog();
00892 };
00893 }
00894
00895 quint64 stationlistModel::bandwidth() const
00896 {
00897 return internal_bandwidth;
00898 }
00899
00900 int stationlistModel::numberOfActiveStreams() const
00901 {
00902 return internal_numberOfActiveStreams;
00903 }
00904
00905 void stationlistModel::rememberListOfStreamsWhichTheUserWantsToRip_ifNotYetDone()
00906 {
00907
00908 int i;
00909 QStringList temp_stringList;
00910
00911
00912 if (m_listOfStreamsOfWhichTheUserWantsThatTheyRip == 0) {
00913 for (i=0; i < rowCount(); i++) {
00914 if (m_stationlist.at(i)->doesTheUserWantsThatTheStreamIsRipping()) {
00915 temp_stringList.append(m_stationlist.at(i)->configFileName());
00916 };
00917 };
00918 m_listOfStreamsOfWhichTheUserWantsThatTheyRip = new QStringList(temp_stringList);
00919 };
00920 }
00921
00922 bool stationlistModel::queryClose()
00923 {
00924
00925 int i;
00926
00927
00928
00929 rememberListOfStreamsWhichTheUserWantsToRip_ifNotYetDone();
00930
00931
00932 if (numberOfActiveStreams() > 0) {
00933 for (i = 0; i < m_stationlist.size(); ++i) {
00934 m_stationlist.at(i)->shutDown();
00935 };
00936 };
00937
00938
00939
00940
00941 if (numberOfActiveStreams() > 0) {
00942 QPointer<KProgressDialog> m_dialog = new KProgressDialog(m_mainWidget,
00943 i18nc("@title:window", "Saving files..."),
00944 i18nc("@label", "Please wait while last files are saved..."));
00945 connect(this, SIGNAL(numberOfActiveStreamsIsZero()), m_dialog, SLOT(reject()));
00946
00947 m_dialog->progressBar()->setMinimum(0);
00948 m_dialog->progressBar()->setMaximum(0);
00949 m_dialog->setModal(true);
00950 m_dialog->setAutoClose(false);
00951 m_dialog->setMinimumDuration(0);
00952
00953
00954 m_dialog->setButtonText(i18nc("@action:button", "Quit without saving"));
00955 m_dialog->exec();
00956 delete m_dialog;
00957 };
00958
00959 return true;
00960 }
00961
00962 void stationlistModel::saveProperties(KConfigGroup & m_configGroup)
00963 {
00964 rememberListOfStreamsWhichTheUserWantsToRip_ifNotYetDone();
00965 m_configGroup.writePathEntry("streamsToResume",
00966 * m_listOfStreamsOfWhichTheUserWantsThatTheyRip);
00967
00968 }
00969
00970 void stationlistModel::readProperties(const KConfigGroup & m_configGroup)
00971 {
00972
00973 QStringList temp_stringList;
00974 int i;
00975
00976
00977 temp_stringList = m_configGroup.readPathEntry("streamsToResume", temp_stringList);
00978 for (i = 0; i < rowCount(); i++) {
00979 if (temp_stringList.contains(m_stationlist.at(i)->configFileName())) {
00980 m_stationlist.at(i)->startStreamripper();
00981 };
00982 };
00983 }
00984
00985 QList<QUrl> stationlistModel::helper_convertToUrl(const QMimeData *data)
00986 {
00987
00988 QList<QUrl> returnValue;
00989
00990
00991 if (data->hasUrls()) {
00992 returnValue = data->urls();
00993 } else if (data->hasText()) {
00994 QStringList temp = data->text().split(QRegExp("\\s"), QString::SkipEmptyParts);
00995 foreach (const QString & singleString, temp) {
00996 returnValue.append(singleString);
00997 };
00998 };
00999 int i = 0;
01000 while (i < returnValue.size()) {
01001 if (returnValue.at(i).isValid() && (!returnValue.at(i).isEmpty())) {
01002 ++i;
01003 } else {
01004 returnValue.removeAt(i);
01005 };
01006 };
01007
01008 return returnValue;
01009 }
01010
01011 void stationlistModel::paste()
01012 {
01013 dropMimeData(QApplication::clipboard()->mimeData(),
01014 Qt::CopyAction,
01015 0,
01016 0,
01017 QModelIndex());
01018 }
01019
01020 void stationlistModel::pasteSelection()
01021 {
01022 dropMimeData(QApplication::clipboard()->mimeData(QClipboard::Selection),
01023 Qt::CopyAction,
01024 0,
01025 0,
01026 QModelIndex());
01027 }
01028
01029 bool stationlistModel::dropMimeData(const QMimeData *data,
01030 Qt::DropAction action,
01031 int,
01032 int,
01033 const QModelIndex &)
01034 {
01035 if (action == Qt::IgnoreAction) {
01036 return true;
01037 };
01038
01039 if (!(action == Qt::CopyAction)) {
01040 return false;
01041 };
01042
01043 QList<QUrl> urlList = helper_convertToUrl(data);
01044
01045 if (urlList.isEmpty()) {
01046 return false;
01047 } else {
01048
01049 const int size_of_list = m_stationlist.size();
01050
01051 QPointer<radioStation> m_newStation;
01052
01053 beginInsertRows(QModelIndex(), size_of_list, size_of_list + urlList.size() - 1);
01054 for (int i = 0; i < urlList.size(); ++i) {
01055 m_newStation = new radioStation(this, m_mainWidget, QString(), size_of_list + i);
01056 m_newStation->setServerUri(urlList.at(i));
01057 m_stationlist.append(m_newStation);
01058 helper_connectSignalsAndSlots(m_stationlist.last());
01059 };
01060 helper_writeStationListToGeneralSettings();
01061 endInsertRows();
01062 if (!view.isNull()) {
01063 view->selectionModel()->clear();
01064 view->selectionModel()->select(
01065 QItemSelection(index(size_of_list, 0),
01066 index(size_of_list + urlList.size() - 1, columnCount() - 1)),
01067 QItemSelectionModel::SelectCurrent);
01068 };
01069 return true;
01070 };
01071
01072 return false;
01073 }
01074
01075 Qt::ItemFlags stationlistModel::flags(const QModelIndex & index) const
01076 {
01077 return (Qt::ItemIsDropEnabled | QAbstractItemModel::flags(index));
01078 }
01079
01080 QStringList stationlistModel::mimeTypes () const
01081 {
01082 QStringList value;
01083 value << "text/plain" << "text/uri-list";
01084 return value;
01085 }
01086
01087 void stationlistModel::enableListeningIn()
01088 {
01089 QModelIndexList actuallySelectedRows = view->selectionModel()->selectedRows();
01090 if (actuallySelectedRows.size() == 1) {
01091 listen.setStation(m_stationlist.at(actuallySelectedRows.at(0).row()));
01092 } else {
01093 listen.setStation(0);
01094 };
01095 }
01096
01097 void stationlistModel::disableListeningIn()
01098 {
01099 listen.setStation(0);
01100 }