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
00023 #include "folderpropertiesdialog.h"
00024 #include "includekio.h"
00025 #include "stationlistwidget.h"
00026 #include "settings_general.h"
00027 #include <QAbstractItemModel>
00028 #include <QApplication>
00029 #include <QClipboard>
00030 #include <QFile>
00031 #include <QItemSelection>
00032 #include <QMimeData>
00033 #include <QXmlStreamReader>
00034 #include <KLocale>
00035 #include <KProgressDialog>
00036 #include <KStandardDirs>
00037 #include <KTemporaryFile>
00038 #define AND &&
00039 #define OR ||
00040 #define NOT !
00041 #define EQUAL ==
00042
00043 stationlistModel::stationlistModel(stationlistWidget *parent,
00044 QWidget *mainWidget) : QAbstractItemModel(parent)
00045 {
00046
00047 QXmlStreamReader stationlistReader;
00048 QFile stationlistFile;
00049 stationlistItem *actualFolder;
00050 stationlistItem *temp_item;
00051 QString temp_string;
00052 QModelIndexList expandedRows;
00053
00054
00055 m_mainWidget = mainWidget;
00056 view = parent;
00057 m_listOfStreamsOfWhichTheUserWantsThatTheyRip = 0;
00058
00059 rootItem = new stationlistItem("");
00060 stationlistFile.setFileName(helper_stationlistXmlFilepath());
00061 if (stationlistFile.open(QIODevice::ReadOnly)) {
00062 stationlistReader.setDevice(&stationlistFile);
00063 actualFolder = rootItem;
00064 while (!stationlistReader.atEnd()) {
00065 stationlistReader.readNext();
00066 if (stationlistReader.name() == "folder") {
00067 if (stationlistReader.isStartElement()) {
00068 temp_item = new stationlistItem(stationlistReader.attributes().value("name").toString());
00069 actualFolder->appendChild(temp_item);
00070 actualFolder = temp_item;
00071 if (stationlistReader.attributes().value("expanded").toString() == "true") {
00072 expandedRows.append(modelindexOfItem(temp_item, 0));
00073 };
00074 } else if (stationlistReader.isEndElement()) {
00075 actualFolder = actualFolder->parent();
00076 if (!actualFolder) {
00077 actualFolder = rootItem;
00078 };
00079 };
00080 } else if (stationlistReader.name() == "stream" && stationlistReader.isStartElement()) {
00081 temp_item = helper_createStreamItem(new radioStation(this,
00082 m_mainWidget,
00083 stationlistReader.readElementText()));
00084 actualFolder->appendChild(temp_item);
00085 };
00086 };
00087 };
00088
00089
00090 recalculate_numberOfActiveStreams_and_bandwidth();
00091
00092 connect(this, SIGNAL(rowsInserted(const QModelIndex &, int, int)),
00093 this, SLOT(recalculate_numberOfActiveStreams_and_bandwidth()));
00094 connect(this, SIGNAL(rowsRemoved(const QModelIndex &, int, int)),
00095 this, SLOT(recalculate_numberOfActiveStreams_and_bandwidth()));
00096 view->setModel(this);
00097 foreach (const QModelIndex &m_index, expandedRows) {
00098 view->expand(m_index);
00099 };
00100 helper_writeStationList();
00101
00102
00103
00104 connect(view->selectionModel(),
00105 SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
00106 this,
00107 SLOT(recalculateSelectedStreams()));
00108 }
00109
00110 stationlistModel::~stationlistModel()
00111 {
00112 delete rootItem;
00113 }
00114
00115 void stationlistModel::helper_connectSignalsAndSlots(radioStation *m_stream)
00116 {
00117 connect(m_stream, SIGNAL(streamNameChanged(void *, PropertyValue)),
00118 this, SLOT(reloadStreamName(void *)));
00119 connect(m_stream, SIGNAL(uriChanged(void *, PropertyValue)),
00120 this, SLOT(reloadUri(void *)));
00121 connect(m_stream, SIGNAL(statusChanged(void *, PropertyValue)),
00122 this, SLOT(reloadStatus(void *)));
00123 connect(m_stream, SIGNAL(errorChanged(void *, PropertyValue)),
00124 this, SLOT(reloadStatus(void *)));
00125 connect(m_stream, SIGNAL(songChanged(void *, PropertyValue)),
00126 this, SLOT(reloadSong(void *)));
00127 connect(m_stream, SIGNAL(dataSizeChanged(void *, PropertyValue)),
00128 this, SLOT(reloadDataSize(void *)));
00129 connect(m_stream, SIGNAL(bitrateChanged(void *, PropertyValue)),
00130 this, SLOT(reloadBitrate(void *)));
00131 connect(m_stream, SIGNAL(bitrateChanged(void *, PropertyValue)),
00132 this, SLOT(recalculate_numberOfActiveStreams_and_bandwidth()));
00133 connect(m_stream, SIGNAL(metaIntervalChanged(void *, PropertyValue)),
00134 this, SLOT(reloadMetaInterval(void *)));
00135 connect(m_stream, SIGNAL(metaInterval_milliSecondsChanged(void *, PropertyValue)),
00136 this, SLOT(reloadMetaInterval_milliSeconds(void *)));
00137 connect(m_stream, SIGNAL(serverNameChanged(void *, PropertyValue)),
00138 this, SLOT(reloadServerName(void *)));
00139 connect(m_stream, SIGNAL(relayPortChanged(void *, PropertyValue)),
00140 this, SLOT(reloadRelayPort(void *)));
00141 connect(m_stream, SIGNAL(running()),
00142 this, SLOT(recalculate_numberOfActiveStreams_and_bandwidth()));
00143 connect(m_stream, SIGNAL(not_running()),
00144 this, SLOT(recalculate_numberOfActiveStreams_and_bandwidth()));
00145 }
00146
00147 inline QString stationlistModel::helper_stationlistXmlFilepath()
00148 {
00149 return KStandardDirs::locateLocal("appdata", "stationlist.xml");
00150 }
00151
00152 int stationlistModel::rowCount (const QModelIndex & parent) const
00153 {
00154
00155 stationlistItem *parentItem = item(parent);
00156
00157
00158 if (parent.column() > 0) {
00159 return 0;
00160 };
00161 return parentItem->childCount();
00162 }
00163
00164 int stationlistModel::columnCount (const QModelIndex &) const
00165 {
00166 return 10;
00167 }
00168
00169 QVariant stationlistModel::columnInfo(const columnInfoType type,
00170 const int column,
00171 const radioStation *stream,
00172 const quint64 value) const
00173 {
00174 QVariant temp;
00175
00176 switch (type) {
00177 case columnHeaderTitle:
00178 case columnHeaderToolTip:
00179 case columnHeaderWhatsThis:
00180 case columnWidth:
00181 case setColumnWidth:
00182 case columnVisibility:
00183 case setColumnVisibility:
00184 break;
00185 default:
00186 if (stream == 0) {
00187 return QVariant();
00188 };
00189 }
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 switch (column) {
00206
00207 case 0:
00208 {
00209 switch (type) {
00210 case columnHeaderTitle:
00211 return i18nc("@title:column", "stream name");
00212 case columnHeaderToolTip:
00213 case columnHeaderWhatsThis:
00214 return QVariant();
00215 case columnWidth:
00216 return settings_general::columnWidth_streamName();
00217 case setColumnWidth:
00218 settings_general::setColumnWidth_streamName(value);
00219 settings_general::self()->writeConfig();
00220 return QVariant();
00221 case columnVisibility:
00222 return settings_general::columnVisibility_streamName();
00223 case setColumnVisibility:
00224 settings_general::setColumnVisibility_streamName(value);
00225 settings_general::self()->writeConfig();
00226 return QVariant();
00227 case columnData:
00228 temp.setValue<PropertyValue>(stream->streamName());
00229 return temp;
00230 };
00231 break;
00232 }
00233
00234 case 1:
00235 {
00236 switch (type) {
00237 case columnHeaderTitle:
00238 return i18nc("@title:column", "URL");
00239 case columnHeaderToolTip:
00240 case columnHeaderWhatsThis:
00241 return QVariant();
00242 case columnWidth:
00243 return settings_general::columnWidth_uri();
00244 case setColumnWidth:
00245 settings_general::setColumnWidth_uri(value);
00246 settings_general::self()->writeConfig();
00247 return QVariant();
00248 case columnVisibility:
00249 return settings_general::columnVisibility_uri();
00250 case setColumnVisibility:
00251 settings_general::setColumnVisibility_uri(value);
00252 settings_general::self()->writeConfig();
00253 return QVariant();
00254 case columnData:
00255 temp.setValue<PropertyValue>(stream->uri());
00256 return temp;
00257 };
00258 break;
00259 }
00260
00261 case 2:
00262 {
00263 switch (type) {
00264 case columnHeaderTitle:
00265 return i18nc("@title:column", "status");
00266 case columnHeaderToolTip:
00267 case columnHeaderWhatsThis:
00268 return QVariant();
00269 case columnWidth:
00270 return settings_general::columnWidth_statusAndError();
00271 case setColumnWidth:
00272 settings_general::setColumnWidth_statusAndError(value);
00273 settings_general::self()->writeConfig();
00274 return QVariant();
00275 case columnVisibility:
00276 return settings_general::columnVisibility_statusAndError();
00277 case setColumnVisibility:
00278 settings_general::setColumnVisibility_statusAndError(value);
00279 settings_general::self()->writeConfig();
00280 return QVariant();
00281 case columnData:
00282 PropertyValue my_statusAndError;
00283 if (stream->error().formatedValue.isEmpty()) {
00284 my_statusAndError.formatedValue = stream->status().formatedValue;
00285 my_statusAndError.toolTip = stream->status().toolTip;
00286 my_statusAndError.whatsThis = stream->status().whatsThis;
00287 } else {
00288 my_statusAndError.toolTip = stream->error().toolTip;
00289 my_statusAndError.whatsThis = stream->error().whatsThis;
00290 if (stream->status().formatedValue.isEmpty()) {
00291 my_statusAndError.formatedValue = stream->error().formatedValue;
00292 } else {
00293 my_statusAndError.formatedValue = QString(i18nc(
00294 "@item:intable This produces the status message from the actual status (%1) and "
00295 "the error message (%3). Both of them are guaranteed to be not empty. %2 is "
00296 "replaced by an en-dash (Unicode U+2013). Use it or replace it by something "
00297 "what looks nicer in your language.",
00298 "%1 %2 %3",
00299 stream->status().formatedValue,
00300 QString(QChar(0x2013)),
00301 stream->error().formatedValue));
00302 };
00303 };
00304 my_statusAndError.internalValue = stream->status().internalValue;
00305 if ((!(stream->error().type == PropertyValue::unset)) ||
00306 (stream->status().type == PropertyValue::error)) {
00307 my_statusAndError.type = PropertyValue::error;
00308 } else if (my_statusAndError.formatedValue.isEmpty()) {
00309 my_statusAndError.type = PropertyValue::unset;
00310 } else {
00311 my_statusAndError.type = PropertyValue::value;
00312 };
00313 temp.setValue<PropertyValue>(my_statusAndError);
00314 return temp;
00315 };
00316 break;
00317 }
00318
00319 case 3:
00320 {
00321 switch (type) {
00322 case columnHeaderTitle:
00323 return i18nc("@title:column header of the column with the name of the actual track",
00324 "track");
00325 case columnHeaderToolTip:
00326 case columnHeaderWhatsThis:
00327 return QVariant();
00328 case columnWidth:
00329 return settings_general::columnWidth_song();
00330 case setColumnWidth:
00331 settings_general::setColumnWidth_song(value);
00332 settings_general::self()->writeConfig();
00333 return QVariant();
00334 case columnVisibility:
00335 return settings_general::columnVisibility_song();
00336 case setColumnVisibility:
00337 settings_general::setColumnVisibility_song(value);
00338 settings_general::self()->writeConfig();
00339 return QVariant();
00340 case columnData:
00341 temp.setValue<PropertyValue>(stream->song());
00342 return temp;
00343 };
00344 break;
00345 }
00346
00347 case 4:
00348 {
00349 switch (type) {
00350 case columnHeaderTitle:
00351 return i18nc("@title:column", "track size");
00352 case columnHeaderToolTip:
00353 case columnHeaderWhatsThis:
00354 return QVariant();
00355 case columnWidth:
00356 return settings_general::columnWidth_dataSize();
00357 case setColumnWidth:
00358 settings_general::setColumnWidth_dataSize(value);
00359 settings_general::self()->writeConfig();
00360 return QVariant();
00361 case columnVisibility:
00362 return settings_general::columnVisibility_dataSize();
00363 case setColumnVisibility:
00364 settings_general::setColumnVisibility_dataSize(value);
00365 settings_general::self()->writeConfig();
00366 return QVariant();
00367 case columnData:
00368 temp.setValue<PropertyValue>(stream->dataSize());
00369 return temp;
00370 };
00371 break;
00372 }
00373
00374 case 5:
00375 {
00376 switch (type) {
00377 case columnHeaderTitle:
00378 return i18nc("@title:column", "bit rate");
00379 case columnHeaderToolTip:
00380 case columnHeaderWhatsThis:
00381 return QVariant();
00382 case columnWidth:
00383 return settings_general::columnWidth_bitrate();
00384 case setColumnWidth:
00385 settings_general::setColumnWidth_bitrate(value);
00386 settings_general::self()->writeConfig();
00387 return QVariant();
00388 case columnVisibility:
00389 return settings_general::columnVisibility_bitrate();
00390 case setColumnVisibility:
00391 settings_general::setColumnVisibility_bitrate(value);
00392 settings_general::self()->writeConfig();
00393 return QVariant();
00394 case columnData:
00395 temp.setValue<PropertyValue>(stream->bitrate());
00396 return temp;
00397 };
00398 break;
00399 }
00400
00401 case 6:
00402 {
00403 switch (type) {
00404 case columnHeaderTitle:
00405 return i18nc("@title:column The unit is KiB instead of kB. See "
00406 "http://en.wikipedia.org/wiki/Binary_prefix for details.",
00407 "meta data interval (KiB)");
00408 case columnHeaderToolTip:
00409 return i18nc("@info:tooltip", "interval of meta data in bytes");
00410 case columnHeaderWhatsThis:
00411 return QVariant();
00412 case columnWidth:
00413 return settings_general::columnWidth_metaInterval();
00414 case setColumnWidth:
00415 settings_general::setColumnWidth_metaInterval(value);
00416 settings_general::self()->writeConfig();
00417 return QVariant();
00418 case columnVisibility:
00419 return settings_general::columnVisibility_metaInterval();
00420 case setColumnVisibility:
00421 settings_general::setColumnVisibility_metaInterval(value);
00422 settings_general::self()->writeConfig();
00423 return QVariant();
00424 case columnData:
00425 temp.setValue<PropertyValue>(stream->metaInterval());
00426 return temp;
00427 };
00428 break;
00429 }
00430
00431 case 7:
00432 {
00433 switch (type) {
00434 case columnHeaderTitle:
00435 return i18nc("@title:column unit is millisecond", "meta data interval (ms)");
00436 case columnHeaderToolTip:
00437 return i18nc("@info:tooltip", "interval of meta data in milliseconds");
00438 case columnHeaderWhatsThis:
00439 return QVariant();
00440 case columnWidth:
00441 return settings_general::columnWidth_metaInterval_milliSeconds();
00442 case setColumnWidth:
00443 settings_general::setColumnWidth_metaInterval_milliSeconds(value);
00444 settings_general::self()->writeConfig();
00445 return QVariant();
00446 case columnVisibility:
00447 return settings_general::columnVisibility_metaInterval_milliSeconds();
00448 case setColumnVisibility:
00449 settings_general::setColumnVisibility_metaInterval_milliSeconds(value);
00450 settings_general::self()->writeConfig();
00451 return QVariant();
00452 case columnData:
00453 temp.setValue<PropertyValue>(stream->metaInterval_milliSeconds());
00454 return temp;
00455 };
00456 break;
00457 }
00458
00459 case 8:
00460 {
00461 switch (type) {
00462 case columnHeaderTitle:
00463 return i18nc("@title:column", "server name");
00464 case columnHeaderToolTip:
00465 case columnHeaderWhatsThis:
00466 return QVariant();
00467 case columnWidth:
00468 return settings_general::columnWidth_serverName();
00469 case setColumnWidth:
00470 settings_general::setColumnWidth_serverName(value);
00471 settings_general::self()->writeConfig();
00472 return QVariant();
00473 case columnVisibility:
00474 return settings_general::columnVisibility_serverName();
00475 case setColumnVisibility:
00476 settings_general::setColumnVisibility_serverName(value);
00477 settings_general::self()->writeConfig();
00478 return QVariant();
00479 case columnData:
00480 temp.setValue<PropertyValue>(stream->serverName());
00481 return temp;
00482 };
00483 break;
00484 }
00485
00486 case 9:
00487 {
00488 switch (type) {
00489 case columnHeaderTitle:
00490 return i18nc("@title:column 'relay port' means 'the port that the relay server uses'",
00491 "relay port");
00492 case columnHeaderToolTip:
00493 return i18nc("@info:tooltip", "port of the relay server");
00494 case columnHeaderWhatsThis:
00495 return QVariant();
00496 case columnWidth:
00497 return settings_general::columnWidth_relayPort();
00498 case setColumnWidth:
00499 settings_general::setColumnWidth_relayPort(value);
00500 settings_general::self()->writeConfig();
00501 return QVariant();
00502 case columnVisibility:
00503 return settings_general::columnVisibility_relayPort();
00504 case setColumnVisibility:
00505 settings_general::setColumnVisibility_relayPort(value);
00506 settings_general::self()->writeConfig();
00507 return QVariant();
00508 case columnData:
00509 temp.setValue<PropertyValue>(stream->relayPort());
00510 return temp;
00511 };
00512 break;
00513 }
00514
00515
00516
00517
00518 };
00519 return QVariant();
00520 }
00521
00522 QList<radioStation *> stationlistModel::helper_listOfAllStreams(stationlistItem *parentItem)
00523 {
00524 QList<radioStation *> list;
00525 if (parentItem->type() == stationlistItem::stream) {
00526 list.append(parentItem->streamObject());
00527 } else {
00528 for (int i = 0; i < parentItem->childCount(); ++i) {
00529 list << helper_listOfAllStreams(parentItem->child(i));
00530 };
00531 };
00532 return list;
00533 }
00534
00535 void stationlistModel::recalculate_numberOfActiveStreams_and_bandwidth()
00536 {
00537
00538 int i;
00539 int temp_numberOfActiveStreams = 0;
00540 quint64 temp_bandwidth = 0;
00541 QList<radioStation *> m_stationlist = helper_listOfAllStreams(rootItem);
00542
00543
00544
00545
00546 for (i=0; i < m_stationlist.size(); ++i) {
00547 if (m_stationlist.at(i)->status().internalValue.value<ripping::statusType>() != ripping::idle) {
00548 temp_numberOfActiveStreams++;
00549 if (m_stationlist.at(i)->bitrate().type == PropertyValue::value) {
00550 temp_bandwidth = temp_bandwidth +
00551 m_stationlist.at(i)->bitrate().internalValue.toULongLong();
00552 };
00553 };
00554 };
00555
00556
00557 if (internal_numberOfActiveStreams != temp_numberOfActiveStreams) {
00558 internal_numberOfActiveStreams = temp_numberOfActiveStreams;
00559 emit numberOfActiveStreamsChanged();
00560 if (internal_numberOfActiveStreams == 0) {
00561 emit numberOfActiveStreamsIsZero();
00562 };
00563 };
00564 if (internal_bandwidth != temp_bandwidth) {
00565 internal_bandwidth = temp_bandwidth;
00566 emit bandwidthChanged();
00567 };
00568 }
00569
00570 QModelIndex stationlistModel::modelindexOfItem(stationlistItem *item, int column)
00571 {
00572 if (item == rootItem || item == 0) {
00573 return QModelIndex();
00574 } else {
00575 return index(item->row(), column, modelindexOfItem(item->parent(), 0));
00576 };
00577 }
00578
00579 void stationlistModel::reloadStreamName(void *stationIndex)
00580 {
00581 emit dataChanged(modelindexOfItem(static_cast<stationlistItem *>(stationIndex), 0),
00582 modelindexOfItem(static_cast<stationlistItem *>(stationIndex), 0));
00583 }
00584
00585 void stationlistModel::reloadUri(void *stationIndex)
00586 {
00587 emit dataChanged(modelindexOfItem(static_cast<stationlistItem *>(stationIndex), 1),
00588 modelindexOfItem(static_cast<stationlistItem *>(stationIndex), 1));
00589 }
00590
00591 void stationlistModel::reloadStatus(void *stationIndex)
00592 {
00593 emit dataChanged(modelindexOfItem(static_cast<stationlistItem *>(stationIndex), 2),
00594 modelindexOfItem(static_cast<stationlistItem *>(stationIndex), 2));
00595 emit statusChanged();
00596 }
00597
00598 void stationlistModel::reloadSong(void *stationIndex)
00599 {
00600 emit dataChanged(modelindexOfItem(static_cast<stationlistItem *>(stationIndex), 3),
00601 modelindexOfItem(static_cast<stationlistItem *>(stationIndex), 3));
00602 }
00603
00604 void stationlistModel::reloadDataSize(void *stationIndex)
00605 {
00606 emit dataChanged(modelindexOfItem(static_cast<stationlistItem *>(stationIndex), 4),
00607 modelindexOfItem(static_cast<stationlistItem *>(stationIndex), 4));
00608 }
00609
00610 void stationlistModel::reloadBitrate(void *stationIndex)
00611 {
00612 emit dataChanged(modelindexOfItem(static_cast<stationlistItem *>(stationIndex), 5),
00613 modelindexOfItem(static_cast<stationlistItem *>(stationIndex), 5));
00614 }
00615
00616 void stationlistModel::reloadMetaInterval(void *stationIndex)
00617 {
00618 emit dataChanged(modelindexOfItem(static_cast<stationlistItem *>(stationIndex), 6),
00619 modelindexOfItem(static_cast<stationlistItem *>(stationIndex), 6));
00620 }
00621
00622 void stationlistModel::reloadMetaInterval_milliSeconds(void *stationIndex)
00623 {
00624 emit dataChanged(modelindexOfItem(static_cast<stationlistItem *>(stationIndex), 7),
00625 modelindexOfItem(static_cast<stationlistItem *>(stationIndex), 7));
00626 }
00627
00628 void stationlistModel::reloadServerName(void *stationIndex)
00629 {
00630 emit dataChanged(modelindexOfItem(static_cast<stationlistItem *>(stationIndex), 8),
00631 modelindexOfItem(static_cast<stationlistItem *>(stationIndex), 8));
00632 }
00633
00634 void stationlistModel::reloadRelayPort(void *stationIndex)
00635 {
00636 emit dataChanged(modelindexOfItem(static_cast<stationlistItem *>(stationIndex), 9),
00637 modelindexOfItem(static_cast<stationlistItem *>(stationIndex), 9));
00638 emit relayportChanged();
00639 }
00640
00641 QVariant stationlistModel::headerData(int section, Qt::Orientation orientation, int role) const
00642 {
00643 if (orientation EQUAL Qt::Vertical) {
00644 if (role == Qt::DisplayRole) {
00645 return (int(section+1));
00646 } else {
00647 return QVariant();
00648 };
00649 } else {
00650 switch (role) {
00651 case Qt::DisplayRole:
00652 return columnInfo(columnHeaderTitle, section);
00653 case Qt::ToolTipRole:
00654 return columnInfo(columnHeaderToolTip, section);
00655 case Qt::WhatsThisRole:
00656 return columnInfo(columnHeaderWhatsThis, section);
00657 default:
00658 return QVariant();
00659 };
00660 };
00661 return QVariant();
00662
00663
00664 }
00665
00666 QVariant stationlistModel::data(const QModelIndex &index, int role) const
00667 {
00668
00669 QVariant returnValue;
00670 stationlistItem *indexItem;
00671
00672
00673 if ((index.model() EQUAL this) AND (index.isValid())) {
00674 indexItem = static_cast<stationlistItem *>(index.internalPointer());
00675 if (indexItem->type() == stationlistItem::stream) {
00676 switch (role) {
00677 case Qt::DisplayRole:
00678 returnValue = columnInfo(columnData, index.column(), indexItem->streamObject())
00679 .value<PropertyValue>().formatedValue;
00680 break;
00681 case Qt::ToolTipRole:
00682 returnValue =
00683 columnInfo(columnData, index.column(), indexItem->streamObject()).
00684 value<PropertyValue>().toolTip;
00685 break;
00686 case Qt::WhatsThisRole:
00687 returnValue =
00688 columnInfo(columnData, index.column(), indexItem->streamObject()).
00689 value<PropertyValue>().whatsThis;
00690 break;
00691 case Qt::TextAlignmentRole:
00692 returnValue = static_cast<int>(
00693 columnInfo(columnData, index.column(), indexItem->streamObject()).
00694 value<PropertyValue>().formatedValueAlignment);
00695 break;
00696 case Qt::DecorationRole:
00697 if (index.column() == 0) {
00698 returnValue = KIcon("audio-x-generic");
00699 };
00700 break;
00701 default:
00702 returnValue = QVariant();
00703 break;
00704 };
00705 } else {
00706 if (role == Qt::DisplayRole AND index.column() == 0) {
00707 returnValue = indexItem->folderName();
00708 } else if (role == Qt::DecorationRole AND index.column() == 0) {
00709 returnValue = KIcon("folder");
00710 };
00711 };
00712 };
00713
00714
00715 return returnValue;
00716 }
00717
00718 void stationlistModel::sort(int column, Qt::SortOrder order)
00719 {
00720
00721 if (column < 0 || column >= columnCount()) {
00722 return;
00723 };
00724
00725
00726 PropertyValue temp;
00727 QList<radioStation *> sorted_list;
00728 QModelIndexList temp_indexList;
00729 QList<stationlistItem *> selection;
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740 sortChildItems(rootItem, column, order);
00741
00742
00743
00744
00745 settings_general::setSortingAscendingly(order == Qt::AscendingOrder);
00746 settings_general::setSortByColumn(column);
00747 settings_general::self()->writeConfig();
00748 }
00749
00750 void stationlistModel::helper_moveItems(const QModelIndex &oldParent,
00751 int first,
00752 int last,
00753 const QModelIndex &newParent,
00754 int newRow)
00755 {
00756 QList<stationlistItem *> itemList = helper_removeItems(oldParent, first, last);
00757 helper_insertItems(itemList, newParent, newRow);
00758 }
00759
00760 void stationlistModel::sortChildItems(stationlistItem *parent, int column, Qt::SortOrder order)
00761 {
00762
00763 const int childCount = parent->childCount();
00764 const int childCount_1 = childCount -1;
00765 QModelIndex parentIndex = modelindexOfItem(parent, 0);
00766
00767
00768 int i;
00769
00770
00771 for (i = 0; i < childCount_1; ++i) {
00772 for (int j = i + 1; j < childCount; ++j) {
00773 if (helper_firstIsAfterSecond(parent->child(i), parent->child(j), column, order)) {
00774 helper_moveItems(parentIndex, j, j, parentIndex, i);
00775 };
00776 };
00777 };
00778 for (i = 0; i < childCount; ++i) {
00779 sortChildItems(parent->child(i), column, order);
00780 };
00781 }
00782
00783 bool stationlistModel::helper_isNumericValue(const QVariant & value)
00784 {
00785
00786 QMetaType::Type type;
00787
00788
00789 type = static_cast<QMetaType::Type>(value.type());
00790 return (type == QMetaType::Int ||
00791 type == QMetaType::UInt ||
00792 type == QMetaType::Double ||
00793 type == QMetaType::Long ||
00794 type == QMetaType::LongLong ||
00795 type == QMetaType::Short ||
00796 type == QMetaType::Char ||
00797 type == QMetaType::ULong ||
00798 type == QMetaType::ULongLong ||
00799 type == QMetaType::UShort ||
00800 type == QMetaType::UChar ||
00801 type == QMetaType::Float ||
00802
00803 value.typeName() == QString("ripping::statusType"));
00804 }
00805
00806 qlonglong stationlistModel::helper_toLongLong(const PropertyValue & value)
00807 {
00808
00809 if (value.internalValue.typeName() == QString("ripping::statusType")) {
00810 return value.internalValue.value<ripping::statusType>();
00811 } else {
00812 return value.internalValue.toLongLong();
00813 };
00814 }
00815
00816 bool stationlistModel::helper_firstIsAfterSecond(stationlistItem *firstItem,
00817 stationlistItem *secondItem,
00818 int column,
00819 Qt::SortOrder order)
00820 {
00821 if (firstItem->type() == stationlistItem::stream) {
00822 if (secondItem->type() == stationlistItem::stream) {
00823 return helper_firstIsAfterSecond(
00824 columnInfo(columnData, column, firstItem->streamObject()).value<PropertyValue>(),
00825 columnInfo(columnData, column, secondItem->streamObject()).value<PropertyValue>(),
00826 order);
00827 } else {
00828 return true;
00829 };
00830 } else {
00831 if (secondItem->type() == stationlistItem::stream) {
00832 return false;
00833 } else {
00834 if (order == Qt::AscendingOrder) {
00835 return (QString::localeAwareCompare(firstItem->folderName(), secondItem->folderName()) >=
00836 0);
00837 } else {
00838 return (QString::localeAwareCompare(firstItem->folderName(), secondItem->folderName()) <=
00839 0);
00840 };
00841 };
00842 };
00843 kDebug() << "Function hasn't calculated a return value. TRUE is returned to prevent a crash.";
00844 return true;
00845 }
00846
00847 bool stationlistModel::helper_firstIsAfterSecond(const PropertyValue & firstValue,
00848 const PropertyValue & secondValue,
00849 Qt::SortOrder order)
00850 {
00851
00852 if (order == Qt::AscendingOrder) {
00853 switch (firstValue.type) {
00854 case PropertyValue::unset:
00855 return (secondValue.type == PropertyValue::unset);
00856 case PropertyValue::value:
00857 if (secondValue.type == PropertyValue::unset) {
00858 return true;
00859 } else if (secondValue.type == PropertyValue::error) {
00860 return false;
00861 } else {
00862 if (helper_isNumericValue(firstValue.internalValue) &&
00863 helper_isNumericValue(secondValue.internalValue)) {
00864 return helper_toLongLong(firstValue) >= helper_toLongLong(secondValue);
00865 } else {
00866 return QString::localeAwareCompare(firstValue.formatedValue,
00867 secondValue.formatedValue) >= 0;
00868 };
00869 };
00870 case PropertyValue::error:
00871 if (secondValue.type == PropertyValue::error) {
00872 return QString::localeAwareCompare(firstValue.formatedValue,
00873 secondValue.formatedValue) >= 0;
00874 } else {
00875 return true;
00876 };
00877 };
00878 } else {
00879 switch (firstValue.type) {
00880 case PropertyValue::unset:
00881 return true;
00882 case PropertyValue::value:
00883 if (secondValue.type == PropertyValue::unset) {
00884 return false;
00885 } else if (secondValue.type == PropertyValue::error) {
00886 return true;
00887 } else {
00888 if (helper_isNumericValue(firstValue.internalValue) &&
00889 helper_isNumericValue(secondValue.internalValue)) {
00890 return helper_toLongLong(firstValue) <= helper_toLongLong(secondValue);
00891 } else {
00892 return QString::localeAwareCompare(firstValue.formatedValue,
00893 secondValue.formatedValue) <= 0;
00894 };
00895 };
00896 case PropertyValue::error:
00897 if (secondValue.type == PropertyValue::error) {
00898 return QString::localeAwareCompare(firstValue.formatedValue,
00899 secondValue.formatedValue) <= 0;
00900 } else {
00901 return false;
00902 };
00903 };
00904 };
00905 kDebug() << "Function hasn't calculated a return value. TRUE is returned to prevent a crash.";
00906 return true;
00907 }
00908
00909 bool stationlistModel::helper_isInTree(stationlistItem *child, stationlistItem *parent)
00910 {
00911 if (child == 0 OR parent == 0) {
00912 return false;
00913 };
00914 if (child->parent() == 0) {
00915 return false;
00916 };
00917 if (child->parent() == parent) {
00918 return true;
00919 } else {
00920 return helper_isInTree(child->parent(), parent);
00921 };
00922 }
00923
00924 QList<stationlistItem *> stationlistModel::helper_removeItems(const QModelIndex &parent,
00925 int first,
00926 int last)
00927 {
00928
00929 QList<stationlistItem *> returnValue;
00930 stationlistItem *parentItem = item(parent);
00931
00932
00933 beginRemoveRows(parent, first, last);
00934 for (int i = last; i >= first; --i) {
00935 returnValue.prepend(parentItem->child(i));
00936 returnValue.first()->detach();
00937 };
00938 endRemoveRows();
00939 return returnValue;
00940 }
00941
00942 void stationlistModel::helper_insertItem(stationlistItem * item,
00943 const QModelIndex &parent,
00944 int row)
00945 {
00946 QList<stationlistItem *> itemList;
00947 itemList.append(item);
00948 helper_insertItems(itemList, parent, row);
00949 }
00950
00951 void stationlistModel::helper_insertItems(QList<stationlistItem *> itemList,
00952 const QModelIndex &parent,
00953 int row)
00954 {
00955
00956 stationlistItem *parentItem = item(parent);
00957
00958
00959 beginInsertRows(parent, row, row + itemList.size() - 1);
00960 for (int i = 0; i < itemList.size(); ++i) {
00961 parentItem->insertChild(itemList.at(i), row + i);
00962 };
00963 endInsertRows();
00964 }
00965
00966 stationlistItem *stationlistModel::helper_createStreamItem(radioStation *stream)
00967 {
00968
00969 stationlistItem *returnValue;
00970
00971
00972 returnValue = new stationlistItem(stream);
00973 stream->setIndex(returnValue);
00974 helper_connectSignalsAndSlots(stream);
00975 return returnValue;
00976 }
00977
00978 void stationlistModel::helper_addNewFolder(const QModelIndex & index)
00979 {
00980
00981 int exitCode;
00982 stationlistItem *new_item, *parent_item;
00983 folderPropertiesDialog *dialog;
00984
00985
00986 dialog = new folderPropertiesDialog();
00987 exitCode = dialog->exec();
00988 if (exitCode == QDialog::Accepted) {
00989 new_item = new stationlistItem(dialog->centralWidget->text());
00990 parent_item = rootItem;
00991 if (index.isValid()) {
00992 if (static_cast<stationlistItem *>(index.internalPointer())->type() ==
00993 stationlistItem::folder) {
00994 parent_item = static_cast<stationlistItem *>(index.internalPointer());
00995 };
00996 };
00997 helper_insertItem(new_item,
00998 modelindexOfItem(parent_item, 0),
00999 parent_item->childCount());
01000 helper_selectAndScrollTo(QModelIndexList() << modelindexOfItem(new_item, 0));
01001 helper_writeStationList();
01002 };
01003 }
01004
01005 void stationlistModel::helper_addNewStation(const QModelIndex & index)
01006 {
01007
01008 radioStation *m_newStation;
01009 int exitCode;
01010 stationlistItem *new_item, *parent_item;
01011
01012
01013 m_newStation = new radioStation(this, m_mainWidget, QString());
01014 exitCode = m_newStation->execSettingsDialogWithoutApplyButton();
01015 if (exitCode == QDialog::Accepted) {
01016 new_item = helper_createStreamItem(m_newStation);
01017 parent_item = rootItem;
01018 if (index.isValid()) {
01019 if (static_cast<stationlistItem *>(index.internalPointer())->type() ==
01020 stationlistItem::folder) {
01021 parent_item = static_cast<stationlistItem *>(index.internalPointer());
01022 };
01023 };
01024 helper_insertItem(new_item,
01025 modelindexOfItem(parent_item, 0),
01026 parent_item->childCount());
01027 helper_selectAndScrollTo(QModelIndexList() << modelindexOfItem(new_item, 0));
01028 helper_writeStationList();
01029 } else {
01030 helper_deleteRadiostationobjectAndRemoveConfigfiles(m_newStation);
01031 };
01032 }
01033
01034 void stationlistModel::helper_selectAndScrollTo(const QModelIndexList & modelIndexList)
01035 {
01036 if (modelIndexList.size() > 0) {
01037 view->clearSelection();
01038 foreach (const QModelIndex & m_index, modelIndexList) {
01039 view->selectionModel()->select(m_index,
01040 QItemSelectionModel::Select | QItemSelectionModel::Rows);
01041 view->scrollToRow(m_index);
01042 };
01043 };
01044 }
01045
01046 void stationlistModel::addNewStationInFolder()
01047 {
01048 QModelIndexList m_list = view->selectionModel()->selectedRows();
01049 if (m_list.size() == 1) {
01050 helper_addNewStation(m_list.at(0));
01051 } else {
01052 helper_addNewStation(QModelIndex());
01053 };
01054 }
01055
01056 void stationlistModel::addNewFolderInFolder()
01057 {
01058 QModelIndexList m_list = view->selectionModel()->selectedRows();
01059 if (m_list.size() == 1) {
01060 helper_addNewFolder(m_list.at(0));
01061 } else {
01062 helper_addNewFolder(QModelIndex());
01063 };
01064 }
01065
01066 void stationlistModel::addNewStation()
01067 {
01068 helper_addNewStation(QModelIndex());
01069 }
01070
01071 void stationlistModel::addNewFolder()
01072 {
01073 helper_addNewFolder(QModelIndex());
01074 }
01075
01076 void stationlistModel::helper_deleteRadiostationobjectAndRemoveConfigfiles(stationlistItem *item)
01077 {
01078 if (item->type() == stationlistItem::stream) {
01079 helper_deleteRadiostationobjectAndRemoveConfigfiles(item->streamObject());
01080 } else {
01081 for (int i = 0; i < item->childCount(); ++i) {
01082 helper_deleteRadiostationobjectAndRemoveConfigfiles(item->child(i));
01083 }
01084 };
01085 }
01086
01087 void stationlistModel::helper_deleteRadiostationobjectAndRemoveConfigfiles(radioStation *station)
01088 {
01089 QString m_filename = station->fullConfigFileName();
01090 delete station;
01091
01092
01093 QFile theFile(m_filename);
01094 theFile.remove();
01095 }
01096
01097 stationlistItem *stationlistModel::item(const QModelIndex & index) const
01098 {
01099 if (index.isValid()) {
01100 return static_cast<stationlistItem *>(index.internalPointer());
01101 } else {
01102 return rootItem;
01103 };
01104 }
01105
01106 bool stationlistModel::removeRows(int row, int count, const QModelIndex & parent)
01107 {
01108
01109 stationlistItem *parentItem = item(parent);
01110 QList<stationlistItem *> itemList;
01111
01112
01113 if (count == 0) {
01114 return true;
01115 };
01116
01117 if ((row >= 0) &&
01118 (count > 0) &&
01119 ((row + count - 1) < parentItem->childCount())) {
01120
01121 itemList = helper_removeItems(parent, row, row + count - 1);
01122
01123 foreach (stationlistItem *item, itemList) {
01124 helper_deleteRadiostationobjectAndRemoveConfigfiles(item);
01125 delete item;
01126 };
01127
01128 helper_writeStationList();
01129 return true;
01130 } else {
01131 return false;
01132 };
01133 }
01134
01135 void stationlistModel::writeItemToFile(stationlistItem *item, QXmlStreamWriter &file)
01136 {
01137 if (item->type() == stationlistItem::stream) {
01138 file.writeTextElement("stream", item->streamObject()->configFileName());
01139 } else {
01140 file.writeStartElement("folder");
01141 file.writeAttribute("name", item->folderName());
01142 if (view->isExpanded(modelindexOfItem(item, 0))) {
01143 file.writeAttribute("expanded", "true");
01144 };
01145 for (int i = 0; i < item->childCount(); ++i) {
01146 writeItemToFile(item->child(i), file);
01147 };
01148 file.writeEndElement();
01149 };
01150 }
01151
01152 inline void stationlistModel::helper_writeStationList()
01153 {
01154
01155 KTemporaryFile tempfile;
01156 QXmlStreamWriter writer;
01157
01158
01159 tempfile.open();
01160 writer.setDevice(&tempfile);
01161 writer.setAutoFormatting(true);
01162 writer.writeStartDocument();
01163 writer.writeStartElement("stationlist");
01164 for (int i = 0; i < rootItem->childCount(); ++i) {
01165 writeItemToFile(rootItem->child(i), writer);
01166 };
01167 writer.writeEndElement();
01168 writer.writeEndDocument();
01169 tempfile.close();
01170 KIO::FileCopyJob *copyjob = KIO::file_move(tempfile.fileName(),
01171 helper_stationlistXmlFilepath(),
01172 -1,
01173 KIO::HideProgressInfo | KIO::Overwrite);
01174 KIO::NetAccess::synchronousRun(copyjob, 0);
01175 }
01176
01177 void stationlistModel::record()
01178 {
01179 foreach (radioStation *stream, internal_selectedStreams) {
01180 stream->startStreamripper();
01181 };
01182 }
01183
01184 void stationlistModel::stopRecording()
01185 {
01186 foreach (radioStation *stream, internal_selectedStreams) {
01187 stream->shutDown();
01188 };
01189 }
01190
01191 void stationlistModel::showConfigDialog()
01192 {
01193 QModelIndexList list = view->selectionModel()->selectedRows();
01194 if (list.size() == 1) {
01195 stationlistItem *item = static_cast<stationlistItem *>(list.at(0).internalPointer());
01196 if (item->type() == stationlistItem::stream) {
01197 item->streamObject()->showSettingsDialogWithApplyButton();
01198 } else {
01199 QPointer<folderPropertiesDialog> dialog = new folderPropertiesDialog(view);
01200 dialog->centralWidget->setText(item->folderName());
01201 int result = dialog->exec();
01202
01203
01204
01205 if (result == QDialog::Accepted && !dialog.isNull()) {
01206 item->setFolderName(dialog->centralWidget->text());
01207 reloadStreamName(item);
01208 };
01209 delete dialog;
01210
01211 };
01212 };
01213 }
01214
01215 quint64 stationlistModel::bandwidth() const
01216 {
01217 return internal_bandwidth;
01218 }
01219
01220 int stationlistModel::numberOfActiveStreams() const
01221 {
01222 return internal_numberOfActiveStreams;
01223 }
01224
01225 void stationlistModel::rememberListOfStreamsWhichTheUserWantsToRip_ifNotYetDone()
01226 {
01227 if (m_listOfStreamsOfWhichTheUserWantsThatTheyRip == 0) {
01228 int i;
01229 QList<radioStation *> m_stationlist = helper_listOfAllStreams(rootItem);
01230 const int m_stationlist_size = m_stationlist.size();
01231 m_listOfStreamsOfWhichTheUserWantsThatTheyRip = new QStringList();
01232 for (i=0; i < m_stationlist_size; i++) {
01233 if (m_stationlist.at(i)->doesTheUserWantsThatTheStreamIsRipping()) {
01234 m_listOfStreamsOfWhichTheUserWantsThatTheyRip->
01235 append(m_stationlist.at(i)->configFileName());
01236 };
01237 };
01238 };
01239 }
01240
01241 bool stationlistModel::queryClose()
01242 {
01243
01244 int i;
01245
01246
01247 helper_writeStationList();
01248 rememberListOfStreamsWhichTheUserWantsToRip_ifNotYetDone();
01249
01250
01251 if (numberOfActiveStreams() > 0) {
01252 QList<radioStation *> m_stationlist = helper_listOfAllStreams(rootItem);
01253 for (i = 0; i < m_stationlist.size(); ++i) {
01254 m_stationlist.at(i)->shutDown();
01255 };
01256 };
01257
01258
01259
01260
01261
01262 if (numberOfActiveStreams() > 0) {
01263 QPointer<KProgressDialog> m_dialog = new KProgressDialog(m_mainWidget,
01264 i18nc("@title:window", "Saving files..."),
01265 i18nc("@label", "Please wait while last files are saved..."));
01266 connect(this, SIGNAL(numberOfActiveStreamsIsZero()), m_dialog, SLOT(reject()));
01267
01268 m_dialog->progressBar()->setMinimum(0);
01269 m_dialog->progressBar()->setMaximum(0);
01270 m_dialog->setModal(true);
01271 m_dialog->setAutoClose(false);
01272 m_dialog->setMinimumDuration(0);
01273
01274
01275 m_dialog->setButtonText(i18nc("@action:button", "Quit without saving"));
01276 m_dialog->exec();
01277 delete m_dialog;
01278 };
01279
01280 return true;
01281 }
01282
01283 void stationlistModel::saveProperties(KConfigGroup & m_configGroup)
01284 {
01285 helper_writeStationList();
01286 rememberListOfStreamsWhichTheUserWantsToRip_ifNotYetDone();
01287 m_configGroup.writePathEntry("streamsToResume",
01288 * m_listOfStreamsOfWhichTheUserWantsThatTheyRip);
01289
01290 }
01291
01292 void stationlistModel::readProperties(const KConfigGroup & m_configGroup)
01293 {
01294
01295 QStringList temp_stringList;
01296 int i;
01297
01298
01299 temp_stringList = m_configGroup.readPathEntry("streamsToResume", temp_stringList);
01300 QList<radioStation *> m_stationlist = helper_listOfAllStreams(rootItem);
01301 const int m_stationlist_size = m_stationlist.size();
01302 for (i = 0; i < m_stationlist_size; ++i) {
01303 if (temp_stringList.contains(m_stationlist.at(i)->configFileName())) {
01304 m_stationlist.at(i)->startStreamripper();
01305 };
01306 };
01307 }
01308
01309 QList<QUrl> stationlistModel::helper_convertToUrl(const QMimeData *data)
01310 {
01311
01312 QList<QUrl> returnValue;
01313
01314
01315 if (data->hasUrls()) {
01316 returnValue = data->urls();
01317 } else if (data->hasText()) {
01318 QStringList temp = data->text().split(QRegExp("\\s"), QString::SkipEmptyParts);
01319 foreach (const QString & singleString, temp) {
01320 returnValue.append(singleString);
01321 };
01322 };
01323 int i = 0;
01324 while (i < returnValue.size()) {
01325 if (returnValue.at(i).isValid() && (!returnValue.at(i).isEmpty())) {
01326 ++i;
01327 } else {
01328 returnValue.removeAt(i);
01329 };
01330 };
01331
01332 return returnValue;
01333 }
01334
01335 void stationlistModel::paste()
01336 {
01337 dropMimeData(QApplication::clipboard()->mimeData(),
01338 Qt::CopyAction,
01339 0,
01340 0,
01341 QModelIndex());
01342 }
01343
01344 void stationlistModel::pasteSelection(const QModelIndex & index)
01345 {
01346 dropMimeData(QApplication::clipboard()->mimeData(QClipboard::Selection),
01347 Qt::CopyAction,
01348 index.row(),
01349 0,
01350 index.parent());
01351 }
01352
01353 bool stationlistModel::dropMimeData(const QMimeData *data,
01354 Qt::DropAction action,
01355 int row,
01356 int,
01357 const QModelIndex &parent)
01358 {
01359 if (action == Qt::IgnoreAction) {
01360 return true;
01361 };
01362
01363 if (!(action == Qt::CopyAction)) {
01364 return false;
01365 };
01366
01367 QList<QUrl> urlList = helper_convertToUrl(data);
01368
01369 if (urlList.isEmpty()) {
01370 return false;
01371 } else {
01372
01373 QPointer<radioStation> m_newStation;
01374 QList<stationlistItem *> m_itemList;
01375 QModelIndex m_parent;
01376 QModelIndexList m_modelIndexList;
01377
01378
01379 for (int i = 0; i < urlList.size(); ++i) {
01380 m_newStation = new radioStation(this, m_mainWidget, QString());
01381 m_newStation->setServerUri(urlList.at(i));
01382 m_itemList.append(helper_createStreamItem(m_newStation));
01383 };
01384
01385 if (index(row, 0, parent).isValid()) {
01386 m_parent = index(row, 0, parent);
01387 } else {
01388 m_parent = parent;
01389 };
01390 if (!(item(m_parent)->type() == stationlistItem::folder)) {
01391 row = m_parent.row();
01392 m_parent = m_parent.parent();
01393 } else {
01394 row = item(m_parent)->childCount();
01395 };
01396
01397 helper_insertItems(m_itemList, m_parent, row);
01398 foreach (stationlistItem *itemInList, m_itemList) {
01399 m_modelIndexList.append(modelindexOfItem(itemInList, 0));
01400 };
01401 helper_selectAndScrollTo(m_modelIndexList);
01402
01403 helper_writeStationList();
01404 return true;
01405 };
01406
01407 return false;
01408 }
01409
01410 Qt::ItemFlags stationlistModel::flags(const QModelIndex & index) const
01411 {
01412 return (Qt::ItemIsDropEnabled | QAbstractItemModel::flags(index));
01413 }
01414
01415 QStringList stationlistModel::mimeTypes () const
01416 {
01417 QStringList value;
01418 value << "text/plain" << "text/uri-list";
01419 return value;
01420 }
01421
01422 void stationlistModel::enableListeningIn()
01423 {
01424 QModelIndexList actuallySelectedRows = view->selectionModel()->selectedRows();
01425 if (actuallySelectedRows.size() == 1) {
01426 stationlistItem *myItem =
01427 static_cast<stationlistItem *>(actuallySelectedRows.at(0).internalPointer());
01428 if (myItem->type() == stationlistItem::stream) {
01429 listen.setStation(myItem->streamObject());
01430 return;
01431 };
01432 };
01433 listen.setStation(0);
01434 }
01435
01436 void stationlistModel::disableListeningIn()
01437 {
01438 listen.setStation(0);
01439 }
01440
01441 QModelIndex stationlistModel::parent(const QModelIndex & index) const
01442 {
01443 if (!index.isValid()) {
01444 return QModelIndex();
01445 };
01446
01447 stationlistItem *childItem = static_cast<stationlistItem *>(index.internalPointer());
01448 stationlistItem *parentItem = childItem->parent();
01449 if (parentItem == rootItem) {
01450 return QModelIndex();
01451 } else {
01452 return createIndex(parentItem->row(), 0, parentItem);
01453 };
01454 }
01455
01456 QModelIndex stationlistModel::index(int row, int column, const QModelIndex & parent) const
01457 {
01458
01459 stationlistItem *parentItem = item(parent);
01460 stationlistItem *childItem;
01461
01462
01463 if (!hasIndex(row, column, parent)) {
01464 return QModelIndex();
01465 };
01466
01467 childItem = parentItem->child(row);
01468 if (childItem) {
01469 return createIndex(row, column, childItem);
01470 } else {
01471 return QModelIndex();
01472 };
01473 }
01474
01475 bool stationlistModel::helper_hasStreams(stationlistItem *item)
01476 {
01477 bool returnValue = false;
01478 int i = 0;
01479 if (item->type() == stationlistItem::folder) {
01480 while (!returnValue && i < item->childCount()) {
01481 returnValue = helper_hasStreams(item->child(i));
01482 ++i;
01483 };
01484 } else {
01485 returnValue = true;
01486 };
01487 return returnValue;
01488 }
01489
01490 void stationlistModel::recalculateSelectedStreams()
01491 {
01492
01493 const QModelIndexList indexList = view->selectionModel()->selectedRows();
01494
01495
01496 internal_selectedStreams.clear();
01497 foreach (const QModelIndex &index, indexList) {
01498 internal_selectedStreams +=
01499 helper_listOfAllStreams(static_cast<stationlistItem *>(index.internalPointer()));
01500 };
01501 for (int i = 0; i < internal_selectedStreams.size() - 1; ++i) {
01502 for (int j = i + 1; j < internal_selectedStreams.size(); ++j) {
01503 if (internal_selectedStreams.at(i) == internal_selectedStreams.at(j)) {
01504 internal_selectedStreams.removeAt(j);
01505 };
01506 };
01507 };
01508 emit selectedStreamsChanged();
01509 }
01510
01511 QList<radioStation *> stationlistModel::selectedStreams() const
01512 {
01513 return internal_selectedStreams;
01514 }