Merge lp:~mixxxdevelopers/mixxx/tree_item_browser into lp:~mixxxdevelopers/mixxx/trunk
- tree_item_browser
- Merge into trunk
Status: | Superseded | ||||
---|---|---|---|---|---|
Proposed branch: | lp:~mixxxdevelopers/mixxx/tree_item_browser | ||||
Merge into: | lp:~mixxxdevelopers/mixxx/trunk | ||||
Diff against target: |
444 lines (+222/-136) 5 files modified
mixxx/build/depends.py (+1/-0) mixxx/src/library/browsetablemodel.cpp (+22/-124) mixxx/src/library/browsetablemodel.h (+22/-12) mixxx/src/library/browsethread.cpp (+140/-0) mixxx/src/library/browsethread.h (+37/-0) |
||||
To merge this branch: | bzr merge lp:~mixxxdevelopers/mixxx/tree_item_browser | ||||
Related bugs: |
|
||||
Related blueprints: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
RJ Skerry-Ryan | Approve | ||
Review via email: mp+47206@code.launchpad.net |
Commit message
Description of the change
This a rewrite of the BrowseFeature and has been tested on OS X, Windows and Linux.
The BrowseFeature is now expandable showing drive letters and folders. All supported audio files are listed in the right track table view along with their metadata.
Known bug:
Folders may have large content. Therefore, the population of the track table view is thread-based. Clicking quickly through the folder structure will cause Mixxx to crash. I need some help to get things thread-safe.
Thanks,
Tobias
RAFFI TEA (raffitea) wrote : | # |
Thanks RJ for your detailed review :-)
> Hey Tobias,
>
> Checking out this I've got a couple of questions and things to fix:
>
> 1) Why the updates to libmad, libid3tag, and libtag?
Sean has used MSVC++ 2005 on Windows to compile Mixxx and its dependencies.
If I compile Mixxx with MSVC++ 2008 library scanning but also track loadings will cause a segfault by taglib for some reason. Other contributors have observed same issues, see Bug #714337. Solution: Compile taglib with MSVC++ 2008 and replace the *.lib and *.dll.
>
> 2) I assume you're adding shell32 because you use system-specific calls in
> foldertreemodel
> that's why it's there (mostly so I don't blindly remove it in the future
> thinking "gee we don't need this" :) )
Good catch, I'll place a comment. System-specific calls are necessary to quickly test if a folder has subfolders. QT is too slow here.
>
> 3) In browsefeature.cpp the "My Music" literal needs a tr(). Also the naming
> of My Music might make Windows users actually think it's their "My Music"
> folder, while it's actually the library folder they picked in Mixxx. Maybe we
> should say "My Library" instead?
I'm happy for this discussion here. I think "My Library" is the best word and others common places should be added, too.
> 4) I think we should add some other useful links, e.g. a 'My Home' for the
> user's home directory, 'My Documents' or 'My Music' for their Music folder (if
> it isn't the same as their Mixxx library). You can do this in a cross-platform
> way with the QDesktopService
>
> 5) I noticed that when expanding directories in the sidebar, if you hit the
> expand triangle on a folder that you are not currently selecting, it won't
> expand. Is this the case in general? Can we fix it so that they expand? I'm on
> Ubuntu 10.04 with standard Qt.
At the moment, this behavior is same on all platforms. I'm pretty sure we can change the behavior somehow. We'll need to change the sidebar view. The models can't change the behavior.
> 6) BrowseTableMode
> tr()'s
Will be done soon.
> 7) (sorry for nitpicking) can isBackgroundThr
> also can you move the initialization of isBackgroundThr
> m_currentPath to the constructor initializer list?
The points 7 and 8 are my problem. Have you ever tried to browse very quickly through the folder structure? Just to for reproduction. Create some folder that that contain > 100 tracks. Now try to click through the folder in Mixxx very quickly using keyboard. At least on Windows and OS X, Mixxx crashes in a regular manner .
I really don't know why. I introduced 'populateMutex ' to prevent the populateModel() method
from running more than once concurrently. However, I think more threads are created. You, RJ, are more thread-experienced as I am. Maybe an implementation of QRunnable is mode suitable. using signal/slots for updating the track table view. I would be thankful if someone can help me out. All previous points can be quickly addressed by me. What really prevents this feature to ge...
RAFFI TEA (raffitea) wrote : | # |
RJ, I've addresses most of the problems. In particular, I've categorized the BrowseFeature. There's now a 'Quick Link" and a 'Devices' item under the root item. The first provides quick access to common places, e.g., Mixxx library, My Music, Desktop and so on. The second item provides access to (removable) drives/devices on all operating systems.
I would be happy if you could lend a hand. I face a second problem: At the moment you can only expand an item by double clicking. The underlying foldertreemodel populates incrementally (lazy). The SidebarTreeView calls canFetchMore() in lazy models if an item is activated somehow (triangle, double click, etc.). The SidebarTreeView will fetch more data from the model if canFetchMore() returns true.
I've implemented the (can)fetchMore methods in SideBarModel and FolderTreeModel. Recall that QAbstracItemMod
RJ, could you please take a look at my code? This might be helpful http://
Thank you very much!
RAFFI TEA (raffitea) wrote : | # |
I have solved the triangle issue!!! Please ignore my previous comment :-)
RJ Skerry-Ryan (rryan) wrote : | # |
All my issues are fixed now, looks good to me.
Thanks Tobias!
RAFFI TEA (raffitea) wrote : | # |
RJ, could you review once again please?
I've introduced signal/slots now to prevent segfaults through quick library navigation. Revision r2653 which is part of trunk works on OS X and Linux, but on Win it caused segfaults. This should be fixed now (at least for me it is).
RJ Skerry-Ryan (rryan) wrote : | # |
It's looking good -- just merged it into trunk. Thanks Tobias!
- 2659. By Raffitea
-
Fixed some typos.
- 2660. By Raffitea
-
Implemented Playlist Export to M3U and PLS.
- 2661. By Raffitea
-
merging from trunk
- 2662. By Raffitea
-
Implemented relative M3U and PLS playlist export. Works fine on OS X with VLC but iTunes does not support relative paths.
- 2663. By Raffitea
-
Added an option to preferences to make relative playlist export optional.
- 2664. By Raffitea
-
Fixed a compiler warning on Windows. Also tested PLS and M3U export on Windows. Works as expected with Media Player and iTunes but also VLC, RealPlayer and Winamp.
- 2665. By Raffitea
-
Added a comment about QDir::relativeP
ath(). - 2666. By Raffitea
-
Merging from trunk
- 2667. By Raffitea
-
Remove qDebug for TIO
- 2668. By Raffitea
-
Improved Playlist export dialog.
- 2669. By Raffitea
-
Drastically improved the population of the tracktable view in BrowseFeature. Hopefully does not freez the GUI while clicking through the folder structure.
- 2670. By Tobias <Tobias@Silverstar>
-
Merging manually from trunk
- 2671. By Tobias <Tobias@Silverstar>
-
Merging manually from trunk the third time.
- 2672. By Tobias <Tobias@Silverstar>
-
Merging from trunk to get library caching fixes
- 2673. By Raffitea
-
made BrowseTableModel singleton because the recording feature will use the BrowseTableModel to display contents of a special recording directory. This approach avoids two BrowseThreads. If I had made BrowseThread singleton there would be two BrowseTableModel objects and both would populate when the Thread is active. This is not performant
- 2674. By Raffitea
-
Merging from trunk to get PrepareFeature fixes
- 2675. By Raffitea
-
Merging from trunk
- 2676. By Raffitea
-
Merging from trunk
- 2677. By Raffitea
-
Removed the singleton character of BrowseTableModel. This was a really stupid idea....
- 2678. By Raffitea
-
Now made BrowseThread singleton. BrowseTableModel objects will only process received signals if they have asked the thread to do so.
- 2679. By Raffitea
-
Merging from trunk to get auto-expand feature
- 2680. By Raffitea
-
Merging from trunk
- 2681. By Raffitea
-
Renamed context menu entry for crate export/import; If file extension is missing, append .m3u to the export file and continue to export in m3u; Replaced Qt::BlockingQue
uedConnection with QueuedConnection, which seems to work for rapid sidebar folder iterations with keyboard/MIDI; Added a global static member for BrowseThread: :getInstance( ).
Unmerged revisions
Preview Diff
1 | === modified file 'mixxx/build/depends.py' |
2 | --- mixxx/build/depends.py 2011-02-13 21:30:36 +0000 |
3 | +++ mixxx/build/depends.py 2011-02-16 20:55:20 +0000 |
4 | @@ -498,6 +498,7 @@ |
5 | "library/traktorfeature.cpp", |
6 | "library/traktortablemodel.cpp", |
7 | "library/traktorplaylistmodel.cpp", |
8 | + "library/browsethread.cpp", |
9 | |
10 | "xmlparse.cpp", |
11 | "library/parser.cpp", |
12 | |
13 | === modified file 'mixxx/src/library/browsetablemodel.cpp' |
14 | --- mixxx/src/library/browsetablemodel.cpp 2011-02-13 22:09:54 +0000 |
15 | +++ mixxx/src/library/browsetablemodel.cpp 2011-02-16 20:55:20 +0000 |
16 | @@ -3,26 +3,13 @@ |
17 | #include <QtSql> |
18 | #include <QStringList> |
19 | #include <QtConcurrentRun> |
20 | +#include <QMetaType> |
21 | |
22 | #include "browsetablemodel.h" |
23 | #include "soundsourceproxy.h" |
24 | #include "mixxxutils.cpp" |
25 | |
26 | -//constants |
27 | -const int COLUMN_FILENAME = 0; |
28 | -const int COLUMN_ARTIST = 1; |
29 | -const int COLUMN_TITLE = 2; |
30 | -const int COLUMN_ALBUM = 3; |
31 | -const int COLUMN_TRACK_NUMBER = 4; |
32 | -const int COLUMN_YEAR = 5; |
33 | -const int COLUMN_GENRE = 6; |
34 | -const int COLUMN_COMMENT = 7; |
35 | -const int COLUMN_DURATION = 8; |
36 | -const int COLUMN_BPM = 9; |
37 | -const int COLUMN_KEY = 10; |
38 | -const int COLUMN_TYPE = 11; |
39 | -const int COLUMN_BITRATE = 12; |
40 | -const int COLUMN_LOCATION = 13; |
41 | + |
42 | |
43 | BrowseTableModel::BrowseTableModel(QObject* parent) |
44 | : QStandardItemModel(parent), |
45 | @@ -53,26 +40,22 @@ |
46 | addSearchColumn(COLUMN_GENRE); |
47 | addSearchColumn(COLUMN_KEY); |
48 | addSearchColumn(COLUMN_COMMENT); |
49 | - |
50 | - setHorizontalHeaderLabels(header_data); |
51 | - |
52 | - /* |
53 | - * Start background thread. |
54 | - * Used to read the ID3 tags |
55 | - */ |
56 | - m_bStopThread = false; |
57 | - m_future = QtConcurrent::run(this, &BrowseTableModel::browserThread); |
58 | - m_path = ""; |
59 | + |
60 | + //m_backgroundThread.moveToThread(&m_backgroundThread); |
61 | + m_backgroundThread.start(QThread::LowestPriority); |
62 | + |
63 | + setHorizontalHeaderLabels(header_data); |
64 | + |
65 | + QObject::connect(&m_backgroundThread, SIGNAL(clearModel()), |
66 | + this, SLOT(slotClear())); |
67 | + QObject::connect(&m_backgroundThread, SIGNAL(rowDataAppended(const QList<QStandardItem*>&)), |
68 | + this, SLOT(slotInsert(const QList<QStandardItem*>&)), Qt::DirectConnection); |
69 | + |
70 | } |
71 | |
72 | BrowseTableModel::~BrowseTableModel() |
73 | { |
74 | - qDebug() << "Wait to finish browser background thread"; |
75 | - m_bStopThread = true; |
76 | - //wake up thread since it might wait for user input |
77 | - m_locationUpdated.wakeAll(); |
78 | - m_future.waitForFinished(); |
79 | - qDebug() << "Browser background thread terminated!"; |
80 | + |
81 | } |
82 | |
83 | const QList<int>& BrowseTableModel::searchColumns() const { |
84 | @@ -83,8 +66,7 @@ |
85 | } |
86 | void BrowseTableModel::setPath(QString absPath) |
87 | { |
88 | - m_path = absPath; |
89 | - m_locationUpdated.wakeAll(); |
90 | + m_backgroundThread.setPath(absPath); |
91 | |
92 | } |
93 | |
94 | @@ -169,99 +151,15 @@ |
95 | mimeData->setUrls(urls); |
96 | return mimeData; |
97 | } |
98 | -void BrowseTableModel::populateModel() |
99 | + |
100 | +void BrowseTableModel::slotClear() |
101 | { |
102 | - //Refresh the name filters in case we loaded new |
103 | - //SoundSource plugins. |
104 | - QStringList nameFilters(SoundSourceProxy::supportedFileExtensionsString().split(" ")); |
105 | - QDirIterator fileIt(m_path, nameFilters, QDir::Files | QDir::NoDotAndDotDot); |
106 | - QString thisPath(m_path); |
107 | - //remove all rows |
108 | removeRows(0, rowCount()); |
109 | - |
110 | - int row = 0; |
111 | - //Iterate over the files |
112 | - while (fileIt.hasNext()) |
113 | - { |
114 | - /* |
115 | - * If a user quickly jumps through the folders |
116 | - * the current task becomes "dirty" |
117 | - */ |
118 | - if(thisPath != m_path){ |
119 | - //qDebug() << "Exit populateModel()"; |
120 | - return; |
121 | - } |
122 | - QString filepath = fileIt.next(); |
123 | - TrackInfoObject tio(filepath); |
124 | - |
125 | - QStandardItem* item = new QStandardItem(tio.getFilename()); |
126 | - setItem(row, COLUMN_FILENAME, item); |
127 | - |
128 | - item = new QStandardItem(tio.getArtist()); |
129 | - setItem(row, COLUMN_ARTIST, item); |
130 | - |
131 | - item = new QStandardItem(tio.getTitle()); |
132 | - setItem(row, COLUMN_TITLE, item); |
133 | - |
134 | - item = new QStandardItem(tio.getAlbum()); |
135 | - setItem(row, COLUMN_ALBUM, item); |
136 | - |
137 | - QString duration = MixxxUtils::secondsToMinutes(qVariantValue<int>(tio.getDuration())); |
138 | - item = new QStandardItem(duration); |
139 | - setItem(row, COLUMN_DURATION, item); |
140 | - |
141 | - item = new QStandardItem(tio.getBpmStr()); |
142 | - setItem(row, COLUMN_BPM, item); |
143 | - |
144 | - item = new QStandardItem(tio.getKey()); |
145 | - setItem(row, COLUMN_KEY, item); |
146 | - |
147 | - item = new QStandardItem(tio.getYear()); |
148 | - setItem(row, COLUMN_YEAR, item); |
149 | - |
150 | - item = new QStandardItem(tio.getBitrateStr()); |
151 | - setItem(row, COLUMN_BITRATE, item); |
152 | - |
153 | - item = new QStandardItem(tio.getType()); |
154 | - setItem(row, COLUMN_TYPE, item); |
155 | - |
156 | - item = new QStandardItem(tio.getGenre()); |
157 | - setItem(row, COLUMN_GENRE, item); |
158 | - |
159 | - item = new QStandardItem(tio.getTrackNumber()); |
160 | - setItem(row, COLUMN_TRACK_NUMBER, item); |
161 | - |
162 | - item = new QStandardItem(tio.getComment()); |
163 | - setItem(row, COLUMN_COMMENT, item); |
164 | - |
165 | - item = new QStandardItem(filepath); |
166 | - setItem(row, COLUMN_LOCATION, item); |
167 | - |
168 | - ++row; |
169 | - |
170 | - } |
171 | } |
172 | -void BrowseTableModel::browserThread() |
173 | +void BrowseTableModel::slotInsert(const QList<QStandardItem*> &column_data) |
174 | { |
175 | - //Give the thread low priority to prevent GUI freezing |
176 | - QThread* thisThread = QThread::currentThread(); |
177 | - thisThread->setPriority(QThread::LowestPriority); |
178 | - |
179 | - while(1){ |
180 | - m_mutex.lock(); |
181 | - //Wait until the user has selected a folder |
182 | - m_locationUpdated.wait(&m_mutex); |
183 | - |
184 | - //Terminate thread if Mixxx closes |
185 | - if(m_bStopThread) |
186 | - return; |
187 | - |
188 | - /* |
189 | - * Populate the model |
190 | - */ |
191 | - populateModel(); |
192 | - |
193 | - m_mutex.unlock(); |
194 | - |
195 | - } |
196 | + qDebug() << "BrowseTableModel::slotInsert"; |
197 | + appendRow(column_data); |
198 | + //Does not work for some reason |
199 | + //setItem(row, column, item); |
200 | } |
201 | |
202 | === modified file 'mixxx/src/library/browsetablemodel.h' |
203 | --- mixxx/src/library/browsetablemodel.h 2011-02-13 19:42:53 +0000 |
204 | +++ mixxx/src/library/browsetablemodel.h 2011-02-16 20:55:20 +0000 |
205 | @@ -3,9 +3,26 @@ |
206 | |
207 | #include <QStandardItemModel> |
208 | #include "trackmodel.h" |
209 | +#include "browsethread.h" |
210 | |
211 | class QMimeData; |
212 | |
213 | +//constants |
214 | +const int COLUMN_FILENAME = 0; |
215 | +const int COLUMN_ARTIST = 1; |
216 | +const int COLUMN_TITLE = 2; |
217 | +const int COLUMN_ALBUM = 3; |
218 | +const int COLUMN_TRACK_NUMBER = 4; |
219 | +const int COLUMN_YEAR = 5; |
220 | +const int COLUMN_GENRE = 6; |
221 | +const int COLUMN_COMMENT = 7; |
222 | +const int COLUMN_DURATION = 8; |
223 | +const int COLUMN_BPM = 9; |
224 | +const int COLUMN_KEY = 10; |
225 | +const int COLUMN_TYPE = 11; |
226 | +const int COLUMN_BITRATE = 12; |
227 | +const int COLUMN_LOCATION = 13; |
228 | + |
229 | class BrowseTableModel : public QStandardItemModel, public TrackModel |
230 | { |
231 | |
232 | @@ -30,20 +47,13 @@ |
233 | virtual bool isColumnHiddenByDefault(int column); |
234 | virtual const QList<int>& searchColumns() const; |
235 | private: |
236 | - void populateModel(); |
237 | - //This method is executed in a Thread |
238 | - void browserThread(); |
239 | - // Add a column to be searched when searching occurs |
240 | void addSearchColumn(int index); |
241 | |
242 | - QMutex m_mutex; |
243 | - QWaitCondition m_locationUpdated; |
244 | - |
245 | - QFuture<void> m_future; |
246 | - QList<int> m_searchColumns; |
247 | - QString m_path; |
248 | - |
249 | - bool m_bStopThread; |
250 | + BrowseThread m_backgroundThread; |
251 | + QList<int> m_searchColumns; |
252 | +public slots: |
253 | + void slotClear(); |
254 | + void slotInsert(const QList<QStandardItem*> &item); |
255 | }; |
256 | |
257 | #endif |
258 | |
259 | === added file 'mixxx/src/library/browsethread.cpp' |
260 | --- mixxx/src/library/browsethread.cpp 1970-01-01 00:00:00 +0000 |
261 | +++ mixxx/src/library/browsethread.cpp 2011-02-16 20:55:20 +0000 |
262 | @@ -0,0 +1,140 @@ |
263 | +#include "browsethread.h" |
264 | +#include "browsetablemodel.h" |
265 | +#include "soundsourceproxy.h" |
266 | +#include "mixxxutils.cpp" |
267 | + |
268 | +#include <QStringList> |
269 | +#include <QDirIterator> |
270 | +#include <QtCore> |
271 | + |
272 | + |
273 | +BrowseThread::BrowseThread(QObject *parent) : QThread(parent) |
274 | +{ |
275 | + //start thread |
276 | + m_bStopThread = false; |
277 | + |
278 | + //QObject::moveToThread(this); |
279 | +} |
280 | +BrowseThread::~BrowseThread() |
281 | +{ |
282 | + qDebug() << "Wait to finish browser background thread"; |
283 | + m_bStopThread = true; |
284 | + //wake up thread since it might wait for user input |
285 | + m_locationUpdated.wakeAll(); |
286 | + //Wait until thread terminated |
287 | + //terminate(); |
288 | + wait(); |
289 | + qDebug() << "Browser background thread terminated!"; |
290 | + |
291 | +} |
292 | + |
293 | +void BrowseThread::setPath(QString& path) |
294 | +{ |
295 | + m_path = path; |
296 | + m_locationUpdated.wakeAll(); |
297 | + |
298 | +} |
299 | + |
300 | +void BrowseThread::run() |
301 | +{ |
302 | + |
303 | + while(1){ |
304 | + m_mutex.lock(); |
305 | + //Wait until the user has selected a folder |
306 | + m_locationUpdated.wait(&m_mutex); |
307 | + |
308 | + //Terminate thread if Mixxx closes |
309 | + if(m_bStopThread) |
310 | + return; |
311 | + |
312 | + /* |
313 | + * Populate the model |
314 | + */ |
315 | + populateModel(); |
316 | + m_mutex.unlock(); |
317 | + |
318 | + } |
319 | + |
320 | +} |
321 | +void BrowseThread::populateModel() |
322 | +{ |
323 | + //Refresh the name filters in case we loaded new |
324 | + //SoundSource plugins. |
325 | + QStringList nameFilters(SoundSourceProxy::supportedFileExtensionsString().split(" ")); |
326 | + QDirIterator fileIt(m_path, nameFilters, QDir::Files | QDir::NoDotAndDotDot); |
327 | + QString thisPath(m_path); |
328 | + //remove all rows |
329 | + emit(clearModel()); |
330 | + QCoreApplication::processEvents(); |
331 | + |
332 | + int row = 0; |
333 | + //Iterate over the files |
334 | + while (fileIt.hasNext()) |
335 | + { |
336 | + /* |
337 | + * If a user quickly jumps through the folders |
338 | + * the current task becomes "dirty" |
339 | + */ |
340 | + if(thisPath != m_path){ |
341 | + qDebug() << "Exit populateModel()"; |
342 | + return populateModel(); |
343 | + } |
344 | + |
345 | + QString filepath = fileIt.next(); |
346 | + TrackInfoObject tio(filepath); |
347 | + QList<QStandardItem*> column_data; |
348 | + |
349 | + QStandardItem* item = new QStandardItem(tio.getFilename()); |
350 | + column_data.insert(COLUMN_FILENAME, item); |
351 | + |
352 | + |
353 | + item = new QStandardItem(tio.getArtist()); |
354 | + column_data.insert(COLUMN_ARTIST, item); |
355 | + |
356 | + item = new QStandardItem(tio.getTitle()); |
357 | + column_data.insert(COLUMN_TITLE, item); |
358 | + |
359 | + item = new QStandardItem(tio.getAlbum()); |
360 | + column_data.insert(COLUMN_ALBUM, item); |
361 | + |
362 | + item = new QStandardItem(tio.getTrackNumber()); |
363 | + column_data.insert(COLUMN_TRACK_NUMBER, item); |
364 | + |
365 | + item = new QStandardItem(tio.getYear()); |
366 | + column_data.insert(COLUMN_YEAR, item); |
367 | + |
368 | + item = new QStandardItem(tio.getGenre()); |
369 | + column_data.insert(COLUMN_GENRE, item); |
370 | + |
371 | + item = new QStandardItem(tio.getComment()); |
372 | + column_data.insert(COLUMN_COMMENT, item); |
373 | + |
374 | + QString duration = MixxxUtils::secondsToMinutes(qVariantValue<int>(tio.getDuration())); |
375 | + item = new QStandardItem(duration); |
376 | + column_data.insert(COLUMN_DURATION, item); |
377 | + |
378 | + item = new QStandardItem(tio.getBpmStr()); |
379 | + column_data.insert(COLUMN_BPM, item); |
380 | + |
381 | + item = new QStandardItem(tio.getKey()); |
382 | + column_data.insert(COLUMN_KEY, item); |
383 | + |
384 | + item = new QStandardItem(tio.getType()); |
385 | + column_data.insert(COLUMN_TYPE, item); |
386 | + |
387 | + item = new QStandardItem(tio.getBitrateStr()); |
388 | + column_data.insert(COLUMN_BITRATE, item); |
389 | + |
390 | + item = new QStandardItem(filepath); |
391 | + column_data.insert(COLUMN_LOCATION, item); |
392 | + |
393 | + emit(rowDataAppended(column_data)); |
394 | + |
395 | + QCoreApplication::processEvents(); |
396 | + ++row; |
397 | + |
398 | + //Sleep for 50ms which prevents us from GUI freezes |
399 | + msleep(50); |
400 | + } |
401 | + |
402 | +} |
403 | |
404 | === added file 'mixxx/src/library/browsethread.h' |
405 | --- mixxx/src/library/browsethread.h 1970-01-01 00:00:00 +0000 |
406 | +++ mixxx/src/library/browsethread.h 2011-02-16 20:55:20 +0000 |
407 | @@ -0,0 +1,37 @@ |
408 | +#ifndef BROWSETHREAD_H |
409 | +#define BROWSETHREAD_H |
410 | + |
411 | +#include <QThread> |
412 | +#include <QMutex> |
413 | +#include <QWaitCondition> |
414 | +#include <QStandardItem> |
415 | +#include <QList> |
416 | + |
417 | +class BrowseThread : public QThread |
418 | +{ |
419 | + Q_OBJECT |
420 | +public: |
421 | + BrowseThread(QObject *parent = 0); |
422 | + ~BrowseThread(); |
423 | + void setPath(QString& path); |
424 | + void run(); |
425 | +signals: |
426 | + void rowDataAppended(const QList<QStandardItem*>&); |
427 | + void clearModel(); |
428 | +private: |
429 | + void populateModel(); |
430 | + QMutex m_mutex; |
431 | + QWaitCondition m_locationUpdated; |
432 | + |
433 | + |
434 | + QList<int> m_searchColumns; |
435 | + QString m_path; |
436 | + |
437 | + bool m_bStopThread; |
438 | + |
439 | + |
440 | + |
441 | + |
442 | +}; |
443 | + |
444 | +#endif // BROWSETHREAD_H |
Hey Tobias,
Checking out this I've got a couple of questions and things to fix:
1) Why the updates to libmad, libid3tag, and libtag?
2) I assume you're adding shell32 because you use system-specific calls in foldertreemodel .cpp? Could you comment that line in the SConscript to mention that's why it's there (mostly so I don't blindly remove it in the future thinking "gee we don't need this" :) )
3) In browsefeature.cpp the "My Music" literal needs a tr(). Also the naming of My Music might make Windows users actually think it's their "My Music" folder, while it's actually the library folder they picked in Mixxx. Maybe we should say "My Library" instead?
4) I think we should add some other useful links, e.g. a 'My Home' for the user's home directory, 'My Documents' or 'My Music' for their Music folder (if it isn't the same as their Mixxx library). You can do this in a cross-platform way with the QDesktopService s::storageLocat ion method
5) I noticed that when expanding directories in the sidebar, if you hit the expand triangle on a folder that you are not currently selecting, it won't expand. Is this the case in general? Can we fix it so that they expand? I'm on Ubuntu 10.04 with standard Qt.
6) BrowseTableMode l::BrowseTableM odel() all those header column names need tr()'s
7) (sorry for nitpicking) can isBackgroundThr eadActive get an "m_b" prefix, also can you move the initialization of isBackgroundThr eadActive and m_currentPath to the constructor initializer list?
8) For the populateModel method in BrowseTableModel, I think you should change it a little bit. Particularly, the lock'ing of the mutex in the setPath is problematic because it could block (not deadlock, but still) the GUI thread if it was called twice before the populateModel method runs. I would change it like this: get rid of the isBackgroundThr eadActive boolean and m_currentPath. Make the currentPath an argument of the populateModel method and add the path to be set as the last argument of the QtConcurrent::run call. You should still lock the populateMutex in populateModel to prevent the populateModel() method from running more than once concurrently. This may result in populateModel being run more than once if someone quickly sets the path and sets it again. I think that's not too terrible, as the UI will eventually update to be correct.
9) In SidebarModel: :hasChildren, can you use dynamic_cast instead of a bare cast (and check that it's not null as a result of the dynamic_cast?)
General comment: It looks like there are still a lot of places where there are tabs. One place I noticed is the addition to sidebarmodel.h and also the additions to depends.py -- could you double check your editor is using 4-space indents?
Based on these things getting fixed, everything else looks good. Thanks Tobias!
If you don't have time to work on this stuff I'm happy to lend a hand.
RJ