diff --git a/Medialib.cpp b/Medialib.cpp new file mode 100644 index 0000000..8fa27ad --- /dev/null +++ b/Medialib.cpp @@ -0,0 +1,146 @@ +#include "XMMSHandler.h" +#include "Medialib.h" + +#include +#include +#include + +MedialibWindow::MedialibWindow (QWidget *parent) : QMainWindow (parent) +{ +#ifndef _WIN32 + setWindowIcon (QIcon (":icon.png")); +#endif + + resize (500, 550); + + m_dummy = new QWidget (parent); + setCentralWidget (m_dummy); + + m_vbox = new QVBoxLayout (m_dummy); + m_search = new QLineEdit (m_dummy); + m_search->setFocusPolicy (Qt::StrongFocus); + m_vbox->addWidget (m_search); + + m_tab = new QTabWidget (m_dummy); + m_vbox->addWidget (m_tab); + + m_list = new MedialibList (m_tab); + m_tab->addTab (new QWidget (m_tab), "Artists"); + m_tab->addTab (m_list, "Albums"); + m_tab->addTab (new QWidget (m_tab), "Songs"); + + connect (m_search, SIGNAL (textEdited (QString)), m_list, SLOT (search (QString))); +} + +MedialibList::MedialibList (QWidget *parent) : QListWidget (parent) +{ + XMMSHandler *xmmsh = XMMSHandler::getInstance (); + m_http = new QHttp (this); + m_httpmap = new QHash; + + setIconSize (QSize (85, 85)); + + xmmsh->medialibQuery ("select distinct m1.value as artist, ifnull(m2.value,'[unknown]') as album, m4.value as image from Media m1 left join Media m2 on m1.id = m2.id and m2.key='album' left join Media m3 on m1.id = m3.id and m3.key='compilation' left join Media m4 on m4.id = m1.id and m4.key='album_front_small' where m1.key='artist' and m3.value is null"); + + connect (xmmsh, SIGNAL (medialibResponse (QList >)), + this, SLOT (queryCallback (QList >))); + + connect (m_http, SIGNAL (requestFinished (int, bool)), this, + SLOT (httpDone (int, bool))); + +} + +void +MedialibList::search (QString s) +{ + if (s.length () > 0) { + for (int i = 0; i < count (); i++) { + MedialibListItem *it = dynamic_cast (item (i)); + if (!it->text().contains (s, Qt::CaseInsensitive)) { + setItemHidden (it, true); + } else if (isItemHidden (it)) { + setItemHidden (it, false); + } + } + + } else { + for (int i = 0; i < count (); i++) { + MedialibListItem *it = dynamic_cast (item (i)); + setItemHidden (it, false); + } + } + +} + +void +MedialibList::httpDone (int id, bool error) +{ + if (error) { + qWarning ("error!"); + return; + } + + MedialibListItem *it = m_httpmap->value (id); + + if (it) { + QFile *f = it->getFile (); + f->close (); + + QIcon ico (f->fileName ()); + it->setIcon (ico); + + delete f; + m_httpmap->remove (id); + } + + update (); + +} + +void +MedialibList::queryCallback (QList >l) +{ + QFont font; + + font.setPixelSize (14); + + for (int i = 0; i < l.count (); i++) { + QHash h(l.value (i)); + + MedialibListItem *item = new MedialibListItem (h.value("artist") + " - " + h.value("album"), this); + item->setSizeHint (QSize (90, 90)); + item->setIcon (QIcon (":nocover.jpg")); + item->setFont (font); + item->setTextAlignment (Qt::AlignHCenter | Qt::AlignVCenter); + + if (h.contains ("image")) { + + QString name = h.value("artist")+"-"+h.value("album")+".jpg"; + + if (!QFile::exists (name)) { + QUrl url (h.value("image")); + + m_http->setHost (url.host(), url.port() != -1 ? url.port() : 80); + if (!url.userName().isEmpty()) { + m_http->setUser (url.userName(), url.password()); + } + + QFile *file = new QFile (h.value("artist")+"-"+h.value("album")+".jpg"); + file->open(QIODevice::WriteOnly); + + item->setFile (file); + + int id = m_http->get (url.path(), file); + m_httpmap->insert (id, item); + } else { + QIcon ico (name); + item->setIcon (ico); + } + + } + + + } + +} + diff --git a/Medialib.h b/Medialib.h new file mode 100644 index 0000000..fa5547b --- /dev/null +++ b/Medialib.h @@ -0,0 +1,59 @@ +#ifndef __MEDIALIB_H__ +#define __MEDIALIB_H__ + +#include +#include +#include +#include +#include +#include +#include +#include + +class MedialibListItem : public QListWidgetItem +{ + public: + MedialibListItem (QString text, QListWidget *parent) : QListWidgetItem (text, parent) {} + ~MedialibListItem () {} + void setFile (QFile *f) { m_file = f; } + QFile *getFile (void) { return m_file; } + + private: + QFile *m_file; +}; + +class MedialibList : public QListWidget +{ + Q_OBJECT + public: + MedialibList (QWidget *parent); + ~MedialibList () {} + + public slots: + void queryCallback (QList >); + void httpDone (int, bool); + void search (QString); + + private: + QHash *m_httpmap; + QHttp *m_http; + +}; + +class MedialibWindow : public QMainWindow +{ + Q_OBJECT + public: + MedialibWindow (QWidget *parent); + ~MedialibWindow () {} + + + private: + QWidget *m_dummy; + QTabWidget *m_tab; + QLineEdit *m_search; + QVBoxLayout *m_vbox; + MedialibList *m_list; +}; + +#endif diff --git a/TitleBar.cpp b/TitleBar.cpp index 80363c7..bda9335 100644 --- a/TitleBar.cpp +++ b/TitleBar.cpp @@ -2,6 +2,7 @@ #include "TitleBar.h" #include "Display.h" #include "SkinChooser.h" +#include "Medialib.h" #include @@ -38,6 +39,11 @@ TitleBar::showMenu (void) QAction *a; + a = new QAction (tr ("Medialib browser"), this); + a->setShortcut (tr ("Alt+M")); + connect (a, SIGNAL (triggered ()), this, SLOT (showMlib ())); + qm.addAction (a); + qm.addSeparator (); a = new QAction (tr ("Theme settings"), this); a->setShortcut (tr ("Alt+T")); connect (a, SIGNAL (triggered ()), this, SLOT (showTheme ())); @@ -58,6 +64,13 @@ TitleBar::showMenu (void) } +void +TitleBar::showMlib () +{ + MedialibWindow *mw = new MedialibWindow (window ()); + mw->show (); +} + void TitleBar::showTheme () { diff --git a/TitleBar.h b/TitleBar.h index 7c51291..be24767 100644 --- a/TitleBar.h +++ b/TitleBar.h @@ -20,6 +20,7 @@ class TitleBar : public PixWidget void setPixmaps (Skin *skin); void showMenu (void); void showTheme (void); + void showMlib (void); protected: void mouseDoubleClickEvent (QMouseEvent *event); diff --git a/XMMSHandler.cpp b/XMMSHandler.cpp index ec1a3d9..d2e3cc4 100644 --- a/XMMSHandler.cpp +++ b/XMMSHandler.cpp @@ -264,6 +264,26 @@ XMMSHandler::PropDictToQHash (XMMSResultDict *res) return h; } +void +XMMSHandler::medialibQuery (QString q) +{ + XMMSResultDictList *r = m_xmmsc->medialib_select (q.toUtf8 ()); + r->connect (sigc::mem_fun (this, &XMMSHandler::medialib_select)); +} + +void +XMMSHandler::medialib_select (XMMSResultDictList *res) +{ + QList > l; + + for (;res->listValid (); res->listNext()) { + QHash h(DictToQHash (static_cast(res))); + l.append (h); + } + + emit medialibResponse (l); +} + void XMMSHandler::playlist_changed (XMMSResultDict *res) { diff --git a/XMMSHandler.h b/XMMSHandler.h index 7da74b9..2d214e1 100644 --- a/XMMSHandler.h +++ b/XMMSHandler.h @@ -21,6 +21,7 @@ class XMMSHandler : public QObject, public sigc::trackable { void playback_status (XMMSResultValue *res); void playlist_list (XMMSResultValueList *res); void medialib_entry_changed (XMMSResultValue *res); + void medialib_select (XMMSResultDictList *res); void requestMediainfo (uint id); void requestPlaylistList (void); @@ -30,7 +31,8 @@ class XMMSHandler : public QObject, public sigc::trackable { void playlistClear (void); void playlistRemove (uint pos) { delete m_xmmsc->playlist_remove (pos); } void playlistMove (uint pos, uint newpos) { delete m_xmmsc->playlist_move (pos, newpos); } - + void medialibQuery (QString); + const XMMSClient *getXMMS () { return m_xmmsc; } public slots: @@ -57,6 +59,7 @@ class XMMSHandler : public QObject, public sigc::trackable { void playlistList (QList); void currentID (uint); void playlistChanged (QHash); + void medialibResponse (QList >); private: XmmsQT4 *m_qt4; diff --git a/nocover.jpg b/nocover.jpg new file mode 100644 index 0000000..f022c94 Binary files /dev/null and b/nocover.jpg differ diff --git a/promoe.pro b/promoe.pro index 890dbdf..cf4d127 100644 --- a/promoe.pro +++ b/promoe.pro @@ -17,7 +17,8 @@ SOURCES += XmmsQT4.cpp \ Playlist.cpp \ PlaylistList.cpp \ SkinChooser.cpp \ - PlaylistShade.cpp + PlaylistShade.cpp \ + Medialib.cpp HEADERS += XmmsQT4.h \ PixWidget.h \ @@ -38,12 +39,14 @@ HEADERS += XmmsQT4.h \ Playlist.h \ PlaylistList.h \ SkinChooser.h \ - PlaylistShade.h + PlaylistShade.h \ + Medialib.h RESOURCES = promoe.qrc macx:RC_FILE = promoe.icns +QT += network CONFIG += link_pkgconfig CXXFLAGS += -g ;CONFIG += debug warn_on diff --git a/promoe.qrc b/promoe.qrc index bdabac9..c8a7bd0 100644 --- a/promoe.qrc +++ b/promoe.qrc @@ -1,5 +1,6 @@ icon.png + nocover.jpg