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 "mainwindow.h"
16 #include "playlistmodel.h"
17 #include "collectionsmodel.h"
21 CMainWindow::CMainWindow(QWidget
* parent
) : QMainWindow(parent
),
22 m_CurrentTitle('-'), m_Client(UI_CLIENT_NAME
, this), m_Playback(&m_Client
), m_Medialib(&m_Client
) {
26 m_PlaylistModel
= new CPlaylistModel(&m_Playback
, &m_Medialib
, this);
27 ui
.playlistView
->setModel(m_PlaylistModel
);
28 ui
.playlistView
->addActions(ui
.menuEdit
->actions());
29 ui
.playlistView
->setContextMenuPolicy(Qt::ActionsContextMenu
);
31 connect(ui
.playlistView
, SIGNAL(activated(QModelIndex
)), this, SLOT(switchToEntry(QModelIndex
)));
32 connect(ui
.playlistView
->selectionModel(), SIGNAL(selectionChanged(const QItemSelection
&, const QItemSelection
&)),
33 this, SLOT(handleEntrySelectionChange(const QItemSelection
&)));
35 m_CollectionsModel
= new CCollectionsModel(&m_Medialib
, this);
36 ui
.collectionsView
->setModel(m_CollectionsModel
);
37 connect(ui
.playlistView
, SIGNAL(activated(QModelIndex
)), this, SLOT(switchToPlaylist(QModelIndex
)));
39 connect(&m_Playback
, SIGNAL(playTimeChanged(quint32
)), this, SLOT(updatePlaytime(quint32
)));
40 connect(&m_Playback
, SIGNAL(volumeChanged()), this, SLOT(updateVolume()));
41 connect(&m_Playback
, SIGNAL(statusChanged(xmms_playback_status_t
)), this, SLOT(updateStatus(xmms_playback_status_t
)));
42 connect(&m_Playback
, SIGNAL(idChanged(quint32
)), this, SLOT(updateCurrentId(quint32
)));
44 connect(&m_Medialib
, SIGNAL(mediaInfoReady(quint32
)), this, SLOT(checkMediaUpdate(quint32
)));
45 connect(&m_Medialib
, SIGNAL(activePlaylistChanged()), this, SLOT(switchToActivePlaylist()));
50 m_Client
.connectToServer();
53 CMainWindow::~CMainWindow() {
57 void CMainWindow::readSettings() {
58 QSettings
settings(UI_FILE_CONFIG
, QSettings::IniFormat
, this);
59 settings
.beginGroup("Main");
60 ui
.actionShowCollections
->setChecked(settings
.value("showCollections", false).toBool());
63 settings
.beginGroup("MainWindow");
64 resize(settings
.value("size", QSize(646, 322)).toSize());
65 move(settings
.value("pos", QPoint(200, 200)).toPoint());
69 void CMainWindow::writeSettings() {
70 QSettings
settings(UI_FILE_CONFIG
, QSettings::IniFormat
, this);
71 settings
.beginGroup("Main");
72 settings
.setValue("showCollections", ui
.actionShowCollections
->isChecked());
75 settings
.beginGroup("MainWindow");
76 settings
.setValue("size", size());
77 settings
.setValue("pos", pos());
81 inline void CMainWindow::setupActions() {
82 ui
.actionPlayPause
->setIcon(QIcon(UI_ICON_PLAY
));
83 ui
.actionStop
->setIcon(QIcon(UI_ICON_STOP
));
84 ui
.actionNext
->setIcon(QIcon(UI_ICON_NEXT
));
85 ui
.actionPrevious
->setIcon(QIcon(UI_ICON_PREVIOUS
));
86 ui
.actionAddFiles
->setIcon(QIcon(UI_ICON_OPEN
));
87 //ui.actionAddDirectory->setIcon(QIcon(UI_ICON_));
88 //ui.actionAddUrl->setIcon(QIcon(UI_ICON_));
89 ui
.actionRemove
->setIcon(QIcon(UI_ICON_REMOVE
));
90 ui
.actionClearPlaylist
->setIcon(QIcon(UI_ICON_CLEAR
));
91 ui
.actionShufflePlaylist
->setIcon(QIcon(UI_ICON_SHUFFLE
));
92 ui
.actionShowCollections
->setIcon(QIcon(UI_ICON_SHOWCOLLECTIONS
));
94 connect(ui
.actionStop
, SIGNAL(triggered()), &m_Playback
, SLOT(stop()));
95 connect(ui
.actionNext
, SIGNAL(triggered()), this, SLOT(switchToNext()));
96 connect(ui
.actionPrevious
, SIGNAL(triggered()), this, SLOT(switchToPrevious()));
97 connect(ui
.actionAddFiles
, SIGNAL(triggered()), this, SLOT(addFiles()));
98 connect(ui
.actionAddDirectory
, SIGNAL(triggered()), this, SLOT(addDirectory()));
99 connect(ui
.actionAddUrl
, SIGNAL(triggered()), this, SLOT(addUrl()));
100 connect(ui
.actionRemove
, SIGNAL(triggered()), this, SLOT(removeSelectedEntries()));
101 connect(ui
.actionClearPlaylist
, SIGNAL(triggered()), this, SLOT(clearPlaylist()));
102 connect(ui
.actionShufflePlaylist
, SIGNAL(triggered()), this, SLOT(randomizePlaylist()));
103 connect(ui
.actionQuit
, SIGNAL(triggered()), this, SLOT(close()));
104 connect(ui
.actionAboutQt
, SIGNAL(triggered()), qApp
, SLOT(aboutQt()));
107 inline void CMainWindow::setupToolbars() {
108 m_VolumeLabel
= new QLabel(this);
109 m_VolumeLabel
->setText(tr("Volume"));
111 m_VolumeSlider
= new QSlider(this);
112 m_VolumeSlider
->setMaximum(100);
113 m_VolumeSlider
->setOrientation(Qt::Horizontal
);
114 m_VolumeSlider
->setSizePolicy(QSizePolicy::Preferred
, QSizePolicy::Preferred
);
116 m_CurrentLabel
= new QLabel(this);
117 m_CurrentLabel
->setText("[disconnected]");
119 m_TimeLabel
= new QLabel(this);
120 m_TimeLabel
->setText("--:--");
122 ui
.playbackBar
->addWidget(m_VolumeLabel
);
123 ui
.playbackBar
->addWidget(m_VolumeSlider
);
125 ui
.currentBar
->addWidget(m_CurrentLabel
);
126 ui
.currentBar
->addSeparator();
127 ui
.currentBar
->addWidget(m_TimeLabel
);
129 connect(m_VolumeSlider
, SIGNAL(valueChanged(int)), &m_Playback
, SLOT(setVolume(int)));
132 inline QString
CMainWindow::toFormatedTitleInfo(quint32 id
) {
133 return m_Medialib
.media()[id
]->artist
+ " - " + m_Medialib
.media()[id
]->title
;
136 void CMainWindow::updatePlaytime(quint32 time
) {
137 //TODO: check this (could be too much overhead if nothing visible changed)
138 m_TimeLabel
->setText(formatedTime(time
));
141 void CMainWindow::updateVolume() {
143 foreach (quint8 i
, m_Playback
.volume())
147 mid
/= m_Playback
.volume().count();
148 m_VolumeSlider
->setValue(mid
);
151 void CMainWindow::updateStatus(xmms_playback_status_t status
) {
152 m_CurrentLabel
->setText(toStringFormated(status
).arg(m_CurrentTitle
));
155 case XMMS_PLAYBACK_STATUS_STOP
:
156 m_TimeLabel
->setText("--:--");
157 case XMMS_PLAYBACK_STATUS_PAUSE
:
158 disconnect(ui
.actionPlayPause
, SIGNAL(triggered()), &m_Playback
, SLOT(pause()));
159 ui
.actionPlayPause
->setText("Play");
160 ui
.actionPlayPause
->setIcon(QIcon(UI_ICON_PLAY
));
161 connect(ui
.actionPlayPause
, SIGNAL(triggered()), &m_Playback
, SLOT(start()));
163 case XMMS_PLAYBACK_STATUS_PLAY
:
164 disconnect(ui
.actionPlayPause
, SIGNAL(triggered()), &m_Playback
, SLOT(start()));
165 ui
.actionPlayPause
->setText("Pause");
166 ui
.actionPlayPause
->setIcon(QIcon(UI_ICON_PAUSE
));
167 connect(ui
.actionPlayPause
, SIGNAL(triggered()), &m_Playback
, SLOT(pause()));
174 void CMainWindow::updateCurrentId(quint32 id
) {
176 m_CurrentTitle
= '-';
177 else if (m_Medialib
.checkMediaInfo(id
))
178 m_CurrentTitle
= toFormatedTitleInfo(id
);
180 m_CurrentTitle
= tr("loading title... (id: %1)").arg(id
);
182 m_CurrentLabel
->setText(toStringFormated(m_Playback
.status()).arg(m_CurrentTitle
));
185 void CMainWindow::checkMediaUpdate(quint32 id
) {
186 if (id
== m_Playback
.currentID()) {
187 m_CurrentTitle
= toFormatedTitleInfo(id
);
188 m_CurrentLabel
->setText(toStringFormated(m_Playback
.status()).arg(m_CurrentTitle
));
192 void CMainWindow::switchToNext() {
193 m_Playback
.setNext(m_Medialib
.activePlaylist()->position()+1);
194 if (m_Playback
.status() != XMMS_PLAYBACK_STATUS_STOP
)
198 void CMainWindow::switchToPrevious() {
199 m_Playback
.setNext(m_Medialib
.activePlaylist()->position()-1);
200 if (m_Playback
.status() != XMMS_PLAYBACK_STATUS_STOP
)
204 void CMainWindow::switchToEntry(QModelIndex index
) {
205 if (m_Medialib
.activePlaylist() != m_PlaylistModel
->playlist())
206 m_Medialib
.setActivePlaylist(m_PlaylistModel
->playlist()->identifier());
207 m_Playback
.setNext(index
.row());
208 if (m_Playback
.status() == XMMS_PLAYBACK_STATUS_STOP
)
214 /* void CMainWindow::openFiles() {
215 QStringList files = QFileDialog::getOpenFileNames(this,
216 tr("Select one or more files to append"), QDir::homePath());
221 m_PlaylistModel->playlist()->clear();
222 foreach(QString i, files) {
223 m_PlaylistModel->playlist()->append("file://"+i);
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() {