Not crap after all...
[amarok.git] / src / collectionbrowser.h
blob74d79a43181721676c76b949ad30a892b9297e6c
1 // (c) 2004 Mark Kretschmann <markey@web.de>
2 // (c) 2004 Christian Muehlhaeuser <chris@chris.de>
3 // (c) 2005 Gábor Lehel <illissius@gmail.com>
4 // (c) 2005 Christan Baumgart <christianbaumgart@web.de>
5 // See COPYING file for licensing information.
7 #ifndef AMAROK_COLLECTIONBROWSER_H
8 #define AMAROK_COLLECTIONBROWSER_H
10 #include "querybuilder.h"
11 #include "amarok_export.h"
13 #include <kdialog.h> //baseclass
14 #include <k3listview.h> //baseclass
15 #include <kurl.h> //stack allocated
16 #include <kvbox.h>
18 #include <QByteArray>
19 #include <QDragEnterEvent>
20 #include <QDragMoveEvent>
21 #include <QDropEvent>
22 #include <QEvent>
23 #include <QKeyEvent>
24 #include <QLabel>
25 #include <QPaintEvent>
26 #include <QPixmap>
27 #include <QResizeEvent>
28 #include <Q3ValueList> //stack allocated
30 #include <QStringList> //stack allocated
33 class ClickLineEdit;
34 class CollectionDB;
36 class QByteArray;
37 class Q3DragObject;
38 class QPixmap;
39 class QPoint;
40 class QStringList;
42 class KAction;
43 class KComboBox;
44 class KMenu;
45 class KTabBar;
46 class KToolBar;
47 class KToggleAction;
49 class CollectionView;
50 class CollectionItem;
51 class DividerItem;
52 class OrganizeCollectionDialog;
53 class SearchWidget;
55 class CollectionTreeView;
58 namespace Amarok
60 class SearchAction;
63 namespace CollectionBrowserIds
65 enum CatMenuId { IdAlbum = QueryBuilder::tabAlbum,
66 IdArtist = QueryBuilder::tabArtist,
67 IdComposer = QueryBuilder::tabComposer,
68 IdGenre = QueryBuilder::tabGenre,
69 IdYear = QueryBuilder::tabYear ,
70 IdScan = 32, IdNone = 64,
71 IdArtistAlbum = 128, IdGenreArtist = 256, IdGenreArtistAlbum = 512, IdVisYearAlbum = 1024, IdArtistVisYearAlbum = 2048,
72 IdLabel = QueryBuilder::tabLabels //=8192
76 class CollectionBrowser: public KVBox
78 Q_OBJECT
79 friend class CollectionView;
81 public:
82 CollectionBrowser( const char* name );
83 virtual bool eventFilter( QObject*, QEvent* );
84 KToolBar* getToolBar() const { return m_toolbar; }
85 static CollectionBrowser *instance() { return s_instance; }
87 public slots:
88 void setupDirs();
89 void toggleDivider();
91 private slots:
92 void slotSetFilterTimeout();
93 void slotSetFilter();
94 void slotSetFilter( const QString &filter );
95 void slotEditFilter();
97 private:
98 void layoutToolbar();
99 void ipodToolbar( bool activate );
100 void appendSearchResults();
102 //attributes:
103 KTabBar* m_tabs; //tree-view, flat-view tabs
104 class KToolBar *m_toolbar;
105 KAction *m_configureAction;
106 SearchWidget *m_searchWidget;
107 // For iPod-style browsing
108 KAction *m_ipodIncrement, *m_ipodDecrement;
109 class KToolBar *m_ipodToolbar;
110 class QWidget *m_ipodHbox;
112 KToggleAction *m_showDividerAction;
113 KAction *m_treeViewAction;
114 KAction *m_flatViewAction;
115 KAction *m_ipodViewAction;
116 QActionGroup *m_viewAction;
117 class KActionMenu *m_tagfilterMenuButton;
119 KMenu* m_categoryMenu;
120 KMenu* m_cat1Menu;
121 KMenu* m_cat2Menu;
122 KMenu* m_cat3Menu;
123 KComboBox* m_timeFilter;
124 CollectionView* m_view;
125 QTimer* m_timer;
127 bool m_returnPressed;
129 CollectionTreeView *m_treeView;
132 static CollectionBrowser *s_instance;
134 // for CatMenuId
135 friend class CollectionItem;
136 friend class DividerItem;
139 class DividerItem : public K3ListViewItem
141 public:
142 static QString createGroup(const QString& src, int cat);
143 static bool shareTheSameGroup(const QString& a, const QString& b, int cat);
145 public:
146 DividerItem( Q3ListView* parent, QString txt, int cat);
148 virtual void paintCell ( QPainter * p, const QColorGroup & cg, int column, int width, int align );
149 virtual void paintFocus ( QPainter * p, const QColorGroup & cg, const QRect & r );
151 virtual QString text(int column) const;
153 void setBlockText(bool block) { m_blockText = block; }
155 private:
156 virtual int compare( Q3ListViewItem*, int, bool ) const;
158 private:
159 bool m_blockText;
160 QString m_text;
161 int m_cat;
166 class CollectionItem : public K3ListViewItem {
167 public:
168 explicit CollectionItem( Q3ListView* parent, int cat = 0, bool unknown = false, bool sampler=false )
169 : K3ListViewItem( parent )
170 , m_cat( cat )
171 , m_isUnknown( unknown )
172 , m_isSampler( sampler ) {};
173 explicit CollectionItem( Q3ListViewItem* parent, int cat = 0, bool unknown = false, bool sampler=false )
174 : K3ListViewItem( parent )
175 , m_cat( cat )
176 , m_isUnknown( unknown )
177 , m_isSampler( sampler ) {};
178 void setUrl( const QString& url ) { m_url.setPath( url ); }
179 const KUrl& url() const { return m_url; }
181 virtual void sortChildItems ( int column, bool ascending ); //reimplemented
183 inline QString getSQLText( int column )
185 return ( !column && m_isUnknown ) ? "" : text( column );
188 inline bool isUnknown() {return m_isUnknown;}
189 inline bool isSampler() {return m_isSampler;}
191 virtual void setPixmap(int column, const QPixmap & pix);
193 static QPixmap *star();
194 static QPixmap *smallStar();
196 /// convenience functions
197 CollectionView *listView() const { return reinterpret_cast<CollectionView*>( K3ListViewItem::listView() ); }
199 private:
200 friend class CollectionView;
201 virtual void paintCell ( QPainter * painter, const QColorGroup & cg, int column, int width, int align );
203 //for sorting
204 virtual int compare( Q3ListViewItem*, int, bool ) const; //reimplemented
206 //attributes:
207 KUrl m_url;
208 int m_cat;
209 bool m_isUnknown;
210 bool m_isSampler;
212 static QPixmap *s_star;
213 static QPixmap *s_smallStar;
217 class CollectionView : public K3ListView
219 Q_OBJECT
220 friend class CollectionBrowser;
222 public:
223 enum ViewMode { modeTreeView, modeFlatView, modeIpodView };
225 friend class CollectionItem; // for access to m_cat2
226 friend class ContextBrowser; // for setupDirs()
228 CollectionView( CollectionBrowser* parent );
229 ~CollectionView();
231 AMAROK_EXPORT static CollectionView* instance() { return m_instance; }
233 void setFilter( const QString &filter ) { m_filter = filter; }
234 void setTimeFilter( const uint timeFilter ) { m_timeFilter = timeFilter; }
235 QString filter() { return m_filter; }
236 uint timeFilter() { return m_timeFilter; }
237 CollectionItem* currentItem() { return static_cast<CollectionItem*>( K3ListView::currentItem() ); }
239 int trackDepth() { return m_trackDepth; }
240 int viewMode() const { return m_viewMode; }
242 // Transform "The Who" -> "Who, The" or the other way
243 static void manipulateThe( QString &str, bool reverse );
245 void setShowDivider(bool show);
247 bool isOrganizingFiles() const;
249 //Useful helper function to avoid duplicating code
250 static inline void yearAlbumCalc( QString &year, QString &text );
252 protected:
253 // Reimplemented for iPod-style navigation, etc.
254 virtual void keyPressEvent( QKeyEvent *e );
257 public slots:
258 /** Rebuilds and displays the treeview by querying the database. */
259 void renderView(bool force = false);
261 void databaseChanged() { m_dirty = true; renderView(); };
263 void setTreeMode() { setViewMode( modeTreeView ); };
264 void setFlatMode() { setViewMode( modeFlatView ); };
265 void setIpodMode() { setViewMode( modeIpodView ); };
267 void presetMenu( int id );
268 void cat1Menu( int id, bool rerender = true );
269 void cat2Menu( int id, bool rerender = true );
270 void cat3Menu( int id, bool rerender = true );
271 AMAROK_EXPORT void organizeFiles( const KUrl::List &list, const QString &caption, bool addToCollection=false );
273 private slots:
274 void setupDirs();
276 void slotEnsureSelectedItemVisible();
278 void renderFlatModeView(bool force = false);
279 void renderTreeModeView(bool force = false);
280 void renderIpodModeView(bool force = false);
282 void scanStarted();
283 void scanDone( bool changed = true );
285 void slotExpand( Q3ListViewItem* );
286 void slotCollapse( Q3ListViewItem* );
287 void enableCat3Menu( bool );
288 void invokeItem( Q3ListViewItem*, const QPoint &, int column );
289 void invokeItem( Q3ListViewItem* );
291 // ipod-style navigation slots
292 void ipodItemClicked( Q3ListViewItem*, const QPoint&, int );
293 void incrementDepth ( bool rerender = true );
294 void decrementDepth ( bool rerender = true );
296 void rmbPressed( Q3ListViewItem*, const QPoint&, int );
297 void selectAll() {Q3ListView::selectAll(true); }
298 /** Tries to download the cover image from Amazon.com */
299 void fetchCover();
300 /** Shows dialog with information on selected track */
301 void showTrackInfo();
304 * Cancel Organizing files
306 void cancelOrganizingFiles();
308 private:
309 enum Tag { Title = 0, Artist, Composer, Album, Genre, Length, DiscNumber, Track, Year,
310 Comment, Playcount, Score, Rating, Filename, Firstplay, Lastplay, Modified,
311 Bitrate, Filesize, BPM, NUM_TAGS };
313 void setViewMode( int mode, bool rerender = true );
314 void removeDuplicatedHeaders();
316 void startDrag();
317 QString getTrueItemText( int, Q3ListViewItem* ) const;
318 QStringList listSelectedSiblingsOf( int, Q3ListViewItem* );
319 KUrl::List listSelected();
321 void playlistFromURLs( const KUrl::List &urls );
322 QPixmap iconForCategory( const int cat ) const;
323 QString captionForCategory( const int cat ) const;
324 inline QString captionForTag( const Tag ) const;
326 // For iPod-style navigation
327 QString allForCategory( const int cat, const int num ) const;
328 void resetIpodDepth ( void );
329 void buildIpodQuery ( QueryBuilder &qb, int depth, QStringList filters[3], QStringList filterYear, bool recursiveSort = false, bool compilationsOnly = false );
330 void selectIpodItems ( void );
331 QPixmap ipodIncrementIcon ( void );
332 QPixmap ipodDecrementIcon ( void );
334 void setCompilation( const KUrl::List &urls, bool compilation );
336 /** Rebuild selections, viewport and expanded items after reloads */
337 void cacheView();
338 void restoreView();
340 //Used to store the name of an item (and its parents), so it can be recalled later
341 //even if the pointer to the item has been invalidated.
342 QStringList makeStructuredNameList( Q3ListViewItem* ) const;
343 Q3ListViewItem* findFromStructuredNameList( const QStringList& ) const;
345 // avoid duplicated code
346 static inline bool endsInThe( const QString & text );
347 inline void updateTrackDepth();
349 uint translateTimeFilter( uint filterMode );
351 /**Call when a category has changed **/
352 void updateColumnHeader();
353 // Reimplemented from K3ListView
354 void viewportPaintEvent( QPaintEvent* );
355 void viewportResizeEvent( QResizeEvent* );
356 bool eventFilter( QObject*, QEvent* );
357 void contentsDragEnterEvent( QDragEnterEvent* );
358 void contentsDragMoveEvent( QDragMoveEvent* );
359 void contentsDropEvent( QDropEvent *e );
360 // Reimplemented from DropProxyTarget
361 void dropProxyEvent( QDropEvent *e );
363 void safeClear();
365 //attributes:
366 AMAROK_EXPORT static CollectionView* m_instance;
368 CollectionBrowser* m_parent;
370 QString m_filter;
371 uint m_timeFilter;
372 int m_cat1;
373 int m_cat2;
374 int m_cat3;
375 int m_trackDepth;
376 int m_viewMode;
378 // The iPod-style viewing attributes
379 int m_currentDepth; // Current viewing depth
380 QStringList m_ipodFilters[3]; // Selections at each stage
381 QStringList m_ipodFilterYear; // See the comment for incrementDepth()
382 // For auto-selection
383 int m_ipodIncremented; // 0 = nothing, 1 = just incremented, 2 = just decremented
384 QStringList m_ipodSelected[3]; // Saved selections at lower levels
385 QString m_ipodCurrent[3]; // Saved current selections
386 QString m_ipodTopItem[3]; // Saved viewport positions
388 bool m_dirty; // we use this to avoid re-rendering the view when unnecessary (eg, browser is not visible)
390 Q3ValueList<QStringList> m_cacheOpenItemPaths;
391 QStringList m_cacheViewportTopItem;
392 QStringList m_cacheCurrentItem;
393 KUrl::List m_organizeURLs;
394 bool m_organizeCopyMode;
396 bool m_organizingFileCancelled;
398 bool m_showDivider;
399 Q3ValueList<int> m_flatColumnWidths;
402 // why is signal detailsClicked() missing from KDialog?
403 class OrganizeCollectionDialogBase : public KDialog
405 Q_OBJECT
406 public:
407 explicit OrganizeCollectionDialogBase( QWidget *parent=0, const char *name=0, bool modal=true,
408 const QString &caption=QString(),
409 QFlags<KDialog::ButtonCode> buttonMask=Ok|Apply|Cancel )
410 : KDialog( parent )
412 setCaption( caption );
413 setModal( modal );
414 setButtons( buttonMask );
415 showButtonSeparator( true );
418 signals:
419 void detailsClicked();
420 public slots:
421 void slotDetails() { KDialog::slotButtonClicked( Details ); emit detailsClicked(); adjustSize(); }
424 inline QPixmap *CollectionItem::star() { return s_star; }
425 inline QPixmap *CollectionItem::smallStar() { return s_smallStar; }
429 #endif /* AMAROK_COLLECTIONBROWSER_H */