2 // C++ Implementation: mainwindow
4 // Author: Oliver Groß <z.o.gross@gmx.de>, (C) 2008
6 // Copyright: See COPYING file that comes with this distribution
10 #include <QFileDialog>
11 #include <QInputDialog>
14 #include <QHeaderView>
15 #include "mainwindow.h"
17 #include "playlistmodel.h"
18 #include "collectionsmodel.h"
22 CMainWindow::CMainWindow(QWidget
* parent
) : QMainWindow(parent
),
23 m_CurrentTitle('-'), m_Client(UI_CLIENT_NAME
, this), m_Playback(&m_Client
), m_Medialib(&m_Client
) {
27 m_PlaylistModel
= new CPlaylistModel(&m_Playback
, &m_Medialib
, this);
28 ui
.playlistView
->setModel(m_PlaylistModel
);
29 ui
.playlistView
->addActions(ui
.menuEdit
->actions());
30 ui
.playlistView
->setContextMenuPolicy(Qt::ActionsContextMenu
);
31 ui
.playlistView
->header()->setResizeMode(QHeaderView::ResizeToContents
);
32 connect(ui
.playlistView
, SIGNAL(activated(QModelIndex
)), this, SLOT(switchToEntry(QModelIndex
)));
33 connect(ui
.playlistView
->selectionModel(), SIGNAL(selectionChanged(const QItemSelection
&, const QItemSelection
&)),
34 this, SLOT(handleEntrySelectionChange(const QItemSelection
&)));
36 m_CollectionsModel
= new CCollectionsModel(&m_Medialib
, this);
37 ui
.collectionsView
->setModel(m_CollectionsModel
);
38 connect(ui
.playlistView
, SIGNAL(activated(QModelIndex
)), this, SLOT(switchToPlaylist(QModelIndex
)));
40 connect(&m_Playback
, SIGNAL(playTimeChanged(quint32
)), this, SLOT(updatePlaytime(quint32
)));
41 connect(&m_Playback
, SIGNAL(volumeChanged()), this, SLOT(updateVolume()));
42 connect(&m_Playback
, SIGNAL(statusChanged(xmms_playback_status_t
)), this, SLOT(updateStatus(xmms_playback_status_t
)));
43 connect(&m_Playback
, SIGNAL(idChanged(quint32
)), this, SLOT(updateCurrentId(quint32
)));
45 connect(&m_Medialib
, SIGNAL(mediaInfoReady(quint32
)), this, SLOT(checkMediaUpdate(quint32
)));
46 connect(&m_Medialib
, SIGNAL(activePlaylistChanged()), this, SLOT(switchToActivePlaylist()));
51 m_Client
.connectToServer();
54 CMainWindow::~CMainWindow() {
58 void CMainWindow::readSettings() {
59 QSettings
settings(UI_FILE_CONFIG
, QSettings::IniFormat
, this);
60 settings
.beginGroup("Main");
61 ui
.actionShowCollections
->setChecked(settings
.value("showCollections", false).toBool());
64 settings
.beginGroup("MainWindow");
65 resize(settings
.value("size", QSize(646, 322)).toSize());
66 move(settings
.value("pos", QPoint(200, 200)).toPoint());
70 void CMainWindow::writeSettings() {
71 QSettings
settings(UI_FILE_CONFIG
, QSettings::IniFormat
, this);
72 settings
.beginGroup("Main");
73 settings
.setValue("showCollections", ui
.actionShowCollections
->isChecked());
76 settings
.beginGroup("MainWindow");
77 settings
.setValue("size", size());
78 settings
.setValue("pos", pos());
82 inline void CMainWindow::setupActions() {
83 ui
.actionPlayPause
->setIcon(QIcon(UI_ICON_PLAY
));
84 ui
.actionStop
->setIcon(QIcon(UI_ICON_STOP
));
85 ui
.actionNext
->setIcon(QIcon(UI_ICON_NEXT
));
86 ui
.actionPrevious
->setIcon(QIcon(UI_ICON_PREVIOUS
));
87 ui
.actionAddFiles
->setIcon(QIcon(UI_ICON_OPEN
));
88 //ui.actionAddDirectory->setIcon(QIcon(UI_ICON_));
89 //ui.actionAddUrl->setIcon(QIcon(UI_ICON_));
90 ui
.actionRemove
->setIcon(QIcon(UI_ICON_REMOVE
));
91 ui
.actionClearPlaylist
->setIcon(QIcon(UI_ICON_CLEAR
));
92 ui
.actionShufflePlaylist
->setIcon(QIcon(UI_ICON_SHUFFLE
));
93 ui
.actionShowCollections
->setIcon(QIcon(UI_ICON_SHOWCOLLECTIONS
));
95 connect(ui
.actionStop
, SIGNAL(triggered()), &m_Playback
, SLOT(stop()));
96 connect(ui
.actionNext
, SIGNAL(triggered()), this, SLOT(switchToNext()));
97 connect(ui
.actionPrevious
, SIGNAL(triggered()), this, SLOT(switchToPrevious()));
98 connect(ui
.actionAddFiles
, SIGNAL(triggered()), this, SLOT(addFiles()));
99 connect(ui
.actionAddDirectory
, SIGNAL(triggered()), this, SLOT(addDirectory()));
100 connect(ui
.actionAddUrl
, SIGNAL(triggered()), this, SLOT(addUrl()));
101 connect(ui
.actionRemove
, SIGNAL(triggered()), this, SLOT(removeSelectedEntries()));
102 connect(ui
.actionClearPlaylist
, SIGNAL(triggered()), this, SLOT(clearPlaylist()));
103 connect(ui
.actionShufflePlaylist
, SIGNAL(triggered()), this, SLOT(randomizePlaylist()));
104 connect(ui
.actionQuit
, SIGNAL(triggered()), this, SLOT(close()));
105 connect(ui
.actionAboutQt
, SIGNAL(triggered()), qApp
, SLOT(aboutQt()));
108 inline void CMainWindow::setupToolbars() {
109 m_VolumeLabel
= new QLabel(this);
110 m_VolumeLabel
->setText(tr("Volume"));
112 m_VolumeSlider
= new QSlider(this);
113 m_VolumeSlider
->setMaximum(100);
114 m_VolumeSlider
->setOrientation(Qt::Horizontal
);
115 m_VolumeSlider
->setSizePolicy(QSizePolicy::Preferred
, QSizePolicy::Preferred
);
117 m_CurrentLabel
= new QLabel(this);
118 m_CurrentLabel
->setText("[disconnected]");
120 /* m_PositionSlider = new QSlider(this);
121 m_PositionSlider->setEnabled(false);
122 m_PositionSlider->setMaximum(1);
123 m_PositionSlider->setOrientation(Qt::Horizontal);
124 m_PositionSlider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);*/
126 m_TimeLabel
= new QLabel(this);
127 m_TimeLabel
->setText("--:--");
129 ui
.playbackBar
->addWidget(m_VolumeLabel
);
130 ui
.playbackBar
->addWidget(m_VolumeSlider
);
132 ui
.currentBar
->addWidget(m_CurrentLabel
);
133 ui
.currentBar
->addSeparator();
134 // ui.playbackBar->addWidget(m_PositionSlider);
135 ui
.currentBar
->addWidget(m_TimeLabel
);
137 connect(m_VolumeSlider
, SIGNAL(valueChanged(int)), &m_Playback
, SLOT(setVolume(int)));
138 //connect(m_PositionSlider, SIGNAL(valueChanged(int)), &m_Playback, SLOT(setPlayTime(int)));
141 inline QString
CMainWindow::toFormatedTitleInfo(quint32 id
) {
142 return m_Medialib
.media()[id
]->artist
+ " - " + m_Medialib
.media()[id
]->title
;
145 void CMainWindow::updatePlaytime(quint32 time
) {
146 //TODO: check this (could be too much overhead if nothing visible changed)
147 m_TimeLabel
->setText(formatedTime(time
));
148 //m_PositionSlider->setValue(time);
151 void CMainWindow::updateVolume() {
153 foreach (quint8 i
, m_Playback
.volume())
157 mid
/= m_Playback
.volume().count();
158 m_VolumeSlider
->setValue(mid
);
161 void CMainWindow::updateStatus(xmms_playback_status_t status
) {
162 m_CurrentLabel
->setText(toStringFormated(status
).arg(m_CurrentTitle
));
165 case XMMS_PLAYBACK_STATUS_STOP
:
166 m_TimeLabel
->setText("--:--");
167 case XMMS_PLAYBACK_STATUS_PAUSE
:
168 disconnect(ui
.actionPlayPause
, SIGNAL(triggered()), &m_Playback
, SLOT(pause()));
169 ui
.actionPlayPause
->setText("Play");
170 ui
.actionPlayPause
->setIcon(QIcon(UI_ICON_PLAY
));
171 connect(ui
.actionPlayPause
, SIGNAL(triggered()), &m_Playback
, SLOT(start()));
173 case XMMS_PLAYBACK_STATUS_PLAY
:
174 disconnect(ui
.actionPlayPause
, SIGNAL(triggered()), &m_Playback
, SLOT(start()));
175 ui
.actionPlayPause
->setText("Pause");
176 ui
.actionPlayPause
->setIcon(QIcon(UI_ICON_PAUSE
));
177 connect(ui
.actionPlayPause
, SIGNAL(triggered()), &m_Playback
, SLOT(pause()));
184 void CMainWindow::updateCurrentId(quint32 id
) {
186 m_CurrentTitle
= '-';
187 else if (m_Medialib
.checkMediaInfo(id
)) {
188 m_CurrentTitle
= toFormatedTitleInfo(id
);
189 //m_PositionSlider->setMaximum(m_Medialib.media()[id]->duration);
190 //m_PositionSlider->setDisabled(m_Playback.status() == XMMS_PLAYBACK_STATUS_STOP);
193 m_CurrentTitle
= tr("loading title... (id: %1)").arg(id
);
195 m_CurrentLabel
->setText(toStringFormated(m_Playback
.status()).arg(m_CurrentTitle
));
198 void CMainWindow::checkMediaUpdate(quint32 id
) {
199 if (id
== m_Playback
.currentID()) {
200 m_CurrentTitle
= toFormatedTitleInfo(id
);
201 m_CurrentLabel
->setText(toStringFormated(m_Playback
.status()).arg(m_CurrentTitle
));
205 void CMainWindow::switchToNext() {
206 m_Playback
.setNext(m_Medialib
.activePlaylist()->position()+1);
207 if (m_Playback
.status() != XMMS_PLAYBACK_STATUS_STOP
)
211 void CMainWindow::switchToPrevious() {
212 m_Playback
.setNext(m_Medialib
.activePlaylist()->position()-1);
213 if (m_Playback
.status() != XMMS_PLAYBACK_STATUS_STOP
)
217 void CMainWindow::switchToEntry(QModelIndex index
) {
218 if (m_Medialib
.activePlaylist() != m_PlaylistModel
->playlist())
219 m_Medialib
.setActivePlaylist(m_PlaylistModel
->playlist()->identifier());
220 m_Playback
.setNext(index
.row());
221 if (m_Playback
.status() == XMMS_PLAYBACK_STATUS_STOP
)
227 void CMainWindow::addFiles() {
228 QFileDialog
fileDialog(this, tr("Select one or more files to add"), lastFilesDir
);
229 fileDialog
.setFileMode(QFileDialog::ExistingFiles
);
230 if (fileDialog
.exec()) {
231 lastFilesDir
= fileDialog
.directory().path();
232 foreach(QString i
, fileDialog
.selectedFiles()) {
233 m_PlaylistModel
->playlist()->append("file://" + i
);
238 void CMainWindow::addDirectory() {
239 QFileDialog
directoryDialog(this, tr("Select a directory to add"), lastDirectoryDir
);
240 directoryDialog
.setFileMode(QFileDialog::DirectoryOnly
);
241 if (directoryDialog
.exec()) {
242 lastDirectoryDir
= directoryDialog
.directory().path();
243 m_PlaylistModel
->playlist()->appendRecursive("file://" + directoryDialog
.selectedFiles()[0]);
247 void CMainWindow::addUrl() {
248 QString url
= QInputDialog::getItem(this, tr("Enter a URL to add"), "URL:", lastAppendedUrls
);
249 if (!url
.isEmpty()) {
250 lastAppendedUrls
.prepend(url
);
251 if (lastAppendedUrls
.count() > 5)
252 lastAppendedUrls
.removeLast();
256 bool gearterRowThan(QModelIndex a
, QModelIndex b
) {
257 return a
.row() > b
.row();
260 void CMainWindow::removeSelectedEntries() {
261 QModelIndexList selectedIndexes
= ui
.playlistView
->selectionModel()->selectedIndexes();
262 if (selectedIndexes
.isEmpty())
265 qSort(selectedIndexes
.begin(), selectedIndexes
.end(), gearterRowThan
);
268 foreach(QModelIndex i
, selectedIndexes
) {
269 if (i
.row() != row
) {
271 m_PlaylistModel
->playlist()->remove(row
);
276 void CMainWindow::clearPlaylist() {
277 m_PlaylistModel
->playlist()->clear();
280 void CMainWindow::randomizePlaylist() {
281 m_PlaylistModel
->playlist()->randomize();
284 void CMainWindow::switchToActivePlaylist() {
285 //disconnect(&m_Medialib, SIGNAL(activePlaylistChanged()), this, SLOT(handleActivePlaylistOnce()));
286 m_PlaylistModel
->setPlaylist(m_Medialib
.activePlaylist());
289 void CMainWindow::handleEntrySelectionChange(const QItemSelection
& selected
) {
290 QModelIndexList selectedIndexes
= selected
.indexes();
291 ui
.actionRemove
->setDisabled(selectedIndexes
.isEmpty());
294 /* void CMainWindow::openPlaylist() {
297 void CMainWindow::savePlaylist() {