Fix both update_tree_view() and traverseUpdate_tree()
[kmk.git] / src / kmk.h
blob15d8cec1c3d28677ed25652e091cee5b269debf9
1 /***************************************************************************
2 * KMK - KDE Music Cataloger - the tool for personal *
3 * audio collection management *
4 * *
5 * Copyright (C) 2006,2007 by Plamen Petrov *
6 * carpo@abv.bg *
7 * *
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. *
12 * *
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. *
17 * *
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 ***************************************************************************/
24 #ifndef _KMK_H_
25 #define _KMK_H_
26 #undef _KMK_DEBUG__
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
32 #include <kmainwindow.h>
33 #include <kaction.h>
34 //#include <kfiledialog.h>
35 #include <ktoolbar.h>
36 #include <klistview.h>
37 #include <klineedit.h>
38 #include <kdebug.h>
39 //#include <qvaluelist.h>
40 #include <qwidget.h>
41 #include <qvariant.h>
42 #include <qlayout.h>
43 #include <qsplitter.h>
44 #include <qtimer.h>
45 #include <qdatetime.h>
46 #include <qdragobject.h>
48 #include "kmk_progress_disp.h"
49 #include "mmdata.h"
50 #include "kmkglobalsettings.h"
51 #include "kmkexternalplayer.h"
53 class QVBoxLayout;
54 class QHBoxLayout;
55 class QGridLayout;
56 class QSpacerItem;
57 class QTabWidget;
58 class QSplitter;
59 class KListView;
60 class QListViewItem;
61 class QPushButton;
62 class QFrame;
63 class QLabel;
64 class KLineEdit;
65 class KListView;
67 class kmk_progress_disp;
69 class kmk_tree_KListView : public KListView
71 Q_OBJECT
72 public:
73 kmk_tree_KListView (QWidget *parent = 0, const char *name = 0)
74 : KListView ( parent, name )
76 virtual ~kmk_tree_KListView()
78 protected:
79 virtual QDragObject *dragObject()
81 QListViewItem* lv = this->currentItem();
82 if ( !lv ) return 0;
83 QStringList l;
84 QString p;
86 while ( TRUE ) {
87 p.prepend( lv->text(0) );
88 if( lv->parent() ) { p.prepend( "/" ); lv = lv->parent(); }
89 else break;
92 l << p;
94 QUriDrag *d = new QUriDrag( this, 0 );
95 if ( !d ) return 0;
96 d->setFileNames( l );
97 return (QDragObject*) d;
101 class kmk_files_KListView : public KListView
103 Q_OBJECT
104 public:
105 kmk_files_KListView (QWidget *parent = 0, const char *name = 0)
106 : KListView ( parent, name )
108 virtual ~kmk_files_KListView()
110 protected:
111 virtual QDragObject *dragObject()
113 QStringList l;
114 KListViewItem *node = (KListViewItem*) this->firstChild();
115 if ( !node ) return 0;
117 while ( node )
119 if ( node->isSelected() ) l << node->text( 0 ) + "/" + node->text( 1 );
120 node = (KListViewItem*) node->nextSibling();
123 QUriDrag *d = new QUriDrag( this, 0 );
124 if ( !d ) return 0;
125 d->setFileNames( l );
126 return (QDragObject*) d;
131 * @short kmk is the main widget which actually makes KMK what it is
133 * This Widget extends the functionality of QListView to honor the system
134 * wide settings for Single Click/Double Click mode, AutoSelection and
135 * ChangeCursorOverLink (TM).
137 * There is a new signal executed(). It gets connected to either
138 * QListView::clicked() or QListView::doubleClicked() depending on the KDE
139 * wide Single Click/Double Click settings. It is strongly recommended that
140 * you use this signal instead of the above mentioned. This way you don�t
141 * need to care about the current settings.
142 * If you want to get informed when the user selects something connect to the
143 * QListView::selectionChanged() signal.
145 * Drag-and-Drop is supported with the signal dropped(), just setAcceptDrops(true)
146 * and connect it to a suitable slot.
147 * To see where you are dropping, setDropVisualizer(true).
148 * And also you'll need acceptDrag(QDropEvent*)
150 * KListView is drag-enabled, too: to benefit from that you have to derive from it.
151 * Reimplement dragObject() and (possibly) startDrag(),
152 * and setDragEnabled(true).
154 * @author Plamen Petrov <carpo@abv.bg>
155 * @version 0.11
157 class kmk : public KMainWindow
159 Q_OBJECT
160 public:
162 * Default constructor
164 kmk();
167 * Default Destructor
169 virtual ~kmk();
171 private slots:
172 /*$PRIVATE_SLOTS$*/
174 * Handle searching trough the selected dir - scan for files
175 * we recognize, and add them accordingly to the catalog tree;
176 * This SLOT initially cleans all contents of MusicCatalog,
177 * the Catalog tree KListView, and the two File list QTables
179 void slotFileNew();
180 void slotFileOpen();
181 void slotCatalogAddNewFolder();
182 /** Saves the catalog in memory to the file @p catalogFileName;
183 * If the string, being a filename in @p catalogFileName does not have
184 * a .kmk extension - this slot adds it
186 void slotFileSave();
187 void slotFileSaveAs();
188 void slotCatalogFileClose();
189 void slotCatalogFileStats();
190 void slotFileQuit();
192 void slotProgramSettings();
195 * This is where the setup for kmkTagEdit takes place:
196 * a QTable::selection(s) is traversersed and relevant data
197 * extracted in MmDataList, for user manipulation in the TagEditor
198 * modal() dialog
200 void slotTagEdit();
201 void slotListTableToggleTitle();
204 * A private slot for kmk which takes care of making the external player
205 * play the previous song - either the song before the current in its
206 * playlist, or if it is in SHUFFLE mode - the previous played
208 void slotPlayerPrevious();
211 * A private slot for kmk which takes care of making the external player
212 * play; if it was playing something at the time the command is issued
213 * there should be no effect whatsoever
215 void slotPlayerPlay();
218 * A private slot for kmk which makes the external player
219 * pause - in reality - if it was paused, it will continue;
220 * if it was playing - it will pause
222 void slotPlayerPause();
225 * A private slot for kmk which makes the external player stop
226 * playing if it is; if it isn't - there is no effect
228 void slotPlayerStop();
231 * Private kmk slot, which essentially behaves like kmk::playerPrevious()
232 * only difference is the "direction"
234 void slotPlayerNext();
237 * This private kmk slot is resposible for enqueing whatever is selected
238 * in the FileList() QTables, or SearchFileList() QTable - its native
239 * call environment is from a popup menu after recieved
240 * contextMenuRequested() signal
242 void slotPlayerEnqueue();
245 * Uses kmk::playerDir to enqueue
247 void slotPlayerEnqueueDir();
250 * Uses kmk::playerDir to enqueue selected folder AND all its subfolder(s) contents
252 void slotPlayerEnqueueDirSubdirs();
255 * Uses kmk::playerDir to play
257 void slotPlayerPlayDir();
260 * Uses kmk::playerDir to play selected folder AND all its subfolder(s) contents
262 void slotPlayerPlayDirSubdirs();
265 * This private slot should play whatever selection in FileList()
266 * or kmkWidget::SearchTreeList() QTable objects
268 void slotPlayerPlaySelection();
271 * Triggers update on currently selected folder in TreeListView
273 void slotCatalogUpdateSubtree();
275 void slotTreeListViewPopupMenuRequested( QListViewItem* itm, const QPoint &pos, int col );
276 void slotTreeListViewCurrentChanged( QListViewItem * itm );
278 void slotFileListTablePopupMenuRequested( QListViewItem* itm, const QPoint &pos, int col );
279 void slotSearchListTablePopupMenuRequested( QListViewItem* itm, const QPoint &pos, int col );
282 * Available for selection in the search results table popup menu ONLY when
283 * one item (row) is selected; shows the catalag AND selects the folder
284 * containing the selected item (currently only files are listed).
286 void slotLocateRequested();
288 void slotSearchButtonClicked();
289 void slotClearButtonClicked();
290 void slotDoneButtonClicked();
292 void slotUpdateProgressDisp();
294 private:
296 QWidget * main_container_widget;
297 QTabWidget* tabWidget1;
298 QWidget* tab;
299 QSplitter* splitter1;
300 kmk_tree_KListView* treeListView;
301 kmk_files_KListView* filesListView;
302 kmk_files_KListView* searchFilesListView;
303 QWidget* tab_2;
304 QTabWidget* tabWidget2;
305 QWidget* tab_3;
306 QPushButton* pbSearch;
307 QPushButton* pbClear;
308 QPushButton* pbDone;
309 QFrame* frame1;
310 QLabel* textLabel1;
311 KLineEdit* leSearchFor;
312 QWidget* tab_4;
314 KToolBar* fileToolsToolbar;
315 KToolBar* playerActionsToolbar;
316 KAction* fileNewAction;
317 KAction* fileOpenAction;
318 KAction* catalogAddNewFolderAction;
319 KAction* fileSaveAction;
320 KAction* fileSaveAsAction;
321 KAction* fileCatalogFileClose;
322 KAction* fileCatalogFileStats;
323 KAction* fileQuitAction;
324 KAction* programSettingsAction;
325 KAction* listTableToggleTitleAction;
326 KAction* TagEditAction;
327 KAction* listTableLocateAction;
328 KAction* playerPreviousAction;
329 KAction* playerPlayAction;
330 KAction* playerPauseAction;
331 KAction* playerStopAction;
332 KAction* playerNextAction;
333 KAction* playerEnqueueAction;
334 KAction* playerEnqueueDirAction;
335 KAction* playerEnqueueDirSubdirsAction;
336 KAction* playerPlayDirAction;
337 KAction* playerPlayDirSubdirsAction;
338 KAction* playerPlaySelectionAction;
339 KAction* catalogUpdateSubtreeAction;
341 QPopupMenu* CTree_PopupMenu;
342 QPopupMenu* CList_PopupMenu;
343 QPopupMenu* CSearchList_PopupMenu;
345 void init_interface();
347 // kmkWidget* kmk_widg;
348 KListViewItem* cur_vlItem;
349 KListViewItem* listViewRootItem;
350 MmDataList MusicCatalog;
352 enum CatalogStateEnum {
353 NoCatalog=0,
354 Modified,
355 Saved
358 CatalogStateEnum CatalogState;
359 void setCatalogStateAndUpdate( const kmk::CatalogStateEnum state );
362 * locateMode [bool] if set to TRUE indicates to the
363 * treeListViewCurrentChanged method that it should select
364 * the row, containing DelSelFile AND DelSelDir, if it finds them
365 * during the FileList() table update...
367 bool locateMode;
368 QString DelSelFile;
369 QString DelSelDir;
371 void clearCatalogData( const bool UpdateState = TRUE );
374 * Used to indicate whether we should stop a long disk operation:
375 * scanning, updating, etc; checked were appropriate:
376 * in traverse_tree( const QString& dir ); and bytes_to_read_by_traverse( const QString& dir );
378 bool break_long_disk_operation;
379 kmk_progress_disp* kmkProgress;
380 QTimer* kmkProgressTimer;
381 QTime* kmkSmooth;
383 bool FileSaveCalledFromFileSaveAs;
385 /** Finds all files in kmkWidget::TreeList() currentItem and all its subfolders
386 * and passes them to player_bin with parameter @param act
388 void playerDir( uint act );
391 * This private function implements recursive search at the
392 * top level dir, specified in the @p dir parameter;
393 * currently there are absolutely no checks if the dir is valid -
394 * first, because this function is called from controlled environment;
395 * second, as I described - it is recursive, so we don't want to loose
396 * any speed, checking if we are called with valid input
398 unsigned long traverse_tree( const QString& dir );
400 * This private function starts by clearing current contents of
401 * Tree KListView; next it goes trough kmk's MusicCatalog, recreating
402 * the tree, described in the MmData structure, inside the Tree view
404 void update_tree_view();
405 bool tree_needs_update;
406 unsigned long traverseUpdate_tree( const QString& dir );
407 void bytes_to_read_by_traverse( const QString& dir );
408 void generateListViewXML( const KListView *list, QDomDocument doc, QDomElement e );
409 uint generateListViewSubtreeXML( const KListViewItem *item, QDomDocument doc, QDomElement e, const uint add_lv );
410 MmData* findMmData( const QString& folder, const QString& filename );
411 void loadCatalog( const QString & fileName );
412 unsigned int subDlevel;
414 * Holds TRUE if Enqueue dir in kmkWidget::FileList() popup
415 * menu should add subdirs, FALSE if not
417 bool _kmk_include_subdirs;
419 * This boolean variable, local and private for kmk indicates
420 * wether a popup menu, including id3 tag editor submenu
421 * was requested at file list in the catalog tab,
422 * or at the search result file list.
424 bool _popup_at_search;
425 const QString formatted_string_from_seconds( const Q_ULLONG t );
426 const bool catalog_has_dir( const QString & );
427 /** Some stats variables
428 * \endcode */
429 Q_ULLONG bytes_to_read;
430 Q_ULLONG files_to_read;
431 Q_ULLONG total_bytes;
432 Q_ULLONG total_files;
433 Q_ULLONG total_folders;
434 Q_ULLONG total_play_time;
435 Q_ULLONG average_file_size;
436 QString savedCaption;
437 QString catalogFileName;
439 KmkGlobalSettings * s;
440 KmkExtPlayer * player;
442 protected:
443 void closeEvent( QCloseEvent* ce );
445 QVBoxLayout* kmkwidgetbaseLayout;
446 QVBoxLayout* tabLayout;
447 QVBoxLayout* tabLayout_2;
448 QVBoxLayout* layout5;
452 #endif // _KMK_H_