diff --git a/BrowseDialog.cpp b/BrowseDialog.cpp new file mode 100644 index 0000000..a2c89a3 --- /dev/null +++ b/BrowseDialog.cpp @@ -0,0 +1,169 @@ +#include "XMMSHandler.h" +#include "BrowseModel.h" +#include "BrowseDialog.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +BrowseDialog::BrowseDialog (QWidget *parent) : QDialog (parent) +{ + setSizeGripEnabled(true); + QGridLayout *grid = new QGridLayout (this); + + m_list = new QListView (this); + + m_model = new BrowseModel (this); + m_list->setModel (m_model); + m_list->setSelectionMode (QAbstractItemView::ExtendedSelection); + m_list->setSelectionBehavior (QAbstractItemView::SelectRows); + m_list->setWrapping (true); + m_list->setResizeMode (QListView::Adjust); + m_list->setEditTriggers (QAbstractItemView::EditKeyPressed); + m_list->setContextMenuPolicy (Qt::CustomContextMenu); + + m_selections = new QItemSelectionModel (m_model); + m_list->setSelectionModel (m_selections); + + connect (m_model, SIGNAL (dirChanged (QString)), + this, SLOT (dirChanged(const QString &))); + + grid->addWidget(m_list, 1, 0, 1, 6); + connect (m_list, SIGNAL (activated (QModelIndex)), + this, SLOT (setPath(const QModelIndex &))); + /* + QObject::connect(m_list, SIGNAL(customContextMenuRequested(QPoint)), + q, SLOT(_q_showContextMenu(QPoint))); + */ + + QHBoxLayout *box = new QHBoxLayout; + box->setMargin(3); + box->setSpacing(3); + QSize tools(22, 22); + + QToolButton *toParentButton = new QToolButton (this); + toParentButton->setIcon (style ()->standardPixmap (QStyle::SP_FileDialogToParent)); + toParentButton->setToolTip (tr("Parent Directory")); + toParentButton->setAutoRaise (true); + toParentButton->setFixedSize (tools); + QObject::connect (toParentButton, SIGNAL(clicked ()), this, SLOT (navigateToPrevious ())); + box->addWidget(toParentButton); + + QToolButton *listModeButton = new QToolButton (this); + listModeButton->setIcon (style ()->standardPixmap (QStyle::SP_FileDialogListView)); + listModeButton->setToolTip (tr("List View")); + listModeButton->setAutoRaise (true); + listModeButton->setDown (true); + listModeButton->setFixedSize (tools); + box->addWidget(listModeButton); + + QToolButton *detailModeButton = new QToolButton (this); + detailModeButton->setIcon(style ()->standardPixmap (QStyle::SP_FileDialogDetailedView)); + detailModeButton->setToolTip (tr("Detail View")); + detailModeButton->setAutoRaise (true); + detailModeButton->setFixedSize (tools); + box->addWidget (detailModeButton); + box->setSizeConstraint (QLayout::SetFixedSize); + + grid->addLayout(box, 0, 4, 1, 2); + + QLabel *lookInLabel = new QLabel (tr ("Look in:"), this); + grid->addWidget (lookInLabel, 0, 0); + + // push buttons + QPushButton *acceptButton = new QPushButton (tr ("Open"), this); + QObject::connect(acceptButton, SIGNAL(clicked()), this, SLOT(accept())); + grid->addWidget(acceptButton, 2, 5); + + QPushButton *rejectButton = new QPushButton (tr ("Cancel"), this); + QObject::connect(rejectButton, SIGNAL(clicked()), this, SLOT(reject())); + grid->addWidget(rejectButton, 2, 4); + + m_lookInCombo = new QComboBox (this); + m_lookInCombo->setInsertPolicy (QComboBox::NoInsert); + m_lookInCombo->setDuplicatesEnabled (false); + m_lookInCombo->setEditable (true); + m_lookInCombo->setAutoCompletion (false); + QObject::connect(m_lookInCombo, SIGNAL(activated(QString)), + this, SLOT(setPath(QString))); + + m_lookInEdit = new QLineEdit (m_lookInCombo); + m_lookInCombo->setLineEdit (m_lookInEdit); + m_lookInCombo->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Fixed); + grid->addWidget (m_lookInCombo, 0, 1, 1, 3); + + QSettings s; + if (!s.contains ("browsedialog/path")) + s.setValue ("browsedialog/path", ""); + m_model->setPath (s.value("browsedialog/path").toString ()); + + resize(530, 340); +} + +QStringList +BrowseDialog::getFiles () +{ + QStringList ret; + if (exec () == QDialog::Accepted) { + QModelIndexList list = m_selections->selectedIndexes (); + for (int i = 0; i < list.size (); i++) { + BrowseModelItem *item = m_model->itemByIndex (list.at (i)); + if (!item) + continue; + + if (!item->isDir ()) + ret.append (item->data("path")); + } + } + return ret; +} + +void +BrowseDialog::accept () +{ + QSettings s; + s.setValue ("browsedialog/path", m_model->currentPath ()); + QDialog::accept (); +} + +void +BrowseDialog::dirChanged (const QString &path) +{ + m_lookInCombo->insertItem (0, path); + m_lookInCombo->setCurrentIndex (0); +} + +void +BrowseDialog::navigateToPrevious () +{ + QString dir = m_model->currentPath (); + if (dir.endsWith ("/")) + m_model->setPath (dir.left (dir.lastIndexOf ("/", -2) + 1)); + else + m_model->setPath (dir.left (dir.lastIndexOf ("/") + 1)); +} + +void +BrowseDialog::setPath (const QModelIndex &index) +{ + XMMSHandler &handler = XMMSHandler::getInstance (); + BrowseModelItem *item = m_model->itemByIndex (index); + if (item->isDir ()) { + m_model->setPath (index); + } else { + handler.playlistAddURL (item->data("path")); + } +} + +void +BrowseDialog::setPath (const QString &path) +{ + m_model->setPath (path); +} + diff --git a/BrowseDialog.h b/BrowseDialog.h new file mode 100644 index 0000000..08982f1 --- /dev/null +++ b/BrowseDialog.h @@ -0,0 +1,38 @@ +#ifndef __BROWSEDIALOG_H__ +#define __BROWSEDIALOG_H__ + +#include "BrowseModel.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +class BrowseDialog : public QDialog +{ + Q_OBJECT + public: + BrowseDialog (QWidget *parent); + + public slots: + void setPath (const QModelIndex &index); + void setPath (const QString &path); + void navigateToPrevious (); + void dirChanged (const QString &path); + void accept (); + QStringList getFiles (); + + private: + QListView *m_list; + QComboBox *m_lookInCombo; + QLineEdit *m_lookInEdit; + QLineEdit *m_fileNameEdit; + QComboBox *m_fileTypeCombo; + BrowseModel *m_model; + QItemSelectionModel *m_selections; +}; +#endif diff --git a/BrowseModel.cpp b/BrowseModel.cpp new file mode 100644 index 0000000..e57cf47 --- /dev/null +++ b/BrowseModel.cpp @@ -0,0 +1,162 @@ +#include "XMMSHandler.h" +#include "BrowseModel.h" + +#include +#include +#include +#include + + +BrowseModel::BrowseModel (QWidget *parent) : QAbstractTableModel () +{ + m_columns.append ("Name"); + m_style = parent->style (); + m_client = XMMSHandler::getInstance ().getClient (); + m_filter_dot = true; + //list_root (); +} + +BrowseModelItem * +BrowseModel::itemByIndex (const QModelIndex &index) +{ + return m_list.at (index.row ()); +} + +void +BrowseModel::setPath (const QModelIndex &index) +{ + BrowseModelItem *item = m_list.at (index.row ()); + m_client->xform.browse (item->data("path").toStdString (), + Xmms::bind (&BrowseModel::list_cb, this)); + m_current_dir = item->data ("path"); +} + +void +BrowseModel::setPath (const QString &path) +{ + if (path.isEmpty()) + list_root (); + + m_client->xform.browse (path.toStdString (), + Xmms::bind (&BrowseModel::list_cb, this), + Xmms::bind (&BrowseModel::list_err, this)); + m_current_dir = path; +} + +void +BrowseModel::list_root () +{ + while (!m_list.isEmpty ()) { + delete m_list.takeFirst (); + } + + m_list.append (new BrowseModelItem ("file:///", "Files", true)); + m_list.append (new BrowseModelItem ("daap://", "DAAP", true)); + emit dirChanged (""); + + reset (); + + m_current_dir = ""; +} + +bool +BrowseModel::list_err (const std::string err) +{ + list_root (); + return true; +} + +bool +BrowseModel::list_cb (const Xmms::List< Xmms::Dict > &res) +{ + while (!m_list.isEmpty ()) { + delete m_list.takeFirst (); + } + + for (res.first (); res.isValid (); ++res) { + const char *tmp; + Xmms::Dict d = *res; + + if (!d.contains ("path")) + continue; + + tmp = xmmsc_result_decode_url (NULL, d.get ("path").c_str ()); + QString path = QString::fromUtf8 (tmp); + free ((char *)tmp); + + QString name; + if (d.contains ("name")) { + name = QString::fromStdString ((*res).get ("name")); + } else { + name = path.mid (path.lastIndexOf ("/")+1); + } + + bool isdir = (*res).get ("isdir"); + + if (m_filter_dot && name.startsWith (".")) + // skip these files + continue; + + m_list.append (new BrowseModelItem (path, name, isdir)); + } + + reset (); + + emit dirChanged (m_current_dir); + + return true; +} + +/* QModel overrides */ +int +BrowseModel::rowCount (const QModelIndex &parent) const +{ + return m_list.size (); +} + +int +BrowseModel::columnCount (const QModelIndex &parent) const +{ + return m_columns.size (); +} + +QVariant +BrowseModel::data (const QModelIndex &index, + int role) const +{ + if (!index.isValid ()) + return QVariant (); + + if (index.column () == 0 && role == Qt::DecorationRole) + return fileIcon(index); + + if (role != Qt::DisplayRole) + return QVariant (); + + QString h = m_columns[index.column ()].toLower (); + + return QVariant (m_list.at (index.row ())->data (h)); +} + +QVariant +BrowseModel::headerData (int section, + Qt::Orientation orientation, + int role) const +{ + if (role == Qt::DisplayRole) + return QVariant (m_columns[section]); + return QVariant (); +} + +QIcon +BrowseModel::fileIcon (const QModelIndex &index) const +{ + if (!index.isValid()) + return QIcon (); + + BrowseModelItem *item = m_list.at (index.row ()); + if (item && item->isDir ()) + return QIcon (m_style->standardPixmap (QStyle::SP_DirClosedIcon)); + + return QIcon (m_style->standardPixmap (QStyle::SP_FileIcon)); +} diff --git a/BrowseModel.h b/BrowseModel.h new file mode 100644 index 0000000..903b203 --- /dev/null +++ b/BrowseModel.h @@ -0,0 +1,86 @@ +#ifndef __BROWSEMODEL_H__ +#define __BROWSEMODEL_H__ + +#include + +#include +#include +#include +#include +#include + +class BrowseModelItem +{ + public: + BrowseModelItem (const QString &path, + const QString &name = 0, + bool isdir = true) + { + m_isdir = isdir; + m_vals["path"] = path; + m_vals["name"] = name; + }; + + QString data (const QString &key) { + return m_vals[key]; + }; + + bool isDir () { + return m_isdir; + }; + + protected: + QHash m_vals; + bool m_isdir; + +}; + +class BrowseModel : public QAbstractTableModel +{ + Q_OBJECT + public: + BrowseModel (QWidget *parent); + + QString currentPath () const + { + return m_current_dir; + }; + + void setFilterDot (bool b) + { + m_filter_dot = b; + }; + + void setPath (const QModelIndex &index); + void setPath (const QString &path); + BrowseModelItem *itemByIndex (const QModelIndex &index); + + /* QModel overrides */ + int rowCount (const QModelIndex &parent) const; + int columnCount (const QModelIndex &parent) const; + QVariant data (const QModelIndex &index, + int role = Qt::DisplayRole) const; + QVariant headerData (int section, + Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + QIcon fileIcon (const QModelIndex &index) const; + + signals: + void dirChanged (QString); + + private: + bool list_cb (const Xmms::List< Xmms::Dict > &res); + bool list_err (const std::string err); + + void list_root (); + + bool m_filter_dot; + + QList m_list; + QStringList m_columns; + QString m_current_dir; + QStyle *m_style; + Xmms::Client *m_client; +}; + +#endif diff --git a/Playlist.cpp b/Playlist.cpp index ea02643..9c95af3 100644 --- a/Playlist.cpp +++ b/Playlist.cpp @@ -1,4 +1,5 @@ #include "MainWindow.h" +#include "BrowseDialog.h" #include "Playlist.h" #include "PlaylistList.h" @@ -361,13 +362,23 @@ PlaylistWidget::menuAddDir () void PlaylistWidget::menuAddFile () { + QSettings s; QStringList files; - FileDialog fd (this, "playlist_add_files"); - files = fd.getFiles (); + if (s.value ("playlist/useremote").toBool () == true) { + BrowseDialog bd (window ()); + files = bd.getFiles (); + for (int i = 0; i < files.count(); i++) { + XMMSHandler::getInstance ().playlistAddURL (files.value (i)); + } + } else { + FileDialog fd (this, "playlist_add_files"); - for (int i = 0; i < files.count(); i++) { - XMMSHandler::getInstance ().playlistAddURL ("file://" + files.value(i)); + files = fd.getFiles (); + + for (int i = 0; i < files.count(); i++) { + XMMSHandler::getInstance ().playlistAddURL ("file://" + files.value(i)); + } } } diff --git a/SettingsWindow.cpp b/SettingsWindow.cpp index 4d3e097..a9e5c2d 100644 --- a/SettingsWindow.cpp +++ b/SettingsWindow.cpp @@ -41,11 +41,15 @@ SettingsWindow::SettingsWindow (QWidget *parent) : QMainWindow (parent) m_mainwindow = new SettingsTabMain (NULL); m_playlistwin = new SettingsTabPlaylist (NULL); + /* m_medialib = new SettingsTabMedialib (NULL); + */ tab->addTab (m_mainwindow, tr ("Main Window")); tab->addTab (m_playlistwin, tr ("Playlist Window")); + /* tab->addTab (m_medialib, tr ("Medialib")); + */ } void @@ -53,12 +57,11 @@ SettingsWindow::okButton (void) { m_mainwindow->saveSettings (); m_playlistwin->saveSettings (); - m_medialib->saveSettings (); - + close (); - XMMSHandler::getInstance ().updateSettings (); } +/* SettingsTabMedialib::SettingsTabMedialib (QWidget *parent) : QWidget (parent) { QSettings s; @@ -231,6 +234,7 @@ SettingsTabMedialib::saveSettings () s.setValue ("medialib_album/size", m_albumsize->currentText ()); s.setValue ("medialib_song/size", m_songsize->currentText ()); } +*/ SettingsTabPlaylist::SettingsTabPlaylist (QWidget *parent) : QWidget (parent) { @@ -269,7 +273,25 @@ SettingsTabPlaylist::SettingsTabPlaylist (QWidget *parent) : QWidget (parent) l = new QLabel (tr ("Playlist shaded mode fontsize"), c); h->addWidget (l, 1); + + QFrame *f = new QFrame (dummy); + f->setFrameStyle (QFrame::HLine | QFrame::Raised); + vbox->addWidget (f); + + c = new QWidget (dummy); + h = new QHBoxLayout (c); + vbox->addWidget (c, 1); + + m_remote_fs = new QCheckBox (c); + if (!s.contains ("useremote")) + s.setValue ("useremote", false); + m_remote_fs->setCheckState (s.value ("useremote").toBool () ? Qt::Checked : Qt::Unchecked); + h->addWidget (m_remote_fs); + + l = new QLabel (tr ("Use remote filebrowsing"), c); + h->addWidget (l, 1); + s.endGroup (); } @@ -279,6 +301,7 @@ SettingsTabPlaylist::saveSettings (void) QSettings s; s.setValue ("playlist/fontsize", m_fontsize->value ()); s.setValue ("playlist/shadedsize", m_shadesize->value ()); + s.setValue ("playlist/useremote", m_remote_fs->checkState () == Qt::Checked); } SettingsTabMain::SettingsTabMain (QWidget *parent) : QWidget (parent) diff --git a/SettingsWindow.h b/SettingsWindow.h index f12ffe1..8a81d3b 100644 --- a/SettingsWindow.h +++ b/SettingsWindow.h @@ -35,6 +35,7 @@ class SettingsTabPlaylist : public QWidget { private: QSpinBox *m_fontsize; QSpinBox *m_shadesize; + QCheckBox *m_remote_fs; }; class SettingsTabMain : public QWidget { diff --git a/TitleBar.cpp b/TitleBar.cpp index fba1e1c..c0d6248 100644 --- a/TitleBar.cpp +++ b/TitleBar.cpp @@ -5,6 +5,7 @@ #include "MedialibWindow.h" #include "SettingsWindow.h" #include "Button.h" +#include "BrowseDialog.h" #include @@ -45,6 +46,10 @@ TitleBar::showMenu (void) a->setShortcut (tr ("Alt+M")); connect (a, SIGNAL (triggered ()), this, SLOT (showMlib ())); qm.addAction (a); + a = new QAction (tr ("Server-side browser"), this); + a->setShortcut (tr ("Alt+S")); + connect (a, SIGNAL (triggered ()), this, SLOT (showServerB ())); + qm.addAction (a); qm.addSeparator (); a = new QAction (tr ("Theme settings"), this); a->setShortcut (tr ("Alt+T")); @@ -76,6 +81,13 @@ TitleBar::showMlib () */ } +void +TitleBar::showServerB () +{ + BrowseDialog *bd = new BrowseDialog (window ()); + bd->show (); +} + void TitleBar::showSettings () { diff --git a/TitleBar.h b/TitleBar.h index 30f6d0f..d50ef68 100644 --- a/TitleBar.h +++ b/TitleBar.h @@ -18,6 +18,7 @@ class TitleBar : public PixWidget public slots: void setPixmaps (Skin *skin); void showMenu (void); + void showServerB (void); void showTheme (void); void showMlib (void); void showSettings (void); diff --git a/XMMSHandler.cpp b/XMMSHandler.cpp index adf84d3..5b7ecc6 100644 --- a/XMMSHandler.cpp +++ b/XMMSHandler.cpp @@ -77,6 +77,13 @@ XMMSHandler::connect (const char *path) return true; } + +Xmms::Client * +XMMSHandler::getClient () +{ + return &m_client; +} + void XMMSHandler::restartPlaytime () { diff --git a/XMMSHandler.h b/XMMSHandler.h index 4374f1d..473debf 100644 --- a/XMMSHandler.h +++ b/XMMSHandler.h @@ -48,6 +48,8 @@ class XMMSHandler : public QObject { void updateSettings () { emit settingsSaved (); } + Xmms::Client *getClient (); + public slots: void setPlaytime (uint pos); void restartPlaytime (); diff --git a/promoe.pro b/promoe.pro index 2803852..57f20cf 100644 --- a/promoe.pro +++ b/promoe.pro @@ -25,7 +25,9 @@ SOURCES += XmmsQT4.cpp \ VolumeSlider.cpp \ ClutterBar.cpp \ Equalizer.cpp \ - FileDialog.cpp + FileDialog.cpp \ + BrowseModel.cpp \ + BrowseDialog.cpp HEADERS += XmmsQT4.h \ @@ -55,7 +57,9 @@ HEADERS += XmmsQT4.h \ VolumeSlider.h \ ClutterBar.h \ Equalizer.h \ - FileDialog.h + FileDialog.h \ + BrowseModel.h \ + BrowseDialog.h