00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "stationlistwidget.h"
00022
00023 #include <QApplication>
00024 #include <QClipboard>
00025 #include <QContextMenuEvent>
00026 #include <QScrollBar>
00027 #include <QStringList>
00028 #include <QTimer>
00029 #include <KAction>
00030 #include <KLocale>
00031 #include <KStandardAction>
00032 #include "settings_general.h"
00033 #define AND &&
00034 #define OR ||
00035 #define NOT !
00036 #define EQUAL ==
00037
00038 stationlistWidget::stationlistWidget(KActionCollection *actionCollection,
00039 QWidget *parent,
00040 QWidget *mainWindow)
00041 : QTreeView(parent)
00042 {
00043
00044
00045 QPointer<CustomizableHeaderView> theHorizontalHeader;
00046 int i;
00047 Qt::SortOrder order;
00048
00049
00050 theHorizontalHeader = new CustomizableHeaderView(Qt::Horizontal);
00051
00052 setHeader(theHorizontalHeader);
00053 theHorizontalHeader->setContextMenuTitle(
00054 i18nc("@title:menu Title of the context menu where you can change visibility of columns",
00055 "Columns"));
00056 if (settings_general::sortingAscendingly()) {
00057 order = Qt::AscendingOrder;
00058 } else {
00059 order = Qt::DescendingOrder;
00060 };
00061 theHorizontalHeader->setSortIndicator(settings_general::sortByColumn(), order);
00062 theHorizontalHeader->setSortIndicatorShown(true);
00063 theHorizontalHeader->setClickable(true);
00064
00065
00066 connect(theHorizontalHeader,
00067 SIGNAL(sectionAboutToBeHidden(int, Qt::Orientation)),
00068 this,
00069 SLOT(saveColumnSize(int)));
00070
00071 setSelectionBehavior(QAbstractItemView::SelectRows);
00072
00073
00074 m_stationlistModel = new stationlistModel(this, mainWindow);
00075
00076
00077 for (i=0; i < m_stationlistModel->columnCount(); ++i) {
00078 setColumnHidden(
00079 i,
00080 !m_stationlistModel->columnInfo(stationlistModel::columnVisibility, i).toBool());
00081 setColumnWidth(
00082 i,
00083 m_stationlistModel->columnInfo(stationlistModel::columnWidth, i).toLongLong());
00084 };
00085
00086
00087 setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
00088 setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
00089 setDragDropMode(QAbstractItemView::DropOnly);
00090 setDragDropOverwriteMode(false);
00091 setAcceptDrops(true);
00092 setSortingEnabled(true);
00093 setItemsExpandable(true);
00094 setAutoExpandDelay(1);
00095 setAnimated(true);
00096 setSelectionMode(QAbstractItemView::ExtendedSelection);
00097 setDropIndicatorShown(true);
00098 setAutoScroll(true);
00099 setAutoExpandDelay(500);
00100 setupActions(actionCollection);
00101 }
00102
00103 stationlistWidget::~stationlistWidget()
00104 {
00105 }
00106
00107 void stationlistWidget::saveAllColumnSizes()
00108 {
00109
00110 int i;
00111
00112
00113 for (i=0; i < m_stationlistModel->columnCount(); i++) {
00114 if (NOT isColumnHidden(i)) {
00115 saveColumnSize(i);
00116 };
00117 m_stationlistModel->columnInfo(stationlistModel::setColumnVisibility,
00118 i,
00119 0,
00120 NOT isColumnHidden(i));
00121 };
00122 }
00123
00124 void stationlistWidget::saveColumnSize(const int column)
00125 {
00126 m_stationlistModel->columnInfo(stationlistModel::setColumnWidth,
00127 column,
00128 0,
00129 columnWidth(column));
00130 }
00131
00132 void stationlistWidget::recalculateActionsStatus()
00133 {
00134 const QModelIndexList list = selectionModel()->selectedRows();
00135 const int number_of_selected_items = list.size();
00136 switch (number_of_selected_items) {
00137 case 0:
00138 emit noneSelected(true);
00139 deleteAction->setEnabled(false);
00140 deleteAction->setData(false);
00141 newStreamAction->setData(true);
00142 newFolderAction->setData(true);
00143 pasteAction->setData(true);
00144 streamSettingsAction->setEnabled(false);
00145 streamSettingsAction->setData(false);
00146 break;
00147 case 1:
00148 emit oneSelected(true);
00149 deleteAction->setEnabled(true);
00150 deleteAction->setData(true);
00151 streamSettingsAction->setEnabled(true);
00152 streamSettingsAction->setData(true);
00153 if (static_cast<stationlistItem *>(list.at(0).internalPointer())->type() ==
00154 stationlistItem::folder) {
00155 newStreamAction->setData(true);
00156 newFolderAction->setData(true);
00157 pasteAction->setData(true);
00158 } else {
00159 newStreamAction->setData(false);
00160 newFolderAction->setData(false);
00161 pasteAction->setData(false);
00162 };
00163 break;
00164 default:
00165 emit multipleSelected(true);
00166 deleteAction->setEnabled(true);
00167 deleteAction->setData(true);
00168 newStreamAction->setData(false);
00169 newFolderAction->setData(false);
00170 pasteAction->setData(false);
00171 streamSettingsAction->setEnabled(false);
00172 streamSettingsAction->setData(false);
00173 break;
00174 };
00175 }
00176
00177 void stationlistWidget::deleteStation()
00178 {
00179
00180 QModelIndexList m_list;
00181
00182
00183
00184 m_list = selectionModel()->selectedRows();
00185 while (m_list.size() > 0) {
00186 m_stationlistModel->removeRow(m_list.at(0).row(), m_list.at(0).parent());
00187 m_list = selectionModel()->selectedRows();
00188 };
00189 }
00190
00191 void stationlistWidget::contextMenuEvent(QContextMenuEvent * e)
00192 {
00193 contextMenu.clear();
00194
00195 if (recordAction->data().toBool()) {
00196 contextMenu.addAction(recordAction);
00197 };
00198 if (stopRecordAction->data().toBool()) {
00199 contextMenu.addAction(stopRecordAction);
00200 };
00201 if (startListenInAction->data().toBool()) {
00202 contextMenu.addAction(startListenInAction);
00203 };
00204 if (stopListenInAction->data().toBool()) {
00205 contextMenu.addAction(stopListenInAction);
00206 };
00207 if (newStreamAction->data().toBool()) {
00208 contextMenu.addAction(newStreamAction);
00209 };
00210
00211 disconnect(newStreamAction, 0, 0, 0);
00212 connect(newStreamAction, SIGNAL(triggered(bool)),
00213 m_stationlistModel, SLOT(addNewStationInFolder()));
00214 if (newFolderAction->data().toBool()) {
00215 contextMenu.addAction(newFolderAction);
00216 };
00217 disconnect(newFolderAction, 0, 0, 0);
00218 connect(newFolderAction, SIGNAL(triggered(bool)),
00219 m_stationlistModel, SLOT(addNewFolderInFolder()));
00220 if (deleteAction->data().toBool()) {
00221 contextMenu.addAction(deleteAction);
00222 };
00223 if (pasteAction->data().toBool()) {
00224 contextMenu.addAction(pasteAction);
00225 };
00226 contextMenu.addAction(selectAllAction);
00227 if (streamSettingsAction->data().toBool()) {
00228 contextMenu.addAction(streamSettingsAction);
00229 };
00230
00231 contextMenu.exec(e->globalPos());
00232
00233
00234 disconnect(newStreamAction, 0, 0, 0);
00235 connect(newStreamAction, SIGNAL(triggered(bool)),
00236 m_stationlistModel, SLOT(addNewStation()));
00237 disconnect(newFolderAction, 0, 0, 0);
00238 connect(newFolderAction, SIGNAL(triggered(bool)),
00239 m_stationlistModel, SLOT(addNewFolder()));
00240 }
00241
00242 QPointer<stationlistModel> stationlistWidget::stationlistmodel()
00243 {
00244 return m_stationlistModel;
00245 }
00246
00247 bool stationlistWidget::queryClose()
00248 {
00249 saveAllColumnSizes();
00250 return stationlistmodel()->queryClose();
00251 }
00252
00253 void stationlistWidget::saveProperties(KConfigGroup & m_configGroup)
00254 {
00255 saveAllColumnSizes();
00256 stationlistmodel()->saveProperties(m_configGroup);
00257 }
00258
00259 void stationlistWidget::readProperties(const KConfigGroup & m_configGroup)
00260 {
00261 stationlistmodel()->readProperties(m_configGroup);
00262 }
00263
00264 void stationlistWidget::mousePressEvent(QMouseEvent *event)
00265 {
00266 if (event->button() == Qt::MidButton) {
00267 stationlistmodel()->pasteSelection(indexAt(viewport()->mapFromGlobal(event->globalPos())));
00268 } else {
00269
00270 QTreeView::mousePressEvent(event);
00271 };
00272 }
00273
00274 void stationlistWidget::scrollToRow(const QModelIndex & index)
00275 {
00276 int temp = horizontalScrollBar()->sliderPosition();
00277 scrollTo(index);
00278 horizontalScrollBar()->setSliderPosition(temp);
00279 }
00280
00281 void stationlistWidget::reloadStatusOfPasteAction()
00282 {
00283 bool isAccepted = false;
00284 const QStringList clipboardFormats = QApplication::clipboard()->mimeData()->formats();
00285 const QStringList acceptedFormats = stationlistmodel()->mimeTypes();
00286 const int numberOfAcceptedFormats = acceptedFormats.size();
00287 int i = 0;
00288 while ((!isAccepted) && (i < numberOfAcceptedFormats)) {
00289 isAccepted = clipboardFormats.contains(acceptedFormats.at(i));
00290 ++i;
00291 };
00292 pasteAction->setEnabled(isAccepted);
00293 }
00294
00295 void stationlistWidget::reloadStatusOfListenInAction()
00296 {
00297 const QModelIndexList list = selectionModel()->selectedRows();
00298 const int number_of_selected_items = list.size();
00299 switch (number_of_selected_items) {
00300 case 0:
00301 startListenInAction->setEnabled(false);
00302 startListenInAction->setData(false);
00303 break;
00304 case 1:
00305 startListenInAction->setData(true);
00306 startListenInAction->setEnabled(false);
00307 if (static_cast<stationlistItem *>(list.at(0).internalPointer())->type() ==
00308 stationlistItem::stream) {
00309 if (static_cast<stationlistItem *>(list.at(0).internalPointer())->
00310 streamObject()->relayPort().type == PropertyValue::value) {
00311 startListenInAction->setEnabled(true);
00312 };
00313 };
00314 break;
00315 default:
00316 startListenInAction->setEnabled(false);
00317 startListenInAction->setData(false);
00318 break;
00319 };
00320 }
00321
00322 void stationlistWidget::setupActions(KActionCollection *actionCollection)
00323 {
00324
00325 recordAction = new KAction(this);
00326 recordAction->setText(i18nc("@action", "&Record"));
00327 recordAction->setIcon(KIcon("media-record"));
00328 QList<QKeySequence> recordAction_tempShortcutList;
00329 recordAction_tempShortcutList.append(Qt::Key_R);
00330 recordAction_tempShortcutList.append(Qt::Key_MediaRecord);
00331 recordAction_tempShortcutList.append(Qt::CTRL + Qt::Key_R);
00332 recordAction->setShortcuts(recordAction_tempShortcutList);
00333 recordAction->setEnabled(false);
00334 connect(recordAction, SIGNAL(triggered(bool)),
00335 stationlistmodel(), SLOT(record()));
00336 actionCollection->addAction("record", recordAction);
00337
00338
00339 stopRecordAction = new KAction(this);
00340 stopRecordAction->setText(i18nc("@action", "&Stop"));
00341 stopRecordAction->setIcon(KIcon("media-playback-stop"));
00342 QList<QKeySequence> stopRecordAction_tempShortcutList;
00343 stopRecordAction_tempShortcutList.append(Qt::Key_S);
00344 stopRecordAction_tempShortcutList.append(Qt::Key_MediaStop);
00345 stopRecordAction_tempShortcutList.append(Qt::CTRL + Qt::Key_S);
00346 stopRecordAction_tempShortcutList.append(Qt::META + Qt::Key_V);
00347 stopRecordAction->setShortcuts(stopRecordAction_tempShortcutList);
00348 stopRecordAction->setEnabled(false);
00349 connect(stopRecordAction, SIGNAL(triggered(bool)),
00350 stationlistmodel(), SLOT(stopRecording()));
00351 actionCollection->addAction("stopRecord", stopRecordAction);
00352
00353 connect(stationlistmodel(), SIGNAL(selectedStreamsChanged()),
00354 this, SLOT(reloadStatusOfStartAndStopActions()));
00355 connect(stationlistmodel(), SIGNAL(statusChanged()),
00356 this, SLOT(reloadStatusOfStartAndStopActions()));
00357
00358
00359 startListenInAction = new KAction(this);
00360
00361 startListenInAction->setText(
00362 i18nc("@action listening in the stream that is actually recorded (and has been selected)",
00363 "&Listen in"));
00364 startListenInAction->setIcon(KIcon("audio-volume-high"));
00365
00366
00367
00368
00369
00370
00371 startListenInAction->setEnabled(false);
00372 connect(startListenInAction, SIGNAL(triggered(bool)),
00373 stationlistmodel(), SLOT(enableListeningIn()));
00374 actionCollection->addAction("startListenIn", startListenInAction);
00375 connect(selectionModel(),
00376 SIGNAL(selectionChanged(const QItemSelection &,const QItemSelection &)),
00377 this,
00378 SLOT(reloadStatusOfListenInAction()));
00379 connect(stationlistmodel(),
00380 SIGNAL(relayportChanged()),
00381 this,
00382 SLOT(reloadStatusOfListenInAction()));
00383
00384
00385 stopListenInAction = new KAction(this);
00386 stopListenInAction->setText(
00387 i18nc("@action listening in the stream that is actually recorded", "&Mute"));
00388 stopListenInAction->setIcon(KIcon("audio-volume-muted"));
00389
00390
00391
00392
00393
00394
00395 stopListenInAction->setEnabled(false);
00396 stopListenInAction->setData(true);
00397 connect(stopListenInAction, SIGNAL(triggered(bool)),
00398 stationlistmodel(), SLOT(disableListeningIn()));
00399 connect(&(stationlistmodel()->listen), SIGNAL(isPlayingChanged(bool)),
00400 this, SLOT(enableStopListenInAction(bool)));
00401 actionCollection->addAction("stopListenIn", stopListenInAction);
00402
00403
00404
00405 newStreamAction = KStandardAction::openNew(
00406 m_stationlistModel,
00407 SLOT(addNewStation()),
00408 this);
00409 newStreamAction->setText(i18nc("@action", "&New stream"));
00410 newStreamAction->setData(true);
00411 actionCollection->addAction("newStream", newStreamAction);
00412
00413
00414 newFolderAction = new KAction(this);
00415 newFolderAction->setText(i18nc("@action", "New &Folder"));
00416 newFolderAction->setIcon(KIcon("folder-new"));
00417
00418 newFolderAction->setData(true);
00419
00420 connect(newFolderAction, SIGNAL(triggered(bool)),
00421 m_stationlistModel, SLOT(addNewFolder()));
00422 actionCollection->addAction("newFolder", newFolderAction);
00423
00424
00425 deleteAction = new KAction(this);
00426 deleteAction->setText(i18nc("@action", "&Delete"));
00427 deleteAction->setIcon(KIcon("edit-delete"));
00428 deleteAction->setShortcut(Qt::SHIFT + Qt::Key_Delete);
00429 deleteAction->setEnabled(false);
00430 connect(deleteAction, SIGNAL(triggered(bool)),
00431 this, SLOT(deleteStation()));
00432 actionCollection->addAction("deleteStream", deleteAction);
00433
00434
00435 pasteAction = KStandardAction::paste(stationlistmodel(), SLOT(paste()), this);
00436 pasteAction->setData(true);
00437 actionCollection->addAction("paste", pasteAction);
00438 connect(QApplication::clipboard(), SIGNAL(dataChanged()),
00439 this, SLOT(reloadStatusOfPasteAction()));
00440 reloadStatusOfPasteAction();
00441
00442
00443 selectAllAction = KStandardAction::selectAll(this, SLOT(selectAll()), actionCollection);
00444 selectAllAction->setData(true);
00445
00446
00447 streamSettingsAction = new KAction(this);
00448 streamSettingsAction->setText(i18nc("@action properties of a stream)", "&Properties"));
00449 streamSettingsAction->setIcon(KIcon("document-properties"));
00450 QList<QKeySequence> streamSettingsAction_tempShortcutList;
00451 streamSettingsAction_tempShortcutList.append(Qt::ALT + Qt::Key_Return);
00452 streamSettingsAction->setShortcuts(streamSettingsAction_tempShortcutList);
00453 streamSettingsAction->setEnabled(false);
00454 connect(streamSettingsAction, SIGNAL(triggered(bool)),
00455 m_stationlistModel, SLOT(showConfigDialog()));
00456 actionCollection->addAction("streamSettings", streamSettingsAction);
00457
00458 connect(selectionModel(),
00459 SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
00460 this,
00461 SLOT(recalculateActionsStatus()));
00462 recalculateActionsStatus();
00463 }
00464
00465 void stationlistWidget::reloadStatusOfStartAndStopActions()
00466 {
00467
00468 const QList<radioStation *> selectedStreams = stationlistmodel()->selectedStreams();
00469 bool start = false;
00470 bool stop = false;
00471
00472
00473 if (selectionModel()->selectedRows().size() == 0) {
00474 recordAction->setEnabled(false);
00475 recordAction->setData(false);
00476 stopRecordAction->setEnabled(false);
00477 stopRecordAction->setData(false);
00478 } else {
00479 foreach (const radioStation *stream, selectedStreams) {
00480 if (!start) {
00481 start = !stream->isRunning();
00482 };
00483 if (!stop) {
00484 stop = stream->doesTheUserWantsThatTheStreamIsRipping();
00485 };
00486 if (start && stop) {
00487 break;
00488 };
00489 };
00490 recordAction->setEnabled(start);
00491 stopRecordAction->setEnabled(stop);
00492 recordAction->setData(true);
00493 stopRecordAction->setData(true);
00494 };
00495 }
00496
00497 void stationlistWidget::enableStopListenInAction(bool enabled)
00498 {
00499 stopListenInAction->setEnabled(enabled);
00500 }