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
19 #include <QDragEnterEvent>
20 #include <QDragMoveEvent>
25 #include <QPaintEvent>
27 #include <QResizeEvent>
28 #include <Q3ValueList> //stack allocated
30 #include <QStringList> //stack allocated
52 class OrganizeCollectionDialog
;
55 class CollectionTreeView
;
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
79 friend class CollectionView
;
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
; }
92 void slotSetFilterTimeout();
94 void slotSetFilter( const QString
&filter
);
95 void slotEditFilter();
99 void ipodToolbar( bool activate
);
100 void appendSearchResults();
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
;
123 KComboBox
* m_timeFilter
;
124 CollectionView
* m_view
;
127 bool m_returnPressed
;
129 CollectionTreeView
*m_treeView
;
132 static CollectionBrowser
*s_instance
;
135 friend class CollectionItem
;
136 friend class DividerItem
;
139 class DividerItem
: public K3ListViewItem
142 static QString
createGroup(const QString
& src
, int cat
);
143 static bool shareTheSameGroup(const QString
& a
, const QString
& b
, int cat
);
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
; }
156 virtual int compare( Q3ListViewItem
*, int, bool ) const;
166 class CollectionItem
: public K3ListViewItem
{
168 explicit CollectionItem( Q3ListView
* parent
, int cat
= 0, bool unknown
= false, bool sampler
=false )
169 : K3ListViewItem( parent
)
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
)
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() ); }
200 friend class CollectionView
;
201 virtual void paintCell ( QPainter
* painter
, const QColorGroup
& cg
, int column
, int width
, int align
);
204 virtual int compare( Q3ListViewItem
*, int, bool ) const; //reimplemented
212 static QPixmap
*s_star
;
213 static QPixmap
*s_smallStar
;
217 class CollectionView
: public K3ListView
220 friend class CollectionBrowser
;
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
);
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
);
253 // Reimplemented for iPod-style navigation, etc.
254 virtual void keyPressEvent( QKeyEvent
*e
);
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 );
276 void slotEnsureSelectedItemVisible();
278 void renderFlatModeView(bool force
= false);
279 void renderTreeModeView(bool force
= false);
280 void renderIpodModeView(bool force
= false);
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 */
300 /** Shows dialog with information on selected track */
301 void showTrackInfo();
304 * Cancel Organizing files
306 void cancelOrganizingFiles();
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();
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 */
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
);
366 AMAROK_EXPORT
static CollectionView
* m_instance
;
368 CollectionBrowser
* m_parent
;
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
;
399 Q3ValueList
<int> m_flatColumnWidths
;
402 // why is signal detailsClicked() missing from KDialog?
403 class OrganizeCollectionDialogBase
: public KDialog
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
)
412 setCaption( caption
);
414 setButtons( buttonMask
);
415 showButtonSeparator( true );
419 void detailsClicked();
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 */