1 /***************************************************************************
2 * KMK - KDE Music Cataloger - the tool for personal *
3 * audio collection management *
5 * Copyright (C) 2006,2007 by Plamen Petrov *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
32 #include <kmainwindow.h>
34 //#include <kfiledialog.h>
36 #include <klistview.h>
37 #include <klineedit.h>
39 //#include <qvaluelist.h>
43 #include <qsplitter.h>
45 #include <qdatetime.h>
46 #include <qdragobject.h>
48 #include "kmk_progress_disp.h"
50 #include "kmkglobalsettings.h"
66 class kmk_progress_disp
;
68 class kmk_tree_KListView
: public KListView
72 kmk_tree_KListView (QWidget
*parent
= 0, const char *name
= 0)
73 : KListView ( parent
, name
)
75 virtual ~kmk_tree_KListView()
78 virtual QDragObject
*dragObject()
80 QListViewItem
* lv
= this->currentItem();
86 p
.prepend( lv
->text(0) );
87 if( lv
->parent() ) { p
.prepend( "/" ); lv
= lv
->parent(); }
93 QUriDrag
*d
= new QUriDrag( this, 0 );
96 return (QDragObject
*) d
;
100 class kmk_files_KListView
: public KListView
104 kmk_files_KListView (QWidget
*parent
= 0, const char *name
= 0)
105 : KListView ( parent
, name
)
107 virtual ~kmk_files_KListView()
110 virtual QDragObject
*dragObject()
113 KListViewItem
*node
= (KListViewItem
*) this->firstChild();
114 if ( !node
) return 0;
118 if ( node
->isSelected() ) l
<< node
->text( 0 ) + "/" + node
->text( 1 );
119 node
= (KListViewItem
*) node
->nextSibling();
122 QUriDrag
*d
= new QUriDrag( this, 0 );
124 d
->setFileNames( l
);
125 return (QDragObject
*) d
;
130 * @short kmk is the main widget which actually makes KMK what it is
132 * This Widget extends the functionality of QListView to honor the system
133 * wide settings for Single Click/Double Click mode, AutoSelection and
134 * ChangeCursorOverLink (TM).
136 * There is a new signal executed(). It gets connected to either
137 * QListView::clicked() or QListView::doubleClicked() depending on the KDE
138 * wide Single Click/Double Click settings. It is strongly recommended that
139 * you use this signal instead of the above mentioned. This way you don�t
140 * need to care about the current settings.
141 * If you want to get informed when the user selects something connect to the
142 * QListView::selectionChanged() signal.
144 * Drag-and-Drop is supported with the signal dropped(), just setAcceptDrops(true)
145 * and connect it to a suitable slot.
146 * To see where you are dropping, setDropVisualizer(true).
147 * And also you'll need acceptDrag(QDropEvent*)
149 * KListView is drag-enabled, too: to benefit from that you have to derive from it.
150 * Reimplement dragObject() and (possibly) startDrag(),
151 * and setDragEnabled(true).
153 * @author Plamen Petrov <carpo@abv.bg>
156 class kmk
: public KMainWindow
161 * Default constructor
173 * Handle searching trough the selected dir - scan for files
174 * we recognize, and add them accordingly to the catalog tree;
175 * This SLOT initially cleans all contents of MusicCatalog,
176 * the Catalog tree KListView, and the two File list QTables
180 void slotCatalogAddNewFolder();
181 /** Saves the catalog in memory to the file @p catalogFileName;
182 * If the string, being a filename in @p catalogFileName does not have
183 * a .kmk extension - this slot adds it
186 void slotFileSaveAs();
187 void slotCatalogFileClose();
188 void slotCatalogFileStats();
191 void slotProgramSettings();
194 * This is where the setup for kmkTagEdit takes place:
195 * a QTable::selection(s) is traversersed and relevant data
196 * extracted in MmDataList, for user manipulation in the TagEditor
200 void slotListTableToggleTitle();
203 * A private slot for kmk which takes care of making the external player
204 * play the previous song - either the song before the current in its
205 * playlist, or if it is in SHUFFLE mode - the previous played
207 void slotPlayerPrevious();
210 * A private slot for kmk which takes care of making the external player
211 * play; if it was playing something at the time the command is issued
212 * there should be no effect whatsoever
214 void slotPlayerPlay();
217 * A private slot for kmk which makes the external player
218 * pause - in reality - if it was paused, it will continue;
219 * if it was playing - it will pause
221 void slotPlayerPause();
224 * A private slot for kmk which makes the external player stop
225 * playing if it is; if it isn't - there is no effect
227 void slotPlayerStop();
230 * Private kmk slot, which essentially behaves like kmk::playerPrevious()
231 * only difference is the "direction"
233 void slotPlayerNext();
236 * This private kmk slot is resposible for enqueing whatever is selected
237 * in the FileList() QTables, or SearchFileList() QTable - its native
238 * call environment is from a popup menu after recieved
239 * contextMenuRequested() signal
241 void slotPlayerEnqueue();
244 * Uses kmk::playerDir to enqueue
246 void slotPlayerEnqueueDir();
249 * Uses kmk::playerDir to enqueue selected folder AND all its subfolder(s) contents
251 void slotPlayerEnqueueDirSubdirs();
254 * Uses kmk::playerDir to play
256 void slotPlayerPlayDir();
259 * Uses kmk::playerDir to play selected folder AND all its subfolder(s) contents
261 void slotPlayerPlayDirSubdirs();
265 * This private slot should play whatever selection in FileList()
266 * or kmkWidget::SearchTreeList() QTable objects
268 void slotPlayerPlaySelection();
270 void slotTreeListViewPopupMenuRequested( QListViewItem
* itm
, const QPoint
&pos
, int col
);
271 void slotTreeListViewCurrentChanged( QListViewItem
* itm
);
273 void slotFileListTablePopupMenuRequested( QListViewItem
* itm
, const QPoint
&pos
, int col
);
274 void slotSearchListTablePopupMenuRequested( QListViewItem
* itm
, const QPoint
&pos
, int col
);
277 * Available for selection in the search results table popup menu ONLY when
278 * one item (row) is selected; shows the catalag AND selects the folder
279 * containing the selected item (currently only files are listed).
281 void slotLocateRequested();
283 void slotSearchButtonClicked();
284 void slotClearButtonClicked();
285 void slotDoneButtonClicked();
287 void slotUpdateProgressDisp();
291 QWidget
* main_container_widget
;
292 QTabWidget
* tabWidget1
;
294 QSplitter
* splitter1
;
295 kmk_tree_KListView
* treeListView
;
296 kmk_files_KListView
* filesListView
;
297 kmk_files_KListView
* searchFilesListView
;
299 QTabWidget
* tabWidget2
;
301 QPushButton
* pbSearch
;
302 QPushButton
* pbClear
;
306 KLineEdit
* leSearchFor
;
309 KToolBar
* fileToolsToolbar
;
310 KToolBar
* playerActionsToolbar
;
311 KAction
* fileNewAction
;
312 KAction
* fileOpenAction
;
313 KAction
* catalogAddNewFolderAction
;
314 KAction
* fileSaveAction
;
315 KAction
* fileSaveAsAction
;
316 KAction
* fileCatalogFileClose
;
317 KAction
* fileCatalogFileStats
;
318 KAction
* fileQuitAction
;
319 KAction
* programSettingsAction
;
320 KAction
* listTableToggleTitleAction
;
321 KAction
* TagEditAction
;
322 KAction
* listTableLocateAction
;
323 KAction
* playerPreviousAction
;
324 KAction
* playerPlayAction
;
325 KAction
* playerPauseAction
;
326 KAction
* playerStopAction
;
327 KAction
* playerNextAction
;
328 KAction
* playerEnqueueAction
;
329 KAction
* playerEnqueueDirAction
;
330 KAction
* playerEnqueueDirSubdirsAction
;
331 KAction
* playerPlayDirAction
;
332 KAction
* playerPlayDirSubdirsAction
;
333 KAction
* playerPlaySelectionAction
;
335 QPopupMenu
* CTree_PopupMenu
;
336 QPopupMenu
* CList_PopupMenu
;
337 QPopupMenu
* CSearchList_PopupMenu
;
339 void init_interface();
341 // kmkWidget* kmk_widg;
342 KListViewItem
* cur_vlItem
;
343 KListViewItem
* listViewRootItem
;
344 MmDataList MusicCatalog
;
346 enum CatalogStateEnum
{
352 CatalogStateEnum CatalogState
;
353 void setCatalogStateAndUpdate( const kmk::CatalogStateEnum state
);
356 * locateMode [bool] if set to TRUE indicates to the
357 * treeListViewCurrentChanged method that it should select
358 * the row, containing DelSelFile AND DelSelDir, if it finds them
359 * during the FileList() table update...
365 void clearCatalogData( const bool UpdateState
= TRUE
);
368 * Used to indicate whether we should stop a long disk operation:
369 * scanning, updating, etc; checked were appropriate:
370 * in traverse_tree( const QString& dir ); and bytes_to_read_by_traverse( const QString& dir );
372 bool break_long_disk_operation
;
373 kmk_progress_disp
* kmkProgress
;
374 QTimer
* kmkProgressTimer
;
377 bool FileSaveCalledFromFileSaveAs
;
379 /** Finds all files in kmkWidget::TreeList() currentItem and all its subfolders
380 * and passes them to player_bin with parameter @param act
382 void playerDir( QString act
);
385 * This private private function implements recursive search at the
386 * top level dir, specified in the @p dir parameter;
387 * currently there are absolutely no checks if the dir is valid -
388 * first, because this function is called from controlled environment;
389 * second, as I described - it is recursive, so we don't want to loose
390 * any speed, checking if we are called with valid input
392 unsigned long traverse_tree( const QString
& dir
);
393 void bytes_to_read_by_traverse( const QString
& dir
);
394 void generateListViewXML( const KListView
*list
, QDomDocument doc
, QDomElement e
);
395 uint
generateListViewSubtreeXML( const KListViewItem
*item
, QDomDocument doc
, QDomElement e
, const uint add_lv
);
396 MmData
* findMmData( const QString
& folder
, const QString
& filename
);
397 void loadCatalog( const QString
& fileName
);
398 unsigned int subDlevel
;
400 * Holds TRUE if Enqueue dir in kmkWidget::FileList() popup
401 * menu should add subdirs, FALSE if not
403 bool _kmk_include_subdirs
;
405 * This boolean variable, local and private for kmk indicates
406 * wether a popup menu, including id3 tag editor submenu
407 * was requested at file list in the catalog tab,
408 * or at the search result file list.
410 bool _popup_at_search
;
411 const QString
formatted_string_from_seconds( const Q_ULLONG t
);
412 const bool catalog_has_dir( const QString
& );
413 /** Some stats variables
415 Q_ULLONG bytes_to_read
;
416 Q_ULLONG files_to_read
;
417 Q_ULLONG total_bytes
;
418 Q_ULLONG total_files
;
419 Q_ULLONG total_folders
;
420 Q_ULLONG total_play_time
;
421 Q_ULLONG average_file_size
;
422 QString savedCaption
;
423 QString catalogFileName
;
425 KmkGlobalSettings
* d
;
428 void closeEvent( QCloseEvent
* ce
);
430 QVBoxLayout
* kmkwidgetbaseLayout
;
431 QVBoxLayout
* tabLayout
;
432 QVBoxLayout
* tabLayout_2
;
433 QVBoxLayout
* layout5
;