From b8f4b7acb74e1ae398b75e66f7d68cd961884283 Mon Sep 17 00:00:00 2001 From: Tobias Rundstrom Date: Thu, 2 Mar 2006 23:50:22 -0300 Subject: [PATCH] Added a beginning of the medialib. --- Medialib.cpp | 146 ++++++++++++++++++++++++++++++++++++++++++++++++ Medialib.h | 59 +++++++++++++++++++ TitleBar.cpp | 13 +++++ TitleBar.h | 1 + XMMSHandler.cpp | 20 +++++++ XMMSHandler.h | 5 +- nocover.jpg | Bin 0 -> 6414 bytes promoe.pro | 7 ++- promoe.qrc | 1 + 9 files changed, 249 insertions(+), 3 deletions(-) create mode 100644 Medialib.cpp create mode 100644 Medialib.h create mode 100644 nocover.jpg 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 0000000000000000000000000000000000000000..f022c9445bf94ee748f17a9fe97e3622bb531e96 GIT binary patch literal 6414 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 MGD-gzIbYBJ51$#(mH+?% literal 0 HcmV?d00001 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