Merge lp:~mixxxdevelopers/mixxx/library_features into lp:~mixxxdevelopers/mixxx/trunk
- library_features
- Merge into trunk
Status: | Needs review | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Proposed branch: | lp:~mixxxdevelopers/mixxx/library_features | ||||||||||||||||
Merge into: | lp:~mixxxdevelopers/mixxx/trunk | ||||||||||||||||
Diff against target: |
5250 lines (+1538/-949) 77 files modified
mixxx/build/depends.py (+1/-0) mixxx/res/schema.xml (+14/-0) mixxx/src/dlgautodj.cpp (+5/-2) mixxx/src/dlgautodj.h (+1/-0) mixxx/src/dlgpreferences.cpp (+5/-0) mixxx/src/dlgpreferences.h (+2/-0) mixxx/src/dlgprefplaylist.cpp (+87/-9) mixxx/src/dlgprefplaylist.h (+9/-0) mixxx/src/dlgprefplaylistdlg.ui (+40/-26) mixxx/src/dlgprefrecord.cpp (+1/-4) mixxx/src/library/autodjfeature.cpp (+2/-0) mixxx/src/library/autodjfeature.h (+3/-0) mixxx/src/library/baseexternalplaylistmodel.cpp (+3/-3) mixxx/src/library/baseexternalplaylistmodel.h (+3/-1) mixxx/src/library/baseexternaltrackmodel.cpp (+3/-3) mixxx/src/library/baseexternaltrackmodel.h (+3/-1) mixxx/src/library/baseplaylistfeature.cpp (+5/-4) mixxx/src/library/baseplaylistfeature.h (+0/-1) mixxx/src/library/basesqltablemodel.cpp (+79/-9) mixxx/src/library/basesqltablemodel.h (+60/-48) mixxx/src/library/basetrackcache.cpp (+2/-0) mixxx/src/library/browse/browsefeature.cpp (+23/-2) mixxx/src/library/browse/browsefeature.h (+3/-0) mixxx/src/library/browse/browsetablemodel.cpp (+2/-1) mixxx/src/library/browse/browsetablemodel.h (+1/-1) mixxx/src/library/browse/browsethread.h (+7/-9) mixxx/src/library/browse/foldertreemodel.cpp (+1/-0) mixxx/src/library/cratefeature.cpp (+10/-7) mixxx/src/library/cratefeature.h (+3/-0) mixxx/src/library/cratetablemodel.cpp (+46/-62) mixxx/src/library/cratetablemodel.h (+7/-20) mixxx/src/library/dao/directorydao.cpp (+143/-0) mixxx/src/library/dao/directorydao.h (+31/-0) mixxx/src/library/dao/trackdao.cpp (+307/-76) mixxx/src/library/dao/trackdao.h (+17/-7) mixxx/src/library/hiddentablemodel.cpp (+42/-50) mixxx/src/library/hiddentablemodel.h (+2/-15) mixxx/src/library/itunes/itunesfeature.cpp (+24/-22) mixxx/src/library/itunes/itunesfeature.h (+5/-1) mixxx/src/library/library.cpp (+79/-19) mixxx/src/library/library.h (+16/-1) mixxx/src/library/libraryfeature.h (+4/-3) mixxx/src/library/libraryscanner.cpp (+40/-26) mixxx/src/library/libraryscanner.h (+6/-3) mixxx/src/library/librarytablemodel.cpp (+44/-66) mixxx/src/library/librarytablemodel.h (+2/-21) mixxx/src/library/missingtablemodel.cpp (+0/-125) mixxx/src/library/missingtablemodel.h (+0/-41) mixxx/src/library/mixxxlibraryfeature.cpp (+4/-4) mixxx/src/library/mixxxlibraryfeature.h (+5/-1) mixxx/src/library/playlistfeature.cpp (+6/-5) mixxx/src/library/playlistfeature.h (+5/-1) mixxx/src/library/playlisttablemodel.cpp (+56/-96) mixxx/src/library/playlisttablemodel.h (+14/-30) mixxx/src/library/preparelibrarytablemodel.cpp (+2/-13) mixxx/src/library/preparelibrarytablemodel.h (+2/-7) mixxx/src/library/promotracksfeature.cpp (+1/-1) mixxx/src/library/proxytrackmodel.cpp (+16/-11) mixxx/src/library/proxytrackmodel.h (+3/-4) mixxx/src/library/rhythmbox/rhythmboxfeature.cpp (+6/-4) mixxx/src/library/rhythmbox/rhythmboxfeature.h (+4/-1) mixxx/src/library/setlogfeature.cpp (+6/-5) mixxx/src/library/stardelegate.cpp (+11/-3) mixxx/src/library/stardelegate.h (+2/-0) mixxx/src/library/trackcollection.cpp (+28/-14) mixxx/src/library/trackcollection.h (+12/-1) mixxx/src/library/trackmodel.h (+18/-12) mixxx/src/library/traktor/traktorfeature.cpp (+14/-10) mixxx/src/library/traktor/traktorfeature.h (+8/-3) mixxx/src/library/treeitem.cpp (+6/-0) mixxx/src/mixxx.cpp (+56/-27) mixxx/src/mixxx.h (+2/-1) mixxx/src/playermanager.cpp (+8/-0) mixxx/src/soundsourceproxy.h (+1/-1) mixxx/src/waveform/waveform.h (+1/-1) mixxx/src/widget/wtracktableview.cpp (+44/-4) mixxx/src/widget/wtracktableview.h (+4/-0) |
||||||||||||||||
To merge this branch: | bzr merge lp:~mixxxdevelopers/mixxx/library_features | ||||||||||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Mixxx Development Team | Pending | ||
Review via email: mp+162700@code.launchpad.net |
Commit message
Description of the change
Getting the ball rolling on the code review for Max's library_features work.
RJ Skerry-Ryan (rryan) wrote : | # |
- 3264. By Max Linke <kain88@640X4.kel.wh.lokal>
-
fix cratetablemodel
.cpp, library is not shown there is something off - 3265. By Max Linke <kain88@640X4.kel.wh.lokal>
-
disabled previewDeck to make everything work for now
- 3266. By Max Linke <kain88@640X4.kel.wh.lokal>
-
reenabled preview deck, fixed temporary view that is created by the tablemodels
- 3267. By Max Linke <kain88@640X4.kel.wh.lokal>
-
changed name for chromaprint library in scons
- 3268. By Max Linke <kain88@640X4.kel.wh.lokal>
-
added missing files
- 3269. By Max Linke <kain88@640X4.kel.wh.lokal>
-
I'm stupid -.-
- 3270. By Max Linke <kain88@640X4.kel.wh.lokal>
-
next try for the build server
- 3271. By RJ Skerry-Ryan
-
Check for chromaprint_p.
- 3272. By RJ Skerry-Ryan
-
Check for chromaprint_p.
- 3273. By RJ Skerry-Ryan
-
Try detecting chromaprint after chromaprint_p?
- 3274. By RJ Skerry-Ryan
-
Roll-back r3273.
- 3275. By RJ Skerry-Ryan
-
Add chromaprint to LIBS manually after CheckLib passes.
- 3276. By RJ Skerry-Ryan
-
Add CHROMAPRINT_NODLL to CPPDEFINES.
- 3277. By RJ Skerry-Ryan
-
Typo.
- 3278. By RJ Skerry-Ryan
-
Only define CHROMAPRINT_NODLL for static_
dependencies. - 3279. By RJ Skerry-Ryan
-
Link fftw3 on Windows only.
- 3280. By Max Linke <kain88@640X4.kel.wh.lokal>
-
merge with trunk, library scanner does not add songs
- 3281. By Max Linke <kain88@640X4.kel.wh.lokal>
-
does launchpad use my email now?
- 3282. By Max Linke <kain88@640X4.kel.wh.lokal>
-
next try
- 3283. By Max Linke <email address hidden>
-
next try 2
- 3284. By Max Linke <email address hidden>
-
removed fringerprinting feature that is moved into chromaprint branch
- 3285. By Max Linke <email address hidden>
-
merge with trunk
- 3286. By Max Linke <email address hidden>
-
merge with trunk
- 3287. By Max Linke <email address hidden>
-
merge with trunk
- 3288. By Max Linke <email address hidden>
-
merge with trunk
Unmerged revisions
- 3288. By Max Linke <email address hidden>
-
merge with trunk
- 3287. By Max Linke <email address hidden>
-
merge with trunk
- 3286. By Max Linke <email address hidden>
-
merge with trunk
- 3285. By Max Linke <email address hidden>
-
merge with trunk
- 3284. By Max Linke <email address hidden>
-
removed fringerprinting feature that is moved into chromaprint branch
- 3283. By Max Linke <email address hidden>
-
next try 2
- 3282. By Max Linke <kain88@640X4.kel.wh.lokal>
-
next try
- 3281. By Max Linke <kain88@640X4.kel.wh.lokal>
-
does launchpad use my email now?
- 3280. By Max Linke <kain88@640X4.kel.wh.lokal>
-
merge with trunk, library scanner does not add songs
- 3279. By RJ Skerry-Ryan
-
Link fftw3 on Windows only.
Preview Diff
1 | === modified file 'mixxx/build/depends.py' | |||
2 | --- mixxx/build/depends.py 2013-05-16 01:40:06 +0000 | |||
3 | +++ mixxx/build/depends.py 2013-05-18 16:32:26 +0000 | |||
4 | @@ -569,6 +569,7 @@ | |||
5 | 569 | "library/libraryfeature.cpp", | 569 | "library/libraryfeature.cpp", |
6 | 570 | "library/preparefeature.cpp", | 570 | "library/preparefeature.cpp", |
7 | 571 | "library/autodjfeature.cpp", | 571 | "library/autodjfeature.cpp", |
8 | 572 | "library/dao/directorydao.cpp", | ||
9 | 572 | "library/mixxxlibraryfeature.cpp", | 573 | "library/mixxxlibraryfeature.cpp", |
10 | 573 | "library/baseplaylistfeature.cpp", | 574 | "library/baseplaylistfeature.cpp", |
11 | 574 | "library/playlistfeature.cpp", | 575 | "library/playlistfeature.cpp", |
12 | 575 | 576 | ||
13 | === modified file 'mixxx/res/schema.xml' | |||
14 | --- mixxx/res/schema.xml 2013-05-07 03:17:23 +0000 | |||
15 | +++ mixxx/res/schema.xml 2013-05-18 16:32:26 +0000 | |||
16 | @@ -338,4 +338,18 @@ | |||
17 | 338 | ALTER TABLE Library ADD COLUMN keys_sub_version TEXT; | 338 | ALTER TABLE Library ADD COLUMN keys_sub_version TEXT; |
18 | 339 | </sql> | 339 | </sql> |
19 | 340 | </revision> | 340 | </revision> |
20 | 341 | <revision version="19" min_compatible="3"> | ||
21 | 342 | <description> | ||
22 | 343 | Add directories table | ||
23 | 344 | </description> | ||
24 | 345 | <sql> | ||
25 | 346 | CREATE TABLE IF NOT EXISTS directories ( | ||
26 | 347 | dir_id INTEGER primary key AUTOINCREMENT, | ||
27 | 348 | directory varchar(1024) | ||
28 | 349 | ); | ||
29 | 350 | CREATE UNIQUE INDEX directory_idx ON directories(directory); | ||
30 | 351 | ALTER TABLE track_locations ADD COLUMN maindir_id INTEGER DEFAULT 0; | ||
31 | 352 | ALTER TABLE track_locations ADD COLUMN checksum varchar(1024); | ||
32 | 353 | </sql> | ||
33 | 354 | </revision> | ||
34 | 341 | </schema> | 355 | </schema> |
35 | 342 | 356 | ||
36 | === modified file 'mixxx/src/dlgautodj.cpp' | |||
37 | --- mixxx/src/dlgautodj.cpp 2013-05-18 16:23:08 +0000 | |||
38 | +++ mixxx/src/dlgautodj.cpp 2013-05-18 16:32:26 +0000 | |||
39 | @@ -43,14 +43,17 @@ | |||
40 | 43 | box->insertWidget(1, m_pTrackTableView); | 43 | box->insertWidget(1, m_pTrackTableView); |
41 | 44 | 44 | ||
42 | 45 | m_pAutoDJTableModel = new PlaylistTableModel(this, pTrackCollection, | 45 | m_pAutoDJTableModel = new PlaylistTableModel(this, pTrackCollection, |
44 | 46 | "mixxx.db.model.autodj"); | 46 | "mixxx.db.model.autodj", |
45 | 47 | m_pConfig); | ||
46 | 48 | connect(this, SIGNAL(configChanged(QString,QString)), | ||
47 | 49 | m_pAutoDJTableModel, SLOT(slotConfigChanged(QString,QString))); | ||
48 | 47 | PlaylistDAO& playlistDao = pTrackCollection->getPlaylistDAO(); | 50 | PlaylistDAO& playlistDao = pTrackCollection->getPlaylistDAO(); |
49 | 48 | int playlistId = playlistDao.getPlaylistIdFromName(AUTODJ_TABLE); | 51 | int playlistId = playlistDao.getPlaylistIdFromName(AUTODJ_TABLE); |
50 | 49 | if (playlistId < 0) { | 52 | if (playlistId < 0) { |
51 | 50 | playlistId = playlistDao.createPlaylist(AUTODJ_TABLE, | 53 | playlistId = playlistDao.createPlaylist(AUTODJ_TABLE, |
52 | 51 | PlaylistDAO::PLHT_AUTO_DJ); | 54 | PlaylistDAO::PLHT_AUTO_DJ); |
53 | 52 | } | 55 | } |
55 | 53 | m_pAutoDJTableModel->setPlaylist(playlistId); | 56 | m_pAutoDJTableModel->setTableModel(playlistId); |
56 | 54 | m_pTrackTableView->loadTrackModel(m_pAutoDJTableModel); | 57 | m_pTrackTableView->loadTrackModel(m_pAutoDJTableModel); |
57 | 55 | 58 | ||
58 | 56 | // Override some playlist-view properties: | 59 | // Override some playlist-view properties: |
59 | 57 | 60 | ||
60 | === modified file 'mixxx/src/dlgautodj.h' | |||
61 | --- mixxx/src/dlgautodj.h 2013-04-12 15:27:07 +0000 | |||
62 | +++ mixxx/src/dlgautodj.h 2013-05-18 16:32:26 +0000 | |||
63 | @@ -47,6 +47,7 @@ | |||
64 | 47 | 47 | ||
65 | 48 | signals: | 48 | signals: |
66 | 49 | void loadTrack(TrackPointer tio); | 49 | void loadTrack(TrackPointer tio); |
67 | 50 | void configChanged(QString,QString); | ||
68 | 50 | void loadTrackToPlayer(TrackPointer tio, QString group, bool); | 51 | void loadTrackToPlayer(TrackPointer tio, QString group, bool); |
69 | 51 | 52 | ||
70 | 52 | private: | 53 | private: |
71 | 53 | 54 | ||
72 | === modified file 'mixxx/src/dlgpreferences.cpp' | |||
73 | --- mixxx/src/dlgpreferences.cpp 2013-05-12 10:15:29 +0000 | |||
74 | +++ mixxx/src/dlgpreferences.cpp 2013-05-18 16:32:26 +0000 | |||
75 | @@ -80,6 +80,11 @@ | |||
76 | 80 | addPageWidget(m_wsound); | 80 | addPageWidget(m_wsound); |
77 | 81 | m_wplaylist = new DlgPrefPlaylist(this, config); | 81 | m_wplaylist = new DlgPrefPlaylist(this, config); |
78 | 82 | addPageWidget(m_wplaylist); | 82 | addPageWidget(m_wplaylist); |
79 | 83 | connect(m_wplaylist, SIGNAL(configChanged(QString,QString)), | ||
80 | 84 | this, SIGNAL(configChanged(QString,QString))); | ||
81 | 85 | connect(m_wplaylist, SIGNAL(dirsChanged(QString,QString)), | ||
82 | 86 | this, SIGNAL(dirsChanged(QString,QString))); | ||
83 | 87 | |||
84 | 83 | m_wcontrols = new DlgPrefControls(this, mixxx, pSkinLoader, pPlayerManager, config); | 88 | m_wcontrols = new DlgPrefControls(this, mixxx, pSkinLoader, pPlayerManager, config); |
85 | 84 | addPageWidget(m_wcontrols); | 89 | addPageWidget(m_wcontrols); |
86 | 85 | m_weq = new DlgPrefEQ(this, config); | 90 | m_weq = new DlgPrefEQ(this, config); |
87 | 86 | 91 | ||
88 | === modified file 'mixxx/src/dlgpreferences.h' | |||
89 | --- mixxx/src/dlgpreferences.h 2013-05-12 10:15:29 +0000 | |||
90 | +++ mixxx/src/dlgpreferences.h 2013-05-18 16:32:26 +0000 | |||
91 | @@ -74,6 +74,8 @@ | |||
92 | 74 | signals: | 74 | signals: |
93 | 75 | void closeDlg(); | 75 | void closeDlg(); |
94 | 76 | void showDlg(); | 76 | void showDlg(); |
95 | 77 | void configChanged(QString, QString); | ||
96 | 78 | void dirsChanged(QString, QString); | ||
97 | 77 | protected: | 79 | protected: |
98 | 78 | bool eventFilter(QObject*, QEvent*); | 80 | bool eventFilter(QObject*, QEvent*); |
99 | 79 | private: | 81 | private: |
100 | 80 | 82 | ||
101 | === modified file 'mixxx/src/dlgprefplaylist.cpp' | |||
102 | --- mixxx/src/dlgprefplaylist.cpp 2013-05-18 16:23:08 +0000 | |||
103 | +++ mixxx/src/dlgprefplaylist.cpp 2013-05-18 16:32:26 +0000 | |||
104 | @@ -15,6 +15,9 @@ | |||
105 | 15 | * * | 15 | * * |
106 | 16 | ***************************************************************************/ | 16 | ***************************************************************************/ |
107 | 17 | 17 | ||
108 | 18 | #include <QSqlDatabase> | ||
109 | 19 | #include <QSqlQuery> | ||
110 | 20 | #include <QSqlRecord> | ||
111 | 18 | #include <QUrl> | 21 | #include <QUrl> |
112 | 19 | #include <QDesktopServices> | 22 | #include <QDesktopServices> |
113 | 20 | #include <QFileDialog> | 23 | #include <QFileDialog> |
114 | @@ -30,6 +33,8 @@ | |||
115 | 30 | 33 | ||
116 | 31 | DlgPrefPlaylist::DlgPrefPlaylist(QWidget * parent, ConfigObject<ConfigValue> * config) | 34 | DlgPrefPlaylist::DlgPrefPlaylist(QWidget * parent, ConfigObject<ConfigValue> * config) |
117 | 32 | : QWidget(parent), | 35 | : QWidget(parent), |
118 | 36 | m_model(), | ||
119 | 37 | m_dirsModified(false), | ||
120 | 33 | m_pconfig(config) { | 38 | m_pconfig(config) { |
121 | 34 | setupUi(this); | 39 | setupUi(this); |
122 | 35 | slotUpdate(); | 40 | slotUpdate(); |
123 | @@ -51,6 +56,10 @@ | |||
124 | 51 | 56 | ||
125 | 52 | connect(PushButtonBrowsePlaylist, SIGNAL(clicked()), | 57 | connect(PushButtonBrowsePlaylist, SIGNAL(clicked()), |
126 | 53 | this, SLOT(slotBrowseDir())); | 58 | this, SLOT(slotBrowseDir())); |
127 | 59 | connect(PushButtonRemovePlaylist, SIGNAL(clicked()), | ||
128 | 60 | this, SLOT(slotRemoveDir())); | ||
129 | 61 | connect(pushButton_2, SIGNAL(clicked()), | ||
130 | 62 | this, SLOT(slotRelocateDir())); | ||
131 | 54 | //connect(pushButtonM4A, SIGNAL(clicked()), this, SLOT(slotM4ACheck())); | 63 | //connect(pushButtonM4A, SIGNAL(clicked()), this, SLOT(slotM4ACheck())); |
132 | 55 | connect(pushButtonExtraPlugins, SIGNAL(clicked()), | 64 | connect(pushButtonExtraPlugins, SIGNAL(clicked()), |
133 | 56 | this, SLOT(slotExtraPlugins())); | 65 | this, SLOT(slotExtraPlugins())); |
134 | @@ -74,6 +83,40 @@ | |||
135 | 74 | DlgPrefPlaylist::~DlgPrefPlaylist() { | 83 | DlgPrefPlaylist::~DlgPrefPlaylist() { |
136 | 75 | } | 84 | } |
137 | 76 | 85 | ||
138 | 86 | bool DlgPrefPlaylist::initializeModel(){ | ||
139 | 87 | // this will hook into the default connection, so we don't need to | ||
140 | 88 | // provide anymore information. This works because the Library is | ||
141 | 89 | // created before the Preferences and a connection already exists. | ||
142 | 90 | // --kain88 July 2012 | ||
143 | 91 | QSqlDatabase database = QSqlDatabase::database(); | ||
144 | 92 | QSqlQuery query; | ||
145 | 93 | query.prepare("SELECT directory from directories"); | ||
146 | 94 | if (!query.exec()) { | ||
147 | 95 | qDebug() << "damn there are no directories to display"; | ||
148 | 96 | return false; | ||
149 | 97 | } | ||
150 | 98 | // save which index was selected | ||
151 | 99 | const int selected = list->currentIndex().row(); | ||
152 | 100 | m_model.clear(); | ||
153 | 101 | while(query.next()){ | ||
154 | 102 | QStandardItem* pitem = new QStandardItem( | ||
155 | 103 | query.value(query.record().indexOf("directory")) | ||
156 | 104 | .toString()); | ||
157 | 105 | m_model.appendRow(pitem); | ||
158 | 106 | } | ||
159 | 107 | list->setModel(&m_model); | ||
160 | 108 | // first select the first index then change it to selected if it still exists | ||
161 | 109 | list->setCurrentIndex(list->model()->index(0, 0)); | ||
162 | 110 | for (int i=0 ; i<list->model()->rowCount() ; ++i) { | ||
163 | 111 | const QModelIndex index = list->model()->index(i, 0); | ||
164 | 112 | if (index.row() == selected) { | ||
165 | 113 | list->setCurrentIndex(index); | ||
166 | 114 | break; | ||
167 | 115 | } | ||
168 | 116 | } | ||
169 | 117 | return true; | ||
170 | 118 | } | ||
171 | 119 | |||
172 | 77 | void DlgPrefPlaylist::slotExtraPlugins() { | 120 | void DlgPrefPlaylist::slotExtraPlugins() { |
173 | 78 | QDesktopServices::openUrl(QUrl(MIXXX_ADDONS_URL)); | 121 | QDesktopServices::openUrl(QUrl(MIXXX_ADDONS_URL)); |
174 | 79 | } | 122 | } |
175 | @@ -141,9 +184,8 @@ | |||
176 | 141 | }*/ | 184 | }*/ |
177 | 142 | 185 | ||
178 | 143 | void DlgPrefPlaylist::slotUpdate() { | 186 | void DlgPrefPlaylist::slotUpdate() { |
182 | 144 | // Library Path | 187 | // Song path |
183 | 145 | LineEditSongfiles->setText(m_pconfig->getValueString( | 188 | initializeModel(); |
181 | 146 | ConfigKey("[Playlist]","Directory"))); | ||
184 | 147 | //Bundled songs stat tracking | 189 | //Bundled songs stat tracking |
185 | 148 | checkBoxPromoStats->setChecked((bool)m_pconfig->getValueString( | 190 | checkBoxPromoStats->setChecked((bool)m_pconfig->getValueString( |
186 | 149 | ConfigKey("[Promo]","StatTracking")).toInt()); | 191 | ConfigKey("[Promo]","StatTracking")).toInt()); |
187 | @@ -159,14 +201,41 @@ | |||
188 | 159 | ConfigKey("[Library]","ShowITunesLibrary"),"1").toInt()); | 201 | ConfigKey("[Library]","ShowITunesLibrary"),"1").toInt()); |
189 | 160 | checkBox_show_traktor->setChecked((bool)m_pconfig->getValueString( | 202 | checkBox_show_traktor->setChecked((bool)m_pconfig->getValueString( |
190 | 161 | ConfigKey("[Library]","ShowTraktorLibrary"),"1").toInt()); | 203 | ConfigKey("[Library]","ShowTraktorLibrary"),"1").toInt()); |
191 | 204 | checkBox_show_missing->setChecked((bool)m_pconfig->getValueString( | ||
192 | 205 | ConfigKey("[Library]","ShowMissingSongs"),"1").toInt()); | ||
193 | 162 | } | 206 | } |
194 | 163 | 207 | ||
195 | 164 | void DlgPrefPlaylist::slotBrowseDir() { | 208 | void DlgPrefPlaylist::slotBrowseDir() { |
196 | 165 | QString fd = QFileDialog::getExistingDirectory(this, | 209 | QString fd = QFileDialog::getExistingDirectory(this, |
199 | 166 | tr("Choose music library directory"), | 210 | tr("Choose music library directory"), |
200 | 167 | m_pconfig->getValueString(ConfigKey("[Playlist]","Directory"))); | 211 | QDesktopServices::storageLocation(QDesktopServices::MusicLocation)); |
201 | 168 | if (fd != "") { | 212 | if (fd != "") { |
203 | 169 | LineEditSongfiles->setText(fd); | 213 | emit(dirsChanged("added",fd)); |
204 | 214 | slotUpdate(); | ||
205 | 215 | m_dirsModified = true; | ||
206 | 216 | } | ||
207 | 217 | } | ||
208 | 218 | |||
209 | 219 | void DlgPrefPlaylist::slotRemoveDir() { | ||
210 | 220 | QModelIndex index = list->currentIndex(); | ||
211 | 221 | QString fd = index.data().toString(); | ||
212 | 222 | emit(dirsChanged("removed",fd)); | ||
213 | 223 | slotUpdate(); | ||
214 | 224 | m_dirsModified = true; | ||
215 | 225 | } | ||
216 | 226 | |||
217 | 227 | void DlgPrefPlaylist::slotRelocateDir() { | ||
218 | 228 | QModelIndex index = list->currentIndex(); | ||
219 | 229 | QString currentFd = index.data().toString(); | ||
220 | 230 | QString fd = QFileDialog::getExistingDirectory(this, | ||
221 | 231 | tr("Choose music library directory"), | ||
222 | 232 | QDesktopServices::storageLocation(QDesktopServices::MusicLocation)); | ||
223 | 233 | |||
224 | 234 | //use !(~)! as a sign where the string has to be seperated later | ||
225 | 235 | if(!fd.isEmpty()){ | ||
226 | 236 | emit(dirsChanged("relocate",fd+"!(~)!"+currentFd)); | ||
227 | 237 | slotUpdate(); | ||
228 | 238 | m_dirsModified = true; | ||
229 | 170 | } | 239 | } |
230 | 171 | } | 240 | } |
231 | 172 | 241 | ||
232 | @@ -186,10 +255,19 @@ | |||
233 | 186 | m_pconfig->set(ConfigKey("[Library]","ShowTraktorLibrary"), | 255 | m_pconfig->set(ConfigKey("[Library]","ShowTraktorLibrary"), |
234 | 187 | ConfigValue((int)checkBox_show_traktor->isChecked())); | 256 | ConfigValue((int)checkBox_show_traktor->isChecked())); |
235 | 188 | 257 | ||
239 | 189 | if (LineEditSongfiles->text() != | 258 | // Update playlist if path has changed |
240 | 190 | m_pconfig->getValueString(ConfigKey("[Playlist]","Directory"))) { | 259 | if (m_dirsModified) { |
238 | 191 | m_pconfig->set(ConfigKey("[Playlist]","Directory"), LineEditSongfiles->text()); | ||
241 | 192 | emit(apply()); | 260 | emit(apply()); |
242 | 193 | } | 261 | } |
243 | 262 | |||
244 | 263 | //update TM if ShowMissingSongs has changed | ||
245 | 264 | if ((int)checkBox_show_missing->isChecked() != m_pconfig->getValueString( | ||
246 | 265 | ConfigKey("[Library]", | ||
247 | 266 | "ShowMissingSongs"),"1").toInt()) { | ||
248 | 267 | m_pconfig->set(ConfigKey("[Library]","ShowMissingSongs"), | ||
249 | 268 | ConfigValue((int)checkBox_show_missing->isChecked())); | ||
250 | 269 | |||
251 | 270 | emit(configChanged("[Library]","ShowMissingSongs")); | ||
252 | 271 | } | ||
253 | 194 | m_pconfig->Save(); | 272 | m_pconfig->Save(); |
254 | 195 | } | 273 | } |
255 | 196 | 274 | ||
256 | === modified file 'mixxx/src/dlgprefplaylist.h' | |||
257 | --- mixxx/src/dlgprefplaylist.h 2013-05-18 16:23:08 +0000 | |||
258 | +++ mixxx/src/dlgprefplaylist.h 2013-05-18 16:32:26 +0000 | |||
259 | @@ -18,6 +18,8 @@ | |||
260 | 18 | #ifndef DLGPREFPLAYLIST_H | 18 | #ifndef DLGPREFPLAYLIST_H |
261 | 19 | #define DLGPREFPLAYLIST_H | 19 | #define DLGPREFPLAYLIST_H |
262 | 20 | 20 | ||
263 | 21 | #include <QStandardItemModel> | ||
264 | 22 | |||
265 | 21 | #include "ui_dlgprefplaylistdlg.h" | 23 | #include "ui_dlgprefplaylistdlg.h" |
266 | 22 | #include "configobject.h" | 24 | #include "configobject.h" |
267 | 23 | 25 | ||
268 | @@ -37,6 +39,8 @@ | |||
269 | 37 | void slotUpdate(); | 39 | void slotUpdate(); |
270 | 38 | // Dialog to browse for music file directory | 40 | // Dialog to browse for music file directory |
271 | 39 | void slotBrowseDir(); | 41 | void slotBrowseDir(); |
272 | 42 | void slotRemoveDir(); | ||
273 | 43 | void slotRelocateDir(); | ||
274 | 40 | // Apply changes to widget | 44 | // Apply changes to widget |
275 | 41 | void slotApply(); | 45 | void slotApply(); |
276 | 42 | // Starts up the PluginDownloader if the plugin isn't present | 46 | // Starts up the PluginDownloader if the plugin isn't present |
277 | @@ -53,8 +57,13 @@ | |||
278 | 53 | 57 | ||
279 | 54 | signals: | 58 | signals: |
280 | 55 | void apply(); | 59 | void apply(); |
281 | 60 | void configChanged(QString, QString); | ||
282 | 61 | void dirsChanged(QString, QString); | ||
283 | 56 | 62 | ||
284 | 57 | private: | 63 | private: |
285 | 64 | bool initializeModel(); | ||
286 | 65 | QStandardItemModel m_model; | ||
287 | 66 | bool m_dirsModified; | ||
288 | 58 | ConfigObject<ConfigValue> *m_pconfig; | 67 | ConfigObject<ConfigValue> *m_pconfig; |
289 | 59 | // SoundSource Plugin Downloader | 68 | // SoundSource Plugin Downloader |
290 | 60 | //PluginDownloader* m_pPluginDownloader; | 69 | //PluginDownloader* m_pPluginDownloader; |
291 | 61 | 70 | ||
292 | === modified file 'mixxx/src/dlgprefplaylistdlg.ui' | |||
293 | --- mixxx/src/dlgprefplaylistdlg.ui 2012-12-09 17:41:04 +0000 | |||
294 | +++ mixxx/src/dlgprefplaylistdlg.ui 2013-05-18 16:32:26 +0000 | |||
295 | @@ -41,30 +41,47 @@ | |||
296 | 41 | <bool>false</bool> | 41 | <bool>false</bool> |
297 | 42 | </property> | 42 | </property> |
298 | 43 | <property name="buddy"> | 43 | <property name="buddy"> |
306 | 44 | <cstring>LineEditSongfiles</cstring> | 44 | <cstring>list</cstring> |
307 | 45 | </property> | 45 | </property> |
308 | 46 | </widget> | 46 | </widget> |
309 | 47 | </item> | 47 | </item> |
310 | 48 | <item row="0" column="1"> | 48 | <item row="3" column="1"> |
311 | 49 | <widget class="QLineEdit" name="LineEditSongfiles"> | 49 | <widget class="QPushButton" name="PushButtonRemovePlaylist"> |
312 | 50 | <property name="minimumSize"> | 50 | <property name="font"> |
313 | 51 | <font/> | ||
314 | 52 | </property> | ||
315 | 53 | <property name="text"> | ||
316 | 54 | <string>Remove</string> | ||
317 | 55 | </property> | ||
318 | 56 | </widget> | ||
319 | 57 | </item> | ||
320 | 58 | <item row="1" column="0" rowspan="3"> | ||
321 | 59 | <widget class="QListView" name="list"> | ||
322 | 60 | <property name="iconSize"> | ||
323 | 51 | <size> | 61 | <size> |
326 | 52 | <width>100</width> | 62 | <width>16</width> |
327 | 53 | <height>10</height> | 63 | <height>16</height> |
328 | 54 | </size> | 64 | </size> |
329 | 55 | </property> | 65 | </property> |
332 | 56 | <property name="font"> | 66 | <property name="uniformItemSizes"> |
333 | 57 | <font/> | 67 | <bool>true</bool> |
334 | 58 | </property> | 68 | </property> |
335 | 59 | </widget> | 69 | </widget> |
336 | 60 | </item> | 70 | </item> |
338 | 61 | <item row="0" column="2"> | 71 | <item row="1" column="1"> |
339 | 62 | <widget class="QPushButton" name="PushButtonBrowsePlaylist"> | 72 | <widget class="QPushButton" name="PushButtonBrowsePlaylist"> |
340 | 63 | <property name="font"> | 73 | <property name="font"> |
341 | 64 | <font/> | 74 | <font/> |
342 | 65 | </property> | 75 | </property> |
343 | 66 | <property name="text"> | 76 | <property name="text"> |
345 | 67 | <string>Browse...</string> | 77 | <string>Add</string> |
346 | 78 | </property> | ||
347 | 79 | </widget> | ||
348 | 80 | </item> | ||
349 | 81 | <item row="2" column="1"> | ||
350 | 82 | <widget class="QPushButton" name="pushButton_2"> | ||
351 | 83 | <property name="text"> | ||
352 | 84 | <string>Relocate</string> | ||
353 | 68 | </property> | 85 | </property> |
354 | 69 | </widget> | 86 | </widget> |
355 | 70 | </item> | 87 | </item> |
356 | @@ -181,6 +198,16 @@ | |||
357 | 181 | </property> | 198 | </property> |
358 | 182 | </widget> | 199 | </widget> |
359 | 183 | </item> | 200 | </item> |
360 | 201 | <item row="4" column="0"> | ||
361 | 202 | <widget class="QCheckBox" name="checkBox_show_missing"> | ||
362 | 203 | <property name="text"> | ||
363 | 204 | <string>Show Missing Songs</string> | ||
364 | 205 | </property> | ||
365 | 206 | <property name="checked"> | ||
366 | 207 | <bool>true</bool> | ||
367 | 208 | </property> | ||
368 | 209 | </widget> | ||
369 | 210 | </item> | ||
370 | 184 | </layout> | 211 | </layout> |
371 | 185 | </widget> | 212 | </widget> |
372 | 186 | </item> | 213 | </item> |
373 | @@ -230,19 +257,6 @@ | |||
374 | 230 | </layout> | 257 | </layout> |
375 | 231 | </widget> | 258 | </widget> |
376 | 232 | </item> | 259 | </item> |
377 | 233 | <item> | ||
378 | 234 | <spacer name="verticalSpacer"> | ||
379 | 235 | <property name="orientation"> | ||
380 | 236 | <enum>Qt::Vertical</enum> | ||
381 | 237 | </property> | ||
382 | 238 | <property name="sizeHint" stdset="0"> | ||
383 | 239 | <size> | ||
384 | 240 | <width>20</width> | ||
385 | 241 | <height>40</height> | ||
386 | 242 | </size> | ||
387 | 243 | </property> | ||
388 | 244 | </spacer> | ||
389 | 245 | </item> | ||
390 | 246 | </layout> | 260 | </layout> |
391 | 247 | </widget> | 261 | </widget> |
392 | 248 | <layoutdefault spacing="6" margin="11"/> | 262 | <layoutdefault spacing="6" margin="11"/> |
393 | 249 | 263 | ||
394 | === modified file 'mixxx/src/dlgprefrecord.cpp' | |||
395 | --- mixxx/src/dlgprefrecord.cpp 2013-05-15 06:09:40 +0000 | |||
396 | +++ mixxx/src/dlgprefrecord.cpp 2013-05-18 16:32:26 +0000 | |||
397 | @@ -47,10 +47,7 @@ | |||
398 | 47 | if (recordingsPath == "") { | 47 | if (recordingsPath == "") { |
399 | 48 | // Initialize recordings path in config to old default path. | 48 | // Initialize recordings path in config to old default path. |
400 | 49 | // Do it here so we show current value in UI correctly. | 49 | // Do it here so we show current value in UI correctly. |
405 | 50 | QString musicDir = config->getValueString(ConfigKey("[Playlist]","Directory")); | 50 | QString musicDir = QDesktopServices::storageLocation(QDesktopServices::MusicLocation); |
402 | 51 | if (musicDir.isEmpty()) { | ||
403 | 52 | musicDir = QDesktopServices::storageLocation(QDesktopServices::MusicLocation); | ||
404 | 53 | } | ||
406 | 54 | QDir recordDir(musicDir + "/Mixxx/Recordings"); | 51 | QDir recordDir(musicDir + "/Mixxx/Recordings"); |
407 | 55 | recordingsPath = recordDir.absolutePath(); | 52 | recordingsPath = recordDir.absolutePath(); |
408 | 56 | } | 53 | } |
409 | 57 | 54 | ||
410 | === modified file 'mixxx/src/library/autodjfeature.cpp' | |||
411 | --- mixxx/src/library/autodjfeature.cpp 2013-05-12 22:17:32 +0000 | |||
412 | +++ mixxx/src/library/autodjfeature.cpp 2013-05-18 16:32:26 +0000 | |||
413 | @@ -45,6 +45,8 @@ | |||
414 | 45 | libraryWidget->registerView(m_sAutoDJViewName, m_pAutoDJView); | 45 | libraryWidget->registerView(m_sAutoDJViewName, m_pAutoDJView); |
415 | 46 | connect(m_pAutoDJView, SIGNAL(loadTrack(TrackPointer)), | 46 | connect(m_pAutoDJView, SIGNAL(loadTrack(TrackPointer)), |
416 | 47 | this, SIGNAL(loadTrack(TrackPointer))); | 47 | this, SIGNAL(loadTrack(TrackPointer))); |
417 | 48 | connect(this, SIGNAL(configChanged(QString,QString)), | ||
418 | 49 | m_pAutoDJView, SIGNAL(configChanged(QString,QString))); | ||
419 | 48 | connect(m_pAutoDJView, SIGNAL(loadTrackToPlayer(TrackPointer, QString, bool)), | 50 | connect(m_pAutoDJView, SIGNAL(loadTrackToPlayer(TrackPointer, QString, bool)), |
420 | 49 | this, SIGNAL(loadTrackToPlayer(TrackPointer, QString, bool))); | 51 | this, SIGNAL(loadTrackToPlayer(TrackPointer, QString, bool))); |
421 | 50 | } | 52 | } |
422 | 51 | 53 | ||
423 | === modified file 'mixxx/src/library/autodjfeature.h' | |||
424 | --- mixxx/src/library/autodjfeature.h 2012-12-12 17:23:33 +0000 | |||
425 | +++ mixxx/src/library/autodjfeature.h 2013-05-18 16:32:26 +0000 | |||
426 | @@ -35,6 +35,9 @@ | |||
427 | 35 | 35 | ||
428 | 36 | TreeItemModel* getChildModel(); | 36 | TreeItemModel* getChildModel(); |
429 | 37 | 37 | ||
430 | 38 | signals: | ||
431 | 39 | void configChanged(QString,QString); | ||
432 | 40 | |||
433 | 38 | public slots: | 41 | public slots: |
434 | 39 | void activate(); | 42 | void activate(); |
435 | 40 | 43 | ||
436 | 41 | 44 | ||
437 | === modified file 'mixxx/src/library/baseexternalplaylistmodel.cpp' | |||
438 | --- mixxx/src/library/baseexternalplaylistmodel.cpp 2012-11-25 11:17:13 +0000 | |||
439 | +++ mixxx/src/library/baseexternalplaylistmodel.cpp 2013-05-18 16:32:26 +0000 | |||
440 | @@ -6,10 +6,10 @@ | |||
441 | 6 | BaseExternalPlaylistModel::BaseExternalPlaylistModel( | 6 | BaseExternalPlaylistModel::BaseExternalPlaylistModel( |
442 | 7 | QObject* parent, TrackCollection* pTrackCollection, | 7 | QObject* parent, TrackCollection* pTrackCollection, |
443 | 8 | QString settingsNamespace, QString playlistsTable, | 8 | QString settingsNamespace, QString playlistsTable, |
445 | 9 | QString playlistTracksTable, QString trackSource) | 9 | QString playlistTracksTable, QString trackSource, |
446 | 10 | ConfigObject<ConfigValue>* pConfig) | ||
447 | 10 | : BaseSqlTableModel(parent, pTrackCollection, | 11 | : BaseSqlTableModel(parent, pTrackCollection, |
450 | 11 | pTrackCollection->getDatabase(), | 12 | pConfig, settingsNamespace), |
449 | 12 | settingsNamespace), | ||
451 | 13 | m_playlistsTable(playlistsTable), | 13 | m_playlistsTable(playlistsTable), |
452 | 14 | m_playlistTracksTable(playlistTracksTable), | 14 | m_playlistTracksTable(playlistTracksTable), |
453 | 15 | m_trackSource(trackSource), | 15 | m_trackSource(trackSource), |
454 | 16 | 16 | ||
455 | === modified file 'mixxx/src/library/baseexternalplaylistmodel.h' | |||
456 | --- mixxx/src/library/baseexternalplaylistmodel.h 2012-11-22 06:59:01 +0000 | |||
457 | +++ mixxx/src/library/baseexternalplaylistmodel.h 2013-05-18 16:32:26 +0000 | |||
458 | @@ -10,13 +10,15 @@ | |||
459 | 10 | #include "library/librarytablemodel.h" | 10 | #include "library/librarytablemodel.h" |
460 | 11 | #include "library/dao/playlistdao.h" | 11 | #include "library/dao/playlistdao.h" |
461 | 12 | #include "library/dao/trackdao.h" | 12 | #include "library/dao/trackdao.h" |
462 | 13 | #include "configobject.h" | ||
463 | 13 | 14 | ||
464 | 14 | class BaseExternalPlaylistModel : public BaseSqlTableModel { | 15 | class BaseExternalPlaylistModel : public BaseSqlTableModel { |
465 | 15 | Q_OBJECT | 16 | Q_OBJECT |
466 | 16 | public: | 17 | public: |
467 | 17 | BaseExternalPlaylistModel(QObject* pParent, TrackCollection* pTrackCollection, | 18 | BaseExternalPlaylistModel(QObject* pParent, TrackCollection* pTrackCollection, |
468 | 18 | QString settingsNamespace, QString playlistsTable, | 19 | QString settingsNamespace, QString playlistsTable, |
470 | 19 | QString playlistTracksTable, QString trackSource); | 20 | QString playlistTracksTable, QString trackSource, |
471 | 21 | ConfigObject<ConfigValue>* pConfig); | ||
472 | 20 | virtual ~BaseExternalPlaylistModel(); | 22 | virtual ~BaseExternalPlaylistModel(); |
473 | 21 | 23 | ||
474 | 22 | virtual TrackPointer getTrack(const QModelIndex& index) const; | 24 | virtual TrackPointer getTrack(const QModelIndex& index) const; |
475 | 23 | 25 | ||
476 | === modified file 'mixxx/src/library/baseexternaltrackmodel.cpp' | |||
477 | --- mixxx/src/library/baseexternaltrackmodel.cpp 2012-11-25 11:17:13 +0000 | |||
478 | +++ mixxx/src/library/baseexternaltrackmodel.cpp 2013-05-18 16:32:26 +0000 | |||
479 | @@ -6,10 +6,10 @@ | |||
480 | 6 | TrackCollection* pTrackCollection, | 6 | TrackCollection* pTrackCollection, |
481 | 7 | QString settingsNamespace, | 7 | QString settingsNamespace, |
482 | 8 | QString trackTable, | 8 | QString trackTable, |
484 | 9 | QString trackSource) | 9 | QString trackSource, |
485 | 10 | ConfigObject<ConfigValue>* pConfig) | ||
486 | 10 | : BaseSqlTableModel(parent, pTrackCollection, | 11 | : BaseSqlTableModel(parent, pTrackCollection, |
489 | 11 | pTrackCollection->getDatabase(), | 12 | pConfig, settingsNamespace), |
488 | 12 | settingsNamespace), | ||
490 | 13 | m_pTrackCollection(pTrackCollection), | 13 | m_pTrackCollection(pTrackCollection), |
491 | 14 | m_database(m_pTrackCollection->getDatabase()) { | 14 | m_database(m_pTrackCollection->getDatabase()) { |
492 | 15 | connect(this, SIGNAL(doSearch(const QString&)), | 15 | connect(this, SIGNAL(doSearch(const QString&)), |
493 | 16 | 16 | ||
494 | === modified file 'mixxx/src/library/baseexternaltrackmodel.h' | |||
495 | --- mixxx/src/library/baseexternaltrackmodel.h 2012-11-22 06:59:01 +0000 | |||
496 | +++ mixxx/src/library/baseexternaltrackmodel.h 2013-05-18 16:32:26 +0000 | |||
497 | @@ -9,6 +9,7 @@ | |||
498 | 9 | #include "library/trackmodel.h" | 9 | #include "library/trackmodel.h" |
499 | 10 | #include "library/basesqltablemodel.h" | 10 | #include "library/basesqltablemodel.h" |
500 | 11 | #include "trackinfoobject.h" | 11 | #include "trackinfoobject.h" |
501 | 12 | #include "configobject.h" | ||
502 | 12 | 13 | ||
503 | 13 | class TrackCollection; | 14 | class TrackCollection; |
504 | 14 | 15 | ||
505 | @@ -18,7 +19,8 @@ | |||
506 | 18 | BaseExternalTrackModel(QObject* parent, TrackCollection* pTrackCollection, | 19 | BaseExternalTrackModel(QObject* parent, TrackCollection* pTrackCollection, |
507 | 19 | QString settingsNamespace, | 20 | QString settingsNamespace, |
508 | 20 | QString trackTable, | 21 | QString trackTable, |
510 | 21 | QString trackSource); | 22 | QString trackSource, |
511 | 23 | ConfigObject<ConfigValue>* pConfig); | ||
512 | 22 | virtual ~BaseExternalTrackModel(); | 24 | virtual ~BaseExternalTrackModel(); |
513 | 23 | 25 | ||
514 | 24 | TrackModel::CapabilitiesFlags getCapabilities() const; | 26 | TrackModel::CapabilitiesFlags getCapabilities() const; |
515 | 25 | 27 | ||
516 | === modified file 'mixxx/src/library/baseplaylistfeature.cpp' | |||
517 | --- mixxx/src/library/baseplaylistfeature.cpp 2013-05-12 22:17:32 +0000 | |||
518 | +++ mixxx/src/library/baseplaylistfeature.cpp 2013-05-18 16:32:26 +0000 | |||
519 | @@ -22,6 +22,7 @@ | |||
520 | 22 | m_trackDao(pTrackCollection->getTrackDAO()), | 22 | m_trackDao(pTrackCollection->getTrackDAO()), |
521 | 23 | m_pPlaylistTableModel(NULL), | 23 | m_pPlaylistTableModel(NULL), |
522 | 24 | m_rootViewName(rootViewName) { | 24 | m_rootViewName(rootViewName) { |
523 | 25 | |||
524 | 25 | m_pCreatePlaylistAction = new QAction(tr("New Playlist"),this); | 26 | m_pCreatePlaylistAction = new QAction(tr("New Playlist"),this); |
525 | 26 | connect(m_pCreatePlaylistAction, SIGNAL(triggered()), | 27 | connect(m_pCreatePlaylistAction, SIGNAL(triggered()), |
526 | 27 | this, SLOT(slotCreatePlaylist())); | 28 | this, SLOT(slotCreatePlaylist())); |
527 | @@ -96,7 +97,7 @@ | |||
528 | 96 | QString playlistName = index.data().toString(); | 97 | QString playlistName = index.data().toString(); |
529 | 97 | int playlistId = m_playlistDao.getPlaylistIdFromName(playlistName); | 98 | int playlistId = m_playlistDao.getPlaylistIdFromName(playlistName); |
530 | 98 | if (m_pPlaylistTableModel) { | 99 | if (m_pPlaylistTableModel) { |
532 | 99 | m_pPlaylistTableModel->setPlaylist(playlistId); | 100 | m_pPlaylistTableModel->setTableModel(playlistId); |
533 | 100 | emit(showTrackModel(m_pPlaylistTableModel)); | 101 | emit(showTrackModel(m_pPlaylistTableModel)); |
534 | 101 | } | 102 | } |
535 | 102 | } | 103 | } |
536 | @@ -337,11 +338,12 @@ | |||
537 | 337 | } | 338 | } |
538 | 338 | 339 | ||
539 | 339 | // Create a new table model since the main one might have an active search. | 340 | // Create a new table model since the main one might have an active search. |
540 | 341 | // This PTM will only use tracks that are not deleted from the FS | ||
541 | 340 | QScopedPointer<PlaylistTableModel> pPlaylistTableModel( | 342 | QScopedPointer<PlaylistTableModel> pPlaylistTableModel( |
542 | 341 | new PlaylistTableModel(this, m_pTrackCollection, | 343 | new PlaylistTableModel(this, m_pTrackCollection, |
544 | 342 | "mixxx.db.model.playlist_export")); | 344 | "mixxx.db.model.playlist_export", m_pConfig)); |
545 | 343 | 345 | ||
547 | 344 | pPlaylistTableModel->setPlaylist(m_pPlaylistTableModel->getPlaylist()); | 346 | pPlaylistTableModel->setTableModel(m_pPlaylistTableModel->getPlaylist()); |
548 | 345 | pPlaylistTableModel->setSort(pPlaylistTableModel->fieldIndex(PLAYLISTTRACKSTABLE_POSITION), Qt::AscendingOrder); | 347 | pPlaylistTableModel->setSort(pPlaylistTableModel->fieldIndex(PLAYLISTTRACKSTABLE_POSITION), Qt::AscendingOrder); |
549 | 346 | pPlaylistTableModel->select(); | 348 | pPlaylistTableModel->select(); |
550 | 347 | 349 | ||
551 | @@ -476,4 +478,3 @@ | |||
552 | 476 | void BasePlaylistFeature::clearChildModel() { | 478 | void BasePlaylistFeature::clearChildModel() { |
553 | 477 | m_childModel.removeRows(0, m_playlistList.size()); | 479 | m_childModel.removeRows(0, m_playlistList.size()); |
554 | 478 | } | 480 | } |
555 | 479 | |||
556 | 480 | 481 | ||
557 | === modified file 'mixxx/src/library/baseplaylistfeature.h' | |||
558 | --- mixxx/src/library/baseplaylistfeature.h 2013-02-23 10:40:40 +0000 | |||
559 | +++ mixxx/src/library/baseplaylistfeature.h 2013-05-18 16:32:26 +0000 | |||
560 | @@ -76,7 +76,6 @@ | |||
561 | 76 | 76 | ||
562 | 77 | private: | 77 | private: |
563 | 78 | virtual QString getRootViewHtml() const = 0; | 78 | virtual QString getRootViewHtml() const = 0; |
564 | 79 | |||
565 | 80 | QString m_rootViewName; | 79 | QString m_rootViewName; |
566 | 81 | }; | 80 | }; |
567 | 82 | 81 | ||
568 | 83 | 82 | ||
569 | === modified file 'mixxx/src/library/basesqltablemodel.cpp' | |||
570 | --- mixxx/src/library/basesqltablemodel.cpp 2013-05-14 22:25:44 +0000 | |||
571 | +++ mixxx/src/library/basesqltablemodel.cpp 2013-05-18 16:32:26 +0000 | |||
572 | @@ -20,16 +20,17 @@ | |||
573 | 20 | 20 | ||
574 | 21 | BaseSqlTableModel::BaseSqlTableModel(QObject* pParent, | 21 | BaseSqlTableModel::BaseSqlTableModel(QObject* pParent, |
575 | 22 | TrackCollection* pTrackCollection, | 22 | TrackCollection* pTrackCollection, |
577 | 23 | QSqlDatabase db, | 23 | ConfigObject<ConfigValue>* pConfig, |
578 | 24 | QString settingsNamespace) | 24 | QString settingsNamespace) |
579 | 25 | : QAbstractTableModel(pParent), | 25 | : QAbstractTableModel(pParent), |
582 | 26 | TrackModel(db, settingsNamespace), | 26 | TrackModel(pTrackCollection->getDatabase(), settingsNamespace), |
581 | 27 | m_currentSearch(""), | ||
583 | 28 | m_previewDeckGroup(PlayerManager::groupForPreviewDeck(0)), | 27 | m_previewDeckGroup(PlayerManager::groupForPreviewDeck(0)), |
584 | 29 | m_iPreviewDeckTrackId(-1), | 28 | m_iPreviewDeckTrackId(-1), |
585 | 30 | m_pTrackCollection(pTrackCollection), | 29 | m_pTrackCollection(pTrackCollection), |
586 | 31 | m_trackDAO(m_pTrackCollection->getTrackDAO()), | 30 | m_trackDAO(m_pTrackCollection->getTrackDAO()), |
588 | 32 | m_database(db) { | 31 | m_pConfig(pConfig), |
589 | 32 | m_currentSearch(""), | ||
590 | 33 | m_database(pTrackCollection->getDatabase()) { | ||
591 | 33 | m_bInitialized = false; | 34 | m_bInitialized = false; |
592 | 34 | m_bDirty = true; | 35 | m_bDirty = true; |
593 | 35 | m_iSortColumn = 0; | 36 | m_iSortColumn = 0; |
594 | @@ -214,7 +215,6 @@ | |||
595 | 214 | 215 | ||
596 | 215 | QLinkedList<int> tableColumnIndices; | 216 | QLinkedList<int> tableColumnIndices; |
597 | 216 | foreach (QString column, m_tableColumns) { | 217 | foreach (QString column, m_tableColumns) { |
598 | 217 | Q_ASSERT(record.indexOf(column) == m_tableColumnIndex[column]); | ||
599 | 218 | tableColumnIndices.push_back(record.indexOf(column)); | 218 | tableColumnIndices.push_back(record.indexOf(column)); |
600 | 219 | } | 219 | } |
601 | 220 | 220 | ||
602 | @@ -227,6 +227,8 @@ | |||
603 | 227 | QSet<int> trackIds; | 227 | QSet<int> trackIds; |
604 | 228 | while (query.next()) { | 228 | while (query.next()) { |
605 | 229 | int id = query.value(idColumn).toInt(); | 229 | int id = query.value(idColumn).toInt(); |
606 | 230 | |||
607 | 231 | |||
608 | 230 | trackIds.insert(id); | 232 | trackIds.insert(id); |
609 | 231 | 233 | ||
610 | 232 | RowInfo thisRowInfo; | 234 | RowInfo thisRowInfo; |
611 | @@ -359,7 +361,7 @@ | |||
612 | 359 | m_bDirty = true; | 361 | m_bDirty = true; |
613 | 360 | } | 362 | } |
614 | 361 | 363 | ||
616 | 362 | void BaseSqlTableModel::search(const QString& searchText, const QString extraFilter) { | 364 | void BaseSqlTableModel::search(const QString& searchText, const QString& extraFilter) { |
617 | 363 | if (sDebug) { | 365 | if (sDebug) { |
618 | 364 | qDebug() << this << "search" << searchText; | 366 | qDebug() << this << "search" << searchText; |
619 | 365 | } | 367 | } |
620 | @@ -436,7 +438,8 @@ | |||
621 | 436 | if (!index.isValid() || (role != Qt::DisplayRole && | 438 | if (!index.isValid() || (role != Qt::DisplayRole && |
622 | 437 | role != Qt::EditRole && | 439 | role != Qt::EditRole && |
623 | 438 | role != Qt::CheckStateRole && | 440 | role != Qt::CheckStateRole && |
625 | 439 | role != Qt::ToolTipRole)) { | 441 | role != Qt::ToolTipRole && |
626 | 442 | role != Qt::BackgroundColorRole)) { | ||
627 | 440 | return QVariant(); | 443 | return QVariant(); |
628 | 441 | } | 444 | } |
629 | 442 | 445 | ||
630 | @@ -451,6 +454,13 @@ | |||
631 | 451 | // role | 454 | // role |
632 | 452 | switch (role) { | 455 | switch (role) { |
633 | 453 | case Qt::ToolTipRole: | 456 | case Qt::ToolTipRole: |
634 | 457 | if(index.sibling(index.row(), | ||
635 | 458 | fieldIndex(TRACKLOCATIONSTABLE_FSDELETED)).data().toInt()==1){ | ||
636 | 459 | QString warning(tr("No such file at : ")); | ||
637 | 460 | value = QVariant(QString(warning+index.sibling(index.row(), | ||
638 | 461 | fieldIndex(LIBRARYTABLE_LOCATION)).data().toString())); | ||
639 | 462 | } | ||
640 | 463 | break; | ||
641 | 454 | case Qt::DisplayRole: | 464 | case Qt::DisplayRole: |
642 | 455 | if (column == fieldIndex(LIBRARYTABLE_DURATION)) { | 465 | if (column == fieldIndex(LIBRARYTABLE_DURATION)) { |
643 | 456 | if (qVariantCanConvert<int>(value)) { | 466 | if (qVariantCanConvert<int>(value)) { |
644 | @@ -499,6 +509,14 @@ | |||
645 | 499 | value = locked ? Qt::Checked : Qt::Unchecked; | 509 | value = locked ? Qt::Checked : Qt::Unchecked; |
646 | 500 | } | 510 | } |
647 | 501 | break; | 511 | break; |
648 | 512 | case Qt::BackgroundColorRole: | ||
649 | 513 | if (index.sibling(index.row(), | ||
650 | 514 | fieldIndex(TRACKLOCATIONSTABLE_FSDELETED)).data().toInt()==1){ | ||
651 | 515 | //TODO kain88 choose a better looking color, this will also | ||
652 | 516 | // have to be changed in stardelegate | ||
653 | 517 | value = QVariant(QColor(Qt::red)); | ||
654 | 518 | } | ||
655 | 519 | break; | ||
656 | 502 | default: | 520 | default: |
657 | 503 | break; | 521 | break; |
658 | 504 | } | 522 | } |
659 | @@ -626,6 +644,10 @@ | |||
660 | 626 | return index.sibling(index.row(), fieldIndex(m_idColumn)).data().toInt(); | 644 | return index.sibling(index.row(), fieldIndex(m_idColumn)).data().toInt(); |
661 | 627 | } | 645 | } |
662 | 628 | 646 | ||
663 | 647 | TrackPointer BaseSqlTableModel::getTrack(const QModelIndex& index) const { | ||
664 | 648 | return m_trackDAO.getTrack(getTrackId(index)); | ||
665 | 649 | } | ||
666 | 650 | |||
667 | 629 | QString BaseSqlTableModel::getTrackLocation(const QModelIndex& index) const { | 651 | QString BaseSqlTableModel::getTrackLocation(const QModelIndex& index) const { |
668 | 630 | if (!index.isValid()) { | 652 | if (!index.isValid()) { |
669 | 631 | return ""; | 653 | return ""; |
670 | @@ -656,7 +678,6 @@ | |||
671 | 656 | if (sDebug) { | 678 | if (sDebug) { |
672 | 657 | qDebug() << this << "trackChanged" << trackIds.size(); | 679 | qDebug() << this << "trackChanged" << trackIds.size(); |
673 | 658 | } | 680 | } |
674 | 659 | |||
675 | 660 | const int numColumns = columnCount(); | 681 | const int numColumns = columnCount(); |
676 | 661 | foreach (int trackId, trackIds) { | 682 | foreach (int trackId, trackIds) { |
677 | 662 | QLinkedList<int> rows = getTrackRows(trackId); | 683 | QLinkedList<int> rows = getTrackRows(trackId); |
678 | @@ -717,7 +738,8 @@ | |||
679 | 717 | const QModelIndex& index, int role) const { | 738 | const QModelIndex& index, int role) const { |
680 | 718 | if (role != Qt::DisplayRole && | 739 | if (role != Qt::DisplayRole && |
681 | 719 | role != Qt::ToolTipRole && | 740 | role != Qt::ToolTipRole && |
683 | 720 | role != Qt::EditRole) { | 741 | role != Qt::EditRole && |
684 | 742 | role != Qt::BackgroundColorRole) { | ||
685 | 721 | return QVariant(); | 743 | return QVariant(); |
686 | 722 | } | 744 | } |
687 | 723 | 745 | ||
688 | @@ -822,3 +844,51 @@ | |||
689 | 822 | // there. | 844 | // there. |
690 | 823 | select(); //Repopulate the data model. | 845 | select(); //Repopulate the data model. |
691 | 824 | } | 846 | } |
692 | 847 | |||
693 | 848 | void BaseSqlTableModel::slotConfigChanged(QString identifier, QString key){ | ||
694 | 849 | Q_UNUSED(identifier); | ||
695 | 850 | if (key=="ShowMissingSongs") { | ||
696 | 851 | setTableModel(); | ||
697 | 852 | select(); | ||
698 | 853 | } | ||
699 | 854 | } | ||
700 | 855 | |||
701 | 856 | void BaseSqlTableModel::setTableModel(int id) { | ||
702 | 857 | Q_UNUSED(id); | ||
703 | 858 | } | ||
704 | 859 | |||
705 | 860 | void BaseSqlTableModel::relocateTracks(const QModelIndexList& indices) { | ||
706 | 861 | foreach (QModelIndex index, indices) { | ||
707 | 862 | int trackId = getTrackId(index); | ||
708 | 863 | TrackPointer ptrack = m_trackDAO.getTrack(trackId); | ||
709 | 864 | if (!ptrack) { | ||
710 | 865 | qDebug() << "strange I can't get that thing"; | ||
711 | 866 | } | ||
712 | 867 | QString newLocation = QFileDialog::getOpenFileName(QApplication::desktop(), | ||
713 | 868 | QString(ptrack->getTitle()), | ||
714 | 869 | ptrack->getLocation()); | ||
715 | 870 | |||
716 | 871 | if (!newLocation.isEmpty()) { | ||
717 | 872 | if (!m_trackDAO.relocateTrack(ptrack, newLocation)) { | ||
718 | 873 | QMessageBox::warning(NULL, tr("Mixxx"), | ||
719 | 874 | tr("The track could not be relocated")); | ||
720 | 875 | } | ||
721 | 876 | } | ||
722 | 877 | } | ||
723 | 878 | setTableModel(); | ||
724 | 879 | select(); | ||
725 | 880 | } | ||
726 | 881 | |||
727 | 882 | bool BaseSqlTableModel::isColumnInternal(int column) { | ||
728 | 883 | Q_UNUSED(column); | ||
729 | 884 | return false; | ||
730 | 885 | } | ||
731 | 886 | |||
732 | 887 | bool BaseSqlTableModel::isColumnHiddenByDefault(int column) { | ||
733 | 888 | Q_UNUSED(column); | ||
734 | 889 | return false; | ||
735 | 890 | } | ||
736 | 891 | |||
737 | 892 | TrackModel::CapabilitiesFlags BaseSqlTableModel::getCapabilities() const { | ||
738 | 893 | return TRACKMODELCAPS_NONE; | ||
739 | 894 | } | ||
740 | 825 | 895 | ||
741 | === modified file 'mixxx/src/library/basesqltablemodel.h' | |||
742 | --- mixxx/src/library/basesqltablemodel.h 2013-01-17 08:16:08 +0000 | |||
743 | +++ mixxx/src/library/basesqltablemodel.h 2013-05-18 16:32:26 +0000 | |||
744 | @@ -22,21 +22,43 @@ | |||
745 | 22 | public: | 22 | public: |
746 | 23 | BaseSqlTableModel(QObject* pParent, | 23 | BaseSqlTableModel(QObject* pParent, |
747 | 24 | TrackCollection* pTrackCollection, | 24 | TrackCollection* pTrackCollection, |
749 | 25 | QSqlDatabase db, QString settingsNamespace); | 25 | ConfigObject<ConfigValue>* pConfig, |
750 | 26 | QString settingsNamespace); | ||
751 | 26 | virtual ~BaseSqlTableModel(); | 27 | virtual ~BaseSqlTableModel(); |
752 | 27 | 28 | ||
763 | 28 | //////////////////////////////////////////////////////////////////////////// | 29 | // functions that HAVE to be implemented in a child class |
764 | 29 | // Methods implemented from QAbstractItemModel | 30 | virtual void setTableModel(int id=-1); |
765 | 30 | //////////////////////////////////////////////////////////////////////////// | 31 | virtual bool isColumnInternal(int column); |
766 | 31 | 32 | virtual bool isColumnHiddenByDefault(int column); | |
767 | 32 | virtual void sort(int column, Qt::SortOrder order); | 33 | virtual TrackModel::CapabilitiesFlags getCapabilities() const; |
768 | 33 | virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; | 34 | // calls readWriteFlags() by default, reimplement this if the child calls |
769 | 34 | virtual bool setData(const QModelIndex& index, const QVariant& value, int role=Qt::EditRole); | 35 | // should be readOnly |
770 | 35 | virtual int columnCount(const QModelIndex& parent=QModelIndex()) const; | 36 | virtual Qt::ItemFlags flags(const QModelIndex &index) const; |
771 | 36 | virtual int rowCount(const QModelIndex& parent=QModelIndex()) const; | 37 | // function to reimplement for external libraries |
772 | 37 | virtual bool setHeaderData(int section, Qt::Orientation orientation, | 38 | virtual TrackPointer getTrack(const QModelIndex& index) const; |
773 | 39 | |||
774 | 40 | // Other public methods | ||
775 | 41 | int getTrackId(const QModelIndex& index) const; | ||
776 | 42 | void search(const QString& searchText, const QString& extraFilter=QString()); | ||
777 | 43 | void setSearch(const QString& searchText, const QString extraFilter=QString()); | ||
778 | 44 | const QString currentSearch() const; | ||
779 | 45 | void setSort(int column, Qt::SortOrder order); | ||
780 | 46 | int fieldIndex(const QString& fieldName) const; | ||
781 | 47 | void select(); | ||
782 | 48 | QString getTrackLocation(const QModelIndex& index) const; | ||
783 | 49 | QAbstractItemDelegate* delegateForColumn(const int i, QObject* pParent); | ||
784 | 50 | void relocateTracks(const QModelIndexList& indices); | ||
785 | 51 | void hideTracks(const QModelIndexList& indices); | ||
786 | 52 | |||
787 | 53 | // Methods reimplemented from QAbstractItemModel | ||
788 | 54 | void sort(int column, Qt::SortOrder order); | ||
789 | 55 | int rowCount(const QModelIndex& parent=QModelIndex()) const; | ||
790 | 56 | QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; | ||
791 | 57 | bool setData(const QModelIndex& index, const QVariant& value, int role=Qt::EditRole); | ||
792 | 58 | int columnCount(const QModelIndex& parent=QModelIndex()) const; | ||
793 | 59 | bool setHeaderData(int section, Qt::Orientation orientation, | ||
794 | 38 | const QVariant &value, int role=Qt::EditRole); | 60 | const QVariant &value, int role=Qt::EditRole); |
796 | 39 | virtual QVariant headerData(int section, Qt::Orientation orientation, | 61 | QVariant headerData(int section, Qt::Orientation orientation, |
797 | 40 | int role=Qt::DisplayRole) const; | 62 | int role=Qt::DisplayRole) const; |
798 | 41 | virtual QMimeData* mimeData(const QModelIndexList &indexes) const; | 63 | virtual QMimeData* mimeData(const QModelIndexList &indexes) const; |
799 | 42 | 64 | ||
800 | @@ -44,44 +66,33 @@ | |||
801 | 44 | // Other public methods | 66 | // Other public methods |
802 | 45 | //////////////////////////////////////////////////////////////////////////// | 67 | //////////////////////////////////////////////////////////////////////////// |
803 | 46 | 68 | ||
804 | 47 | virtual void search(const QString& searchText, const QString extraFilter=QString()); | ||
805 | 48 | virtual void setSearch(const QString& searchText, const QString extraFilter=QString()); | ||
806 | 49 | virtual const QString currentSearch() const; | ||
807 | 50 | virtual void setSort(int column, Qt::SortOrder order); | ||
808 | 51 | virtual int fieldIndex(const QString& fieldName) const; | ||
809 | 52 | virtual void select(); | ||
810 | 53 | virtual int getTrackId(const QModelIndex& index) const; | ||
811 | 54 | virtual QString getTrackLocation(const QModelIndex& index) const; | ||
812 | 55 | virtual QAbstractItemDelegate* delegateForColumn(const int i, QObject* pParent); | ||
813 | 56 | virtual void hideTracks(const QModelIndexList& indices); | ||
814 | 57 | // Returns true if the BaseSqlTableModel has been initialized. Calling data | 69 | // Returns true if the BaseSqlTableModel has been initialized. Calling data |
815 | 58 | // access methods on a BaseSqlTableModel which is not initialized is likely | 70 | // access methods on a BaseSqlTableModel which is not initialized is likely |
816 | 59 | // to cause instability / crashes. | 71 | // to cause instability / crashes. |
817 | 60 | bool initialized() const { return m_bInitialized; } | 72 | bool initialized() const { return m_bInitialized; } |
818 | 61 | 73 | ||
820 | 62 | protected: | 74 | protected://functions |
821 | 63 | // Returns the row of trackId in this result set. If trackId is not present, | 75 | // Returns the row of trackId in this result set. If trackId is not present, |
822 | 64 | // returns -1. | 76 | // returns -1. |
843 | 65 | virtual const QLinkedList<int> getTrackRows(int trackId) const; | 77 | const QLinkedList<int> getTrackRows(int trackId) const; |
844 | 66 | 78 | void setTable(const QString& tableName, const QString& trackIdColumn, | |
845 | 67 | virtual void setTable(const QString& tableName, | 79 | const QStringList& tableColumns, |
846 | 68 | const QString& trackIdColumn, | 80 | QSharedPointer<BaseTrackCache> trackSource); |
847 | 69 | const QStringList& tableColumns, | 81 | void initHeaderData(); |
848 | 70 | QSharedPointer<BaseTrackCache> trackSource); | 82 | |
849 | 71 | QSqlDatabase database() const; | 83 | // Use this if you want a model that is read-only. |
850 | 72 | 84 | Qt::ItemFlags readOnlyFlags(const QModelIndex &index) const; | |
851 | 73 | /** Use this if you want a model that is read-only. */ | 85 | // Use this if you want a model that can be changed |
852 | 74 | virtual Qt::ItemFlags readOnlyFlags(const QModelIndex &index) const; | 86 | Qt::ItemFlags readWriteFlags(const QModelIndex &index) const; |
853 | 75 | /** Use this if you want a model that can be changed */ | 87 | |
854 | 76 | virtual Qt::ItemFlags readWriteFlags(const QModelIndex &index) const; | 88 | //variables |
855 | 77 | /** calls readWriteFlags() by default */ | 89 | TrackCollection* m_pTrackCollection; |
856 | 78 | virtual Qt::ItemFlags flags(const QModelIndex &index) const; | 90 | TrackDAO& m_trackDAO; |
857 | 79 | 91 | ConfigObject<ConfigValue>* m_pConfig; | |
858 | 80 | // Set the columns used for searching. Names must correspond to the column | 92 | QSqlDatabase m_database; |
859 | 81 | // names in the table provided to setTable. Must be called after setTable is | 93 | |
860 | 82 | // called. | 94 | protected slots: |
861 | 83 | virtual QString orderByClause() const; | 95 | void slotConfigChanged(QString,QString); |
842 | 84 | virtual void initHeaderData(); | ||
862 | 85 | 96 | ||
863 | 86 | private slots: | 97 | private slots: |
864 | 87 | void tracksChanged(QSet<int> trackIds); | 98 | void tracksChanged(QSet<int> trackIds); |
865 | @@ -90,6 +101,11 @@ | |||
866 | 90 | private: | 101 | private: |
867 | 91 | inline void setTrackValueForColumn(TrackPointer pTrack, int column, QVariant value); | 102 | inline void setTrackValueForColumn(TrackPointer pTrack, int column, QVariant value); |
868 | 92 | QVariant getBaseValue(const QModelIndex& index, int role = Qt::DisplayRole) const; | 103 | QVariant getBaseValue(const QModelIndex& index, int role = Qt::DisplayRole) const; |
869 | 104 | // Set the columns used for searching. Names must correspond to the column | ||
870 | 105 | // names in the table provided to setTable. Must be called after setTable is | ||
871 | 106 | // called. | ||
872 | 107 | QString orderByClause() const; | ||
873 | 108 | QSqlDatabase database() const; | ||
874 | 93 | 109 | ||
875 | 94 | struct RowInfo { | 110 | struct RowInfo { |
876 | 95 | int trackId; | 111 | int trackId; |
877 | @@ -106,6 +122,7 @@ | |||
878 | 106 | return order < other.order; | 122 | return order < other.order; |
879 | 107 | } | 123 | } |
880 | 108 | }; | 124 | }; |
881 | 125 | QVector<RowInfo> m_rowInfo; | ||
882 | 109 | 126 | ||
883 | 110 | QString m_tableName; | 127 | QString m_tableName; |
884 | 111 | QString m_idColumn; | 128 | QString m_idColumn; |
885 | @@ -120,7 +137,6 @@ | |||
886 | 120 | bool m_bInitialized; | 137 | bool m_bInitialized; |
887 | 121 | bool m_bDirty; | 138 | bool m_bDirty; |
888 | 122 | QSqlRecord m_queryRecord; | 139 | QSqlRecord m_queryRecord; |
889 | 123 | QVector<RowInfo> m_rowInfo; | ||
890 | 124 | QHash<int, int> m_trackSortOrder; | 140 | QHash<int, int> m_trackSortOrder; |
891 | 125 | QHash<int, QLinkedList<int> > m_trackIdToRows; | 141 | QHash<int, QLinkedList<int> > m_trackIdToRows; |
892 | 126 | 142 | ||
893 | @@ -132,10 +148,6 @@ | |||
894 | 132 | 148 | ||
895 | 133 | QVector<QHash<int, QVariant> > m_headerInfo; | 149 | QVector<QHash<int, QVariant> > m_headerInfo; |
896 | 134 | 150 | ||
897 | 135 | TrackCollection* m_pTrackCollection; | ||
898 | 136 | TrackDAO& m_trackDAO; | ||
899 | 137 | QSqlDatabase m_database; | ||
900 | 138 | |||
901 | 139 | DISALLOW_COPY_AND_ASSIGN(BaseSqlTableModel); | 151 | DISALLOW_COPY_AND_ASSIGN(BaseSqlTableModel); |
902 | 140 | }; | 152 | }; |
903 | 141 | 153 | ||
904 | 142 | 154 | ||
905 | === modified file 'mixxx/src/library/basetrackcache.cpp' | |||
906 | --- mixxx/src/library/basetrackcache.cpp 2013-04-25 04:56:07 +0000 | |||
907 | +++ mixxx/src/library/basetrackcache.cpp 2013-05-18 16:32:26 +0000 | |||
908 | @@ -87,6 +87,7 @@ | |||
909 | 87 | qDebug() << this << "slotTracksAdded" << trackIds.size(); | 87 | qDebug() << this << "slotTracksAdded" << trackIds.size(); |
910 | 88 | } | 88 | } |
911 | 89 | updateTracksInIndex(trackIds); | 89 | updateTracksInIndex(trackIds); |
912 | 90 | buildIndex(); | ||
913 | 90 | } | 91 | } |
914 | 91 | 92 | ||
915 | 92 | void BaseTrackCache::slotDbTrackAdded(TrackPointer pTrack) { | 93 | void BaseTrackCache::slotDbTrackAdded(TrackPointer pTrack) { |
916 | @@ -118,6 +119,7 @@ | |||
917 | 118 | } | 119 | } |
918 | 119 | QSet<int> trackIds; | 120 | QSet<int> trackIds; |
919 | 120 | trackIds.insert(trackId); | 121 | trackIds.insert(trackId); |
920 | 122 | updateTracksInIndex(trackIds); | ||
921 | 121 | emit(tracksChanged(trackIds)); | 123 | emit(tracksChanged(trackIds)); |
922 | 122 | } | 124 | } |
923 | 123 | 125 | ||
924 | 124 | 126 | ||
925 | === modified file 'mixxx/src/library/browse/browsefeature.cpp' | |||
926 | --- mixxx/src/library/browse/browsefeature.cpp 2013-01-01 11:53:13 +0000 | |||
927 | +++ mixxx/src/library/browse/browsefeature.cpp 2013-05-18 16:32:26 +0000 | |||
928 | @@ -29,7 +29,12 @@ | |||
929 | 29 | m_pConfig(pConfig), | 29 | m_pConfig(pConfig), |
930 | 30 | m_browseModel(this, pTrackCollection, pRecordingManager), | 30 | m_browseModel(this, pTrackCollection, pRecordingManager), |
931 | 31 | m_proxyModel(&m_browseModel), | 31 | m_proxyModel(&m_browseModel), |
933 | 32 | m_pTrackCollection(pTrackCollection) { | 32 | m_pAddtoLibraryAction(NULL), |
934 | 33 | m_pLastRightClickedItem(NULL), | ||
935 | 34 | m_pTrackCollection(pTrackCollection){ | ||
936 | 35 | |||
937 | 36 | connect(this, SIGNAL(dirsChanged(QString,QString)), | ||
938 | 37 | parent, SLOT(slotDirsChanged(QString,QString))); | ||
939 | 33 | 38 | ||
940 | 34 | m_pAddQuickLinkAction = new QAction(tr("Add to Quick Links"),this); | 39 | m_pAddQuickLinkAction = new QAction(tr("Add to Quick Links"),this); |
941 | 35 | connect(m_pAddQuickLinkAction, SIGNAL(triggered()), this, SLOT(slotAddQuickLink())); | 40 | connect(m_pAddQuickLinkAction, SIGNAL(triggered()), this, SLOT(slotAddQuickLink())); |
942 | @@ -37,6 +42,10 @@ | |||
943 | 37 | m_pRemoveQuickLinkAction = new QAction(tr("Remove from Quick Links"),this); | 42 | m_pRemoveQuickLinkAction = new QAction(tr("Remove from Quick Links"),this); |
944 | 38 | connect(m_pRemoveQuickLinkAction, SIGNAL(triggered()), this, SLOT(slotRemoveQuickLink())); | 43 | connect(m_pRemoveQuickLinkAction, SIGNAL(triggered()), this, SLOT(slotRemoveQuickLink())); |
945 | 39 | 44 | ||
946 | 45 | m_pAddtoLibraryAction = new QAction(tr("Add to Library"),this); | ||
947 | 46 | connect(m_pAddtoLibraryAction, SIGNAL(triggered()), | ||
948 | 47 | this, SLOT(slotAddToLibrary())); | ||
949 | 48 | |||
950 | 40 | m_proxyModel.setFilterCaseSensitivity(Qt::CaseInsensitive); | 49 | m_proxyModel.setFilterCaseSensitivity(Qt::CaseInsensitive); |
951 | 41 | m_proxyModel.setSortCaseSensitivity(Qt::CaseInsensitive); | 50 | m_proxyModel.setSortCaseSensitivity(Qt::CaseInsensitive); |
952 | 42 | 51 | ||
953 | @@ -75,7 +84,7 @@ | |||
954 | 75 | 84 | ||
955 | 76 | // show root directory on UNIX-based operating systems | 85 | // show root directory on UNIX-based operating systems |
956 | 77 | TreeItem* root_folder_item = new TreeItem( | 86 | TreeItem* root_folder_item = new TreeItem( |
958 | 78 | QDir::rootPath(), QDir::rootPath(), this, rootItem); | 87 | QDir::homePath(), QDir::homePath(), this, rootItem); |
959 | 79 | rootItem->appendChild(root_folder_item); | 88 | rootItem->appendChild(root_folder_item); |
960 | 80 | #endif | 89 | #endif |
961 | 81 | 90 | ||
962 | @@ -100,11 +109,14 @@ | |||
963 | 100 | m_pQuickLinkItem->appendChild(item); | 109 | m_pQuickLinkItem->appendChild(item); |
964 | 101 | } | 110 | } |
965 | 102 | 111 | ||
966 | 112 | |||
967 | 103 | // initialize the model | 113 | // initialize the model |
968 | 104 | m_childModel.setRootItem(rootItem); | 114 | m_childModel.setRootItem(rootItem); |
969 | 105 | } | 115 | } |
970 | 106 | 116 | ||
971 | 107 | BrowseFeature::~BrowseFeature() { | 117 | BrowseFeature::~BrowseFeature() { |
972 | 118 | //delete m_pLastRightClickedItem; | ||
973 | 119 | // delete m_pQuickLinkItem; | ||
974 | 108 | } | 120 | } |
975 | 109 | 121 | ||
976 | 110 | QVariant BrowseFeature::title() { | 122 | QVariant BrowseFeature::title() { |
977 | @@ -124,6 +136,14 @@ | |||
978 | 124 | saveQuickLinks(); | 136 | saveQuickLinks(); |
979 | 125 | } | 137 | } |
980 | 126 | 138 | ||
981 | 139 | void BrowseFeature::slotAddToLibrary() { | ||
982 | 140 | if (!m_pLastRightClickedItem) { | ||
983 | 141 | return; | ||
984 | 142 | } | ||
985 | 143 | QString spath = m_pLastRightClickedItem->dataPath().toString(); | ||
986 | 144 | emit dirsChanged("added" ,spath); | ||
987 | 145 | } | ||
988 | 146 | |||
989 | 127 | void BrowseFeature::slotRemoveQuickLink() { | 147 | void BrowseFeature::slotRemoveQuickLink() { |
990 | 128 | if (!m_pLastRightClickedItem) { | 148 | if (!m_pLastRightClickedItem) { |
991 | 129 | return; | 149 | return; |
992 | @@ -200,6 +220,7 @@ | |||
993 | 200 | } | 220 | } |
994 | 201 | 221 | ||
995 | 202 | menu.addAction(m_pAddQuickLinkAction); | 222 | menu.addAction(m_pAddQuickLinkAction); |
996 | 223 | menu.addAction(m_pAddtoLibraryAction); | ||
997 | 203 | menu.exec(globalPos); | 224 | menu.exec(globalPos); |
998 | 204 | onLazyChildExpandation(index); | 225 | onLazyChildExpandation(index); |
999 | 205 | } | 226 | } |
1000 | 206 | 227 | ||
1001 | === modified file 'mixxx/src/library/browse/browsefeature.h' | |||
1002 | --- mixxx/src/library/browse/browsefeature.h 2013-01-01 11:53:13 +0000 | |||
1003 | +++ mixxx/src/library/browse/browsefeature.h 2013-05-18 16:32:26 +0000 | |||
1004 | @@ -38,6 +38,7 @@ | |||
1005 | 38 | public slots: | 38 | public slots: |
1006 | 39 | void slotAddQuickLink(); | 39 | void slotAddQuickLink(); |
1007 | 40 | void slotRemoveQuickLink(); | 40 | void slotRemoveQuickLink(); |
1008 | 41 | void slotAddToLibrary(); | ||
1009 | 41 | void activate(); | 42 | void activate(); |
1010 | 42 | void activateChild(const QModelIndex& index); | 43 | void activateChild(const QModelIndex& index); |
1011 | 43 | void onRightClickChild(const QPoint& globalPos, QModelIndex index); | 44 | void onRightClickChild(const QPoint& globalPos, QModelIndex index); |
1012 | @@ -45,6 +46,7 @@ | |||
1013 | 45 | 46 | ||
1014 | 46 | signals: | 47 | signals: |
1015 | 47 | void setRootIndex(const QModelIndex&); | 48 | void setRootIndex(const QModelIndex&); |
1016 | 49 | void dirsChanged(QString,QString); | ||
1017 | 48 | 50 | ||
1018 | 49 | private: | 51 | private: |
1019 | 50 | QString getRootViewHtml() const; | 52 | QString getRootViewHtml() const; |
1020 | @@ -60,6 +62,7 @@ | |||
1021 | 60 | FolderTreeModel m_childModel; | 62 | FolderTreeModel m_childModel; |
1022 | 61 | QAction* m_pAddQuickLinkAction; | 63 | QAction* m_pAddQuickLinkAction; |
1023 | 62 | QAction* m_pRemoveQuickLinkAction; | 64 | QAction* m_pRemoveQuickLinkAction; |
1024 | 65 | QAction* m_pAddtoLibraryAction; | ||
1025 | 63 | TreeItem* m_pLastRightClickedItem; | 66 | TreeItem* m_pLastRightClickedItem; |
1026 | 64 | TreeItem* m_pQuickLinkItem; | 67 | TreeItem* m_pQuickLinkItem; |
1027 | 65 | QStringList m_quickLinkList; | 68 | QStringList m_quickLinkList; |
1028 | 66 | 69 | ||
1029 | === modified file 'mixxx/src/library/browse/browsetablemodel.cpp' | |||
1030 | --- mixxx/src/library/browse/browsetablemodel.cpp 2013-01-19 12:15:22 +0000 | |||
1031 | +++ mixxx/src/library/browse/browsetablemodel.cpp 2013-05-18 16:32:26 +0000 | |||
1032 | @@ -124,7 +124,8 @@ | |||
1033 | 124 | return QLinkedList<int>(); | 124 | return QLinkedList<int>(); |
1034 | 125 | } | 125 | } |
1035 | 126 | 126 | ||
1037 | 127 | void BrowseTableModel::search(const QString& searchText) { | 127 | void BrowseTableModel::search(const QString& searchText, const QString& extraFilter) { |
1038 | 128 | Q_UNUSED(extraFilter); | ||
1039 | 128 | Q_UNUSED(searchText); | 129 | Q_UNUSED(searchText); |
1040 | 129 | } | 130 | } |
1041 | 130 | 131 | ||
1042 | 131 | 132 | ||
1043 | === modified file 'mixxx/src/library/browse/browsetablemodel.h' | |||
1044 | --- mixxx/src/library/browse/browsetablemodel.h 2012-08-10 15:03:46 +0000 | |||
1045 | +++ mixxx/src/library/browse/browsetablemodel.h 2013-05-18 16:32:26 +0000 | |||
1046 | @@ -42,7 +42,7 @@ | |||
1047 | 42 | virtual int getTrackId(const QModelIndex& index) const; | 42 | virtual int getTrackId(const QModelIndex& index) const; |
1048 | 43 | TrackModel::CapabilitiesFlags getCapabilities() const; | 43 | TrackModel::CapabilitiesFlags getCapabilities() const; |
1049 | 44 | virtual const QLinkedList<int> getTrackRows(int trackId) const; | 44 | virtual const QLinkedList<int> getTrackRows(int trackId) const; |
1051 | 45 | virtual void search(const QString& searchText); | 45 | virtual void search(const QString& searchText,const QString& extraFilter=QString()); |
1052 | 46 | virtual void removeTrack(const QModelIndex& index); | 46 | virtual void removeTrack(const QModelIndex& index); |
1053 | 47 | virtual void removeTracks(const QModelIndexList& indices); | 47 | virtual void removeTracks(const QModelIndexList& indices); |
1054 | 48 | virtual bool addTrack(const QModelIndex& index, QString location); | 48 | virtual bool addTrack(const QModelIndex& index, QString location); |
1055 | 49 | 49 | ||
1056 | === modified file 'mixxx/src/library/browse/browsethread.h' | |||
1057 | --- mixxx/src/library/browse/browsethread.h 2012-03-13 04:36:19 +0000 | |||
1058 | +++ mixxx/src/library/browse/browsethread.h 2013-05-18 16:32:26 +0000 | |||
1059 | @@ -11,15 +11,13 @@ | |||
1060 | 11 | #include <QStandardItem> | 11 | #include <QStandardItem> |
1061 | 12 | #include <QList> | 12 | #include <QList> |
1062 | 13 | 13 | ||
1072 | 14 | /* | 14 | // This class is a singleton and represents a thread |
1073 | 15 | * This class is a singleton and represents a thread | 15 | // that is used to read ID3 metadata |
1074 | 16 | * that is used to read ID3 metadata | 16 | // from a particular folder. |
1075 | 17 | * from a particular folder. | 17 | // |
1076 | 18 | * | 18 | // The BroseTableModel uses this class. |
1077 | 19 | * The BroseTableModel uses this class. | 19 | // Note: Don't call getInstance() from places |
1078 | 20 | * Note: Don't call getInstance() from places | 20 | // other than the GUI thread. |
1070 | 21 | * other than the GUI thread. | ||
1071 | 22 | */ | ||
1079 | 23 | class BrowseTableModel; | 21 | class BrowseTableModel; |
1080 | 24 | 22 | ||
1081 | 25 | class BrowseThread : public QThread { | 23 | class BrowseThread : public QThread { |
1082 | 26 | 24 | ||
1083 | === modified file 'mixxx/src/library/browse/foldertreemodel.cpp' | |||
1084 | --- mixxx/src/library/browse/foldertreemodel.cpp 2012-07-18 21:22:53 +0000 | |||
1085 | +++ mixxx/src/library/browse/foldertreemodel.cpp 2013-05-18 16:32:26 +0000 | |||
1086 | @@ -25,6 +25,7 @@ | |||
1087 | 25 | } | 25 | } |
1088 | 26 | 26 | ||
1089 | 27 | FolderTreeModel::~FolderTreeModel() { | 27 | FolderTreeModel::~FolderTreeModel() { |
1090 | 28 | qDebug() << "~FolderTreeModel()"; | ||
1091 | 28 | } | 29 | } |
1092 | 29 | 30 | ||
1093 | 30 | /* A tree model of the filesystem should be initialized lazy. | 31 | /* A tree model of the filesystem should be initialized lazy. |
1094 | 31 | 32 | ||
1095 | === modified file 'mixxx/src/library/cratefeature.cpp' | |||
1096 | --- mixxx/src/library/cratefeature.cpp 2013-04-22 19:29:54 +0000 | |||
1097 | +++ mixxx/src/library/cratefeature.cpp 2013-05-18 16:32:26 +0000 | |||
1098 | @@ -20,10 +20,11 @@ | |||
1099 | 20 | #include "soundsourceproxy.h" | 20 | #include "soundsourceproxy.h" |
1100 | 21 | 21 | ||
1101 | 22 | CrateFeature::CrateFeature(QObject* parent, | 22 | CrateFeature::CrateFeature(QObject* parent, |
1103 | 23 | TrackCollection* pTrackCollection, ConfigObject<ConfigValue>* pConfig) | 23 | TrackCollection* pTrackCollection, |
1104 | 24 | ConfigObject<ConfigValue>* pConfig) | ||
1105 | 24 | : m_pTrackCollection(pTrackCollection), | 25 | : m_pTrackCollection(pTrackCollection), |
1106 | 25 | m_crateDao(pTrackCollection->getCrateDAO()), | 26 | m_crateDao(pTrackCollection->getCrateDAO()), |
1108 | 26 | m_crateTableModel(this, pTrackCollection), | 27 | m_crateTableModel(this, pTrackCollection,pConfig), |
1109 | 27 | m_pConfig(pConfig) { | 28 | m_pConfig(pConfig) { |
1110 | 28 | Q_UNUSED(parent); | 29 | Q_UNUSED(parent); |
1111 | 29 | m_pCreateCrateAction = new QAction(tr("New Crate"),this); | 30 | m_pCreateCrateAction = new QAction(tr("New Crate"),this); |
1112 | @@ -65,6 +66,9 @@ | |||
1113 | 65 | connect(&m_crateDao, SIGNAL(lockChanged(int)), | 66 | connect(&m_crateDao, SIGNAL(lockChanged(int)), |
1114 | 66 | this, SLOT(slotCrateTableChanged(int))); | 67 | this, SLOT(slotCrateTableChanged(int))); |
1115 | 67 | 68 | ||
1116 | 69 | connect(this, SIGNAL(configChanged(QString,QString)), | ||
1117 | 70 | &m_crateTableModel, SLOT(slotConfigChanged(QString,QString))); | ||
1118 | 71 | |||
1119 | 68 | // construct child model | 72 | // construct child model |
1120 | 69 | TreeItem *rootItem = new TreeItem(); | 73 | TreeItem *rootItem = new TreeItem(); |
1121 | 70 | m_childModel.setRootItem(rootItem); | 74 | m_childModel.setRootItem(rootItem); |
1122 | @@ -156,7 +160,7 @@ | |||
1123 | 156 | return; | 160 | return; |
1124 | 157 | QString crateName = index.data().toString(); | 161 | QString crateName = index.data().toString(); |
1125 | 158 | int crateId = m_crateDao.getCrateIdByName(crateName); | 162 | int crateId = m_crateDao.getCrateIdByName(crateName); |
1127 | 159 | m_crateTableModel.setCrate(crateId); | 163 | m_crateTableModel.setTableModel(crateId); |
1128 | 160 | emit(showTrackModel(&m_crateTableModel)); | 164 | emit(showTrackModel(&m_crateTableModel)); |
1129 | 161 | } | 165 | } |
1130 | 162 | 166 | ||
1131 | @@ -473,7 +477,6 @@ | |||
1132 | 473 | } | 477 | } |
1133 | 474 | 478 | ||
1134 | 475 | QList<QString> entries = playlist_parser->parse(playlist_file); | 479 | QList<QString> entries = playlist_parser->parse(playlist_file); |
1135 | 476 | //qDebug() << "Size of Imported Playlist: " << entries.size(); | ||
1136 | 477 | 480 | ||
1137 | 478 | //Iterate over the List that holds URLs of playlist entires | 481 | //Iterate over the List that holds URLs of playlist entires |
1138 | 479 | m_crateTableModel.addTracks(QModelIndex(), entries); | 482 | m_crateTableModel.addTracks(QModelIndex(), entries); |
1139 | @@ -503,8 +506,8 @@ | |||
1140 | 503 | QList<QString> playlist_items; | 506 | QList<QString> playlist_items; |
1141 | 504 | // Create a new table model since the main one might have an active search. | 507 | // Create a new table model since the main one might have an active search. |
1142 | 505 | QScopedPointer<CrateTableModel> pCrateTableModel( | 508 | QScopedPointer<CrateTableModel> pCrateTableModel( |
1145 | 506 | new CrateTableModel(this, m_pTrackCollection)); | 509 | new CrateTableModel(this, m_pTrackCollection,m_pConfig)); |
1146 | 507 | pCrateTableModel->setCrate(m_crateTableModel.getCrate()); | 510 | pCrateTableModel->setTableModel(m_crateTableModel.getCrate()); |
1147 | 508 | pCrateTableModel->select(); | 511 | pCrateTableModel->select(); |
1148 | 509 | 512 | ||
1149 | 510 | if (file_location.endsWith(".csv", Qt::CaseInsensitive)) { | 513 | if (file_location.endsWith(".csv", Qt::CaseInsensitive)) { |
1150 | @@ -542,7 +545,7 @@ | |||
1151 | 542 | clearChildModel(); | 545 | clearChildModel(); |
1152 | 543 | m_lastRightClickedIndex = constructChildModel(crateId); | 546 | m_lastRightClickedIndex = constructChildModel(crateId); |
1153 | 544 | // Switch the view to the crate. | 547 | // Switch the view to the crate. |
1155 | 545 | m_crateTableModel.setCrate(crateId); | 548 | m_crateTableModel.setTableModel(crateId); |
1156 | 546 | // Update selection | 549 | // Update selection |
1157 | 547 | emit(featureSelect(this, m_lastRightClickedIndex)); | 550 | emit(featureSelect(this, m_lastRightClickedIndex)); |
1158 | 548 | } | 551 | } |
1159 | 549 | 552 | ||
1160 | === modified file 'mixxx/src/library/cratefeature.h' | |||
1161 | --- mixxx/src/library/cratefeature.h 2013-05-18 16:23:08 +0000 | |||
1162 | +++ mixxx/src/library/cratefeature.h 2013-05-18 16:32:26 +0000 | |||
1163 | @@ -34,6 +34,9 @@ | |||
1164 | 34 | 34 | ||
1165 | 35 | TreeItemModel* getChildModel(); | 35 | TreeItemModel* getChildModel(); |
1166 | 36 | 36 | ||
1167 | 37 | signals: | ||
1168 | 38 | void configChanged(QString,QString); | ||
1169 | 39 | |||
1170 | 37 | public slots: | 40 | public slots: |
1171 | 38 | void activate(); | 41 | void activate(); |
1172 | 39 | void activateChild(const QModelIndex& index); | 42 | void activateChild(const QModelIndex& index); |
1173 | 40 | 43 | ||
1174 | === modified file 'mixxx/src/library/cratetablemodel.cpp' | |||
1175 | --- mixxx/src/library/cratetablemodel.cpp 2013-04-22 19:29:54 +0000 | |||
1176 | +++ mixxx/src/library/cratetablemodel.cpp 2013-05-18 16:32:26 +0000 | |||
1177 | @@ -4,53 +4,69 @@ | |||
1178 | 4 | #include <QtDebug> | 4 | #include <QtDebug> |
1179 | 5 | 5 | ||
1180 | 6 | #include "library/cratetablemodel.h" | 6 | #include "library/cratetablemodel.h" |
1181 | 7 | |||
1182 | 8 | #include "library/dao/cratedao.h" | ||
1183 | 9 | #include "library/librarytablemodel.h" | ||
1184 | 10 | #include "library/queryutil.h" | 7 | #include "library/queryutil.h" |
1185 | 11 | #include "library/trackcollection.h" | 8 | #include "library/trackcollection.h" |
1186 | 12 | #include "mixxxutils.cpp" | 9 | #include "mixxxutils.cpp" |
1187 | 13 | #include "playermanager.h" | 10 | #include "playermanager.h" |
1188 | 14 | 11 | ||
1190 | 15 | CrateTableModel::CrateTableModel(QObject* pParent, TrackCollection* pTrackCollection) | 12 | CrateTableModel::CrateTableModel(QObject* pParent, |
1191 | 13 | TrackCollection* pTrackCollection, | ||
1192 | 14 | ConfigObject<ConfigValue>* pConfig) | ||
1193 | 16 | : BaseSqlTableModel(pParent, pTrackCollection, | 15 | : BaseSqlTableModel(pParent, pTrackCollection, |
1200 | 17 | pTrackCollection->getDatabase(), | 16 | pConfig, "mixxx.db.model.crate"), |
1201 | 18 | "mixxx.db.model.crate"), | 17 | m_iCrateId(-1), |
1202 | 19 | m_pTrackCollection(pTrackCollection), | 18 | m_crateDAO(pTrackCollection->getCrateDAO()) { |
1197 | 20 | m_iCrateId(-1) { | ||
1198 | 21 | connect(this, SIGNAL(doSearch(const QString&)), | ||
1199 | 22 | this, SLOT(slotSearch(const QString&))); | ||
1203 | 23 | } | 19 | } |
1204 | 24 | 20 | ||
1205 | 25 | CrateTableModel::~CrateTableModel() { | 21 | CrateTableModel::~CrateTableModel() { |
1206 | 26 | } | 22 | } |
1207 | 27 | 23 | ||
1209 | 28 | void CrateTableModel::setCrate(int crateId) { | 24 | void CrateTableModel::setTableModel(int crateId) { |
1210 | 29 | //qDebug() << "CrateTableModel::setCrate()" << crateId; | 25 | //qDebug() << "CrateTableModel::setCrate()" << crateId; |
1211 | 26 | if (crateId == m_iCrateId) { | ||
1212 | 27 | qDebug() << "Already focused on crate " << crateId; | ||
1213 | 28 | return; | ||
1214 | 29 | } else if (crateId == -1) { | ||
1215 | 30 | // calls from parent class use -1 as id then just set the current crate | ||
1216 | 31 | crateId = m_iCrateId; | ||
1217 | 32 | } | ||
1218 | 30 | m_iCrateId = crateId; | 33 | m_iCrateId = crateId; |
1219 | 31 | 34 | ||
1221 | 32 | QString tableName = QString("crate_%1").arg(m_iCrateId); | 35 | QString tableName = QString("crate_%1_").arg(m_iCrateId); |
1222 | 33 | QSqlQuery query(m_pTrackCollection->getDatabase()); | 36 | QSqlQuery query(m_pTrackCollection->getDatabase()); |
1223 | 34 | FieldEscaper escaper(m_pTrackCollection->getDatabase()); | 37 | FieldEscaper escaper(m_pTrackCollection->getDatabase()); |
1224 | 38 | |||
1225 | 35 | QStringList columns; | 39 | QStringList columns; |
1227 | 36 | columns << CRATETRACKSTABLE_TRACKID + " as " + LIBRARYTABLE_ID | 40 | QStringList tableColumns; |
1228 | 41 | QString filter; | ||
1229 | 42 | columns << "crate_tracks."+CRATETRACKSTABLE_TRACKID + " as " + LIBRARYTABLE_ID | ||
1230 | 37 | << "'' as preview"; | 43 | << "'' as preview"; |
1231 | 44 | tableColumns << CRATETRACKSTABLE_TRACKID; | ||
1232 | 45 | bool showMissing = m_pConfig->getValueString(ConfigKey("[Library]","ShowMissingSongs"),"1").toInt(); | ||
1233 | 46 | if(showMissing){ | ||
1234 | 47 | filter = "library.mixxx_deleted=0"; | ||
1235 | 48 | tableName.append("_missing"); | ||
1236 | 49 | } else { | ||
1237 | 50 | filter = "library.mixxx_deleted=0 AND track_locations.fs_deleted=0"; | ||
1238 | 51 | } | ||
1239 | 38 | 52 | ||
1240 | 39 | // We drop files that have been explicitly deleted from mixxx | 53 | // We drop files that have been explicitly deleted from mixxx |
1241 | 40 | // (mixxx_deleted=0) from the view. There was a bug in <= 1.9.0 where | 54 | // (mixxx_deleted=0) from the view. There was a bug in <= 1.9.0 where |
1243 | 41 | // removed files were not removed from playlists, so some users will have | 55 | // removed files were not removed from crates, so some users will have |
1244 | 42 | // libraries where this is the case. | 56 | // libraries where this is the case. |
1245 | 43 | QString queryString = QString( | 57 | QString queryString = QString( |
1246 | 44 | "CREATE TEMPORARY VIEW IF NOT EXISTS %1 AS " | 58 | "CREATE TEMPORARY VIEW IF NOT EXISTS %1 AS " |
1247 | 45 | "SELECT %2 FROM %3 " | 59 | "SELECT %2 FROM %3 " |
1248 | 46 | "INNER JOIN library ON library.id = %3.%4 " | 60 | "INNER JOIN library ON library.id = %3.%4 " |
1250 | 47 | "WHERE %3.%5 = %6 AND library.mixxx_deleted = 0") | 61 | "INNER JOIN track_locations ON track_locations.id=crate_tracks.track_id " |
1251 | 62 | "WHERE %3.%5 = %6 AND %7") | ||
1252 | 48 | .arg(escaper.escapeString(tableName), | 63 | .arg(escaper.escapeString(tableName), |
1253 | 49 | columns.join(","), | 64 | columns.join(","), |
1254 | 50 | CRATE_TRACKS_TABLE, | 65 | CRATE_TRACKS_TABLE, |
1255 | 51 | CRATETRACKSTABLE_TRACKID, | 66 | CRATETRACKSTABLE_TRACKID, |
1256 | 52 | CRATETRACKSTABLE_CRATEID, | 67 | CRATETRACKSTABLE_CRATEID, |
1258 | 53 | QString::number(crateId)); | 68 | QString::number(crateId), |
1259 | 69 | filter); | ||
1260 | 54 | query.prepare(queryString); | 70 | query.prepare(queryString); |
1261 | 55 | if (!query.exec()) { | 71 | if (!query.exec()) { |
1262 | 56 | LOG_FAILED_QUERY(query); | 72 | LOG_FAILED_QUERY(query); |
1263 | @@ -103,10 +119,9 @@ | |||
1264 | 103 | fileInfoList.append(QFileInfo(fileLocation)); | 119 | fileInfoList.append(QFileInfo(fileLocation)); |
1265 | 104 | } | 120 | } |
1266 | 105 | 121 | ||
1269 | 106 | TrackDAO& trackDao = m_pTrackCollection->getTrackDAO(); | 122 | QList<int> trackIDs = m_trackDAO.addTracks(fileInfoList, true); |
1268 | 107 | QList<int> trackIDs = trackDao.addTracks(fileInfoList, true); | ||
1270 | 108 | 123 | ||
1272 | 109 | int tracksAdded = m_pTrackCollection->getCrateDAO().addTracksToCrate( | 124 | int tracksAdded = m_crateDAO.addTracksToCrate( |
1273 | 110 | trackIDs, m_iCrateId); | 125 | trackIDs, m_iCrateId); |
1274 | 111 | if (tracksAdded > 0) { | 126 | if (tracksAdded > 0) { |
1275 | 112 | select(); | 127 | select(); |
1276 | @@ -120,58 +135,19 @@ | |||
1277 | 120 | return tracksAdded; | 135 | return tracksAdded; |
1278 | 121 | } | 136 | } |
1279 | 122 | 137 | ||
1280 | 123 | TrackPointer CrateTableModel::getTrack(const QModelIndex& index) const { | ||
1281 | 124 | int trackId = getTrackId(index); | ||
1282 | 125 | return m_pTrackCollection->getTrackDAO().getTrack(trackId); | ||
1283 | 126 | } | ||
1284 | 127 | |||
1285 | 128 | void CrateTableModel::removeTracks(const QModelIndexList& indices) { | 138 | void CrateTableModel::removeTracks(const QModelIndexList& indices) { |
1288 | 129 | CrateDAO& crateDao = m_pTrackCollection->getCrateDAO(); | 139 | bool locked = m_crateDAO.isCrateLocked(m_iCrateId); |
1287 | 130 | bool locked = crateDao.isCrateLocked(m_iCrateId); | ||
1289 | 131 | 140 | ||
1290 | 132 | if (!locked) { | 141 | if (!locked) { |
1291 | 133 | QList<int> trackIds; | 142 | QList<int> trackIds; |
1292 | 134 | foreach (QModelIndex index, indices) { | 143 | foreach (QModelIndex index, indices) { |
1293 | 135 | trackIds.append(getTrackId(index)); | 144 | trackIds.append(getTrackId(index)); |
1294 | 136 | } | 145 | } |
1296 | 137 | crateDao.removeTracksFromCrate(trackIds, m_iCrateId); | 146 | m_crateDAO.removeTracksFromCrate(trackIds, m_iCrateId); |
1297 | 138 | select(); | 147 | select(); |
1298 | 139 | } | 148 | } |
1299 | 140 | } | 149 | } |
1300 | 141 | 150 | ||
1301 | 142 | void CrateTableModel::removeTrack(const QModelIndex& index) { | ||
1302 | 143 | CrateDAO& crateDao = m_pTrackCollection->getCrateDAO(); | ||
1303 | 144 | bool locked = crateDao.isCrateLocked(m_iCrateId); | ||
1304 | 145 | |||
1305 | 146 | if (!locked) { | ||
1306 | 147 | int trackId = getTrackId(index); | ||
1307 | 148 | if (m_pTrackCollection->getCrateDAO(). | ||
1308 | 149 | removeTrackFromCrate(trackId, m_iCrateId)) { | ||
1309 | 150 | select(); | ||
1310 | 151 | } else { | ||
1311 | 152 | // TODO(XXX) feedback | ||
1312 | 153 | } | ||
1313 | 154 | } | ||
1314 | 155 | } | ||
1315 | 156 | |||
1316 | 157 | void CrateTableModel::moveTrack(const QModelIndex& sourceIndex, | ||
1317 | 158 | const QModelIndex& destIndex) { | ||
1318 | 159 | Q_UNUSED(sourceIndex); | ||
1319 | 160 | Q_UNUSED(destIndex); | ||
1320 | 161 | return; | ||
1321 | 162 | } | ||
1322 | 163 | |||
1323 | 164 | void CrateTableModel::search(const QString& searchText) { | ||
1324 | 165 | // qDebug() << "CrateTableModel::search()" << searchText | ||
1325 | 166 | // << QThread::currentThread(); | ||
1326 | 167 | emit(doSearch(searchText)); | ||
1327 | 168 | } | ||
1328 | 169 | |||
1329 | 170 | void CrateTableModel::slotSearch(const QString& searchText) { | ||
1330 | 171 | BaseSqlTableModel::search( | ||
1331 | 172 | searchText, LibraryTableModel::DEFAULT_LIBRARYFILTER); | ||
1332 | 173 | } | ||
1333 | 174 | |||
1334 | 175 | bool CrateTableModel::isColumnInternal(int column) { | 151 | bool CrateTableModel::isColumnInternal(int column) { |
1335 | 176 | if (column == fieldIndex(LIBRARYTABLE_ID) || | 152 | if (column == fieldIndex(LIBRARYTABLE_ID) || |
1336 | 177 | column == fieldIndex(CRATETRACKSTABLE_TRACKID) || | 153 | column == fieldIndex(CRATETRACKSTABLE_TRACKID) || |
1337 | @@ -179,6 +155,7 @@ | |||
1338 | 179 | column == fieldIndex(LIBRARYTABLE_MIXXXDELETED) || | 155 | column == fieldIndex(LIBRARYTABLE_MIXXXDELETED) || |
1339 | 180 | column == fieldIndex(LIBRARYTABLE_BPM_LOCK) || | 156 | column == fieldIndex(LIBRARYTABLE_BPM_LOCK) || |
1340 | 181 | column == fieldIndex(TRACKLOCATIONSTABLE_FSDELETED) || | 157 | column == fieldIndex(TRACKLOCATIONSTABLE_FSDELETED) || |
1341 | 158 | column == fieldIndex(TRACKLOCATIONSTABLE_MAINDIRID) || | ||
1342 | 182 | (PlayerManager::numPreviewDecks() == 0 && column == fieldIndex("preview"))) { | 159 | (PlayerManager::numPreviewDecks() == 0 && column == fieldIndex("preview"))) { |
1343 | 183 | return true; | 160 | return true; |
1344 | 184 | } | 161 | } |
1345 | @@ -202,12 +179,12 @@ | |||
1346 | 202 | | TRACKMODELCAPS_LOADTOSAMPLER | 179 | | TRACKMODELCAPS_LOADTOSAMPLER |
1347 | 203 | | TRACKMODELCAPS_LOADTOPREVIEWDECK | 180 | | TRACKMODELCAPS_LOADTOPREVIEWDECK |
1348 | 204 | | TRACKMODELCAPS_REMOVE | 181 | | TRACKMODELCAPS_REMOVE |
1349 | 182 | | TRACKMODELCAPS_RELOCATE | ||
1350 | 205 | | TRACKMODELCAPS_BPMLOCK | 183 | | TRACKMODELCAPS_BPMLOCK |
1351 | 206 | | TRACKMODELCAPS_CLEAR_BEATS | 184 | | TRACKMODELCAPS_CLEAR_BEATS |
1352 | 207 | | TRACKMODELCAPS_RESETPLAYED; | 185 | | TRACKMODELCAPS_RESETPLAYED; |
1353 | 208 | 186 | ||
1356 | 209 | CrateDAO& crateDao = m_pTrackCollection->getCrateDAO(); | 187 | bool locked = m_crateDAO.isCrateLocked(m_iCrateId); |
1355 | 210 | bool locked = crateDao.isCrateLocked(m_iCrateId); | ||
1357 | 211 | 188 | ||
1358 | 212 | if (locked) { | 189 | if (locked) { |
1359 | 213 | caps |= TRACKMODELCAPS_LOCKED; | 190 | caps |= TRACKMODELCAPS_LOCKED; |
1360 | @@ -215,3 +192,10 @@ | |||
1361 | 215 | 192 | ||
1362 | 216 | return caps; | 193 | return caps; |
1363 | 217 | } | 194 | } |
1364 | 195 | |||
1365 | 196 | void CrateTableModel::moveTrack(const QModelIndex& sourceIndex, | ||
1366 | 197 | const QModelIndex& destIndex) { | ||
1367 | 198 | Q_UNUSED(sourceIndex); | ||
1368 | 199 | Q_UNUSED(destIndex); | ||
1369 | 200 | return; | ||
1370 | 201 | } | ||
1371 | 218 | 202 | ||
1372 | === modified file 'mixxx/src/library/cratetablemodel.h' | |||
1373 | --- mixxx/src/library/cratetablemodel.h 2013-04-22 19:29:54 +0000 | |||
1374 | +++ mixxx/src/library/cratetablemodel.h 2013-05-18 16:32:26 +0000 | |||
1375 | @@ -4,48 +4,35 @@ | |||
1376 | 4 | #ifndef CRATETABLEMODEL_H | 4 | #ifndef CRATETABLEMODEL_H |
1377 | 5 | #define CRATETABLEMODEL_H | 5 | #define CRATETABLEMODEL_H |
1378 | 6 | 6 | ||
1379 | 7 | #include <QItemDelegate> | ||
1380 | 8 | #include <QSqlTableModel> | ||
1381 | 9 | |||
1382 | 10 | #include "library/basesqltablemodel.h" | 7 | #include "library/basesqltablemodel.h" |
1385 | 11 | 8 | #include "library/dao/cratedao.h" | |
1384 | 12 | class TrackCollection; | ||
1386 | 13 | 9 | ||
1387 | 14 | class CrateTableModel : public BaseSqlTableModel { | 10 | class CrateTableModel : public BaseSqlTableModel { |
1388 | 15 | Q_OBJECT | 11 | Q_OBJECT |
1389 | 16 | public: | 12 | public: |
1391 | 17 | CrateTableModel(QObject* parent, TrackCollection* pTrackCollection); | 13 | CrateTableModel(QObject* parent, TrackCollection* pTrackCollection, |
1392 | 14 | ConfigObject<ConfigValue>* pConfig); | ||
1393 | 18 | virtual ~CrateTableModel(); | 15 | virtual ~CrateTableModel(); |
1394 | 19 | 16 | ||
1396 | 20 | void setCrate(int crateId); | 17 | void setTableModel(int crateId=-1); |
1397 | 21 | int getCrate() const { | 18 | int getCrate() const { |
1398 | 22 | return m_iCrateId; | 19 | return m_iCrateId; |
1399 | 23 | } | 20 | } |
1400 | 24 | 21 | ||
1401 | 25 | // From TrackModel | 22 | // From TrackModel |
1402 | 26 | TrackPointer getTrack(const QModelIndex& index) const; | ||
1403 | 27 | void search(const QString& searchText); | ||
1404 | 28 | bool isColumnInternal(int column); | 23 | bool isColumnInternal(int column); |
1405 | 29 | bool isColumnHiddenByDefault(int column); | 24 | bool isColumnHiddenByDefault(int column); |
1406 | 30 | void removeTrack(const QModelIndex& index); | ||
1407 | 31 | void removeTracks(const QModelIndexList& indices); | 25 | void removeTracks(const QModelIndexList& indices); |
1409 | 32 | bool addTrack(const QModelIndex& index, QString location); | 26 | bool addTrack(const QModelIndex &index, QString location); |
1410 | 33 | // Returns the number of unsuccessful track additions | 27 | // Returns the number of unsuccessful track additions |
1413 | 34 | int addTracks(const QModelIndex& index, | 28 | int addTracks(const QModelIndex& index,const QList <QString> &locations); |
1412 | 35 | const QList <QString> &locations); | ||
1414 | 36 | void moveTrack(const QModelIndex& sourceIndex, | 29 | void moveTrack(const QModelIndex& sourceIndex, |
1415 | 37 | const QModelIndex& destIndex); | 30 | const QModelIndex& destIndex); |
1416 | 38 | TrackModel::CapabilitiesFlags getCapabilities() const; | 31 | TrackModel::CapabilitiesFlags getCapabilities() const; |
1417 | 39 | 32 | ||
1418 | 40 | private slots: | ||
1419 | 41 | void slotSearch(const QString& searchText); | ||
1420 | 42 | |||
1421 | 43 | signals: | ||
1422 | 44 | void doSearch(const QString& searchText); | ||
1423 | 45 | |||
1424 | 46 | private: | 33 | private: |
1425 | 47 | TrackCollection* m_pTrackCollection; | ||
1426 | 48 | int m_iCrateId; | 34 | int m_iCrateId; |
1427 | 35 | CrateDAO& m_crateDAO; | ||
1428 | 49 | }; | 36 | }; |
1429 | 50 | 37 | ||
1430 | 51 | #endif /* CRATETABLEMODEL_H */ | 38 | #endif /* CRATETABLEMODEL_H */ |
1431 | 52 | 39 | ||
1432 | === added file 'mixxx/src/library/dao/directorydao.cpp' | |||
1433 | --- mixxx/src/library/dao/directorydao.cpp 1970-01-01 00:00:00 +0000 | |||
1434 | +++ mixxx/src/library/dao/directorydao.cpp 2013-05-18 16:32:26 +0000 | |||
1435 | @@ -0,0 +1,143 @@ | |||
1436 | 1 | #include <QtSql> | ||
1437 | 2 | #include <QtDebug> | ||
1438 | 3 | #include <QStringBuilder> | ||
1439 | 4 | |||
1440 | 5 | #include "directorydao.h" | ||
1441 | 6 | #include "library/queryutil.h" | ||
1442 | 7 | |||
1443 | 8 | DirectoryDAO::DirectoryDAO(QSqlDatabase& database) | ||
1444 | 9 | : m_database(database) { | ||
1445 | 10 | } | ||
1446 | 11 | |||
1447 | 12 | DirectoryDAO::DirectoryDAO(const DirectoryDAO& directoryDao) | ||
1448 | 13 | : m_database(directoryDao.m_database){ | ||
1449 | 14 | } | ||
1450 | 15 | |||
1451 | 16 | DirectoryDAO::~DirectoryDAO(){ | ||
1452 | 17 | } | ||
1453 | 18 | |||
1454 | 19 | void DirectoryDAO::initialize() | ||
1455 | 20 | { | ||
1456 | 21 | qDebug() << "DirectoryDAO::initialize" << QThread::currentThread() | ||
1457 | 22 | << m_database.connectionName(); | ||
1458 | 23 | } | ||
1459 | 24 | |||
1460 | 25 | bool DirectoryDAO::addDirectory(QString dir){ | ||
1461 | 26 | ScopedTransaction transaction(m_database); | ||
1462 | 27 | QSqlQuery query(m_database); | ||
1463 | 28 | query.prepare("INSERT OR REPLACE INTO directories (directory) " | ||
1464 | 29 | "VALUES (\""% dir %"\")"); | ||
1465 | 30 | |||
1466 | 31 | if (!query.exec()) { | ||
1467 | 32 | qDebug() << "Adding new dir ("% dir %") failed:" | ||
1468 | 33 | <<query.lastError(); | ||
1469 | 34 | return false; | ||
1470 | 35 | } | ||
1471 | 36 | transaction.commit(); | ||
1472 | 37 | return true; | ||
1473 | 38 | } | ||
1474 | 39 | |||
1475 | 40 | bool DirectoryDAO::purgeDirectory(QString dir){ | ||
1476 | 41 | QSqlQuery query(m_database); | ||
1477 | 42 | query.prepare("DELETE FROM directories WHERE directory=\"" % dir % "\""); | ||
1478 | 43 | |||
1479 | 44 | if (!query.exec()) { | ||
1480 | 45 | qDebug() << "purging dir ("%dir%") failed:"<<query.lastError(); | ||
1481 | 46 | return false; | ||
1482 | 47 | } | ||
1483 | 48 | return true; | ||
1484 | 49 | } | ||
1485 | 50 | |||
1486 | 51 | bool DirectoryDAO::relocateDirectory(QString oldFolder, QString newFolder){ | ||
1487 | 52 | ScopedTransaction transaction(m_database); | ||
1488 | 53 | QSqlQuery query(m_database); | ||
1489 | 54 | |||
1490 | 55 | // update directory in directories table | ||
1491 | 56 | query.prepare("UPDATE "%DIRECTORYDAO_TABLE%" SET "%DIRECTORYDAO_DIR%"=" | ||
1492 | 57 | "\":newFolder\" WHERE "%DIRECTORYDAO_DIR%"=\":oldFolder\""); | ||
1493 | 58 | query.bindValue(":newFolder", newFolder); | ||
1494 | 59 | query.bindValue(":oldFolder", oldFolder); | ||
1495 | 60 | if (!query.exec()) { | ||
1496 | 61 | LOG_FAILED_QUERY(query) << "coud not relocate directory"; | ||
1497 | 62 | return false; | ||
1498 | 63 | } | ||
1499 | 64 | |||
1500 | 65 | // update location and directory in track_locations table | ||
1501 | 66 | query.prepare("UPDATE track_locations SET location=" | ||
1502 | 67 | "REPLACE(location,\":oldFolder\",\":newFolder\")" | ||
1503 | 68 | ", directory=" | ||
1504 | 69 | "REPLACE(directory,\":oldFolder\",\":newFolder\") " | ||
1505 | 70 | "WHERE "%DIRECTORYDAO_DIR%"=\":oldFolder\""); | ||
1506 | 71 | query.bindValue(":newFolder", newFolder); | ||
1507 | 72 | query.bindValue(":oldFolder", oldFolder); | ||
1508 | 73 | if (!query.exec()) { | ||
1509 | 74 | LOG_FAILED_QUERY(query) << "coud not relocate path of tracks"; | ||
1510 | 75 | return false; | ||
1511 | 76 | } | ||
1512 | 77 | |||
1513 | 78 | // updating the dir_id column is not necessary because it does not change | ||
1514 | 79 | |||
1515 | 80 | transaction.commit(); | ||
1516 | 81 | return true; | ||
1517 | 82 | } | ||
1518 | 83 | |||
1519 | 84 | QStringList DirectoryDAO::getDirs(){ | ||
1520 | 85 | QSqlQuery query(m_database); | ||
1521 | 86 | query.prepare("SELECT " % DIRECTORYDAO_DIR % " FROM " % DIRECTORYDAO_TABLE); | ||
1522 | 87 | if (!query.exec()) { | ||
1523 | 88 | LOG_FAILED_QUERY(query) << "There are no directories saved in the db"; | ||
1524 | 89 | } | ||
1525 | 90 | QStringList dirs; | ||
1526 | 91 | while (query.next()) { | ||
1527 | 92 | dirs << query.value(query.record().indexOf(DIRECTORYDAO_DIR)).toString(); | ||
1528 | 93 | } | ||
1529 | 94 | return dirs; | ||
1530 | 95 | } | ||
1531 | 96 | |||
1532 | 97 | QList<int> DirectoryDAO::getDirIds(QStringList& dirs){ | ||
1533 | 98 | QSqlQuery query(m_database); | ||
1534 | 99 | query.prepare("SELECT " % DIRECTORYDAO_ID % " FROM " % DIRECTORYDAO_TABLE % | ||
1535 | 100 | " WHERE " % DIRECTORYDAO_DIR %" in (\":dirs\")"); | ||
1536 | 101 | query.bindValue(":dirs", dirs.join("\",\"") ); | ||
1537 | 102 | if (!query.exec()) { | ||
1538 | 103 | LOG_FAILED_QUERY(query) << "couldn't find directory:"<<dirs; | ||
1539 | 104 | } | ||
1540 | 105 | QList<int> ids; | ||
1541 | 106 | while (query.next()) { | ||
1542 | 107 | ids.append(query.value(query.record().indexOf(DIRECTORYDAO_ID)).toInt()); | ||
1543 | 108 | } | ||
1544 | 109 | |||
1545 | 110 | return ids; | ||
1546 | 111 | } | ||
1547 | 112 | |||
1548 | 113 | //TODO(kain88) check if this is not obsolete because of getDirIds | ||
1549 | 114 | int DirectoryDAO::getDirId(const QString dir){ | ||
1550 | 115 | QSqlQuery query(m_database); | ||
1551 | 116 | query.prepare("SELECT " % DIRECTORYDAO_ID % " FROM " % DIRECTORYDAO_TABLE % | ||
1552 | 117 | " WHERE " % DIRECTORYDAO_DIR %" in (\":dir\")"); | ||
1553 | 118 | query.bindValue(":dir",dir); | ||
1554 | 119 | if (!query.exec()) { | ||
1555 | 120 | LOG_FAILED_QUERY(query) << "couldn't find directory:"<<dir; | ||
1556 | 121 | } | ||
1557 | 122 | int id=0; | ||
1558 | 123 | while (query.next()) { | ||
1559 | 124 | id = query.value(query.record().indexOf(DIRECTORYDAO_ID)).toInt(); | ||
1560 | 125 | } | ||
1561 | 126 | return id; | ||
1562 | 127 | } | ||
1563 | 128 | |||
1564 | 129 | // Only call this when an update happens from an old library version!!! | ||
1565 | 130 | // TODO move this into update code | ||
1566 | 131 | bool DirectoryDAO::updateTrackLocations(QString dir){ | ||
1567 | 132 | QString dirId = QString::number(getDirId(dir)); | ||
1568 | 133 | ScopedTransaction transaction(m_database); | ||
1569 | 134 | QSqlQuery query(m_database); | ||
1570 | 135 | query.prepare("UPDATE track_locations SET maindir_id = :dirId"); | ||
1571 | 136 | query.bindValue(":dirId", dirId); | ||
1572 | 137 | if (!query.exec()) { | ||
1573 | 138 | LOG_FAILED_QUERY(query) << " could not update TrackLocations"; | ||
1574 | 139 | return false; | ||
1575 | 140 | } | ||
1576 | 141 | transaction.commit(); | ||
1577 | 142 | return true; | ||
1578 | 143 | } | ||
1579 | 0 | 144 | ||
1580 | === added file 'mixxx/src/library/dao/directorydao.h' | |||
1581 | --- mixxx/src/library/dao/directorydao.h 1970-01-01 00:00:00 +0000 | |||
1582 | +++ mixxx/src/library/dao/directorydao.h 2013-05-18 16:32:26 +0000 | |||
1583 | @@ -0,0 +1,31 @@ | |||
1584 | 1 | #ifndef DIRECTORYDAO_H | ||
1585 | 2 | #define DIRECTORYDAO_H | ||
1586 | 3 | |||
1587 | 4 | #include <QSqlDatabase> | ||
1588 | 5 | #include "library/dao/dao.h" | ||
1589 | 6 | |||
1590 | 7 | const QString DIRECTORYDAO_DIR = "directory"; | ||
1591 | 8 | const QString DIRECTORYDAO_ID = "dir_id"; | ||
1592 | 9 | const QString DIRECTORYDAO_TABLE = "directories"; | ||
1593 | 10 | |||
1594 | 11 | class DirectoryDAO : public DAO { | ||
1595 | 12 | public: | ||
1596 | 13 | // normal method | ||
1597 | 14 | DirectoryDAO(QSqlDatabase& database); | ||
1598 | 15 | DirectoryDAO(const DirectoryDAO& directoryDao); | ||
1599 | 16 | virtual ~DirectoryDAO(); | ||
1600 | 17 | |||
1601 | 18 | void initialize(); | ||
1602 | 19 | bool addDirectory(QString dir); | ||
1603 | 20 | bool purgeDirectory(QString dir); | ||
1604 | 21 | bool relocateDirectory(QString oldFolder,QString newFolder); | ||
1605 | 22 | bool updateTrackLocations(QString dir); | ||
1606 | 23 | QList<int> getDirIds(QStringList& dirs); | ||
1607 | 24 | int getDirId(const QString dir); | ||
1608 | 25 | QStringList getDirs(); | ||
1609 | 26 | |||
1610 | 27 | private: | ||
1611 | 28 | QSqlDatabase m_database; | ||
1612 | 29 | }; | ||
1613 | 30 | |||
1614 | 31 | #endif //DIRECTORYDAO_H | ||
1615 | 0 | 32 | ||
1616 | === modified file 'mixxx/src/library/dao/trackdao.cpp' | |||
1617 | --- mixxx/src/library/dao/trackdao.cpp 2013-05-03 23:33:12 +0000 | |||
1618 | +++ mixxx/src/library/dao/trackdao.cpp 2013-05-18 16:32:26 +0000 | |||
1619 | @@ -1,6 +1,7 @@ | |||
1620 | 1 | #include <QtDebug> | 1 | #include <QtDebug> |
1621 | 2 | #include <QtCore> | 2 | #include <QtCore> |
1622 | 3 | #include <QtSql> | 3 | #include <QtSql> |
1623 | 4 | #include <QMessageBox> | ||
1624 | 4 | 5 | ||
1625 | 5 | #include "library/dao/trackdao.h" | 6 | #include "library/dao/trackdao.h" |
1626 | 6 | 7 | ||
1627 | @@ -14,6 +15,7 @@ | |||
1628 | 14 | #include "library/dao/cuedao.h" | 15 | #include "library/dao/cuedao.h" |
1629 | 15 | #include "library/dao/playlistdao.h" | 16 | #include "library/dao/playlistdao.h" |
1630 | 16 | #include "library/dao/analysisdao.h" | 17 | #include "library/dao/analysisdao.h" |
1631 | 18 | #include "library/dao/directorydao.h" | ||
1632 | 17 | 19 | ||
1633 | 18 | QHash<int, TrackWeakPointer> TrackDAO::m_sTracks; | 20 | QHash<int, TrackWeakPointer> TrackDAO::m_sTracks; |
1634 | 19 | QMutex TrackDAO::m_sTracksMutex; | 21 | QMutex TrackDAO::m_sTracksMutex; |
1635 | @@ -30,12 +32,14 @@ | |||
1636 | 30 | PlaylistDAO& playlistDao, | 32 | PlaylistDAO& playlistDao, |
1637 | 31 | CrateDAO& crateDao, | 33 | CrateDAO& crateDao, |
1638 | 32 | AnalysisDao& analysisDao, | 34 | AnalysisDao& analysisDao, |
1639 | 35 | DirectoryDAO& directoryDao, | ||
1640 | 33 | ConfigObject<ConfigValue> * pConfig) | 36 | ConfigObject<ConfigValue> * pConfig) |
1641 | 34 | : m_database(database), | 37 | : m_database(database), |
1642 | 35 | m_cueDao(cueDao), | 38 | m_cueDao(cueDao), |
1643 | 36 | m_playlistDao(playlistDao), | 39 | m_playlistDao(playlistDao), |
1644 | 37 | m_crateDao(crateDao), | 40 | m_crateDao(crateDao), |
1645 | 38 | m_analysisDao(analysisDao), | 41 | m_analysisDao(analysisDao), |
1646 | 42 | m_directoryDAO(directoryDao), | ||
1647 | 39 | m_pConfig(pConfig), | 43 | m_pConfig(pConfig), |
1648 | 40 | m_trackCache(TRACK_CACHE_SIZE), | 44 | m_trackCache(TRACK_CACHE_SIZE), |
1649 | 41 | m_pQueryTrackLocationInsert(NULL), | 45 | m_pQueryTrackLocationInsert(NULL), |
1650 | @@ -268,7 +272,8 @@ | |||
1651 | 268 | 272 | ||
1652 | 269 | // No need to check here if the querys exist, this is already done in | 273 | // No need to check here if the querys exist, this is already done in |
1653 | 270 | // addTracksAdd, which is the only function that calls this | 274 | // addTracksAdd, which is the only function that calls this |
1655 | 271 | void TrackDAO::bindTrackToTrackLocationsInsert(TrackInfoObject* pTrack) { | 275 | void TrackDAO::bindTrackToTrackLocationsInsert(TrackInfoObject* pTrack, int dirId, |
1656 | 276 | QString& checksum) { | ||
1657 | 272 | // gets called only in addTracksAdd | 277 | // gets called only in addTracksAdd |
1658 | 273 | m_pQueryTrackLocationInsert->bindValue(":location", pTrack->getLocation()); | 278 | m_pQueryTrackLocationInsert->bindValue(":location", pTrack->getLocation()); |
1659 | 274 | m_pQueryTrackLocationInsert->bindValue(":directory", pTrack->getDirectory()); | 279 | m_pQueryTrackLocationInsert->bindValue(":directory", pTrack->getDirectory()); |
1660 | @@ -277,6 +282,8 @@ | |||
1661 | 277 | // Should this check pTrack->exists()? | 282 | // Should this check pTrack->exists()? |
1662 | 278 | m_pQueryTrackLocationInsert->bindValue(":fs_deleted", 0); | 283 | m_pQueryTrackLocationInsert->bindValue(":fs_deleted", 0); |
1663 | 279 | m_pQueryTrackLocationInsert->bindValue(":needs_verification", 0); | 284 | m_pQueryTrackLocationInsert->bindValue(":needs_verification", 0); |
1664 | 285 | m_pQueryTrackLocationInsert->bindValue(":maindir_id", dirId); | ||
1665 | 286 | m_pQueryTrackLocationInsert->bindValue(":checksum", checksum); | ||
1666 | 280 | } | 287 | } |
1667 | 281 | 288 | ||
1668 | 282 | // No need to check here if the querys exist, this is already done in | 289 | // No need to check here if the querys exist, this is already done in |
1669 | @@ -335,7 +342,6 @@ | |||
1670 | 335 | } | 342 | } |
1671 | 336 | 343 | ||
1672 | 337 | void TrackDAO::addTracksPrepare() { | 344 | void TrackDAO::addTracksPrepare() { |
1673 | 338 | |||
1674 | 339 | if (m_pQueryLibraryInsert || m_pQueryTrackLocationInsert || | 345 | if (m_pQueryLibraryInsert || m_pQueryTrackLocationInsert || |
1675 | 340 | m_pQueryLibrarySelect || m_pQueryTrackLocationSelect || | 346 | m_pQueryLibrarySelect || m_pQueryTrackLocationSelect || |
1676 | 341 | m_pTransaction) { | 347 | m_pTransaction) { |
1677 | @@ -353,9 +359,8 @@ | |||
1678 | 353 | m_pQueryLibrarySelect = new QSqlQuery(m_database); | 359 | m_pQueryLibrarySelect = new QSqlQuery(m_database); |
1679 | 354 | 360 | ||
1680 | 355 | m_pQueryTrackLocationInsert->prepare("INSERT INTO track_locations " | 361 | m_pQueryTrackLocationInsert->prepare("INSERT INTO track_locations " |
1684 | 356 | "(location, directory, filename, filesize, fs_deleted, needs_verification) " | 362 | "(location, directory, filename, filesize, fs_deleted, needs_verification, maindir_id, checksum) " |
1685 | 357 | "VALUES (:location, :directory, :filename, :filesize, :fs_deleted, :needs_verification)" | 363 | "VALUES (:location, :directory, :filename, :filesize, :fs_deleted, :needs_verification, :maindir_id, :checksum)"); |
1683 | 358 | ); | ||
1686 | 359 | 364 | ||
1687 | 360 | m_pQueryTrackLocationSelect->prepare("SELECT id FROM track_locations WHERE location=:location"); | 365 | m_pQueryTrackLocationSelect->prepare("SELECT id FROM track_locations WHERE location=:location"); |
1688 | 361 | 366 | ||
1689 | @@ -398,7 +403,8 @@ | |||
1690 | 398 | m_tracksAddedSet.clear(); | 403 | m_tracksAddedSet.clear(); |
1691 | 399 | } | 404 | } |
1692 | 400 | 405 | ||
1694 | 401 | bool TrackDAO::addTracksAdd(TrackInfoObject* pTrack, bool unremove) { | 406 | bool TrackDAO::addTracksAdd(TrackInfoObject* pTrack, bool unremove,const int dirId) { |
1695 | 407 | |||
1696 | 402 | 408 | ||
1697 | 403 | if (!m_pQueryLibraryInsert || !m_pQueryTrackLocationInsert || | 409 | if (!m_pQueryLibraryInsert || !m_pQueryTrackLocationInsert || |
1698 | 404 | !m_pQueryLibrarySelect || !m_pQueryTrackLocationSelect) { | 410 | !m_pQueryLibrarySelect || !m_pQueryTrackLocationSelect) { |
1699 | @@ -409,11 +415,12 @@ | |||
1700 | 409 | 415 | ||
1701 | 410 | int trackLocationId = -1; | 416 | int trackLocationId = -1; |
1702 | 411 | int trackId = -1; | 417 | int trackId = -1; |
1703 | 418 | QString checksum = calcChecksum(*pTrack); | ||
1704 | 412 | 419 | ||
1705 | 413 | // Insert the track location into the corresponding table. This will fail | 420 | // Insert the track location into the corresponding table. This will fail |
1706 | 414 | // silently if the location is already in the table because it has a UNIQUE | 421 | // silently if the location is already in the table because it has a UNIQUE |
1707 | 415 | // constraint. | 422 | // constraint. |
1709 | 416 | bindTrackToTrackLocationsInsert(pTrack); | 423 | bindTrackToTrackLocationsInsert(pTrack,dirId,checksum); |
1710 | 417 | 424 | ||
1711 | 418 | if (!m_pQueryTrackLocationInsert->exec()) { | 425 | if (!m_pQueryTrackLocationInsert->exec()) { |
1712 | 419 | qDebug() << "Location " << pTrack->getLocation() << " is already in the DB"; | 426 | qDebug() << "Location " << pTrack->getLocation() << " is already in the DB"; |
1713 | @@ -522,7 +529,7 @@ | |||
1714 | 522 | } | 529 | } |
1715 | 523 | 530 | ||
1716 | 524 | addTracksPrepare(); | 531 | addTracksPrepare(); |
1718 | 525 | addTracksAdd(pTrack, unremove); | 532 | addTracksAdd(pTrack, unremove, 0); |
1719 | 526 | addTracksFinish(); | 533 | addTracksFinish(); |
1720 | 527 | } | 534 | } |
1721 | 528 | 535 | ||
1722 | @@ -530,6 +537,8 @@ | |||
1723 | 530 | bool unremove) { | 537 | bool unremove) { |
1724 | 531 | QSqlQuery query(m_database); | 538 | QSqlQuery query(m_database); |
1725 | 532 | QList<int> trackIDs; | 539 | QList<int> trackIDs; |
1726 | 540 | TrackInfoObject* pTrack; | ||
1727 | 541 | |||
1728 | 533 | 542 | ||
1729 | 534 | // Create a temporary database of the paths of all the imported tracks. | 543 | // Create a temporary database of the paths of all the imported tracks. |
1730 | 535 | query.prepare("CREATE TEMP TABLE playlist_import " | 544 | query.prepare("CREATE TEMP TABLE playlist_import " |
1731 | @@ -589,7 +598,8 @@ | |||
1732 | 589 | while (query.next()) { | 598 | while (query.next()) { |
1733 | 590 | QString filePath = query.value(query.record().indexOf("location")).toString(); | 599 | QString filePath = query.value(query.record().indexOf("location")).toString(); |
1734 | 591 | TrackInfoObject* pTrack = new TrackInfoObject(QFileInfo(filePath)); | 600 | TrackInfoObject* pTrack = new TrackInfoObject(QFileInfo(filePath)); |
1736 | 592 | addTracksAdd(pTrack, unremove); | 601 | //TODO kain88 fix dirID |
1737 | 602 | addTracksAdd(pTrack, unremove,0); | ||
1738 | 593 | int trackID = pTrack->getId(); | 603 | int trackID = pTrack->getId(); |
1739 | 594 | if (trackID >= 0) { | 604 | if (trackID >= 0) { |
1740 | 595 | trackIDs.append(trackID); | 605 | trackIDs.append(trackID); |
1741 | @@ -625,6 +635,7 @@ | |||
1742 | 625 | 635 | ||
1743 | 626 | // This signal is received by basetrackcache to remove the tracks from cache | 636 | // This signal is received by basetrackcache to remove the tracks from cache |
1744 | 627 | QSet<int> tracksRemovedSet = QSet<int>::fromList(ids); | 637 | QSet<int> tracksRemovedSet = QSet<int>::fromList(ids); |
1745 | 638 | uncacheTracks(tracksRemovedSet); | ||
1746 | 628 | emit(tracksRemoved(tracksRemovedSet)); | 639 | emit(tracksRemoved(tracksRemovedSet)); |
1747 | 629 | } | 640 | } |
1748 | 630 | 641 | ||
1749 | @@ -647,6 +658,7 @@ | |||
1750 | 647 | LOG_FAILED_QUERY(query); | 658 | LOG_FAILED_QUERY(query); |
1751 | 648 | } | 659 | } |
1752 | 649 | QSet<int> tracksAddedSet = QSet<int>::fromList(ids); | 660 | QSet<int> tracksAddedSet = QSet<int>::fromList(ids); |
1753 | 661 | uncacheTracks(tracksAddedSet); | ||
1754 | 650 | emit(tracksAdded(tracksAddedSet)); | 662 | emit(tracksAdded(tracksAddedSet)); |
1755 | 651 | } | 663 | } |
1756 | 652 | 664 | ||
1757 | @@ -675,18 +687,17 @@ | |||
1758 | 675 | 687 | ||
1759 | 676 | FieldEscaper escaper(m_database); | 688 | FieldEscaper escaper(m_database); |
1760 | 677 | QStringList locationList; | 689 | QStringList locationList; |
1762 | 678 | QSet<QString> dirs; | 690 | QStringList dirs; |
1763 | 679 | while (query.next()) { | 691 | while (query.next()) { |
1764 | 680 | QString filePath = query.value(query.record().indexOf("location")).toString(); | 692 | QString filePath = query.value(query.record().indexOf("location")).toString(); |
1765 | 681 | locationList << escaper.escapeString(filePath); | 693 | locationList << escaper.escapeString(filePath); |
1766 | 682 | QString directory = query.value(query.record().indexOf("directory")).toString(); | 694 | QString directory = query.value(query.record().indexOf("directory")).toString(); |
1768 | 683 | dirs.insert(directory); | 695 | dirs << directory; |
1769 | 684 | } | 696 | } |
1770 | 685 | 697 | ||
1771 | 686 | QStringList dirList; | 698 | QStringList dirList; |
1775 | 687 | for (QSet<QString>::const_iterator it = dirs.constBegin(); | 699 | foreach(QString dir, dirs) { |
1776 | 688 | it != dirs.constEnd(); ++it) { | 700 | dirList << escaper.escapeString(dir); |
1774 | 689 | dirList << escaper.escapeString(*it); | ||
1777 | 690 | } | 701 | } |
1778 | 691 | 702 | ||
1779 | 692 | if (locationList.empty()) { | 703 | if (locationList.empty()) { |
1780 | @@ -724,16 +735,68 @@ | |||
1781 | 724 | transaction.commit(); | 735 | transaction.commit(); |
1782 | 725 | 736 | ||
1783 | 726 | // also need to clean playlists, crates, cues and track_analyses | 737 | // also need to clean playlists, crates, cues and track_analyses |
1784 | 727 | |||
1785 | 728 | m_cueDao.deleteCuesForTracks(ids); | 738 | m_cueDao.deleteCuesForTracks(ids); |
1786 | 729 | m_playlistDao.removeTracksFromPlaylists(ids); | 739 | m_playlistDao.removeTracksFromPlaylists(ids); |
1787 | 730 | m_crateDao.removeTracksFromCrates(ids); | 740 | m_crateDao.removeTracksFromCrates(ids); |
1788 | 731 | m_analysisDao.deleteAnalysises(ids); | 741 | m_analysisDao.deleteAnalysises(ids); |
1789 | 732 | 742 | ||
1790 | 733 | QSet<int> tracksRemovedSet = QSet<int>::fromList(ids); | 743 | QSet<int> tracksRemovedSet = QSet<int>::fromList(ids); |
1791 | 744 | uncacheTracks(tracksRemovedSet); | ||
1792 | 734 | emit(tracksRemoved(tracksRemovedSet)); | 745 | emit(tracksRemoved(tracksRemovedSet)); |
1793 | 735 | } | 746 | } |
1794 | 736 | 747 | ||
1795 | 748 | //TODO(kain88) check if this works as desired | ||
1796 | 749 | QStringList TrackDAO::deleteTracksFromFS(QList<int> ids){ | ||
1797 | 750 | if (ids.empty()) { | ||
1798 | 751 | return QStringList(); | ||
1799 | 752 | } | ||
1800 | 753 | |||
1801 | 754 | QStringList idList; | ||
1802 | 755 | foreach (int id, ids) { | ||
1803 | 756 | idList << QString::number(id); | ||
1804 | 757 | } | ||
1805 | 758 | |||
1806 | 759 | QSqlQuery query(m_database); | ||
1807 | 760 | query.prepare("SELECT track_locations.location, track_locations.directory FROM " | ||
1808 | 761 | "track_locations INNER JOIN library ON library.location = " | ||
1809 | 762 | "track_locations.id WHERE library.id in (:idList)"); | ||
1810 | 763 | query.bindValue("idList", idList.join(",")); | ||
1811 | 764 | if (!query.exec()) { | ||
1812 | 765 | LOG_FAILED_QUERY(query); | ||
1813 | 766 | } | ||
1814 | 767 | |||
1815 | 768 | FieldEscaper escaper(m_database); | ||
1816 | 769 | QStringList locationList; | ||
1817 | 770 | while (query.next()) { | ||
1818 | 771 | locationList << escaper.escapeString(query.value( | ||
1819 | 772 | query.record().indexOf("location")).toString()); | ||
1820 | 773 | } | ||
1821 | 774 | |||
1822 | 775 | QStringList failed; | ||
1823 | 776 | foreach (QString loc, locationList) { | ||
1824 | 777 | if (!QFile::remove(loc)) { | ||
1825 | 778 | failed.append(loc); | ||
1826 | 779 | } | ||
1827 | 780 | } | ||
1828 | 781 | |||
1829 | 782 | query.prepare("SELECT libary.id FROM library INNER JOIN track_locations ON " | ||
1830 | 783 | "library.location = track_locations.id WHERE " | ||
1831 | 784 | "track_locations.location in (:locList)"); | ||
1832 | 785 | query.bindValue(":locList", failed.join(",")); | ||
1833 | 786 | |||
1834 | 787 | if (!query.exec()) { | ||
1835 | 788 | LOG_FAILED_QUERY(query); | ||
1836 | 789 | } | ||
1837 | 790 | |||
1838 | 791 | while (query.next()) { | ||
1839 | 792 | ids.removeAll(query.value(query.record().indexOf("if")).toInt()); | ||
1840 | 793 | } | ||
1841 | 794 | // clean all DB entries AFTER the file is removed, otherwise the remove | ||
1842 | 795 | // function fails. | ||
1843 | 796 | purgeTracks(ids); | ||
1844 | 797 | return failed; | ||
1845 | 798 | } | ||
1846 | 799 | |||
1847 | 737 | // deleter of the TrackInfoObject, for delete a Track from Library use hide or purge | 800 | // deleter of the TrackInfoObject, for delete a Track from Library use hide or purge |
1848 | 738 | // static | 801 | // static |
1849 | 739 | void TrackDAO::deleteTrack(TrackInfoObject* pTrack) { | 802 | void TrackDAO::deleteTrack(TrackInfoObject* pTrack) { |
1850 | @@ -764,7 +827,8 @@ | |||
1851 | 764 | "filetype, rating, key, track_locations.location as location, " | 827 | "filetype, rating, key, track_locations.location as location, " |
1852 | 765 | "track_locations.filesize as filesize, comment, url, duration, bitrate, " | 828 | "track_locations.filesize as filesize, comment, url, duration, bitrate, " |
1853 | 766 | "samplerate, cuepoint, bpm, replaygain, channels, " | 829 | "samplerate, cuepoint, bpm, replaygain, channels, " |
1855 | 767 | "header_parsed, timesplayed, played, beats_version, beats_sub_version, beats, datetime_added, bpm_lock " | 830 | "header_parsed, timesplayed, played, beats_version, beats_sub_version, beats, " |
1856 | 831 | "datetime_added, bpm_lock " | ||
1857 | 768 | "FROM Library " | 832 | "FROM Library " |
1858 | 769 | "INNER JOIN track_locations " | 833 | "INNER JOIN track_locations " |
1859 | 770 | "ON library.location = track_locations.id " | 834 | "ON library.location = track_locations.id " |
1860 | @@ -1035,19 +1099,16 @@ | |||
1861 | 1035 | // Mark all the tracks whose paths begin with libraryPath as invalid. | 1099 | // Mark all the tracks whose paths begin with libraryPath as invalid. |
1862 | 1036 | // That means we'll need to later check that those tracks actually | 1100 | // That means we'll need to later check that those tracks actually |
1863 | 1037 | // (still) exist as part of the library scanning procedure. | 1101 | // (still) exist as part of the library scanning procedure. |
1865 | 1038 | void TrackDAO::invalidateTrackLocationsInLibrary(QString libraryPath) { | 1102 | void TrackDAO::invalidateTrackLocationsInLibrary() { |
1866 | 1039 | //qDebug() << "TrackDAO::invalidateTrackLocations" << QThread::currentThread() << m_database.connectionName(); | 1103 | //qDebug() << "TrackDAO::invalidateTrackLocations" << QThread::currentThread() << m_database.connectionName(); |
1867 | 1040 | //qDebug() << "invalidateTrackLocations(" << libraryPath << ")"; | 1104 | //qDebug() << "invalidateTrackLocations(" << libraryPath << ")"; |
1868 | 1041 | libraryPath += "%"; //Add wildcard to SQL query to match subdirectories! | ||
1869 | 1042 | 1105 | ||
1870 | 1043 | QSqlQuery query(m_database); | 1106 | QSqlQuery query(m_database); |
1871 | 1044 | query.prepare("UPDATE track_locations " | 1107 | query.prepare("UPDATE track_locations " |
1875 | 1045 | "SET needs_verification=1 " | 1108 | "SET needs_verification=1"); |
1873 | 1046 | "WHERE directory LIKE :directory"); | ||
1874 | 1047 | query.bindValue(":directory", libraryPath); | ||
1876 | 1048 | if (!query.exec()) { | 1109 | if (!query.exec()) { |
1877 | 1049 | LOG_FAILED_QUERY(query) | 1110 | LOG_FAILED_QUERY(query) |
1879 | 1050 | << "Couldn't mark tracks in directory" << libraryPath | 1111 | << "Couldn't mark tracks in directory " |
1880 | 1051 | << "as needing verification."; | 1112 | << "as needing verification."; |
1881 | 1052 | } | 1113 | } |
1882 | 1053 | } | 1114 | } |
1883 | @@ -1087,13 +1148,24 @@ | |||
1884 | 1087 | LOG_FAILED_QUERY(query) | 1148 | LOG_FAILED_QUERY(query) |
1885 | 1088 | << "Couldn't mark tracks in" << directories.size() << "directories as verified."; | 1149 | << "Couldn't mark tracks in" << directories.size() << "directories as verified."; |
1886 | 1089 | } | 1150 | } |
1887 | 1151 | // qDebug() << directories; | ||
1888 | 1090 | } | 1152 | } |
1889 | 1091 | 1153 | ||
1890 | 1092 | void TrackDAO::markUnverifiedTracksAsDeleted() { | 1154 | void TrackDAO::markUnverifiedTracksAsDeleted() { |
1891 | 1093 | //qDebug() << "TrackDAO::markUnverifiedTracksAsDeleted" << QThread::currentThread() << m_database.connectionName(); | 1155 | //qDebug() << "TrackDAO::markUnverifiedTracksAsDeleted" << QThread::currentThread() << m_database.connectionName(); |
1894 | 1094 | //qDebug() << "markUnverifiedTracksAsDeleted()"; | 1156 | qDebug() << "markUnverifiedTracksAsDeleted()"; |
1895 | 1095 | 1157 | ||
1896 | 1096 | QSqlQuery query(m_database); | 1158 | QSqlQuery query(m_database); |
1897 | 1159 | query.prepare("SELECT id FROM track_locations WHERE needs_verification=1"); | ||
1898 | 1160 | QSet<int> trackIds; | ||
1899 | 1161 | if (!query.exec()) { | ||
1900 | 1162 | LOG_FAILED_QUERY(query) | ||
1901 | 1163 | << "Couldn't find unverified tracks"; | ||
1902 | 1164 | } | ||
1903 | 1165 | while (query.next()){ | ||
1904 | 1166 | trackIds.insert(query.value(query.record().indexOf("id")).toInt()); | ||
1905 | 1167 | } | ||
1906 | 1168 | emit(tracksRemoved(trackIds)); | ||
1907 | 1097 | query.prepare("UPDATE track_locations " | 1169 | query.prepare("UPDATE track_locations " |
1908 | 1098 | "SET fs_deleted=1, needs_verification=0 " | 1170 | "SET fs_deleted=1, needs_verification=0 " |
1909 | 1099 | "WHERE needs_verification=1"); | 1171 | "WHERE needs_verification=1"); |
1910 | @@ -1121,55 +1193,54 @@ | |||
1911 | 1121 | // and see if another "file" with the same name and filesize exists in the track_locations | 1193 | // and see if another "file" with the same name and filesize exists in the track_locations |
1912 | 1122 | // table. That means the file has moved instead of being deleted outright, and so | 1194 | // table. That means the file has moved instead of being deleted outright, and so |
1913 | 1123 | // we can salvage your existing metadata that you have in your DB (like cue points, etc.). | 1195 | // we can salvage your existing metadata that you have in your DB (like cue points, etc.). |
1915 | 1124 | void TrackDAO::detectMovedFiles(QSet<int>* pTracksMovedSetOld, QSet<int>* pTracksMovedSetNew) { | 1196 | void TrackDAO::detectMovedFiles(QSet<int>& tracksMovedSetOld, QSet<int>& tracksMovedSetNew) { |
1916 | 1125 | //This function should not start a transaction on it's own! | 1197 | //This function should not start a transaction on it's own! |
1917 | 1126 | //When it's called from libraryscanner.cpp, there already is a transaction | 1198 | //When it's called from libraryscanner.cpp, there already is a transaction |
1918 | 1127 | //started! | 1199 | //started! |
1919 | 1128 | |||
1920 | 1129 | QSqlQuery query(m_database); | 1200 | QSqlQuery query(m_database); |
1921 | 1130 | QSqlQuery query2(m_database); | 1201 | QSqlQuery query2(m_database); |
1922 | 1131 | QSqlQuery query3(m_database); | 1202 | QSqlQuery query3(m_database); |
1923 | 1132 | int oldTrackLocationId = -1; | 1203 | int oldTrackLocationId = -1; |
1924 | 1133 | int newTrackLocationId = -1; | 1204 | int newTrackLocationId = -1; |
1927 | 1134 | QString filename; | 1205 | QString checksum; |
1928 | 1135 | int fileSize; | 1206 | int duration = -1; |
1929 | 1207 | int fileSize = -1; | ||
1930 | 1136 | 1208 | ||
1932 | 1137 | query.prepare("SELECT id, filename, filesize FROM track_locations WHERE fs_deleted=1"); | 1209 | query.prepare("SELECT track_locations.id, checksum, filesize, duration FROM track_locations " |
1933 | 1210 | "INNER JOIN library ON track_locations.id=library.location " | ||
1934 | 1211 | "WHERE fs_deleted=1"); | ||
1935 | 1138 | 1212 | ||
1936 | 1139 | if (!query.exec()) { | 1213 | if (!query.exec()) { |
1937 | 1140 | LOG_FAILED_QUERY(query); | 1214 | LOG_FAILED_QUERY(query); |
1938 | 1141 | } | 1215 | } |
1939 | 1142 | 1216 | ||
1944 | 1143 | query2.prepare("SELECT id FROM track_locations WHERE " | 1217 | query2.prepare("SELECT track_locations.id FROM track_locations " |
1945 | 1144 | "fs_deleted=0 AND " | 1218 | "INNER JOIN library ON track_locations.id=library.location " |
1946 | 1145 | "filename=:filename AND " | 1219 | "WHERE fs_deleted=0 AND " |
1947 | 1146 | "filesize=:filesize"); | 1220 | "checksum=:checksum AND " |
1948 | 1221 | "filesize=:filesize AND " | ||
1949 | 1222 | "duration=:duration"); | ||
1950 | 1147 | 1223 | ||
1951 | 1148 | //For each track that's been "deleted" on disk... | 1224 | //For each track that's been "deleted" on disk... |
1952 | 1149 | while (query.next()) { | 1225 | while (query.next()) { |
1953 | 1150 | newTrackLocationId = -1; //Reset this var | 1226 | newTrackLocationId = -1; //Reset this var |
1954 | 1151 | oldTrackLocationId = query.value(query.record().indexOf("id")).toInt(); | 1227 | oldTrackLocationId = query.value(query.record().indexOf("id")).toInt(); |
1956 | 1152 | filename = query.value(query.record().indexOf("filename")).toString(); | 1228 | checksum = query.value(query.record().indexOf("checksum")).toString(); |
1957 | 1153 | fileSize = query.value(query.record().indexOf("filesize")).toInt(); | 1229 | fileSize = query.value(query.record().indexOf("filesize")).toInt(); |
1958 | 1230 | duration = query.value(query.record().indexOf("duration")).toInt(); | ||
1959 | 1154 | 1231 | ||
1961 | 1155 | query2.bindValue(":filename", filename); | 1232 | query2.bindValue(":checksum", checksum); |
1962 | 1156 | query2.bindValue(":filesize", fileSize); | 1233 | query2.bindValue(":filesize", fileSize); |
1963 | 1234 | query2.bindValue(":duration", duration); | ||
1964 | 1157 | Q_ASSERT(query2.exec()); | 1235 | Q_ASSERT(query2.exec()); |
1965 | 1158 | 1236 | ||
1966 | 1159 | Q_ASSERT(query2.size() <= 1); //WTF duplicate tracks? | 1237 | Q_ASSERT(query2.size() <= 1); //WTF duplicate tracks? |
1969 | 1160 | while (query2.next()) | 1238 | while (query2.next()) { |
1968 | 1161 | { | ||
1970 | 1162 | newTrackLocationId = query2.value(query2.record().indexOf("id")).toInt(); | 1239 | newTrackLocationId = query2.value(query2.record().indexOf("id")).toInt(); |
1977 | 1163 | } | 1240 | qDebug() << "Found moved track!" << checksum; |
1972 | 1164 | |||
1973 | 1165 | //If we found a moved track... | ||
1974 | 1166 | if (newTrackLocationId >= 0) | ||
1975 | 1167 | { | ||
1976 | 1168 | qDebug() << "Found moved track!" << filename; | ||
1978 | 1169 | 1241 | ||
1979 | 1170 | //Remove old row from track_locations table | 1242 | //Remove old row from track_locations table |
1982 | 1171 | query3.prepare("DELETE FROM track_locations WHERE " | 1243 | query3.prepare("DELETE FROM track_locations WHERE id=:id"); |
1981 | 1172 | "id=:id"); | ||
1983 | 1173 | query3.bindValue(":id", oldTrackLocationId); | 1244 | query3.bindValue(":id", oldTrackLocationId); |
1984 | 1174 | Q_ASSERT(query3.exec()); | 1245 | Q_ASSERT(query3.exec()); |
1985 | 1175 | 1246 | ||
1986 | @@ -1181,42 +1252,37 @@ | |||
1987 | 1181 | "location=:location"); | 1252 | "location=:location"); |
1988 | 1182 | query3.bindValue(":location", newTrackLocationId); | 1253 | query3.bindValue(":location", newTrackLocationId); |
1989 | 1183 | Q_ASSERT(query3.exec()); | 1254 | Q_ASSERT(query3.exec()); |
2001 | 1184 | 1255 | // We collect all the new tracks the where added to BaseTrackCache as well | |
2002 | 1185 | while (query3.next()) | 1256 | while (query3.next()) { |
2003 | 1186 | { | 1257 | int newTrackId = query3.value(0).toInt(); |
2004 | 1187 | int newTrackId = query3.value(query3.record().indexOf("id")).toInt(); | 1258 | tracksMovedSetNew.insert(newTrackId); |
1994 | 1188 | query3.prepare("DELETE FROM library WHERE " | ||
1995 | 1189 | "id=:newid"); | ||
1996 | 1190 | query3.bindValue(":newid", newTrackLocationId); | ||
1997 | 1191 | Q_ASSERT(query3.exec()); | ||
1998 | 1192 | |||
1999 | 1193 | // We collect all the new tracks the where added to BaseTrackCache as well | ||
2000 | 1194 | pTracksMovedSetNew->insert(newTrackId); | ||
2005 | 1195 | } | 1259 | } |
2006 | 1260 | // Delete the track | ||
2007 | 1261 | query3.prepare("DELETE FROM library WHERE " | ||
2008 | 1262 | "id=:newid"); | ||
2009 | 1263 | query3.bindValue(":newid", newTrackLocationId); | ||
2010 | 1264 | Q_ASSERT(query3.exec()); | ||
2011 | 1196 | 1265 | ||
2012 | 1197 | //Update the location foreign key for the existing row in the library table | 1266 | //Update the location foreign key for the existing row in the library table |
2013 | 1198 | //to point to the correct row in the track_locations table. | 1267 | //to point to the correct row in the track_locations table. |
2014 | 1268 | query3.prepare("UPDATE library " | ||
2015 | 1269 | "SET location=:newloc WHERE location=:oldloc"); | ||
2016 | 1270 | query3.bindValue(":newloc", newTrackLocationId); | ||
2017 | 1271 | query3.bindValue(":oldloc", oldTrackLocationId); | ||
2018 | 1272 | Q_ASSERT(query3.exec()); | ||
2019 | 1273 | |||
2020 | 1274 | // We collect all the old tracks that has to be updated in BaseTrackCache as well | ||
2021 | 1199 | query3.prepare("SELECT id FROM library WHERE " | 1275 | query3.prepare("SELECT id FROM library WHERE " |
2022 | 1200 | "location=:location"); | 1276 | "location=:location"); |
2024 | 1201 | query3.bindValue(":location", oldTrackLocationId); | 1277 | query3.bindValue(":location", newTrackLocationId); |
2025 | 1202 | Q_ASSERT(query3.exec()); | 1278 | Q_ASSERT(query3.exec()); |
2040 | 1203 | 1279 | while (query3.next()) { | |
2041 | 1204 | 1280 | int oldTrackId = query3.value(0).toInt(); | |
2042 | 1205 | while (query3.next()) | 1281 | tracksMovedSetOld.insert(oldTrackId); |
2029 | 1206 | { | ||
2030 | 1207 | int oldTrackId = query3.value(query3.record().indexOf("id")).toInt(); | ||
2031 | 1208 | |||
2032 | 1209 | query3.prepare("UPDATE library " | ||
2033 | 1210 | "SET location=:newloc WHERE id=:oldid"); | ||
2034 | 1211 | query3.bindValue(":newloc", newTrackLocationId); | ||
2035 | 1212 | query3.bindValue(":oldid", oldTrackId); | ||
2036 | 1213 | Q_ASSERT(query3.exec()); | ||
2037 | 1214 | |||
2038 | 1215 | // We collect all the old tracks that has to be updated in BaseTrackCache as well | ||
2039 | 1216 | pTracksMovedSetOld->insert(oldTrackId); | ||
2043 | 1217 | } | 1282 | } |
2044 | 1218 | } | 1283 | } |
2045 | 1219 | } | 1284 | } |
2046 | 1285 | databaseTracksMoved(tracksMovedSetOld, tracksMovedSetNew); | ||
2047 | 1220 | } | 1286 | } |
2048 | 1221 | 1287 | ||
2049 | 1222 | void TrackDAO::clearCache() { | 1288 | void TrackDAO::clearCache() { |
2050 | @@ -1248,7 +1314,125 @@ | |||
2051 | 1248 | return false; | 1314 | return false; |
2052 | 1249 | } | 1315 | } |
2053 | 1250 | 1316 | ||
2055 | 1251 | void TrackDAO::verifyTracksOutside(const QString& libraryPath, volatile bool* pCancel) { | 1317 | bool TrackDAO::relocateTrack(TrackPointer pTrack, QString newLocation) { |
2056 | 1318 | int newFileSize=-1; | ||
2057 | 1319 | int newDuration=-1; | ||
2058 | 1320 | int newTrackLocationId = -1; | ||
2059 | 1321 | int oldTrackLocationId = -1; | ||
2060 | 1322 | QString oldCheckSum; | ||
2061 | 1323 | QString newCheckSum; | ||
2062 | 1324 | int newMainDirId=0; | ||
2063 | 1325 | QString oldLocation = pTrack->getLocation(); | ||
2064 | 1326 | int oldFileSize = pTrack->getLength(); | ||
2065 | 1327 | int oldDuration = pTrack->getDuration(); | ||
2066 | 1328 | int id = getTrackId(pTrack->getLocation()); | ||
2067 | 1329 | |||
2068 | 1330 | ScopedTransaction transaction(m_database); | ||
2069 | 1331 | // see if this track is not already in the database and retrieve information | ||
2070 | 1332 | QSqlQuery query(m_database); | ||
2071 | 1333 | query.prepare("SELECT track_locations.id, checksum, filesize, duration FROM track_locations " | ||
2072 | 1334 | "INNER JOIN library ON track_locations.id=library.location " | ||
2073 | 1335 | "WHERE location= \"" + newLocation + "\""); | ||
2074 | 1336 | if (!query.exec()) | ||
2075 | 1337 | LOG_FAILED_QUERY(query); | ||
2076 | 1338 | |||
2077 | 1339 | while (query.next()) { | ||
2078 | 1340 | newTrackLocationId = query.value(query.record().indexOf("id")).toInt(); | ||
2079 | 1341 | newFileSize = query.value(query.record().indexOf("filesize")).toInt(); | ||
2080 | 1342 | newCheckSum = query.value(query.record().indexOf("checksum")).toString(); | ||
2081 | 1343 | newDuration = query.value(query.record().indexOf("duration")).toInt(); | ||
2082 | 1344 | } | ||
2083 | 1345 | |||
2084 | 1346 | // retrieve information about the old track | ||
2085 | 1347 | query.prepare("SELECT id, checksum FROM track_locations " | ||
2086 | 1348 | "WHERE location = \""+oldLocation+"\""); | ||
2087 | 1349 | if (!query.exec()) | ||
2088 | 1350 | LOG_FAILED_QUERY(query); | ||
2089 | 1351 | while (query.next()) { | ||
2090 | 1352 | oldCheckSum = query.value(query.record().indexOf("checksum")).toString(); | ||
2091 | 1353 | oldTrackLocationId = query.value(query.record().indexOf("id")).toInt(); | ||
2092 | 1354 | //qDebug() << oldTrackLocationId << " old id"; | ||
2093 | 1355 | } | ||
2094 | 1356 | |||
2095 | 1357 | // check if the new track is in a Folder that mixxx watches | ||
2096 | 1358 | query.prepare("SELECT dir_id, directory FROM directories"); | ||
2097 | 1359 | if (!query.exec()) { | ||
2098 | 1360 | LOG_FAILED_QUERY(query) << "There are no directories saved in the db"; | ||
2099 | 1361 | } | ||
2100 | 1362 | while (query.next()) { | ||
2101 | 1363 | QString dir = query.value(query.record().indexOf("directory")).toString(); | ||
2102 | 1364 | if (newLocation.contains(dir)) { | ||
2103 | 1365 | newMainDirId = query.value(query.record().indexOf("dir_id")).toInt(); | ||
2104 | 1366 | } | ||
2105 | 1367 | } | ||
2106 | 1368 | |||
2107 | 1369 | // check we already know a track in that location and make sanity check | ||
2108 | 1370 | // that this new track actually is the same as the old one | ||
2109 | 1371 | if (newTrackLocationId >= 0 && | ||
2110 | 1372 | ((newFileSize == oldFileSize) && | ||
2111 | 1373 | (oldCheckSum==newCheckSum) && | ||
2112 | 1374 | (newDuration==oldDuration))) { | ||
2113 | 1375 | |||
2114 | 1376 | //The library scanner will have added a new row to the Library | ||
2115 | 1377 | //table which corresponds to the track in the new location. We need | ||
2116 | 1378 | //to remove that so we don't end up with two rows in the library table | ||
2117 | 1379 | //for the same track. | ||
2118 | 1380 | query.prepare("DELETE FROM library INNER JOIN track_locations ON " | ||
2119 | 1381 | "library.locations = track_locations.id WHERE library.location=:newid"); | ||
2120 | 1382 | query.bindValue(":newid", newTrackLocationId); | ||
2121 | 1383 | Q_ASSERT(query.exec()); | ||
2122 | 1384 | |||
2123 | 1385 | // Update the location foreign key for the existing row in the library table | ||
2124 | 1386 | // to point to the correct row in the track_locations table. | ||
2125 | 1387 | query.prepare("UPDATE track_locations " | ||
2126 | 1388 | "SET location=:newloc, maindir_id=:dirid WHERE location=:oldloc"); | ||
2127 | 1389 | query.bindValue(":newloc", "\"" +newLocation + "\""); | ||
2128 | 1390 | query.bindValue(":dirid",newMainDirId); | ||
2129 | 1391 | query.bindValue(":oldloc","\"" +oldLocation + "\""); | ||
2130 | 1392 | Q_ASSERT(query.exec()); | ||
2131 | 1393 | } else { | ||
2132 | 1394 | // New locazion was unknown, | ||
2133 | 1395 | // we can simply change the location | ||
2134 | 1396 | TrackInfoObject newTrack(newLocation); | ||
2135 | 1397 | QString filename = newTrack.getFilename(); | ||
2136 | 1398 | QString location = newTrack.getLocation(); | ||
2137 | 1399 | QString directory = newTrack.getDirectory(); | ||
2138 | 1400 | newFileSize = newTrack.getLength(); | ||
2139 | 1401 | newDuration = newTrack.getDuration(); | ||
2140 | 1402 | |||
2141 | 1403 | newCheckSum = calcChecksum(newLocation); | ||
2142 | 1404 | if ((newCheckSum != oldCheckSum) && (oldFileSize != newFileSize) | ||
2143 | 1405 | && (newDuration!=oldDuration)) { | ||
2144 | 1406 | qDebug() << "that is another song"; | ||
2145 | 1407 | qDebug() << "checksum " << oldCheckSum << " vs " << newCheckSum; | ||
2146 | 1408 | qDebug() << "filesize " << oldFileSize << " vs " << newFileSize; | ||
2147 | 1409 | qDebug() << "duration " << oldDuration << " vs " << newDuration; | ||
2148 | 1410 | return false; | ||
2149 | 1411 | } | ||
2150 | 1412 | |||
2151 | 1413 | query.prepare("UPDATE track_locations " | ||
2152 | 1414 | "SET location=\""+location+"\", filename=\""+filename+"\"," | ||
2153 | 1415 | " directory=\""+directory+"\", " | ||
2154 | 1416 | "fs_deleted=0, maindir_id= "+QString::number(newMainDirId)+ | ||
2155 | 1417 | " WHERE id="+QString::number(oldTrackLocationId)); | ||
2156 | 1418 | |||
2157 | 1419 | // qDebug() << "will update it"; | ||
2158 | 1420 | // qDebug() << query.lastQuery(); | ||
2159 | 1421 | if (!query.exec()) { | ||
2160 | 1422 | LOG_FAILED_QUERY(query) << " update failed"; | ||
2161 | 1423 | return false; | ||
2162 | 1424 | } | ||
2163 | 1425 | } | ||
2164 | 1426 | transaction.commit(); | ||
2165 | 1427 | // remove tracks from cache and BTC | ||
2166 | 1428 | QSet<int> ids; | ||
2167 | 1429 | ids.insert(id); | ||
2168 | 1430 | databaseTracksMoved(ids,ids); | ||
2169 | 1431 | uncacheTracks(ids); | ||
2170 | 1432 | return true; | ||
2171 | 1433 | } | ||
2172 | 1434 | |||
2173 | 1435 | void TrackDAO::verifyTracksOutside(volatile bool* pCancel) { | ||
2174 | 1252 | // This function is called from the LibraryScanner Thread | 1436 | // This function is called from the LibraryScanner Thread |
2175 | 1253 | ScopedTransaction transaction(m_database); | 1437 | ScopedTransaction transaction(m_database); |
2176 | 1254 | QSqlQuery query(m_database); | 1438 | QSqlQuery query(m_database); |
2177 | @@ -1258,10 +1442,7 @@ | |||
2178 | 1258 | query.setForwardOnly(true); | 1442 | query.setForwardOnly(true); |
2179 | 1259 | query.prepare("SELECT location " | 1443 | query.prepare("SELECT location " |
2180 | 1260 | "FROM track_locations " | 1444 | "FROM track_locations " |
2185 | 1261 | "WHERE directory NOT LIKE '" + | 1445 | "WHERE maindir_id=0"); |
2182 | 1262 | libraryPath + | ||
2183 | 1263 | "/%'"); //Add wildcard to SQL query to match subdirectories! | ||
2184 | 1264 | |||
2186 | 1265 | if (!query.exec()) { | 1446 | if (!query.exec()) { |
2187 | 1266 | LOG_FAILED_QUERY(query); | 1447 | LOG_FAILED_QUERY(query); |
2188 | 1267 | return; | 1448 | return; |
2189 | @@ -1287,3 +1468,53 @@ | |||
2190 | 1287 | qDebug() << "verifyTracksOutside finished"; | 1468 | qDebug() << "verifyTracksOutside finished"; |
2191 | 1288 | } | 1469 | } |
2192 | 1289 | 1470 | ||
2193 | 1471 | void TrackDAO::markTrackAsDeleted(TrackPointer pTrack){ | ||
2194 | 1472 | int id = pTrack->getId(); | ||
2195 | 1473 | ScopedTransaction transaction(m_database); | ||
2196 | 1474 | QSqlQuery query; | ||
2197 | 1475 | query.prepare("UPDATE track_locations SET fs_deleted=1 WHERE id="+QString::number(id)); | ||
2198 | 1476 | if (!query.exec()) { | ||
2199 | 1477 | LOG_FAILED_QUERY(query) << "Could not mark Track as deleted"; | ||
2200 | 1478 | return; | ||
2201 | 1479 | } | ||
2202 | 1480 | transaction.commit(); | ||
2203 | 1481 | QSet<int> ids; | ||
2204 | 1482 | ids.insert(id); | ||
2205 | 1483 | uncacheTracks(ids); | ||
2206 | 1484 | emit(tracksRemoved(ids)); | ||
2207 | 1485 | } | ||
2208 | 1486 | |||
2209 | 1487 | |||
2210 | 1488 | void TrackDAO::uncacheTracks(QSet<int> ids){ | ||
2211 | 1489 | QMutexLocker locker(&m_sTracksMutex); | ||
2212 | 1490 | foreach (int id, ids) { | ||
2213 | 1491 | m_sTracks.remove(id); | ||
2214 | 1492 | m_trackCache.remove(id); | ||
2215 | 1493 | } | ||
2216 | 1494 | } | ||
2217 | 1495 | |||
2218 | 1496 | QString TrackDAO::calcChecksum(TrackInfoObject& pTrack) { | ||
2219 | 1497 | return calcChecksum(pTrack.getLocation()); | ||
2220 | 1498 | } | ||
2221 | 1499 | |||
2222 | 1500 | QString TrackDAO::calcChecksum(QString location){ | ||
2223 | 1501 | QFile file(location); | ||
2224 | 1502 | if (!file.exists()) { | ||
2225 | 1503 | return QString(); | ||
2226 | 1504 | } | ||
2227 | 1505 | file.open(QIODevice::ReadOnly); | ||
2228 | 1506 | const int block_size = 4096; | ||
2229 | 1507 | char buffer[block_size]; | ||
2230 | 1508 | int bytes_read; | ||
2231 | 1509 | // only ID3v1-Tags are at the end of the file and have a fixed size of | ||
2232 | 1510 | // 128byte this way we only calc the checksum of the audio | ||
2233 | 1511 | file.seek(file.size() - 2*block_size); | ||
2234 | 1512 | |||
2235 | 1513 | QCryptographicHash hash(QCryptographicHash::Md5); | ||
2236 | 1514 | if ( (bytes_read = file.read(buffer, block_size)) ) { | ||
2237 | 1515 | hash.addData(buffer,bytes_read); | ||
2238 | 1516 | } | ||
2239 | 1517 | return hash.result().toHex(); | ||
2240 | 1518 | } | ||
2241 | 1519 | |||
2242 | 1520 | |||
2243 | 1290 | 1521 | ||
2244 | === modified file 'mixxx/src/library/dao/trackdao.h' | |||
2245 | --- mixxx/src/library/dao/trackdao.h 2013-04-22 19:29:54 +0000 | |||
2246 | +++ mixxx/src/library/dao/trackdao.h 2013-05-18 16:32:26 +0000 | |||
2247 | @@ -52,12 +52,15 @@ | |||
2248 | 52 | const QString TRACKLOCATIONSTABLE_FILESIZE = "filesize"; | 52 | const QString TRACKLOCATIONSTABLE_FILESIZE = "filesize"; |
2249 | 53 | const QString TRACKLOCATIONSTABLE_FSDELETED = "fs_deleted"; | 53 | const QString TRACKLOCATIONSTABLE_FSDELETED = "fs_deleted"; |
2250 | 54 | const QString TRACKLOCATIONSTABLE_NEEDSVERIFICATION = "needs_verification"; | 54 | const QString TRACKLOCATIONSTABLE_NEEDSVERIFICATION = "needs_verification"; |
2251 | 55 | const QString TRACKLOCATIONSTABLE_FINGERPRINT = "fingerprint"; | ||
2252 | 56 | const QString TRACKLOCATIONSTABLE_MAINDIRID = "maindir_id"; | ||
2253 | 55 | 57 | ||
2254 | 56 | class ScopedTransaction; | 58 | class ScopedTransaction; |
2255 | 57 | class PlaylistDAO; | 59 | class PlaylistDAO; |
2256 | 58 | class AnalysisDao; | 60 | class AnalysisDao; |
2257 | 59 | class CueDAO; | 61 | class CueDAO; |
2258 | 60 | class CrateDAO; | 62 | class CrateDAO; |
2259 | 63 | class DirectoryDAO; | ||
2260 | 61 | 64 | ||
2261 | 62 | class TrackDAO : public QObject, public virtual DAO { | 65 | class TrackDAO : public QObject, public virtual DAO { |
2262 | 63 | Q_OBJECT | 66 | Q_OBJECT |
2263 | @@ -66,8 +69,8 @@ | |||
2264 | 66 | // synchronized on track metadata change | 69 | // synchronized on track metadata change |
2265 | 67 | TrackDAO(QSqlDatabase& database, CueDAO& cueDao, | 70 | TrackDAO(QSqlDatabase& database, CueDAO& cueDao, |
2266 | 68 | PlaylistDAO& playlistDao, CrateDAO& crateDao, | 71 | PlaylistDAO& playlistDao, CrateDAO& crateDao, |
2269 | 69 | AnalysisDao& analysisDao, | 72 | AnalysisDao& analysisDao, DirectoryDAO& directoryDao, |
2270 | 70 | ConfigObject<ConfigValue>* pConfig); | 73 | ConfigObject<ConfigValue>* pConfig = NULL); |
2271 | 71 | virtual ~TrackDAO(); | 74 | virtual ~TrackDAO(); |
2272 | 72 | 75 | ||
2273 | 73 | void finish(); | 76 | void finish(); |
2274 | @@ -81,25 +84,28 @@ | |||
2275 | 81 | int addTrack(const QString& file, bool unremove); | 84 | int addTrack(const QString& file, bool unremove); |
2276 | 82 | int addTrack(const QFileInfo& fileInfo, bool unremove); | 85 | int addTrack(const QFileInfo& fileInfo, bool unremove); |
2277 | 83 | void addTracksPrepare(); | 86 | void addTracksPrepare(); |
2279 | 84 | bool addTracksAdd(TrackInfoObject* pTrack, bool unremove); | 87 | bool addTracksAdd(TrackInfoObject* pTrack, bool unremove,const int dirId); |
2280 | 85 | void addTracksFinish(); | 88 | void addTracksFinish(); |
2281 | 86 | QList<int> addTracks(const QList<QFileInfo> &fileInfoList, bool unremove); | 89 | QList<int> addTracks(const QList<QFileInfo> &fileInfoList, bool unremove); |
2282 | 87 | void hideTracks(QList<int> ids); | 90 | void hideTracks(QList<int> ids); |
2283 | 88 | void purgeTracks(QList<int> ids); | 91 | void purgeTracks(QList<int> ids); |
2284 | 92 | QStringList deleteTracksFromFS(QList<int> ids); | ||
2285 | 89 | void unhideTracks(QList<int> ids); | 93 | void unhideTracks(QList<int> ids); |
2286 | 90 | TrackPointer getTrack(int id, bool cacheOnly=false) const; | 94 | TrackPointer getTrack(int id, bool cacheOnly=false) const; |
2287 | 91 | bool isDirty(int trackId); | 95 | bool isDirty(int trackId); |
2288 | 96 | bool relocateTrack(TrackPointer pTrack, QString newLocation); | ||
2289 | 97 | void markTrackAsDeleted(TrackPointer pTrack); | ||
2290 | 92 | 98 | ||
2291 | 93 | // Scanning related calls. Should be elsewhere or private somehow. | 99 | // Scanning related calls. Should be elsewhere or private somehow. |
2292 | 94 | void markTrackLocationAsVerified(QString location); | 100 | void markTrackLocationAsVerified(QString location); |
2293 | 95 | void markTracksInDirectoriesAsVerified(QStringList directories); | 101 | void markTracksInDirectoriesAsVerified(QStringList directories); |
2295 | 96 | void invalidateTrackLocationsInLibrary(QString libraryPath); | 102 | void invalidateTrackLocationsInLibrary(); |
2296 | 97 | void markUnverifiedTracksAsDeleted(); | 103 | void markUnverifiedTracksAsDeleted(); |
2297 | 98 | void markTrackLocationsAsDeleted(QString directory); | 104 | void markTrackLocationsAsDeleted(QString directory); |
2299 | 99 | void detectMovedFiles(QSet<int>* pTracksMovedSetNew, QSet<int>* pTracksMovedSetOld); | 105 | void detectMovedFiles(QSet<int>& tracksMovedSetNew, QSet<int>& tracksMovedSetOld); |
2300 | 100 | void databaseTrackAdded(TrackPointer pTrack); | 106 | void databaseTrackAdded(TrackPointer pTrack); |
2301 | 101 | void databaseTracksMoved(QSet<int> tracksMovedSetOld, QSet<int> tracksMovedSetNew); | 107 | void databaseTracksMoved(QSet<int> tracksMovedSetOld, QSet<int> tracksMovedSetNew); |
2303 | 102 | void verifyTracksOutside(const QString& libraryPath, volatile bool* pCancel); | 108 | void verifyTracksOutside(volatile bool* pCancel); |
2304 | 103 | 109 | ||
2305 | 104 | signals: | 110 | signals: |
2306 | 105 | void trackDirty(int trackId); | 111 | void trackDirty(int trackId); |
2307 | @@ -134,10 +140,13 @@ | |||
2308 | 134 | void saveTrack(TrackInfoObject* pTrack); | 140 | void saveTrack(TrackInfoObject* pTrack); |
2309 | 135 | void updateTrack(TrackInfoObject* pTrack); | 141 | void updateTrack(TrackInfoObject* pTrack); |
2310 | 136 | void addTrack(TrackInfoObject* pTrack, bool unremove); | 142 | void addTrack(TrackInfoObject* pTrack, bool unremove); |
2311 | 143 | QString calcChecksum(TrackInfoObject& pTrack); | ||
2312 | 144 | QString calcChecksum(QString location); | ||
2313 | 137 | TrackPointer getTrackFromDB(int id) const; | 145 | TrackPointer getTrackFromDB(int id) const; |
2314 | 138 | QString absoluteFilePath(QString location); | 146 | QString absoluteFilePath(QString location); |
2315 | 147 | void uncacheTracks(QSet<int> ids); | ||
2316 | 139 | 148 | ||
2318 | 140 | void bindTrackToTrackLocationsInsert(TrackInfoObject* pTrack); | 149 | void bindTrackToTrackLocationsInsert(TrackInfoObject* pTrack, int dirId,QString& checksum); |
2319 | 141 | void bindTrackToLibraryInsert(TrackInfoObject* pTrack, int trackLocationId); | 150 | void bindTrackToLibraryInsert(TrackInfoObject* pTrack, int trackLocationId); |
2320 | 142 | 151 | ||
2321 | 143 | void writeAudioMetaData(TrackInfoObject* pTrack); | 152 | void writeAudioMetaData(TrackInfoObject* pTrack); |
2322 | @@ -149,6 +158,7 @@ | |||
2323 | 149 | PlaylistDAO &m_playlistDao; | 158 | PlaylistDAO &m_playlistDao; |
2324 | 150 | CrateDAO &m_crateDao; | 159 | CrateDAO &m_crateDao; |
2325 | 151 | AnalysisDao& m_analysisDao; | 160 | AnalysisDao& m_analysisDao; |
2326 | 161 | DirectoryDAO& m_directoryDAO; | ||
2327 | 152 | ConfigObject<ConfigValue> * m_pConfig; | 162 | ConfigObject<ConfigValue> * m_pConfig; |
2328 | 153 | static QHash<int, TrackWeakPointer> m_sTracks; | 163 | static QHash<int, TrackWeakPointer> m_sTracks; |
2329 | 154 | static QMutex m_sTracksMutex; | 164 | static QMutex m_sTracksMutex; |
2330 | 155 | 165 | ||
2331 | === modified file 'mixxx/src/library/hiddentablemodel.cpp' | |||
2332 | --- mixxx/src/library/hiddentablemodel.cpp 2012-06-20 15:49:14 +0000 | |||
2333 | +++ mixxx/src/library/hiddentablemodel.cpp 2013-05-18 16:32:26 +0000 | |||
2334 | @@ -1,28 +1,25 @@ | |||
2339 | 1 | #include <QtCore> | 1 | #include <QMessageBox> |
2340 | 2 | #include <QtGui> | 2 | |
2337 | 3 | #include <QtSql> | ||
2338 | 4 | #include "library/trackcollection.h" | ||
2341 | 5 | #include "library/hiddentablemodel.h" | 3 | #include "library/hiddentablemodel.h" |
2342 | 6 | #include "library/librarytablemodel.h" | ||
2343 | 7 | #include "mixxxutils.cpp" | ||
2344 | 8 | |||
2345 | 9 | 4 | ||
2346 | 10 | HiddenTableModel::HiddenTableModel(QObject* parent, | 5 | HiddenTableModel::HiddenTableModel(QObject* parent, |
2347 | 11 | TrackCollection* pTrackCollection) | 6 | TrackCollection* pTrackCollection) |
2348 | 12 | : BaseSqlTableModel(parent, pTrackCollection, | 7 | : BaseSqlTableModel(parent, pTrackCollection, |
2354 | 13 | pTrackCollection->getDatabase(), | 8 | NULL,"mixxx.db.model.missing") { |
2355 | 14 | "mixxx.db.model.missing"), | 9 | setTableModel(); |
2356 | 15 | m_pTrackCollection(pTrackCollection), | 10 | } |
2357 | 16 | m_trackDao(m_pTrackCollection->getTrackDAO()) { | 11 | |
2358 | 17 | 12 | HiddenTableModel::~HiddenTableModel() { | |
2359 | 13 | } | ||
2360 | 14 | |||
2361 | 15 | void HiddenTableModel::setTableModel(int id){ | ||
2362 | 16 | Q_UNUSED(id); | ||
2363 | 18 | QSqlQuery query; | 17 | QSqlQuery query; |
2365 | 19 | QString tableName("hidden_songs"); | 18 | QString tableName("hidden_songs_"); |
2366 | 20 | 19 | ||
2367 | 21 | QStringList columns; | 20 | QStringList columns; |
2368 | 22 | columns << "library." + LIBRARYTABLE_ID; | 21 | columns << "library." + LIBRARYTABLE_ID; |
2372 | 23 | 22 | QString filter("mixxx_deleted=1"); | |
2370 | 24 | QString filter("mixxx_deleted"); | ||
2371 | 25 | |||
2373 | 26 | query.prepare("CREATE TEMPORARY VIEW IF NOT EXISTS " + tableName + " AS " | 23 | query.prepare("CREATE TEMPORARY VIEW IF NOT EXISTS " + tableName + " AS " |
2374 | 27 | "SELECT " | 24 | "SELECT " |
2375 | 28 | + columns.join(",") + | 25 | + columns.join(",") + |
2376 | @@ -36,7 +33,7 @@ | |||
2377 | 36 | 33 | ||
2378 | 37 | //Print out any SQL error, if there was one. | 34 | //Print out any SQL error, if there was one. |
2379 | 38 | if (query.lastError().isValid()) { | 35 | if (query.lastError().isValid()) { |
2381 | 39 | qDebug() << __FILE__ << __LINE__ << query.lastError(); | 36 | qDebug() << __FILE__ << __LINE__ << query.lastError(); |
2382 | 40 | } | 37 | } |
2383 | 41 | 38 | ||
2384 | 42 | QStringList tableColumns; | 39 | QStringList tableColumns; |
2385 | @@ -48,26 +45,6 @@ | |||
2386 | 48 | setDefaultSort(fieldIndex("artist"), Qt::AscendingOrder); | 45 | setDefaultSort(fieldIndex("artist"), Qt::AscendingOrder); |
2387 | 49 | setSearch(""); | 46 | setSearch(""); |
2388 | 50 | 47 | ||
2389 | 51 | connect(this, SIGNAL(doSearch(const QString&)), | ||
2390 | 52 | this, SLOT(slotSearch(const QString&))); | ||
2391 | 53 | } | ||
2392 | 54 | |||
2393 | 55 | HiddenTableModel::~HiddenTableModel() { | ||
2394 | 56 | } | ||
2395 | 57 | |||
2396 | 58 | bool HiddenTableModel::addTrack(const QModelIndex& index, QString location) { | ||
2397 | 59 | Q_UNUSED(index); | ||
2398 | 60 | Q_UNUSED(location); | ||
2399 | 61 | return false; | ||
2400 | 62 | } | ||
2401 | 63 | |||
2402 | 64 | TrackPointer HiddenTableModel::getTrack(const QModelIndex& index) const { | ||
2403 | 65 | //FIXME: use position instead of location for playlist tracks? | ||
2404 | 66 | |||
2405 | 67 | //const int locationColumnIndex = this->fieldIndex(LIBRARYTABLE_LOCATION); | ||
2406 | 68 | //QString location = index.sibling(index.row(), locationColumnIndex).data().toString(); | ||
2407 | 69 | int trackId = getTrackId(index); | ||
2408 | 70 | return m_trackDao.getTrack(trackId); | ||
2409 | 71 | } | 48 | } |
2410 | 72 | 49 | ||
2411 | 73 | void HiddenTableModel::purgeTracks(const QModelIndexList& indices) { | 50 | void HiddenTableModel::purgeTracks(const QModelIndexList& indices) { |
2412 | @@ -78,7 +55,7 @@ | |||
2413 | 78 | trackIds.append(trackId); | 55 | trackIds.append(trackId); |
2414 | 79 | } | 56 | } |
2415 | 80 | 57 | ||
2417 | 81 | m_trackDao.purgeTracks(trackIds); | 58 | m_trackDAO.purgeTracks(trackIds); |
2418 | 82 | 59 | ||
2419 | 83 | // TODO(rryan) : do not select, instead route event to BTC and notify from | 60 | // TODO(rryan) : do not select, instead route event to BTC and notify from |
2420 | 84 | // there. | 61 | // there. |
2421 | @@ -93,22 +70,34 @@ | |||
2422 | 93 | trackIds.append(trackId); | 70 | trackIds.append(trackId); |
2423 | 94 | } | 71 | } |
2424 | 95 | 72 | ||
2426 | 96 | m_trackDao.unhideTracks(trackIds); | 73 | m_trackDAO.unhideTracks(trackIds); |
2427 | 97 | 74 | ||
2428 | 98 | // TODO(rryan) : do not select, instead route event to BTC and notify from | 75 | // TODO(rryan) : do not select, instead route event to BTC and notify from |
2429 | 99 | // there. | 76 | // there. |
2430 | 100 | select(); //Repopulate the data model. | 77 | select(); //Repopulate the data model. |
2431 | 101 | } | 78 | } |
2432 | 102 | 79 | ||
2442 | 103 | 80 | void HiddenTableModel::deleteTracks(const QModelIndexList& indices) { | |
2443 | 104 | void HiddenTableModel::search(const QString& searchText) { | 81 | QMessageBox::StandardButton btn = QMessageBox::question( |
2444 | 105 | // qDebug() << "HiddenTableModel::search()" << searchText | 82 | NULL, tr("Confirm Delete"), |
2445 | 106 | // << QThread::currentThread(); | 83 | tr("Are you sure you want to delete these files?"), |
2446 | 107 | emit(doSearch(searchText)); | 84 | QMessageBox::Yes | QMessageBox::No, QMessageBox::No); |
2447 | 108 | } | 85 | if (btn == QMessageBox::No) { |
2448 | 109 | 86 | return ; | |
2449 | 110 | void HiddenTableModel::slotSearch(const QString& searchText) { | 87 | } |
2450 | 111 | BaseSqlTableModel::search(searchText); | 88 | |
2451 | 89 | QList<int> trackIds; | ||
2452 | 90 | foreach (QModelIndex index, indices) { | ||
2453 | 91 | int trackId = getTrackId(index); | ||
2454 | 92 | trackIds.append(trackId); | ||
2455 | 93 | } | ||
2456 | 94 | QStringList failed = m_trackDAO.deleteTracksFromFS(trackIds); | ||
2457 | 95 | if (!failed.isEmpty()) { | ||
2458 | 96 | QMessageBox::warning(NULL, tr("Mixxx"), | ||
2459 | 97 | tr("The following track (%1) could not be removed" | ||
2460 | 98 | "because the files are still in use").arg(failed.join(","))); | ||
2461 | 99 | } | ||
2462 | 100 | select(); //Repopulate the data model. | ||
2463 | 112 | } | 101 | } |
2464 | 113 | 102 | ||
2465 | 114 | bool HiddenTableModel::isColumnInternal(int column) { | 103 | bool HiddenTableModel::isColumnInternal(int column) { |
2466 | @@ -116,7 +105,8 @@ | |||
2467 | 116 | column == fieldIndex(LIBRARYTABLE_PLAYED) || | 105 | column == fieldIndex(LIBRARYTABLE_PLAYED) || |
2468 | 117 | column == fieldIndex(LIBRARYTABLE_BPM_LOCK) || | 106 | column == fieldIndex(LIBRARYTABLE_BPM_LOCK) || |
2469 | 118 | column == fieldIndex(LIBRARYTABLE_MIXXXDELETED) || | 107 | column == fieldIndex(LIBRARYTABLE_MIXXXDELETED) || |
2471 | 119 | column == fieldIndex(TRACKLOCATIONSTABLE_FSDELETED)) { | 108 | column == fieldIndex(TRACKLOCATIONSTABLE_FSDELETED) || |
2472 | 109 | column == fieldIndex(TRACKLOCATIONSTABLE_MAINDIRID)) { | ||
2473 | 120 | return true; | 110 | return true; |
2474 | 121 | } | 111 | } |
2475 | 122 | return false; | 112 | return false; |
2476 | @@ -136,5 +126,7 @@ | |||
2477 | 136 | TrackModel::CapabilitiesFlags HiddenTableModel::getCapabilities() const { | 126 | TrackModel::CapabilitiesFlags HiddenTableModel::getCapabilities() const { |
2478 | 137 | return TRACKMODELCAPS_NONE | 127 | return TRACKMODELCAPS_NONE |
2479 | 138 | | TRACKMODELCAPS_PURGE | 128 | | TRACKMODELCAPS_PURGE |
2481 | 139 | | TRACKMODELCAPS_UNHIDE; | 129 | | TRACKMODELCAPS_UNHIDE |
2482 | 130 | | TRACKMODELCAPS_RELOCATE | ||
2483 | 131 | | TRACKMODELCAPS_DELETEFS; | ||
2484 | 140 | } | 132 | } |
2485 | 141 | 133 | ||
2486 | === modified file 'mixxx/src/library/hiddentablemodel.h' | |||
2487 | --- mixxx/src/library/hiddentablemodel.h 2013-05-18 16:23:08 +0000 | |||
2488 | +++ mixxx/src/library/hiddentablemodel.h 2013-05-18 16:32:26 +0000 | |||
2489 | @@ -3,33 +3,20 @@ | |||
2490 | 3 | 3 | ||
2491 | 4 | #include "library/basesqltablemodel.h" | 4 | #include "library/basesqltablemodel.h" |
2492 | 5 | 5 | ||
2493 | 6 | class TrackCollection; | ||
2494 | 7 | |||
2495 | 8 | class HiddenTableModel : public BaseSqlTableModel { | 6 | class HiddenTableModel : public BaseSqlTableModel { |
2496 | 9 | Q_OBJECT | 7 | Q_OBJECT |
2497 | 10 | public: | 8 | public: |
2498 | 11 | HiddenTableModel(QObject* parent, TrackCollection* pTrackCollection); | 9 | HiddenTableModel(QObject* parent, TrackCollection* pTrackCollection); |
2499 | 12 | virtual ~HiddenTableModel(); | 10 | virtual ~HiddenTableModel(); |
2502 | 13 | TrackPointer getTrack(const QModelIndex& index) const; | 11 | void setTableModel(int id = -1); |
2501 | 14 | void search(const QString& searchText); | ||
2503 | 15 | bool isColumnInternal(int column); | 12 | bool isColumnInternal(int column); |
2504 | 16 | bool isColumnHiddenByDefault(int column); | 13 | bool isColumnHiddenByDefault(int column); |
2505 | 17 | void purgeTracks(const QModelIndexList& indices); | 14 | void purgeTracks(const QModelIndexList& indices); |
2506 | 15 | void deleteTracks(const QModelIndexList& indices); | ||
2507 | 18 | void unhideTracks(const QModelIndexList& indices); | 16 | void unhideTracks(const QModelIndexList& indices); |
2508 | 19 | bool addTrack(const QModelIndex& index, QString location); | ||
2509 | 20 | 17 | ||
2510 | 21 | Qt::ItemFlags flags(const QModelIndex &index) const; | 18 | Qt::ItemFlags flags(const QModelIndex &index) const; |
2511 | 22 | TrackModel::CapabilitiesFlags getCapabilities() const; | 19 | TrackModel::CapabilitiesFlags getCapabilities() const; |
2512 | 23 | |||
2513 | 24 | private slots: | ||
2514 | 25 | void slotSearch(const QString& searchText); | ||
2515 | 26 | |||
2516 | 27 | signals: | ||
2517 | 28 | void doSearch(const QString& searchText); | ||
2518 | 29 | |||
2519 | 30 | private: | ||
2520 | 31 | TrackCollection* m_pTrackCollection; | ||
2521 | 32 | TrackDAO& m_trackDao; | ||
2522 | 33 | }; | 20 | }; |
2523 | 34 | 21 | ||
2524 | 35 | #endif | 22 | #endif |
2525 | 36 | 23 | ||
2526 | === modified file 'mixxx/src/library/itunes/itunesfeature.cpp' | |||
2527 | --- mixxx/src/library/itunes/itunesfeature.cpp 2013-01-01 11:53:13 +0000 | |||
2528 | +++ mixxx/src/library/itunes/itunesfeature.cpp 2013-05-18 16:32:26 +0000 | |||
2529 | @@ -25,10 +25,12 @@ | |||
2530 | 25 | #endif | 25 | #endif |
2531 | 26 | } | 26 | } |
2532 | 27 | 27 | ||
2534 | 28 | ITunesFeature::ITunesFeature(QObject* parent, TrackCollection* pTrackCollection) | 28 | ITunesFeature::ITunesFeature(QObject* parent, TrackCollection* pTrackCollection |
2535 | 29 | ,ConfigObject<ConfigValue>* pConfig) | ||
2536 | 29 | : BaseExternalLibraryFeature(parent, pTrackCollection), | 30 | : BaseExternalLibraryFeature(parent, pTrackCollection), |
2539 | 30 | m_pTrackCollection(pTrackCollection), | 31 | m_pTrackCollection(pTrackCollection), |
2540 | 31 | m_cancelImport(false) { | 32 | m_cancelImport(false), |
2541 | 33 | m_pConfig(pConfig) { | ||
2542 | 32 | QString tableName = "itunes_library"; | 34 | QString tableName = "itunes_library"; |
2543 | 33 | QString idColumn = "id"; | 35 | QString idColumn = "id"; |
2544 | 34 | QStringList columns; | 36 | QStringList columns; |
2545 | @@ -53,13 +55,13 @@ | |||
2546 | 53 | this, m_pTrackCollection, | 55 | this, m_pTrackCollection, |
2547 | 54 | "mixxx.db.model.itunes", | 56 | "mixxx.db.model.itunes", |
2548 | 55 | "itunes_library", | 57 | "itunes_library", |
2550 | 56 | "itunes"); | 58 | "itunes",m_pConfig); |
2551 | 57 | m_pITunesPlaylistModel = new BaseExternalPlaylistModel( | 59 | m_pITunesPlaylistModel = new BaseExternalPlaylistModel( |
2552 | 58 | this, m_pTrackCollection, | 60 | this, m_pTrackCollection, |
2553 | 59 | "mixxx.db.model.itunes_playlist", | 61 | "mixxx.db.model.itunes_playlist", |
2554 | 60 | "itunes_playlists", | 62 | "itunes_playlists", |
2555 | 61 | "itunes_playlist_tracks", | 63 | "itunes_playlist_tracks", |
2557 | 62 | "itunes"); | 64 | "itunes",m_pConfig); |
2558 | 63 | m_isActivated = false; | 65 | m_isActivated = false; |
2559 | 64 | m_title = tr("iTunes"); | 66 | m_title = tr("iTunes"); |
2560 | 65 | 67 | ||
2561 | @@ -86,7 +88,7 @@ | |||
2562 | 86 | "mixxx.db.model.itunes_playlist", | 88 | "mixxx.db.model.itunes_playlist", |
2563 | 87 | "itunes_playlists", | 89 | "itunes_playlists", |
2564 | 88 | "itunes_playlist_tracks", | 90 | "itunes_playlist_tracks", |
2566 | 89 | "itunes"); | 91 | "itunes", m_pConfig); |
2567 | 90 | pModel->setPlaylist(playlist); | 92 | pModel->setPlaylist(playlist); |
2568 | 91 | return pModel; | 93 | return pModel; |
2569 | 92 | } | 94 | } |
2570 | @@ -360,12 +362,12 @@ | |||
2571 | 360 | void ITunesFeature::parseTracks(QXmlStreamReader &xml) { | 362 | void ITunesFeature::parseTracks(QXmlStreamReader &xml) { |
2572 | 361 | QSqlQuery query(m_database); | 363 | QSqlQuery query(m_database); |
2573 | 362 | query.prepare("INSERT INTO itunes_library (id, artist, title, album, year, genre, comment, tracknumber," | 364 | query.prepare("INSERT INTO itunes_library (id, artist, title, album, year, genre, comment, tracknumber," |
2580 | 363 | "bpm, bitrate," | 365 | "bpm, bitrate," |
2581 | 364 | "duration, location," | 366 | "duration, location," |
2582 | 365 | "rating ) " | 367 | "rating ) " |
2583 | 366 | "VALUES (:id, :artist, :title, :album, :year, :genre, :comment, :tracknumber," | 368 | "VALUES (:id, :artist, :title, :album, :year, :genre, :comment, :tracknumber," |
2584 | 367 | ":bpm, :bitrate," | 369 | ":bpm, :bitrate," |
2585 | 368 | ":duration, :location," ":rating )"); | 370 | ":duration, :location," ":rating )"); |
2586 | 369 | 371 | ||
2587 | 370 | 372 | ||
2588 | 371 | bool in_container_dictionary = false; | 373 | bool in_container_dictionary = false; |
2589 | @@ -533,7 +535,7 @@ | |||
2590 | 533 | TreeItem* rootItem = new TreeItem(); | 535 | TreeItem* rootItem = new TreeItem(); |
2591 | 534 | QSqlQuery query_insert_to_playlists(m_database); | 536 | QSqlQuery query_insert_to_playlists(m_database); |
2592 | 535 | query_insert_to_playlists.prepare("INSERT INTO itunes_playlists (id, name) " | 537 | query_insert_to_playlists.prepare("INSERT INTO itunes_playlists (id, name) " |
2594 | 536 | "VALUES (:id, :name)"); | 538 | "VALUES (:id, :name)"); |
2595 | 537 | 539 | ||
2596 | 538 | QSqlQuery query_insert_to_playlist_tracks(m_database); | 540 | QSqlQuery query_insert_to_playlist_tracks(m_database); |
2597 | 539 | query_insert_to_playlist_tracks.prepare( | 541 | query_insert_to_playlist_tracks.prepare( |
2598 | @@ -545,9 +547,9 @@ | |||
2599 | 545 | //We process and iterate the <dict> tags holding playlist summary information here | 547 | //We process and iterate the <dict> tags holding playlist summary information here |
2600 | 546 | if (xml.isStartElement() && xml.name() == "dict") { | 548 | if (xml.isStartElement() && xml.name() == "dict") { |
2601 | 547 | parsePlaylist(xml, | 549 | parsePlaylist(xml, |
2605 | 548 | query_insert_to_playlists, | 550 | query_insert_to_playlists, |
2606 | 549 | query_insert_to_playlist_tracks, | 551 | query_insert_to_playlist_tracks, |
2607 | 550 | rootItem); | 552 | rootItem); |
2608 | 551 | continue; | 553 | continue; |
2609 | 552 | } | 554 | } |
2610 | 553 | if (xml.isEndElement()) { | 555 | if (xml.isEndElement()) { |
2611 | @@ -570,7 +572,7 @@ | |||
2612 | 570 | } | 572 | } |
2613 | 571 | 573 | ||
2614 | 572 | void ITunesFeature::parsePlaylist(QXmlStreamReader &xml, QSqlQuery &query_insert_to_playlists, | 574 | void ITunesFeature::parsePlaylist(QXmlStreamReader &xml, QSqlQuery &query_insert_to_playlists, |
2616 | 573 | QSqlQuery &query_insert_to_playlist_tracks, TreeItem* root) { | 575 | QSqlQuery &query_insert_to_playlist_tracks, TreeItem* root) { |
2617 | 574 | //qDebug() << "Parse Playlist"; | 576 | //qDebug() << "Parse Playlist"; |
2618 | 575 | 577 | ||
2619 | 576 | QString playlistname; | 578 | QString playlistname; |
2620 | @@ -623,7 +625,7 @@ | |||
2621 | 623 | bool success = query_insert_to_playlists.exec(); | 625 | bool success = query_insert_to_playlists.exec(); |
2622 | 624 | if (!success) { | 626 | if (!success) { |
2623 | 625 | qDebug() << "SQL Error in ITunesTableModel.cpp: line" << __LINE__ | 627 | qDebug() << "SQL Error in ITunesTableModel.cpp: line" << __LINE__ |
2625 | 626 | << " " << query_insert_to_playlists.lastError(); | 628 | << " " << query_insert_to_playlists.lastError(); |
2626 | 627 | return; | 629 | return; |
2627 | 628 | } | 630 | } |
2628 | 629 | //append the playlist to the child model | 631 | //append the playlist to the child model |
2629 | @@ -646,7 +648,7 @@ | |||
2630 | 646 | //Insert tracks if we are not in a pre-build playlist | 648 | //Insert tracks if we are not in a pre-build playlist |
2631 | 647 | if (!isSystemPlaylist && !query_insert_to_playlist_tracks.exec()) { | 649 | if (!isSystemPlaylist && !query_insert_to_playlist_tracks.exec()) { |
2632 | 648 | qDebug() << "SQL Error in ITunesFeature.cpp: line" << __LINE__ << " " | 650 | qDebug() << "SQL Error in ITunesFeature.cpp: line" << __LINE__ << " " |
2634 | 649 | << query_insert_to_playlist_tracks.lastError(); | 651 | << query_insert_to_playlist_tracks.lastError(); |
2635 | 650 | qDebug() << "trackid" << track_reference; | 652 | qDebug() << "trackid" << track_reference; |
2636 | 651 | qDebug() << "playlistname; " << playlistname; | 653 | qDebug() << "playlistname; " << playlistname; |
2637 | 652 | qDebug() << "-----------------"; | 654 | qDebug() << "-----------------"; |
2638 | @@ -670,10 +672,10 @@ | |||
2639 | 670 | 672 | ||
2640 | 671 | if (!success) { | 673 | if (!success) { |
2641 | 672 | qDebug() << "Could not delete remove old entries from table " | 674 | qDebug() << "Could not delete remove old entries from table " |
2643 | 673 | << table_name << " : " << query.lastError(); | 675 | << table_name << " : " << query.lastError(); |
2644 | 674 | } else { | 676 | } else { |
2645 | 675 | qDebug() << "iTunes table entries of '" | 677 | qDebug() << "iTunes table entries of '" |
2647 | 676 | << table_name <<"' have been cleared."; | 678 | << table_name <<"' have been cleared."; |
2648 | 677 | } | 679 | } |
2649 | 678 | } | 680 | } |
2650 | 679 | 681 | ||
2651 | @@ -693,7 +695,7 @@ | |||
2652 | 693 | NULL, | 695 | NULL, |
2653 | 694 | tr("Error Loading iTunes Library"), | 696 | tr("Error Loading iTunes Library"), |
2654 | 695 | tr("There was an error loading your iTunes library. Some of " | 697 | tr("There was an error loading your iTunes library. Some of " |
2656 | 696 | "your iTunes tracks or playlists may not have loaded.")); | 698 | "your iTunes tracks or playlists may not have loaded.")); |
2657 | 697 | } | 699 | } |
2658 | 698 | // calls a slot in the sidebarmodel such that 'isLoading' is removed from the feature title. | 700 | // calls a slot in the sidebarmodel such that 'isLoading' is removed from the feature title. |
2659 | 699 | m_title = tr("iTunes"); | 701 | m_title = tr("iTunes"); |
2660 | 700 | 702 | ||
2661 | === modified file 'mixxx/src/library/itunes/itunesfeature.h' | |||
2662 | --- mixxx/src/library/itunes/itunesfeature.h 2013-01-01 11:53:13 +0000 | |||
2663 | +++ mixxx/src/library/itunes/itunesfeature.h 2013-05-18 16:32:26 +0000 | |||
2664 | @@ -14,6 +14,7 @@ | |||
2665 | 14 | #include "library/trackcollection.h" | 14 | #include "library/trackcollection.h" |
2666 | 15 | #include "library/treeitemmodel.h" | 15 | #include "library/treeitemmodel.h" |
2667 | 16 | #include "library/treeitem.h" | 16 | #include "library/treeitem.h" |
2668 | 17 | #include "configobject.h" | ||
2669 | 17 | 18 | ||
2670 | 18 | class BaseExternalTrackModel; | 19 | class BaseExternalTrackModel; |
2671 | 19 | class BaseExternalPlaylistModel; | 20 | class BaseExternalPlaylistModel; |
2672 | @@ -21,7 +22,8 @@ | |||
2673 | 21 | class ITunesFeature : public BaseExternalLibraryFeature { | 22 | class ITunesFeature : public BaseExternalLibraryFeature { |
2674 | 22 | Q_OBJECT | 23 | Q_OBJECT |
2675 | 23 | public: | 24 | public: |
2677 | 24 | ITunesFeature(QObject* parent, TrackCollection* pTrackCollection); | 25 | ITunesFeature(QObject* parent, TrackCollection* pTrackCollection |
2678 | 26 | ,ConfigObject<ConfigValue>* pConfig); | ||
2679 | 25 | virtual ~ITunesFeature(); | 27 | virtual ~ITunesFeature(); |
2680 | 26 | static bool isSupported(); | 28 | static bool isSupported(); |
2681 | 27 | 29 | ||
2682 | @@ -62,6 +64,8 @@ | |||
2683 | 62 | bool m_isActivated; | 64 | bool m_isActivated; |
2684 | 63 | QString m_dbfile; | 65 | QString m_dbfile; |
2685 | 64 | 66 | ||
2686 | 67 | ConfigObject<ConfigValue>* m_pConfig; | ||
2687 | 68 | |||
2688 | 65 | QFutureWatcher<TreeItem*> m_future_watcher; | 69 | QFutureWatcher<TreeItem*> m_future_watcher; |
2689 | 66 | QFuture<TreeItem*> m_future; | 70 | QFuture<TreeItem*> m_future; |
2690 | 67 | QString m_title; | 71 | QString m_title; |
2691 | 68 | 72 | ||
2692 | === modified file 'mixxx/src/library/library.cpp' | |||
2693 | --- mixxx/src/library/library.cpp 2013-05-18 16:23:08 +0000 | |||
2694 | +++ mixxx/src/library/library.cpp 2013-05-18 16:32:26 +0000 | |||
2695 | @@ -2,6 +2,8 @@ | |||
2696 | 2 | // Created 8/23/2009 by RJ Ryan (rryan@mit.edu) | 2 | // Created 8/23/2009 by RJ Ryan (rryan@mit.edu) |
2697 | 3 | 3 | ||
2698 | 4 | #include <QItemSelectionModel> | 4 | #include <QItemSelectionModel> |
2699 | 5 | #include <QFuture> | ||
2700 | 6 | #include <QtConcurrentMap> | ||
2701 | 5 | 7 | ||
2702 | 6 | #include "library/library.h" | 8 | #include "library/library.h" |
2703 | 7 | #include "library/libraryfeature.h" | 9 | #include "library/libraryfeature.h" |
2704 | @@ -41,48 +43,50 @@ | |||
2705 | 41 | m_pSidebarModel(new SidebarModel(parent)), | 43 | m_pSidebarModel(new SidebarModel(parent)), |
2706 | 42 | m_pTrackCollection(new TrackCollection(pConfig)), | 44 | m_pTrackCollection(new TrackCollection(pConfig)), |
2707 | 43 | m_pLibraryControl(new LibraryControl), | 45 | m_pLibraryControl(new LibraryControl), |
2709 | 44 | m_pRecordingManager(pRecordingManager) { | 46 | m_pRecordingManager(pRecordingManager), |
2710 | 47 | m_directoryDAO(m_pTrackCollection->getDirectoryDAO()) { | ||
2711 | 45 | 48 | ||
2712 | 46 | // TODO(rryan) -- turn this construction / adding of features into a static | 49 | // TODO(rryan) -- turn this construction / adding of features into a static |
2713 | 47 | // method or something -- CreateDefaultLibrary | 50 | // method or something -- CreateDefaultLibrary |
2716 | 48 | m_pMixxxLibraryFeature = new MixxxLibraryFeature(this, m_pTrackCollection,m_pConfig); | 51 | m_pMixxxLibraryFeature = new MixxxLibraryFeature(this, m_pTrackCollection,pConfig); |
2717 | 49 | addFeature(m_pMixxxLibraryFeature); | 52 | addFeature(m_pMixxxLibraryFeature,true); |
2718 | 50 | 53 | ||
2719 | 51 | #ifdef __PROMO__ | 54 | #ifdef __PROMO__ |
2720 | 52 | if (PromoTracksFeature::isSupported(m_pConfig)) { | 55 | if (PromoTracksFeature::isSupported(m_pConfig)) { |
2721 | 53 | m_pPromoTracksFeature = new PromoTracksFeature(this, pConfig, | 56 | m_pPromoTracksFeature = new PromoTracksFeature(this, pConfig, |
2722 | 54 | m_pTrackCollection, | 57 | m_pTrackCollection, |
2723 | 55 | firstRun); | 58 | firstRun); |
2725 | 56 | addFeature(m_pPromoTracksFeature); | 59 | addFeature(m_pPromoTracksFeature,false); |
2726 | 57 | } else { | 60 | } else { |
2727 | 58 | m_pPromoTracksFeature = NULL; | 61 | m_pPromoTracksFeature = NULL; |
2728 | 59 | } | 62 | } |
2729 | 60 | #endif | 63 | #endif |
2730 | 61 | 64 | ||
2732 | 62 | addFeature(new AutoDJFeature(this, pConfig, m_pTrackCollection)); | 65 | addFeature(new AutoDJFeature(this, pConfig, m_pTrackCollection),true); |
2733 | 63 | m_pPlaylistFeature = new PlaylistFeature(this, m_pTrackCollection, pConfig); | 66 | m_pPlaylistFeature = new PlaylistFeature(this, m_pTrackCollection, pConfig); |
2735 | 64 | addFeature(m_pPlaylistFeature); | 67 | addFeature(m_pPlaylistFeature,true); |
2736 | 65 | m_pCrateFeature = new CrateFeature(this, m_pTrackCollection, pConfig); | 68 | m_pCrateFeature = new CrateFeature(this, m_pTrackCollection, pConfig); |
2741 | 66 | addFeature(m_pCrateFeature); | 69 | addFeature(m_pCrateFeature,true); |
2742 | 67 | addFeature(new BrowseFeature(this, pConfig, m_pTrackCollection, m_pRecordingManager)); | 70 | addFeature(new BrowseFeature(this, pConfig, m_pTrackCollection, m_pRecordingManager),false); |
2743 | 68 | addFeature(new RecordingFeature(this, pConfig, m_pTrackCollection, m_pRecordingManager)); | 71 | addFeature(new RecordingFeature(this, pConfig, m_pTrackCollection, m_pRecordingManager),false); |
2744 | 69 | addFeature(new SetlogFeature(this, pConfig, m_pTrackCollection)); | 72 | // the history should show ALL songs |
2745 | 73 | addFeature(new SetlogFeature(this, pConfig, m_pTrackCollection),false); | ||
2746 | 70 | m_pPrepareFeature = new PrepareFeature(this, pConfig, m_pTrackCollection); | 74 | m_pPrepareFeature = new PrepareFeature(this, pConfig, m_pTrackCollection); |
2748 | 71 | addFeature(m_pPrepareFeature); | 75 | addFeature(m_pPrepareFeature,false); |
2749 | 72 | //iTunes and Rhythmbox should be last until we no longer have an obnoxious | 76 | //iTunes and Rhythmbox should be last until we no longer have an obnoxious |
2750 | 73 | //messagebox popup when you select them. (This forces you to reach for your | 77 | //messagebox popup when you select them. (This forces you to reach for your |
2751 | 74 | //mouse or keyboard if you're using MIDI control and you scroll through them...) | 78 | //mouse or keyboard if you're using MIDI control and you scroll through them...) |
2752 | 75 | if (RhythmboxFeature::isSupported() && | 79 | if (RhythmboxFeature::isSupported() && |
2753 | 76 | pConfig->getValueString(ConfigKey("[Library]","ShowRhythmboxLibrary"),"1").toInt()) { | 80 | pConfig->getValueString(ConfigKey("[Library]","ShowRhythmboxLibrary"),"1").toInt()) { |
2755 | 77 | addFeature(new RhythmboxFeature(this, m_pTrackCollection)); | 81 | addFeature(new RhythmboxFeature(this, m_pTrackCollection,pConfig),false); |
2756 | 78 | } | 82 | } |
2757 | 79 | if (ITunesFeature::isSupported() && | 83 | if (ITunesFeature::isSupported() && |
2758 | 80 | pConfig->getValueString(ConfigKey("[Library]","ShowITunesLibrary"),"1").toInt()) { | 84 | pConfig->getValueString(ConfigKey("[Library]","ShowITunesLibrary"),"1").toInt()) { |
2760 | 81 | addFeature(new ITunesFeature(this, m_pTrackCollection)); | 85 | addFeature(new ITunesFeature(this, m_pTrackCollection, pConfig),false); |
2761 | 82 | } | 86 | } |
2762 | 83 | if (TraktorFeature::isSupported() && | 87 | if (TraktorFeature::isSupported() && |
2763 | 84 | pConfig->getValueString(ConfigKey("[Library]","ShowTraktorLibrary"),"1").toInt()) { | 88 | pConfig->getValueString(ConfigKey("[Library]","ShowTraktorLibrary"),"1").toInt()) { |
2765 | 85 | addFeature(new TraktorFeature(this, m_pTrackCollection)); | 89 | addFeature(new TraktorFeature(this, m_pTrackCollection,pConfig),false); |
2766 | 86 | } | 90 | } |
2767 | 87 | 91 | ||
2768 | 88 | //Show the promo tracks view on first run, otherwise show the library | 92 | //Show the promo tracks view on first run, otherwise show the library |
2769 | @@ -157,7 +161,7 @@ | |||
2770 | 157 | } | 161 | } |
2771 | 158 | } | 162 | } |
2772 | 159 | 163 | ||
2774 | 160 | void Library::addFeature(LibraryFeature* feature) { | 164 | void Library::addFeature(LibraryFeature* feature, bool config) { |
2775 | 161 | Q_ASSERT(feature); | 165 | Q_ASSERT(feature); |
2776 | 162 | m_features.push_back(feature); | 166 | m_features.push_back(feature); |
2777 | 163 | m_pSidebarModel->addLibraryFeature(feature); | 167 | m_pSidebarModel->addLibraryFeature(feature); |
2778 | @@ -171,15 +175,19 @@ | |||
2779 | 171 | this, SLOT(slotLoadTrackToPlayer(TrackPointer, QString, bool))); | 175 | this, SLOT(slotLoadTrackToPlayer(TrackPointer, QString, bool))); |
2780 | 172 | connect(feature, SIGNAL(restoreSearch(const QString&)), | 176 | connect(feature, SIGNAL(restoreSearch(const QString&)), |
2781 | 173 | this, SLOT(slotRestoreSearch(const QString&))); | 177 | this, SLOT(slotRestoreSearch(const QString&))); |
2782 | 178 | if (config) { | ||
2783 | 179 | connect(this, SIGNAL(configChanged(QString,QString)), | ||
2784 | 180 | feature, SIGNAL(configChanged(QString,QString))); | ||
2785 | 181 | } | ||
2786 | 174 | } | 182 | } |
2787 | 175 | 183 | ||
2788 | 176 | void Library::slotShowTrackModel(QAbstractItemModel* model) { | 184 | void Library::slotShowTrackModel(QAbstractItemModel* model) { |
2792 | 177 | //qDebug() << "Library::slotShowTrackModel" << model; | 185 | qDebug() << "Library::slotShowTrackModel" << model; |
2793 | 178 | TrackModel* trackModel = dynamic_cast<TrackModel*>(model); | 186 | m_ptrackModel = dynamic_cast<TrackModel*>(model); |
2794 | 179 | Q_ASSERT(trackModel); | 187 | Q_ASSERT(m_ptrackModel); |
2795 | 180 | emit(showTrackModel(model)); | 188 | emit(showTrackModel(model)); |
2796 | 181 | emit(switchToView(m_sTrackViewName)); | 189 | emit(switchToView(m_sTrackViewName)); |
2798 | 182 | emit(restoreSearch(trackModel->currentSearch())); | 190 | emit(restoreSearch(m_ptrackModel->currentSearch())); |
2799 | 183 | } | 191 | } |
2800 | 184 | 192 | ||
2801 | 185 | void Library::slotSwitchToView(const QString& view) { | 193 | void Library::slotSwitchToView(const QString& view) { |
2802 | @@ -242,3 +250,55 @@ | |||
2803 | 242 | #endif | 250 | #endif |
2804 | 243 | return QList<TrackPointer>(); | 251 | return QList<TrackPointer>(); |
2805 | 244 | } | 252 | } |
2806 | 253 | |||
2807 | 254 | MixxxLibraryFeature* Library::getpMixxxLibraryFeature(){ | ||
2808 | 255 | return m_pMixxxLibraryFeature; | ||
2809 | 256 | } | ||
2810 | 257 | |||
2811 | 258 | void Library::slotDirsChanged(QString op, QString dir){ | ||
2812 | 259 | qDebug() << "kain88 slotDirsChanged"; | ||
2813 | 260 | qDebug() << op << '\t' << dir; | ||
2814 | 261 | if (op=="added") { | ||
2815 | 262 | m_directoryDAO.addDirectory(dir); | ||
2816 | 263 | } else if (op=="removed") { | ||
2817 | 264 | purgeTracks(m_directoryDAO.getDirId(dir)); | ||
2818 | 265 | m_directoryDAO.purgeDirectory(dir); | ||
2819 | 266 | } else if (op=="relocate") { | ||
2820 | 267 | // see dlgprefplaylist for this | ||
2821 | 268 | QStringList dirs = dir.split("!(~)!"); | ||
2822 | 269 | QString newFolder = dirs[0]; | ||
2823 | 270 | QString oldFolder = dirs[1]; | ||
2824 | 271 | m_directoryDAO.relocateDirectory(oldFolder,newFolder); | ||
2825 | 272 | } else if (op=="update") { | ||
2826 | 273 | // this will be signaled from the library scanner if the db needs to be | ||
2827 | 274 | // updated | ||
2828 | 275 | m_directoryDAO.addDirectory(dir); | ||
2829 | 276 | m_directoryDAO.updateTrackLocations(dir); | ||
2830 | 277 | } | ||
2831 | 278 | } | ||
2832 | 279 | |||
2833 | 280 | void Library::purgeTracks(const int dirId) { | ||
2834 | 281 | QSqlQuery query; | ||
2835 | 282 | QList<int> trackIds; | ||
2836 | 283 | query.prepare("SELECT library.id FROM library INNER JOIN track_locations " | ||
2837 | 284 | "ON library.location=track_locations.id " | ||
2838 | 285 | "WHERE maindir_id="+QString::number(dirId)); | ||
2839 | 286 | |||
2840 | 287 | if (!query.exec()) { | ||
2841 | 288 | qDebug() << "could not purge tracks from libraryPath "<<dirId; | ||
2842 | 289 | } | ||
2843 | 290 | |||
2844 | 291 | while (query.next()) { | ||
2845 | 292 | trackIds.append(query.value(query.record().indexOf("id")).toInt()); | ||
2846 | 293 | } | ||
2847 | 294 | qDebug() << "starting to purge Tracks " << trackIds; | ||
2848 | 295 | m_pTrackCollection->getTrackDAO().purgeTracks(trackIds); | ||
2849 | 296 | } | ||
2850 | 297 | |||
2851 | 298 | void Library::slotLoadTrackFailed(TrackPointer pTrack){ | ||
2852 | 299 | m_pTrackCollection->getTrackDAO().markTrackAsDeleted(pTrack); | ||
2853 | 300 | } | ||
2854 | 301 | |||
2855 | 302 | QStringList Library::getDirs(){ | ||
2856 | 303 | return m_directoryDAO.getDirs(); | ||
2857 | 304 | } | ||
2858 | 245 | 305 | ||
2859 | === modified file 'mixxx/src/library/library.h' | |||
2860 | --- mixxx/src/library/library.h 2013-02-09 00:38:39 +0000 | |||
2861 | +++ mixxx/src/library/library.h 2013-05-18 16:32:26 +0000 | |||
2862 | @@ -14,7 +14,9 @@ | |||
2863 | 14 | #include "configobject.h" | 14 | #include "configobject.h" |
2864 | 15 | #include "trackinfoobject.h" | 15 | #include "trackinfoobject.h" |
2865 | 16 | #include "recording/recordingmanager.h" | 16 | #include "recording/recordingmanager.h" |
2866 | 17 | #include "mixxxlibraryfeature.h" | ||
2867 | 17 | #include "preparefeature.h" | 18 | #include "preparefeature.h" |
2868 | 19 | #include "library/dao/directorydao.h" | ||
2869 | 18 | 20 | ||
2870 | 19 | class TrackModel; | 21 | class TrackModel; |
2871 | 20 | class TrackCollection; | 22 | class TrackCollection; |
2872 | @@ -24,6 +26,7 @@ | |||
2873 | 24 | class WLibrarySidebar; | 26 | class WLibrarySidebar; |
2874 | 25 | class WLibrary; | 27 | class WLibrary; |
2875 | 26 | class WSearchLineEdit; | 28 | class WSearchLineEdit; |
2876 | 29 | class PromoTracksFeature; | ||
2877 | 27 | class MixxxLibraryFeature; | 30 | class MixxxLibraryFeature; |
2878 | 28 | class PlaylistFeature; | 31 | class PlaylistFeature; |
2879 | 29 | class CrateFeature; | 32 | class CrateFeature; |
2880 | @@ -42,8 +45,10 @@ | |||
2881 | 42 | MixxxKeyboard* pKeyboard); | 45 | MixxxKeyboard* pKeyboard); |
2882 | 43 | void bindSidebarWidget(WLibrarySidebar* sidebarWidget); | 46 | void bindSidebarWidget(WLibrarySidebar* sidebarWidget); |
2883 | 44 | 47 | ||
2885 | 45 | void addFeature(LibraryFeature* feature); | 48 | void addFeature(LibraryFeature* feature, bool config); |
2886 | 46 | QList<TrackPointer> getTracksToAutoLoad(); | 49 | QList<TrackPointer> getTracksToAutoLoad(); |
2887 | 50 | MixxxLibraryFeature* getpMixxxLibraryFeature(); | ||
2888 | 51 | QStringList getDirs(); | ||
2889 | 47 | 52 | ||
2890 | 48 | // TODO(rryan) Transitionary only -- the only reason this is here is so the | 53 | // TODO(rryan) Transitionary only -- the only reason this is here is so the |
2891 | 49 | // waveform widgets can signal to a player to load a track. This can be | 54 | // waveform widgets can signal to a player to load a track. This can be |
2892 | @@ -65,6 +70,8 @@ | |||
2893 | 65 | void slotRefreshLibraryModels(); | 70 | void slotRefreshLibraryModels(); |
2894 | 66 | void slotCreatePlaylist(); | 71 | void slotCreatePlaylist(); |
2895 | 67 | void slotCreateCrate(); | 72 | void slotCreateCrate(); |
2896 | 73 | void slotDirsChanged(QString,QString); | ||
2897 | 74 | void slotLoadTrackFailed(TrackPointer pTrack); | ||
2898 | 68 | void onSkinLoadFinished(); | 75 | void onSkinLoadFinished(); |
2899 | 69 | 76 | ||
2900 | 70 | signals: | 77 | signals: |
2901 | @@ -73,11 +80,17 @@ | |||
2902 | 73 | void loadTrack(TrackPointer pTrack); | 80 | void loadTrack(TrackPointer pTrack); |
2903 | 74 | void loadTrackToPlayer(TrackPointer pTrack, QString group, bool play = false); | 81 | void loadTrackToPlayer(TrackPointer pTrack, QString group, bool play = false); |
2904 | 75 | void restoreSearch(const QString&); | 82 | void restoreSearch(const QString&); |
2905 | 83 | void configChanged(QString, QString); | ||
2906 | 84 | void dirsChanged(QString,QString); | ||
2907 | 85 | void loadTrackFailed(TrackPointer); | ||
2908 | 76 | void search(const QString& text); | 86 | void search(const QString& text); |
2909 | 77 | void searchCleared(); | 87 | void searchCleared(); |
2910 | 78 | void searchStarting(); | 88 | void searchStarting(); |
2911 | 79 | 89 | ||
2912 | 80 | private: | 90 | private: |
2913 | 91 | void purgeTracks(const int dirId); | ||
2914 | 92 | static QString mpChanged(const QString); | ||
2915 | 93 | |||
2916 | 81 | ConfigObject<ConfigValue>* m_pConfig; | 94 | ConfigObject<ConfigValue>* m_pConfig; |
2917 | 82 | SidebarModel* m_pSidebarModel; | 95 | SidebarModel* m_pSidebarModel; |
2918 | 83 | TrackCollection* m_pTrackCollection; | 96 | TrackCollection* m_pTrackCollection; |
2919 | @@ -94,6 +107,8 @@ | |||
2920 | 94 | PrepareFeature* m_pPrepareFeature; | 107 | PrepareFeature* m_pPrepareFeature; |
2921 | 95 | LibraryControl* m_pLibraryControl; | 108 | LibraryControl* m_pLibraryControl; |
2922 | 96 | RecordingManager* m_pRecordingManager; | 109 | RecordingManager* m_pRecordingManager; |
2923 | 110 | TrackModel* m_ptrackModel; | ||
2924 | 111 | DirectoryDAO m_directoryDAO; | ||
2925 | 97 | }; | 112 | }; |
2926 | 98 | 113 | ||
2927 | 99 | #endif /* LIBRARY_H */ | 114 | #endif /* LIBRARY_H */ |
2928 | 100 | 115 | ||
2929 | === modified file 'mixxx/src/library/libraryfeature.h' | |||
2930 | --- mixxx/src/library/libraryfeature.h 2013-02-03 18:50:24 +0000 | |||
2931 | +++ mixxx/src/library/libraryfeature.h 2013-05-18 16:32:26 +0000 | |||
2932 | @@ -9,6 +9,7 @@ | |||
2933 | 9 | #include <QModelIndex> | 9 | #include <QModelIndex> |
2934 | 10 | #include <QObject> | 10 | #include <QObject> |
2935 | 11 | #include <QString> | 11 | #include <QString> |
2936 | 12 | #include <QStringList> | ||
2937 | 12 | #include <QVariant> | 13 | #include <QVariant> |
2938 | 13 | #include <QAbstractItemModel> | 14 | #include <QAbstractItemModel> |
2939 | 14 | #include <QUrl> | 15 | #include <QUrl> |
2940 | @@ -87,11 +88,11 @@ | |||
2941 | 87 | void restoreSearch(const QString&); | 88 | void restoreSearch(const QString&); |
2942 | 88 | // emit this signal before you parse a large music collection, e.g., iTunes, Traktor. | 89 | // emit this signal before you parse a large music collection, e.g., iTunes, Traktor. |
2943 | 89 | void featureIsLoading(LibraryFeature*); | 90 | void featureIsLoading(LibraryFeature*); |
2945 | 90 | // emit this signal if the foreign music collection has been imported/parsed. | 91 | // emit this signal if the foreign music collection has been imported/parsed. |
2946 | 91 | void featureLoadingFinished(LibraryFeature*s); | 92 | void featureLoadingFinished(LibraryFeature*s); |
2948 | 92 | // emit this signal to select pFeature | 93 | // emit this signal to select pFeature |
2949 | 93 | void featureSelect(LibraryFeature* pFeature, const QModelIndex& index); | 94 | void featureSelect(LibraryFeature* pFeature, const QModelIndex& index); |
2951 | 94 | 95 | void availableDirsChanged(QList<int>); | |
2952 | 95 | }; | 96 | }; |
2953 | 96 | 97 | ||
2954 | 97 | #endif /* LIBRARYFEATURE_H */ | 98 | #endif /* LIBRARYFEATURE_H */ |
2955 | 98 | 99 | ||
2956 | === modified file 'mixxx/src/library/libraryscanner.cpp' | |||
2957 | --- mixxx/src/library/libraryscanner.cpp 2013-02-09 22:06:46 +0000 | |||
2958 | +++ mixxx/src/library/libraryscanner.cpp 2013-05-18 16:32:26 +0000 | |||
2959 | @@ -33,9 +33,10 @@ | |||
2960 | 33 | m_cueDao(m_database), | 33 | m_cueDao(m_database), |
2961 | 34 | m_playlistDao(m_database), | 34 | m_playlistDao(m_database), |
2962 | 35 | m_crateDao(m_database), | 35 | m_crateDao(m_database), |
2963 | 36 | m_directoryDao(m_database), | ||
2964 | 36 | m_analysisDao(m_database, collection->getConfig()), | 37 | m_analysisDao(m_database, collection->getConfig()), |
2965 | 37 | m_trackDao(m_database, m_cueDao, m_playlistDao, m_crateDao, | 38 | m_trackDao(m_database, m_cueDao, m_playlistDao, m_crateDao, |
2967 | 38 | m_analysisDao, collection->getConfig()), | 39 | m_analysisDao,m_directoryDao, collection->getConfig()), |
2968 | 39 | // Don't initialize m_database here, we need to do it in run() so the DB | 40 | // Don't initialize m_database here, we need to do it in run() so the DB |
2969 | 40 | // conn is in the right thread. | 41 | // conn is in the right thread. |
2970 | 41 | m_nameFilters(SoundSourceProxy::supportedFileExtensionsString().split(" ")), | 42 | m_nameFilters(SoundSourceProxy::supportedFileExtensionsString().split(" ")), |
2971 | @@ -51,6 +52,17 @@ | |||
2972 | 51 | connect(this, SIGNAL(scanFinished()), | 52 | connect(this, SIGNAL(scanFinished()), |
2973 | 52 | &(collection->getTrackDAO()), SLOT(clearCache())); | 53 | &(collection->getTrackDAO()), SLOT(clearCache())); |
2974 | 53 | 54 | ||
2975 | 55 | //connect the new trackDAO with the default BaseTrackCacheR | ||
2976 | 56 | connect(&m_trackDao, SIGNAL(tracksRemoved(QSet<int>)), | ||
2977 | 57 | &*(collection->getTrackSource(QString("default"))), | ||
2978 | 58 | SLOT(slotTracksRemoved(QSet<int>))); | ||
2979 | 59 | connect(&m_trackDao, SIGNAL(tracksAdded(QSet<int>)), | ||
2980 | 60 | &*(collection->getTrackSource(QString("default"))), | ||
2981 | 61 | SLOT(slotTracksAdded(QSet<int>))); | ||
2982 | 62 | connect(this, SIGNAL(tracksRestored(QSet<int>)), | ||
2983 | 63 | &*(collection->getTrackSource(QString("default"))), | ||
2984 | 64 | SLOT(slotTracksAdded(QSet<int>))); | ||
2985 | 65 | |||
2986 | 54 | // The "Album Artwork" folder within iTunes stores Album Arts. | 66 | // The "Album Artwork" folder within iTunes stores Album Arts. |
2987 | 55 | // It has numerous hundreds of sub folders but no audio files | 67 | // It has numerous hundreds of sub folders but no audio files |
2988 | 56 | // We put this folder on a "black list" | 68 | // We put this folder on a "black list" |
2989 | @@ -128,7 +140,7 @@ | |||
2990 | 128 | // Rollback any uncommitted transaction | 140 | // Rollback any uncommitted transaction |
2991 | 129 | if (m_database.rollback()) { | 141 | if (m_database.rollback()) { |
2992 | 130 | qDebug() << "ERROR: There was a transaction in progress while closing the library scanner connection." | 142 | qDebug() << "ERROR: There was a transaction in progress while closing the library scanner connection." |
2994 | 131 | << "There is a logic error somewhere."; | 143 | << "There is a logic error somewhere."; |
2995 | 132 | } | 144 | } |
2996 | 133 | // Close our database connection | 145 | // Close our database connection |
2997 | 134 | m_database.close(); | 146 | m_database.close(); |
2998 | @@ -214,7 +226,7 @@ | |||
2999 | 214 | // verification of their existance... | 226 | // verification of their existance... |
3000 | 215 | // (ie. we want to check they're still on your hard drive where | 227 | // (ie. we want to check they're still on your hard drive where |
3001 | 216 | // we think they are) | 228 | // we think they are) |
3003 | 217 | m_trackDao.invalidateTrackLocationsInLibrary(m_qLibraryPath); | 229 | m_trackDao.invalidateTrackLocationsInLibrary(); |
3004 | 218 | 230 | ||
3005 | 219 | qDebug() << "Recursively scanning library."; | 231 | qDebug() << "Recursively scanning library."; |
3006 | 220 | // Start scanning the library. | 232 | // Start scanning the library. |
3007 | @@ -224,19 +236,26 @@ | |||
3008 | 224 | m_trackDao.addTracksPrepare(); | 236 | m_trackDao.addTracksPrepare(); |
3009 | 225 | QStringList verifiedDirectories; | 237 | QStringList verifiedDirectories; |
3010 | 226 | 238 | ||
3017 | 227 | bool bScanFinishedCleanly = recursiveScan(m_qLibraryPath, verifiedDirectories); | 239 | QStringList dirs = m_directoryDao.getDirs(); |
3018 | 228 | 240 | QSet<int> restoredTracks; | |
3019 | 229 | if (!bScanFinishedCleanly) { | 241 | bool bScanFinishedCleanly=false; |
3020 | 230 | qDebug() << "Recursive scan interrupted."; | 242 | //recursivly scan each dir that is saved in the directories table |
3021 | 231 | } else { | 243 | foreach (QString dir , dirs) { |
3022 | 232 | qDebug() << "Recursive scan finished cleanly."; | 244 | int dirId = m_directoryDao.getDirId(dir); |
3023 | 245 | bScanFinishedCleanly = recursiveScan(dir,verifiedDirectories,restoredTracks,dirId); | ||
3024 | 246 | //Verify all Tracks inside Library but outside the library path | ||
3025 | 247 | if (!bScanFinishedCleanly) { | ||
3026 | 248 | qDebug() << "Recursive scan interrupted."; | ||
3027 | 249 | } else { | ||
3028 | 250 | qDebug() << "Recursive scan finished cleanly."; | ||
3029 | 251 | } | ||
3030 | 233 | } | 252 | } |
3031 | 253 | m_trackDao.verifyTracksOutside(&m_bCancelLibraryScan); | ||
3032 | 234 | 254 | ||
3033 | 235 | // Runs inside a transaction | 255 | // Runs inside a transaction |
3034 | 236 | m_trackDao.addTracksFinish(); | 256 | m_trackDao.addTracksFinish(); |
3038 | 237 | 257 | // this will cause BaseTrackCache to update the index of all restored tracks | |
3039 | 238 | //Verify all Tracks inside Library but outside the library path | 258 | emit(tracksRestored(restoredTracks)); |
3037 | 239 | m_trackDao.verifyTracksOutside(m_qLibraryPath, &m_bCancelLibraryScan); | ||
3040 | 240 | 259 | ||
3041 | 241 | // Start a transaction for all the library hashing (moved file detection) | 260 | // Start a transaction for all the library hashing (moved file detection) |
3042 | 242 | // stuff. | 261 | // stuff. |
3043 | @@ -263,7 +282,7 @@ | |||
3044 | 263 | // Check to see if the "deleted" tracks showed up in another location, | 282 | // Check to see if the "deleted" tracks showed up in another location, |
3045 | 264 | // and if so, do some magic to update all our tables. | 283 | // and if so, do some magic to update all our tables. |
3046 | 265 | qDebug() << "Detecting moved files."; | 284 | qDebug() << "Detecting moved files."; |
3048 | 266 | m_trackDao.detectMovedFiles(&tracksMovedSetOld, &tracksMovedSetNew); | 285 | m_trackDao.detectMovedFiles(tracksMovedSetOld, tracksMovedSetNew); |
3049 | 267 | 286 | ||
3050 | 268 | // Remove the hashes for any directories that have been | 287 | // Remove the hashes for any directories that have been |
3051 | 269 | // marked as deleted to clean up. We need to do this otherwise | 288 | // marked as deleted to clean up. We need to do this otherwise |
3052 | @@ -289,10 +308,8 @@ | |||
3053 | 289 | emit(scanFinished()); | 308 | emit(scanFinished()); |
3054 | 290 | } | 309 | } |
3055 | 291 | 310 | ||
3060 | 292 | void LibraryScanner::scan(QString libraryPath, QWidget *parent) | 311 | void LibraryScanner::scan() { |
3061 | 293 | { | 312 | m_pProgress = new LibraryScannerDlg(); |
3058 | 294 | m_qLibraryPath = libraryPath; | ||
3059 | 295 | m_pProgress = new LibraryScannerDlg(parent); | ||
3062 | 296 | m_pProgress->setAttribute(Qt::WA_DeleteOnClose); | 313 | m_pProgress->setAttribute(Qt::WA_DeleteOnClose); |
3063 | 297 | 314 | ||
3064 | 298 | // The important part here is that we need to use | 315 | // The important part here is that we need to use |
3065 | @@ -314,7 +331,7 @@ | |||
3066 | 314 | this, SLOT(cancel())); | 331 | this, SLOT(cancel())); |
3067 | 315 | connect(&m_trackDao, SIGNAL(progressVerifyTracksOutside(QString)), | 332 | connect(&m_trackDao, SIGNAL(progressVerifyTracksOutside(QString)), |
3068 | 316 | m_pProgress, SLOT(slotUpdate(QString))); | 333 | m_pProgress, SLOT(slotUpdate(QString))); |
3070 | 317 | scan(); | 334 | start(); |
3071 | 318 | } | 335 | } |
3072 | 319 | 336 | ||
3073 | 320 | //slot | 337 | //slot |
3074 | @@ -328,15 +345,11 @@ | |||
3075 | 328 | m_bCancelLibraryScan = 0; | 345 | m_bCancelLibraryScan = 0; |
3076 | 329 | } | 346 | } |
3077 | 330 | 347 | ||
3078 | 331 | void LibraryScanner::scan() | ||
3079 | 332 | { | ||
3080 | 333 | start(); // Starts the thread by calling run() | ||
3081 | 334 | } | ||
3082 | 335 | |||
3083 | 336 | // Recursively scan a music library. Doesn't import tracks for any directories that | 348 | // Recursively scan a music library. Doesn't import tracks for any directories that |
3084 | 337 | // have already been scanned and have not changed. Changes are tracked by performing | 349 | // have already been scanned and have not changed. Changes are tracked by performing |
3085 | 338 | // a hash of the directory's file list, and those hashes are stored in the database. | 350 | // a hash of the directory's file list, and those hashes are stored in the database. |
3087 | 339 | bool LibraryScanner::recursiveScan(QString dirPath, QStringList& verifiedDirectories) { | 351 | bool LibraryScanner::recursiveScan(QString dirPath, QStringList& verifiedDirectories, |
3088 | 352 | QSet<int>& restoredTracks, const int dirId) { | ||
3089 | 340 | QDirIterator fileIt(dirPath, m_nameFilters, QDir::Files | QDir::NoDotAndDotDot); | 353 | QDirIterator fileIt(dirPath, m_nameFilters, QDir::Files | QDir::NoDotAndDotDot); |
3090 | 341 | QString currentFile; | 354 | QString currentFile; |
3091 | 342 | bool bScanFinishedCleanly = true; | 355 | bool bScanFinishedCleanly = true; |
3092 | @@ -376,7 +389,8 @@ | |||
3093 | 376 | } | 389 | } |
3094 | 377 | 390 | ||
3095 | 378 | // Rescan that mofo! | 391 | // Rescan that mofo! |
3097 | 379 | bScanFinishedCleanly = m_pCollection->importDirectory(dirPath, m_trackDao, m_nameFilters, &m_bCancelLibraryScan); | 392 | bScanFinishedCleanly = m_pCollection->importDirectory(dirPath, m_trackDao, m_nameFilters, |
3098 | 393 | restoredTracks,dirId,&m_bCancelLibraryScan); | ||
3099 | 380 | } else { //prevHash == newHash | 394 | } else { //prevHash == newHash |
3100 | 381 | // Add the directory to the verifiedDirectories list, so that later they | 395 | // Add the directory to the verifiedDirectories list, so that later they |
3101 | 382 | // (and the tracks inside them) will be marked as verified | 396 | // (and the tracks inside them) will be marked as verified |
3102 | @@ -401,7 +415,7 @@ | |||
3103 | 401 | if (m_directoriesBlacklist.contains(nextPath)) | 415 | if (m_directoriesBlacklist.contains(nextPath)) |
3104 | 402 | continue; | 416 | continue; |
3105 | 403 | 417 | ||
3107 | 404 | if (!recursiveScan(nextPath, verifiedDirectories)) { | 418 | if (!recursiveScan(nextPath, verifiedDirectories,restoredTracks,dirId)) { |
3108 | 405 | bScanFinishedCleanly = false; | 419 | bScanFinishedCleanly = false; |
3109 | 406 | } | 420 | } |
3110 | 407 | } | 421 | } |
3111 | 408 | 422 | ||
3112 | === modified file 'mixxx/src/library/libraryscanner.h' | |||
3113 | --- mixxx/src/library/libraryscanner.h 2012-12-06 17:11:14 +0000 | |||
3114 | +++ mixxx/src/library/libraryscanner.h 2013-05-18 16:32:26 +0000 | |||
3115 | @@ -16,7 +16,6 @@ | |||
3116 | 16 | * * | 16 | * * |
3117 | 17 | ***************************************************************************/ | 17 | ***************************************************************************/ |
3118 | 18 | 18 | ||
3119 | 19 | |||
3120 | 20 | #ifndef LIBRARYSCANNER_H | 19 | #ifndef LIBRARYSCANNER_H |
3121 | 21 | #define LIBRARYSCANNER_H | 20 | #define LIBRARYSCANNER_H |
3122 | 22 | 21 | ||
3123 | @@ -27,6 +26,7 @@ | |||
3124 | 27 | #include "library/dao/cratedao.h" | 26 | #include "library/dao/cratedao.h" |
3125 | 28 | #include "library/dao/cuedao.h" | 27 | #include "library/dao/cuedao.h" |
3126 | 29 | #include "library/dao/libraryhashdao.h" | 28 | #include "library/dao/libraryhashdao.h" |
3127 | 29 | #include "library/dao/directorydao.h" | ||
3128 | 30 | #include "library/dao/playlistdao.h" | 30 | #include "library/dao/playlistdao.h" |
3129 | 31 | #include "library/dao/trackdao.h" | 31 | #include "library/dao/trackdao.h" |
3130 | 32 | #include "library/dao/analysisdao.h" | 32 | #include "library/dao/analysisdao.h" |
3131 | @@ -46,18 +46,20 @@ | |||
3132 | 46 | void run(); | 46 | void run(); |
3133 | 47 | void scan(QString libraryPath, QWidget *parent); | 47 | void scan(QString libraryPath, QWidget *parent); |
3134 | 48 | void scan(); | 48 | void scan(); |
3136 | 49 | bool recursiveScan(QString dirPath, QStringList& verifiedDirectories); | 49 | |
3137 | 50 | public slots: | 50 | public slots: |
3138 | 51 | void cancel(); | 51 | void cancel(); |
3139 | 52 | void resetCancel(); | 52 | void resetCancel(); |
3140 | 53 | signals: | 53 | signals: |
3141 | 54 | void scanFinished(); | 54 | void scanFinished(); |
3142 | 55 | void progressHashing(QString); | 55 | void progressHashing(QString); |
3143 | 56 | void tracksRestored(QSet<int>); | ||
3144 | 56 | private: | 57 | private: |
3145 | 58 | bool recursiveScan(QString dirPath, QStringList& verifiedDirectories, | ||
3146 | 59 | QSet<int>& restoredTracks,const int dirId); | ||
3147 | 57 | TrackCollection* m_pCollection; // The library trackcollection | 60 | TrackCollection* m_pCollection; // The library trackcollection |
3148 | 58 | QSqlDatabase m_database; // Hang on to a different DB connection | 61 | QSqlDatabase m_database; // Hang on to a different DB connection |
3149 | 59 | // since we run in a different thread */ | 62 | // since we run in a different thread */ |
3150 | 60 | QString m_qLibraryPath; // The path to the library on disk | ||
3151 | 61 | LibraryScannerDlg* m_pProgress; // The library scanning window | 63 | LibraryScannerDlg* m_pProgress; // The library scanning window |
3152 | 62 | 64 | ||
3153 | 63 | LibraryHashDAO m_libraryHashDao; | 65 | LibraryHashDAO m_libraryHashDao; |
3154 | @@ -65,6 +67,7 @@ | |||
3155 | 65 | PlaylistDAO m_playlistDao; | 67 | PlaylistDAO m_playlistDao; |
3156 | 66 | CrateDAO m_crateDao; | 68 | CrateDAO m_crateDao; |
3157 | 67 | AnalysisDao m_analysisDao; | 69 | AnalysisDao m_analysisDao; |
3158 | 70 | DirectoryDAO m_directoryDao; | ||
3159 | 68 | TrackDAO m_trackDao; | 71 | TrackDAO m_trackDao; |
3160 | 69 | 72 | ||
3161 | 70 | QStringList m_nameFilters; | 73 | QStringList m_nameFilters; |
3162 | 71 | 74 | ||
3163 | === modified file 'mixxx/src/library/librarytablemodel.cpp' | |||
3164 | --- mixxx/src/library/librarytablemodel.cpp 2012-11-25 11:17:13 +0000 | |||
3165 | +++ mixxx/src/library/librarytablemodel.cpp 2013-05-18 16:32:26 +0000 | |||
3166 | @@ -1,33 +1,53 @@ | |||
3167 | 1 | #include <QtCore> | ||
3168 | 2 | #include <QtGui> | ||
3169 | 3 | #include <QtSql> | ||
3170 | 4 | 1 | ||
3171 | 5 | #include "library/trackcollection.h" | ||
3172 | 6 | #include "library/librarytablemodel.h" | 2 | #include "library/librarytablemodel.h" |
3173 | 7 | #include "library/queryutil.h" | 3 | #include "library/queryutil.h" |
3174 | 4 | #include "controlobjectthread.h" | ||
3175 | 5 | #include "controlobject.h" | ||
3176 | 8 | #include "mixxxutils.cpp" | 6 | #include "mixxxutils.cpp" |
3177 | 9 | #include "playermanager.h" | 7 | #include "playermanager.h" |
3178 | 10 | 8 | ||
3179 | 11 | const QString LibraryTableModel::DEFAULT_LIBRARYFILTER = | 9 | const QString LibraryTableModel::DEFAULT_LIBRARYFILTER = |
3181 | 12 | "mixxx_deleted=0 AND fs_deleted=0"; | 10 | "mixxx_deleted=0 AND fs_deleted=0"; |
3182 | 13 | 11 | ||
3183 | 14 | LibraryTableModel::LibraryTableModel(QObject* parent, | 12 | LibraryTableModel::LibraryTableModel(QObject* parent, |
3184 | 15 | TrackCollection* pTrackCollection, | 13 | TrackCollection* pTrackCollection, |
3185 | 14 | ConfigObject<ConfigValue>* pConfig, | ||
3186 | 16 | QString settingsNamespace) | 15 | QString settingsNamespace) |
3191 | 17 | : BaseSqlTableModel(parent, pTrackCollection, | 16 | : BaseSqlTableModel(parent, pTrackCollection, pConfig, settingsNamespace){ |
3192 | 18 | pTrackCollection->getDatabase(), | 17 | setTableModel(); |
3193 | 19 | settingsNamespace), | 18 | } |
3194 | 20 | m_trackDao(pTrackCollection->getTrackDAO()) { | 19 | |
3195 | 20 | LibraryTableModel::~LibraryTableModel() { | ||
3196 | 21 | } | ||
3197 | 22 | |||
3198 | 23 | void LibraryTableModel::setTableModel(int id){ | ||
3199 | 24 | Q_UNUSED(id); | ||
3200 | 21 | QStringList columns; | 25 | QStringList columns; |
3207 | 22 | columns << "library." + LIBRARYTABLE_ID; | 26 | columns << "library."+LIBRARYTABLE_ID << "'' as preview"; |
3208 | 23 | columns << "'' as preview"; | 27 | |
3209 | 24 | 28 | //prepareLibrary give a NULL to the constructor so check for it | |
3210 | 25 | QSqlQuery query(pTrackCollection->getDatabase()); | 29 | bool showMissing; |
3211 | 26 | QString queryString = "CREATE TEMPORARY VIEW IF NOT EXISTS library_view AS " | 30 | if (m_pConfig) { |
3212 | 27 | "SELECT " + columns.join(",") + | 31 | showMissing = m_pConfig->getValueString( |
3213 | 32 | ConfigKey("[Library]","ShowMissingSongs"),"1").toInt(); | ||
3214 | 33 | } else { | ||
3215 | 34 | showMissing = false; | ||
3216 | 35 | } | ||
3217 | 36 | QString tableName = "library_view"; | ||
3218 | 37 | QString libraryFilter; | ||
3219 | 38 | if (showMissing) { | ||
3220 | 39 | libraryFilter = "mixxx_deleted=0"; | ||
3221 | 40 | tableName.append("_missing"); | ||
3222 | 41 | } else { | ||
3223 | 42 | libraryFilter = "mixxx_deleted=0 AND fs_deleted=0"; | ||
3224 | 43 | } | ||
3225 | 44 | |||
3226 | 45 | QSqlQuery query(m_pTrackCollection->getDatabase()); | ||
3227 | 46 | QString queryString = "CREATE TEMPORARY VIEW IF NOT EXISTS "+tableName+" AS " | ||
3228 | 47 | "SELECT " + columns.join(", ") + | ||
3229 | 28 | " FROM library INNER JOIN track_locations " | 48 | " FROM library INNER JOIN track_locations " |
3230 | 29 | "ON library.location = track_locations.id " | 49 | "ON library.location = track_locations.id " |
3232 | 30 | "WHERE (" + LibraryTableModel::DEFAULT_LIBRARYFILTER + ")"; | 50 | "WHERE (" + libraryFilter + ")"; |
3233 | 31 | query.prepare(queryString); | 51 | query.prepare(queryString); |
3234 | 32 | if (!query.exec()) { | 52 | if (!query.exec()) { |
3235 | 33 | LOG_FAILED_QUERY(query); | 53 | LOG_FAILED_QUERY(query); |
3236 | @@ -36,36 +56,16 @@ | |||
3237 | 36 | QStringList tableColumns; | 56 | QStringList tableColumns; |
3238 | 37 | tableColumns << LIBRARYTABLE_ID; | 57 | tableColumns << LIBRARYTABLE_ID; |
3239 | 38 | tableColumns << "preview"; | 58 | tableColumns << "preview"; |
3242 | 39 | setTable("library_view", LIBRARYTABLE_ID, tableColumns, | 59 | setTable(tableName, LIBRARYTABLE_ID, tableColumns, |
3243 | 40 | pTrackCollection->getTrackSource("default")); | 60 | m_pTrackCollection->getTrackSource("default")); |
3244 | 41 | 61 | ||
3245 | 42 | // BaseSqlTabelModel will setup the header info | 62 | // BaseSqlTabelModel will setup the header info |
3246 | 43 | initHeaderData(); | 63 | initHeaderData(); |
3247 | 44 | 64 | ||
3248 | 45 | setSearch(""); | 65 | setSearch(""); |
3249 | 46 | setDefaultSort(fieldIndex("artist"), Qt::AscendingOrder); | 66 | setDefaultSort(fieldIndex("artist"), Qt::AscendingOrder); |
3272 | 47 | 67 | } | |
3273 | 48 | connect(this, SIGNAL(doSearch(const QString&)), | 68 | |
3252 | 49 | this, SLOT(slotSearch(const QString&))); | ||
3253 | 50 | } | ||
3254 | 51 | |||
3255 | 52 | LibraryTableModel::~LibraryTableModel() { | ||
3256 | 53 | } | ||
3257 | 54 | |||
3258 | 55 | bool LibraryTableModel::addTrack(const QModelIndex& index, QString location) { | ||
3259 | 56 | Q_UNUSED(index); | ||
3260 | 57 | QFileInfo fileInfo(location); | ||
3261 | 58 | |||
3262 | 59 | // Adds track, does not insert duplicates, handles unremoving logic. | ||
3263 | 60 | int trackId = m_trackDao.addTrack(fileInfo, true); | ||
3264 | 61 | if (trackId >= 0) { | ||
3265 | 62 | // TODO(rryan) do not select since we will get a signal. instead, do | ||
3266 | 63 | // something nice UI wise and select the track they dropped. | ||
3267 | 64 | select(); //Repopulate the data model. | ||
3268 | 65 | return true; | ||
3269 | 66 | } | ||
3270 | 67 | return false; | ||
3271 | 68 | } | ||
3274 | 69 | 69 | ||
3275 | 70 | int LibraryTableModel::addTracks(const QModelIndex& index, QList<QString> locations) { | 70 | int LibraryTableModel::addTracks(const QModelIndex& index, QList<QString> locations) { |
3276 | 71 | Q_UNUSED(index); | 71 | Q_UNUSED(index); |
3277 | @@ -73,35 +73,11 @@ | |||
3278 | 73 | foreach (QString fileLocation, locations) { | 73 | foreach (QString fileLocation, locations) { |
3279 | 74 | fileInfoList.append(QFileInfo(fileLocation)); | 74 | fileInfoList.append(QFileInfo(fileLocation)); |
3280 | 75 | } | 75 | } |
3282 | 76 | QList<int> trackIds = m_trackDao.addTracks(fileInfoList, true); | 76 | QList<int> trackIds = m_trackDAO.addTracks(fileInfoList, true); |
3283 | 77 | select(); | 77 | select(); |
3284 | 78 | return trackIds.size(); | 78 | return trackIds.size(); |
3285 | 79 | } | 79 | } |
3286 | 80 | 80 | ||
3287 | 81 | TrackPointer LibraryTableModel::getTrack(const QModelIndex& index) const { | ||
3288 | 82 | int trackId = getTrackId(index); | ||
3289 | 83 | return m_trackDao.getTrack(trackId); | ||
3290 | 84 | } | ||
3291 | 85 | |||
3292 | 86 | void LibraryTableModel::moveTrack(const QModelIndex& sourceIndex, | ||
3293 | 87 | const QModelIndex& destIndex) { | ||
3294 | 88 | Q_UNUSED(sourceIndex); | ||
3295 | 89 | Q_UNUSED(destIndex); | ||
3296 | 90 | // Does nothing because we don't support reordering tracks in the library, | ||
3297 | 91 | // and getCapabilities() reports that. | ||
3298 | 92 | } | ||
3299 | 93 | |||
3300 | 94 | void LibraryTableModel::search(const QString& searchText) { | ||
3301 | 95 | // qDebug() << "LibraryTableModel::search()" << searchText | ||
3302 | 96 | // << QThread::currentThread(); | ||
3303 | 97 | emit(doSearch(searchText)); | ||
3304 | 98 | } | ||
3305 | 99 | |||
3306 | 100 | void LibraryTableModel::slotSearch(const QString& searchText) { | ||
3307 | 101 | // qDebug() << "slotSearch()" << searchText << QThread::currentThread(); | ||
3308 | 102 | BaseSqlTableModel::search(searchText); | ||
3309 | 103 | } | ||
3310 | 104 | |||
3311 | 105 | bool LibraryTableModel::isColumnInternal(int column) { | 81 | bool LibraryTableModel::isColumnInternal(int column) { |
3312 | 106 | if ((column == fieldIndex(LIBRARYTABLE_ID)) || | 82 | if ((column == fieldIndex(LIBRARYTABLE_ID)) || |
3313 | 107 | (column == fieldIndex(LIBRARYTABLE_URL)) || | 83 | (column == fieldIndex(LIBRARYTABLE_URL)) || |
3314 | @@ -115,6 +91,7 @@ | |||
3315 | 115 | (column == fieldIndex(LIBRARYTABLE_BPM_LOCK)) || | 91 | (column == fieldIndex(LIBRARYTABLE_BPM_LOCK)) || |
3316 | 116 | (column == fieldIndex(LIBRARYTABLE_CHANNELS)) || | 92 | (column == fieldIndex(LIBRARYTABLE_CHANNELS)) || |
3317 | 117 | (column == fieldIndex(TRACKLOCATIONSTABLE_FSDELETED)) || | 93 | (column == fieldIndex(TRACKLOCATIONSTABLE_FSDELETED)) || |
3318 | 94 | (column == fieldIndex(TRACKLOCATIONSTABLE_MAINDIRID)) || | ||
3319 | 118 | (PlayerManager::numPreviewDecks() == 0 && column == fieldIndex("preview"))) { | 95 | (PlayerManager::numPreviewDecks() == 0 && column == fieldIndex("preview"))) { |
3320 | 119 | return true; | 96 | return true; |
3321 | 120 | } | 97 | } |
3322 | @@ -141,5 +118,6 @@ | |||
3323 | 141 | | TRACKMODELCAPS_HIDE | 118 | | TRACKMODELCAPS_HIDE |
3324 | 142 | | TRACKMODELCAPS_BPMLOCK | 119 | | TRACKMODELCAPS_BPMLOCK |
3325 | 143 | | TRACKMODELCAPS_CLEAR_BEATS | 120 | | TRACKMODELCAPS_CLEAR_BEATS |
3327 | 144 | | TRACKMODELCAPS_RESETPLAYED; | 121 | | TRACKMODELCAPS_RESETPLAYED |
3328 | 122 | | TRACKMODELCAPS_RELOCATE; | ||
3329 | 145 | } | 123 | } |
3330 | 146 | 124 | ||
3331 | === modified file 'mixxx/src/library/librarytablemodel.h' | |||
3332 | --- mixxx/src/library/librarytablemodel.h 2013-05-18 16:23:08 +0000 | |||
3333 | +++ mixxx/src/library/librarytablemodel.h 2013-05-18 16:32:26 +0000 | |||
3334 | @@ -1,43 +1,24 @@ | |||
3335 | 1 | #ifndef LIBRARYTABLEMODEL_H | 1 | #ifndef LIBRARYTABLEMODEL_H |
3336 | 2 | #define LIBRARYTABLEMODEL_H | 2 | #define LIBRARYTABLEMODEL_H |
3337 | 3 | 3 | ||
3338 | 4 | #include <QtSql> | ||
3339 | 5 | #include <QtCore> | ||
3340 | 6 | |||
3341 | 7 | #include "library/basesqltablemodel.h" | 4 | #include "library/basesqltablemodel.h" |
3342 | 8 | #include "library/trackmodel.h" | ||
3343 | 9 | #include "library/dao/trackdao.h" | ||
3344 | 10 | |||
3345 | 11 | class TrackCollection; | ||
3346 | 12 | 5 | ||
3347 | 13 | class LibraryTableModel : public BaseSqlTableModel { | 6 | class LibraryTableModel : public BaseSqlTableModel { |
3348 | 14 | Q_OBJECT | 7 | Q_OBJECT |
3349 | 15 | public: | 8 | public: |
3350 | 16 | LibraryTableModel(QObject* parent, TrackCollection* pTrackCollection, | 9 | LibraryTableModel(QObject* parent, TrackCollection* pTrackCollection, |
3351 | 10 | ConfigObject<ConfigValue>* pConfig, | ||
3352 | 17 | QString settingsNamespace="mixxx.db.model.library"); | 11 | QString settingsNamespace="mixxx.db.model.library"); |
3353 | 18 | virtual ~LibraryTableModel(); | 12 | virtual ~LibraryTableModel(); |
3354 | 13 | void setTableModel(int id =-1); | ||
3355 | 19 | 14 | ||
3356 | 20 | TrackPointer getTrack(const QModelIndex& index) const; | ||
3357 | 21 | void search(const QString& searchText); | ||
3358 | 22 | bool isColumnInternal(int column); | 15 | bool isColumnInternal(int column); |
3359 | 23 | bool isColumnHiddenByDefault(int column); | 16 | bool isColumnHiddenByDefault(int column); |
3360 | 24 | bool addTrack(const QModelIndex& index, QString location); | ||
3361 | 25 | // Takes a list of locations and add the tracks to the library. Returns the | 17 | // Takes a list of locations and add the tracks to the library. Returns the |
3362 | 26 | // number of successful additions. | 18 | // number of successful additions. |
3363 | 27 | int addTracks(const QModelIndex& index, QList<QString> locations); | 19 | int addTracks(const QModelIndex& index, QList<QString> locations); |
3364 | 28 | void moveTrack(const QModelIndex& sourceIndex, | ||
3365 | 29 | const QModelIndex& destIndex); | ||
3366 | 30 | TrackModel::CapabilitiesFlags getCapabilities() const; | 20 | TrackModel::CapabilitiesFlags getCapabilities() const; |
3367 | 31 | static const QString DEFAULT_LIBRARYFILTER; | 21 | static const QString DEFAULT_LIBRARYFILTER; |
3368 | 32 | |||
3369 | 33 | private: | ||
3370 | 34 | TrackDAO& m_trackDao; | ||
3371 | 35 | |||
3372 | 36 | private slots: | ||
3373 | 37 | void slotSearch(const QString& searchText); | ||
3374 | 38 | |||
3375 | 39 | signals: | ||
3376 | 40 | void doSearch(const QString& searchText); | ||
3377 | 41 | }; | 22 | }; |
3378 | 42 | 23 | ||
3379 | 43 | #endif | 24 | #endif |
3380 | 44 | 25 | ||
3381 | === added file 'mixxx/src/library/missingtablemodel.cpp' | |||
3382 | --- mixxx/src/library/missingtablemodel.cpp 1970-01-01 00:00:00 +0000 | |||
3383 | +++ mixxx/src/library/missingtablemodel.cpp 2013-05-18 16:32:26 +0000 | |||
3384 | @@ -0,0 +1,126 @@ | |||
3385 | 1 | #include <QtCore> | ||
3386 | 2 | #include <QtGui> | ||
3387 | 3 | #include <QtSql> | ||
3388 | 4 | #include "library/trackcollection.h" | ||
3389 | 5 | #include "library/missingtablemodel.h" | ||
3390 | 6 | #include "library/librarytablemodel.h" | ||
3391 | 7 | #include "mixxxutils.cpp" | ||
3392 | 8 | |||
3393 | 9 | const QString MissingTableModel::MISSINGFILTER = "mixxx_deleted=0 AND fs_deleted=1"; | ||
3394 | 10 | |||
3395 | 11 | MissingTableModel::MissingTableModel(QObject* parent, | ||
3396 | 12 | TrackCollection* pTrackCollection) | ||
3397 | 13 | : BaseSqlTableModel(parent, pTrackCollection, | ||
3398 | 14 | //TODO kain88 this is not quite right | ||
3399 | 15 | NULL, | ||
3400 | 16 | "mixxx.db.model.missing"), | ||
3401 | 17 | m_pTrackCollection(pTrackCollection), | ||
3402 | 18 | m_trackDao(m_pTrackCollection->getTrackDAO()) { | ||
3403 | 19 | |||
3404 | 20 | QSqlQuery query; | ||
3405 | 21 | //query.prepare("DROP VIEW " + playlistTableName); | ||
3406 | 22 | //query.exec(); | ||
3407 | 23 | QString tableName("missing_songs"); | ||
3408 | 24 | |||
3409 | 25 | QStringList columns; | ||
3410 | 26 | columns << "library." + LIBRARYTABLE_ID; | ||
3411 | 27 | |||
3412 | 28 | query.prepare("CREATE TEMPORARY VIEW IF NOT EXISTS " + tableName + " AS " | ||
3413 | 29 | "SELECT " | ||
3414 | 30 | + columns.join(",") + | ||
3415 | 31 | " FROM library " | ||
3416 | 32 | "INNER JOIN track_locations " | ||
3417 | 33 | "ON library.location=track_locations.id " | ||
3418 | 34 | "WHERE " + MissingTableModel::MISSINGFILTER); | ||
3419 | 35 | if (!query.exec()) { | ||
3420 | 36 | qDebug() << query.executedQuery() << query.lastError(); | ||
3421 | 37 | } | ||
3422 | 38 | |||
3423 | 39 | //Print out any SQL error, if there was one. | ||
3424 | 40 | if (query.lastError().isValid()) { | ||
3425 | 41 | qDebug() << __FILE__ << __LINE__ << query.lastError(); | ||
3426 | 42 | } | ||
3427 | 43 | |||
3428 | 44 | QStringList tableColumns; | ||
3429 | 45 | tableColumns << LIBRARYTABLE_ID; | ||
3430 | 46 | setTable(tableName, LIBRARYTABLE_ID, tableColumns, | ||
3431 | 47 | m_pTrackCollection->getTrackSource("default")); | ||
3432 | 48 | |||
3433 | 49 | initHeaderData(); | ||
3434 | 50 | setDefaultSort(fieldIndex("artist"), Qt::AscendingOrder); | ||
3435 | 51 | setSearch(""); | ||
3436 | 52 | |||
3437 | 53 | connect(this, SIGNAL(doSearch(const QString&)), | ||
3438 | 54 | this, SLOT(slotSearch(const QString&))); | ||
3439 | 55 | } | ||
3440 | 56 | |||
3441 | 57 | MissingTableModel::~MissingTableModel() { | ||
3442 | 58 | } | ||
3443 | 59 | |||
3444 | 60 | bool MissingTableModel::addTrack(const QModelIndex& index, QString location) { | ||
3445 | 61 | Q_UNUSED(index); | ||
3446 | 62 | Q_UNUSED(location); | ||
3447 | 63 | return false; | ||
3448 | 64 | } | ||
3449 | 65 | |||
3450 | 66 | TrackPointer MissingTableModel::getTrack(const QModelIndex& index) const { | ||
3451 | 67 | //FIXME: use position instead of location for playlist tracks? | ||
3452 | 68 | |||
3453 | 69 | //const int locationColumnIndex = this->fieldIndex(LIBRARYTABLE_LOCATION); | ||
3454 | 70 | //QString location = index.sibling(index.row(), locationColumnIndex).data().toString(); | ||
3455 | 71 | int trackId = getTrackId(index); | ||
3456 | 72 | return m_trackDao.getTrack(trackId); | ||
3457 | 73 | } | ||
3458 | 74 | |||
3459 | 75 | void MissingTableModel::purgeTracks(const QModelIndexList& indices) { | ||
3460 | 76 | QList<int> trackIds; | ||
3461 | 77 | |||
3462 | 78 | foreach (QModelIndex index, indices) { | ||
3463 | 79 | int trackId = getTrackId(index); | ||
3464 | 80 | trackIds.append(trackId); | ||
3465 | 81 | } | ||
3466 | 82 | |||
3467 | 83 | m_trackDao.purgeTracks(trackIds); | ||
3468 | 84 | |||
3469 | 85 | // TODO(rryan) : do not select, instead route event to BTC and notify from | ||
3470 | 86 | // there. | ||
3471 | 87 | select(); //Repopulate the data model. | ||
3472 | 88 | } | ||
3473 | 89 | |||
3474 | 90 | |||
3475 | 91 | void MissingTableModel::search(const QString& searchText) { | ||
3476 | 92 | // qDebug() << "MissingTableModel::search()" << searchText | ||
3477 | 93 | // << QThread::currentThread(); | ||
3478 | 94 | emit(doSearch(searchText)); | ||
3479 | 95 | } | ||
3480 | 96 | |||
3481 | 97 | void MissingTableModel::slotSearch(const QString& searchText) { | ||
3482 | 98 | BaseSqlTableModel::search(searchText); | ||
3483 | 99 | } | ||
3484 | 100 | |||
3485 | 101 | bool MissingTableModel::isColumnInternal(int column) { | ||
3486 | 102 | if (column == fieldIndex(LIBRARYTABLE_ID) || | ||
3487 | 103 | column == fieldIndex(LIBRARYTABLE_PLAYED) || | ||
3488 | 104 | column == fieldIndex(LIBRARYTABLE_BPM_LOCK) || | ||
3489 | 105 | column == fieldIndex(LIBRARYTABLE_MIXXXDELETED) || | ||
3490 | 106 | column == fieldIndex(TRACKLOCATIONSTABLE_FSDELETED)) { | ||
3491 | 107 | return true; | ||
3492 | 108 | } | ||
3493 | 109 | return false; | ||
3494 | 110 | } | ||
3495 | 111 | bool MissingTableModel::isColumnHiddenByDefault(int column) { | ||
3496 | 112 | if (column == fieldIndex(LIBRARYTABLE_KEY)) { | ||
3497 | 113 | return true; | ||
3498 | 114 | } | ||
3499 | 115 | return false; | ||
3500 | 116 | } | ||
3501 | 117 | |||
3502 | 118 | /** Override flags from BaseSqlModel since we don't want edit this model */ | ||
3503 | 119 | Qt::ItemFlags MissingTableModel::flags(const QModelIndex &index) const { | ||
3504 | 120 | return readOnlyFlags(index); | ||
3505 | 121 | } | ||
3506 | 122 | |||
3507 | 123 | TrackModel::CapabilitiesFlags MissingTableModel::getCapabilities() const { | ||
3508 | 124 | return TRACKMODELCAPS_NONE | ||
3509 | 125 | | TRACKMODELCAPS_PURGE; | ||
3510 | 126 | } | ||
3511 | 0 | 127 | ||
3512 | === removed file 'mixxx/src/library/missingtablemodel.cpp' | |||
3513 | --- mixxx/src/library/missingtablemodel.cpp 2013-05-01 02:15:05 +0000 | |||
3514 | +++ mixxx/src/library/missingtablemodel.cpp 1970-01-01 00:00:00 +0000 | |||
3515 | @@ -1,125 +0,0 @@ | |||
3516 | 1 | #include <QtCore> | ||
3517 | 2 | #include <QtGui> | ||
3518 | 3 | #include <QtSql> | ||
3519 | 4 | #include "library/trackcollection.h" | ||
3520 | 5 | #include "library/missingtablemodel.h" | ||
3521 | 6 | #include "library/librarytablemodel.h" | ||
3522 | 7 | #include "mixxxutils.cpp" | ||
3523 | 8 | |||
3524 | 9 | const QString MissingTableModel::MISSINGFILTER = "mixxx_deleted=0 AND fs_deleted=1"; | ||
3525 | 10 | |||
3526 | 11 | MissingTableModel::MissingTableModel(QObject* parent, | ||
3527 | 12 | TrackCollection* pTrackCollection) | ||
3528 | 13 | : BaseSqlTableModel(parent, pTrackCollection, | ||
3529 | 14 | pTrackCollection->getDatabase(), | ||
3530 | 15 | "mixxx.db.model.missing"), | ||
3531 | 16 | m_pTrackCollection(pTrackCollection), | ||
3532 | 17 | m_trackDao(m_pTrackCollection->getTrackDAO()) { | ||
3533 | 18 | |||
3534 | 19 | QSqlQuery query(pTrackCollection->getDatabase()); | ||
3535 | 20 | //query.prepare("DROP VIEW " + playlistTableName); | ||
3536 | 21 | //query.exec(); | ||
3537 | 22 | QString tableName("missing_songs"); | ||
3538 | 23 | |||
3539 | 24 | QStringList columns; | ||
3540 | 25 | columns << "library." + LIBRARYTABLE_ID; | ||
3541 | 26 | |||
3542 | 27 | query.prepare("CREATE TEMPORARY VIEW IF NOT EXISTS " + tableName + " AS " | ||
3543 | 28 | "SELECT " | ||
3544 | 29 | + columns.join(",") + | ||
3545 | 30 | " FROM library " | ||
3546 | 31 | "INNER JOIN track_locations " | ||
3547 | 32 | "ON library.location=track_locations.id " | ||
3548 | 33 | "WHERE " + MissingTableModel::MISSINGFILTER); | ||
3549 | 34 | if (!query.exec()) { | ||
3550 | 35 | qDebug() << query.executedQuery() << query.lastError(); | ||
3551 | 36 | } | ||
3552 | 37 | |||
3553 | 38 | //Print out any SQL error, if there was one. | ||
3554 | 39 | if (query.lastError().isValid()) { | ||
3555 | 40 | qDebug() << __FILE__ << __LINE__ << query.lastError(); | ||
3556 | 41 | } | ||
3557 | 42 | |||
3558 | 43 | QStringList tableColumns; | ||
3559 | 44 | tableColumns << LIBRARYTABLE_ID; | ||
3560 | 45 | setTable(tableName, LIBRARYTABLE_ID, tableColumns, | ||
3561 | 46 | m_pTrackCollection->getTrackSource("default")); | ||
3562 | 47 | |||
3563 | 48 | initHeaderData(); | ||
3564 | 49 | setDefaultSort(fieldIndex("artist"), Qt::AscendingOrder); | ||
3565 | 50 | setSearch(""); | ||
3566 | 51 | |||
3567 | 52 | connect(this, SIGNAL(doSearch(const QString&)), | ||
3568 | 53 | this, SLOT(slotSearch(const QString&))); | ||
3569 | 54 | } | ||
3570 | 55 | |||
3571 | 56 | MissingTableModel::~MissingTableModel() { | ||
3572 | 57 | } | ||
3573 | 58 | |||
3574 | 59 | bool MissingTableModel::addTrack(const QModelIndex& index, QString location) { | ||
3575 | 60 | Q_UNUSED(index); | ||
3576 | 61 | Q_UNUSED(location); | ||
3577 | 62 | return false; | ||
3578 | 63 | } | ||
3579 | 64 | |||
3580 | 65 | TrackPointer MissingTableModel::getTrack(const QModelIndex& index) const { | ||
3581 | 66 | //FIXME: use position instead of location for playlist tracks? | ||
3582 | 67 | |||
3583 | 68 | //const int locationColumnIndex = this->fieldIndex(LIBRARYTABLE_LOCATION); | ||
3584 | 69 | //QString location = index.sibling(index.row(), locationColumnIndex).data().toString(); | ||
3585 | 70 | int trackId = getTrackId(index); | ||
3586 | 71 | return m_trackDao.getTrack(trackId); | ||
3587 | 72 | } | ||
3588 | 73 | |||
3589 | 74 | void MissingTableModel::purgeTracks(const QModelIndexList& indices) { | ||
3590 | 75 | QList<int> trackIds; | ||
3591 | 76 | |||
3592 | 77 | foreach (QModelIndex index, indices) { | ||
3593 | 78 | int trackId = getTrackId(index); | ||
3594 | 79 | trackIds.append(trackId); | ||
3595 | 80 | } | ||
3596 | 81 | |||
3597 | 82 | m_trackDao.purgeTracks(trackIds); | ||
3598 | 83 | |||
3599 | 84 | // TODO(rryan) : do not select, instead route event to BTC and notify from | ||
3600 | 85 | // there. | ||
3601 | 86 | select(); //Repopulate the data model. | ||
3602 | 87 | } | ||
3603 | 88 | |||
3604 | 89 | |||
3605 | 90 | void MissingTableModel::search(const QString& searchText) { | ||
3606 | 91 | // qDebug() << "MissingTableModel::search()" << searchText | ||
3607 | 92 | // << QThread::currentThread(); | ||
3608 | 93 | emit(doSearch(searchText)); | ||
3609 | 94 | } | ||
3610 | 95 | |||
3611 | 96 | void MissingTableModel::slotSearch(const QString& searchText) { | ||
3612 | 97 | BaseSqlTableModel::search(searchText); | ||
3613 | 98 | } | ||
3614 | 99 | |||
3615 | 100 | bool MissingTableModel::isColumnInternal(int column) { | ||
3616 | 101 | if (column == fieldIndex(LIBRARYTABLE_ID) || | ||
3617 | 102 | column == fieldIndex(LIBRARYTABLE_PLAYED) || | ||
3618 | 103 | column == fieldIndex(LIBRARYTABLE_BPM_LOCK) || | ||
3619 | 104 | column == fieldIndex(LIBRARYTABLE_MIXXXDELETED) || | ||
3620 | 105 | column == fieldIndex(TRACKLOCATIONSTABLE_FSDELETED)) { | ||
3621 | 106 | return true; | ||
3622 | 107 | } | ||
3623 | 108 | return false; | ||
3624 | 109 | } | ||
3625 | 110 | bool MissingTableModel::isColumnHiddenByDefault(int column) { | ||
3626 | 111 | if (column == fieldIndex(LIBRARYTABLE_KEY)) { | ||
3627 | 112 | return true; | ||
3628 | 113 | } | ||
3629 | 114 | return false; | ||
3630 | 115 | } | ||
3631 | 116 | |||
3632 | 117 | /** Override flags from BaseSqlModel since we don't want edit this model */ | ||
3633 | 118 | Qt::ItemFlags MissingTableModel::flags(const QModelIndex &index) const { | ||
3634 | 119 | return readOnlyFlags(index); | ||
3635 | 120 | } | ||
3636 | 121 | |||
3637 | 122 | TrackModel::CapabilitiesFlags MissingTableModel::getCapabilities() const { | ||
3638 | 123 | return TRACKMODELCAPS_NONE | ||
3639 | 124 | | TRACKMODELCAPS_PURGE; | ||
3640 | 125 | } | ||
3641 | 126 | 0 | ||
3642 | === added file 'mixxx/src/library/missingtablemodel.h' | |||
3643 | --- mixxx/src/library/missingtablemodel.h 1970-01-01 00:00:00 +0000 | |||
3644 | +++ mixxx/src/library/missingtablemodel.h 2013-05-18 16:32:26 +0000 | |||
3645 | @@ -0,0 +1,41 @@ | |||
3646 | 1 | #ifndef MISSINGTABLEMODEL_H | ||
3647 | 2 | #define MISSINGTABLEMODEL_H | ||
3648 | 3 | |||
3649 | 4 | #include <QtSql> | ||
3650 | 5 | #include <QItemDelegate> | ||
3651 | 6 | #include <QtCore> | ||
3652 | 7 | |||
3653 | 8 | #include "trackmodel.h" | ||
3654 | 9 | #include "library/dao/trackdao.h" | ||
3655 | 10 | #include "library/basesqltablemodel.h" | ||
3656 | 11 | |||
3657 | 12 | class TrackCollection; | ||
3658 | 13 | |||
3659 | 14 | class MissingTableModel : public BaseSqlTableModel { | ||
3660 | 15 | Q_OBJECT | ||
3661 | 16 | public: | ||
3662 | 17 | MissingTableModel(QObject* parent, TrackCollection* pTrackCollection); | ||
3663 | 18 | virtual ~MissingTableModel(); | ||
3664 | 19 | virtual TrackPointer getTrack(const QModelIndex& index) const; | ||
3665 | 20 | virtual void search(const QString& searchText); | ||
3666 | 21 | virtual bool isColumnInternal(int column); | ||
3667 | 22 | virtual bool isColumnHiddenByDefault(int column); | ||
3668 | 23 | virtual void purgeTracks(const QModelIndexList& indices); | ||
3669 | 24 | virtual bool addTrack(const QModelIndex& index, QString location); | ||
3670 | 25 | |||
3671 | 26 | Qt::ItemFlags flags(const QModelIndex &index) const; | ||
3672 | 27 | TrackModel::CapabilitiesFlags getCapabilities() const; | ||
3673 | 28 | |||
3674 | 29 | private slots: | ||
3675 | 30 | void slotSearch(const QString& searchText); | ||
3676 | 31 | |||
3677 | 32 | signals: | ||
3678 | 33 | void doSearch(const QString& searchText); | ||
3679 | 34 | |||
3680 | 35 | private: | ||
3681 | 36 | TrackCollection* m_pTrackCollection; | ||
3682 | 37 | TrackDAO& m_trackDao; | ||
3683 | 38 | static const QString MISSINGFILTER; | ||
3684 | 39 | }; | ||
3685 | 40 | |||
3686 | 41 | #endif | ||
3687 | 0 | 42 | ||
3688 | === removed file 'mixxx/src/library/missingtablemodel.h' | |||
3689 | --- mixxx/src/library/missingtablemodel.h 2012-08-10 15:03:46 +0000 | |||
3690 | +++ mixxx/src/library/missingtablemodel.h 1970-01-01 00:00:00 +0000 | |||
3691 | @@ -1,41 +0,0 @@ | |||
3692 | 1 | #ifndef MISSINGTABLEMODEL_H | ||
3693 | 2 | #define MISSINGTABLEMODEL_H | ||
3694 | 3 | |||
3695 | 4 | #include <QtSql> | ||
3696 | 5 | #include <QItemDelegate> | ||
3697 | 6 | #include <QtCore> | ||
3698 | 7 | |||
3699 | 8 | #include "trackmodel.h" | ||
3700 | 9 | #include "library/dao/trackdao.h" | ||
3701 | 10 | #include "library/basesqltablemodel.h" | ||
3702 | 11 | |||
3703 | 12 | class TrackCollection; | ||
3704 | 13 | |||
3705 | 14 | class MissingTableModel : public BaseSqlTableModel { | ||
3706 | 15 | Q_OBJECT | ||
3707 | 16 | public: | ||
3708 | 17 | MissingTableModel(QObject* parent, TrackCollection* pTrackCollection); | ||
3709 | 18 | virtual ~MissingTableModel(); | ||
3710 | 19 | virtual TrackPointer getTrack(const QModelIndex& index) const; | ||
3711 | 20 | virtual void search(const QString& searchText); | ||
3712 | 21 | virtual bool isColumnInternal(int column); | ||
3713 | 22 | virtual bool isColumnHiddenByDefault(int column); | ||
3714 | 23 | virtual void purgeTracks(const QModelIndexList& indices); | ||
3715 | 24 | virtual bool addTrack(const QModelIndex& index, QString location); | ||
3716 | 25 | |||
3717 | 26 | Qt::ItemFlags flags(const QModelIndex &index) const; | ||
3718 | 27 | TrackModel::CapabilitiesFlags getCapabilities() const; | ||
3719 | 28 | |||
3720 | 29 | private slots: | ||
3721 | 30 | void slotSearch(const QString& searchText); | ||
3722 | 31 | |||
3723 | 32 | signals: | ||
3724 | 33 | void doSearch(const QString& searchText); | ||
3725 | 34 | |||
3726 | 35 | private: | ||
3727 | 36 | TrackCollection* m_pTrackCollection; | ||
3728 | 37 | TrackDAO& m_trackDao; | ||
3729 | 38 | static const QString MISSINGFILTER; | ||
3730 | 39 | }; | ||
3731 | 40 | |||
3732 | 41 | #endif | ||
3733 | 42 | 0 | ||
3734 | === modified file 'mixxx/src/library/mixxxlibraryfeature.cpp' | |||
3735 | --- mixxx/src/library/mixxxlibraryfeature.cpp 2013-01-17 08:16:08 +0000 | |||
3736 | +++ mixxx/src/library/mixxxlibraryfeature.cpp 2013-05-18 16:32:26 +0000 | |||
3737 | @@ -1,13 +1,10 @@ | |||
3738 | 1 | // mixxxlibraryfeature.cpp | 1 | // mixxxlibraryfeature.cpp |
3739 | 2 | // Created 8/23/2009 by RJ Ryan (rryan@mit.edu) | 2 | // Created 8/23/2009 by RJ Ryan (rryan@mit.edu) |
3740 | 3 | 3 | ||
3741 | 4 | #include <QtDebug> | ||
3742 | 5 | |||
3743 | 6 | #include "library/mixxxlibraryfeature.h" | 4 | #include "library/mixxxlibraryfeature.h" |
3744 | 7 | 5 | ||
3745 | 8 | #include "library/basetrackcache.h" | 6 | #include "library/basetrackcache.h" |
3746 | 9 | #include "library/librarytablemodel.h" | 7 | #include "library/librarytablemodel.h" |
3747 | 10 | #include "library/missingtablemodel.h" | ||
3748 | 11 | #include "library/hiddentablemodel.h" | 8 | #include "library/hiddentablemodel.h" |
3749 | 12 | #include "library/queryutil.h" | 9 | #include "library/queryutil.h" |
3750 | 13 | #include "library/trackcollection.h" | 10 | #include "library/trackcollection.h" |
3751 | @@ -88,11 +85,14 @@ | |||
3752 | 88 | connect(&m_trackDao, SIGNAL(dbTrackAdded(TrackPointer)), | 85 | connect(&m_trackDao, SIGNAL(dbTrackAdded(TrackPointer)), |
3753 | 89 | pBaseTrackCache, SLOT(slotDbTrackAdded(TrackPointer))); | 86 | pBaseTrackCache, SLOT(slotDbTrackAdded(TrackPointer))); |
3754 | 90 | 87 | ||
3755 | 88 | |||
3756 | 91 | m_pBaseTrackCache = QSharedPointer<BaseTrackCache>(pBaseTrackCache); | 89 | m_pBaseTrackCache = QSharedPointer<BaseTrackCache>(pBaseTrackCache); |
3757 | 92 | pTrackCollection->addTrackSource(QString("default"), m_pBaseTrackCache); | 90 | pTrackCollection->addTrackSource(QString("default"), m_pBaseTrackCache); |
3758 | 93 | 91 | ||
3759 | 94 | // These rely on the 'default' track source being present. | 92 | // These rely on the 'default' track source being present. |
3761 | 95 | m_pLibraryTableModel = new LibraryTableModel(this, pTrackCollection); | 93 | m_pLibraryTableModel = new LibraryTableModel(this, pTrackCollection,pConfig); |
3762 | 94 | connect(this,SIGNAL(configChanged(QString,QString)), | ||
3763 | 95 | m_pLibraryTableModel, SLOT(slotConfigChanged(QString, QString))); | ||
3764 | 96 | 96 | ||
3765 | 97 | TreeItem* pRootItem = new TreeItem(); | 97 | TreeItem* pRootItem = new TreeItem(); |
3766 | 98 | TreeItem* pmissingChildItem = new TreeItem(kMissingTitle, kMissingTitle, | 98 | TreeItem* pmissingChildItem = new TreeItem(kMissingTitle, kMissingTitle, |
3767 | 99 | 99 | ||
3768 | === modified file 'mixxx/src/library/mixxxlibraryfeature.h' | |||
3769 | --- mixxx/src/library/mixxxlibraryfeature.h 2013-01-17 08:16:08 +0000 | |||
3770 | +++ mixxx/src/library/mixxxlibraryfeature.h 2013-05-18 16:32:26 +0000 | |||
3771 | @@ -7,6 +7,7 @@ | |||
3772 | 7 | #include <QStringListModel> | 7 | #include <QStringListModel> |
3773 | 8 | 8 | ||
3774 | 9 | #include "library/libraryfeature.h" | 9 | #include "library/libraryfeature.h" |
3775 | 10 | #include "configobject.h" | ||
3776 | 10 | #include "library/dao/trackdao.h" | 11 | #include "library/dao/trackdao.h" |
3777 | 11 | #include "treeitemmodel.h" | 12 | #include "treeitemmodel.h" |
3778 | 12 | #include "configobject.h" | 13 | #include "configobject.h" |
3779 | @@ -34,12 +35,16 @@ | |||
3780 | 34 | void bindWidget(WLibrary* pLibrary, | 35 | void bindWidget(WLibrary* pLibrary, |
3781 | 35 | MixxxKeyboard* pKeyboard); | 36 | MixxxKeyboard* pKeyboard); |
3782 | 36 | 37 | ||
3783 | 38 | signals: | ||
3784 | 39 | void configChanged(QString, QString); | ||
3785 | 40 | |||
3786 | 37 | public slots: | 41 | public slots: |
3787 | 38 | void activate(); | 42 | void activate(); |
3788 | 39 | void activateChild(const QModelIndex& index); | 43 | void activateChild(const QModelIndex& index); |
3789 | 40 | void refreshLibraryModels(); | 44 | void refreshLibraryModels(); |
3790 | 41 | 45 | ||
3791 | 42 | private: | 46 | private: |
3792 | 47 | TrackCollection* m_pTrackCollection; | ||
3793 | 43 | const QString kMissingTitle; | 48 | const QString kMissingTitle; |
3794 | 44 | const QString kHiddenTitle; | 49 | const QString kHiddenTitle; |
3795 | 45 | QSharedPointer<BaseTrackCache> m_pBaseTrackCache; | 50 | QSharedPointer<BaseTrackCache> m_pBaseTrackCache; |
3796 | @@ -49,7 +54,6 @@ | |||
3797 | 49 | TreeItemModel m_childModel; | 54 | TreeItemModel m_childModel; |
3798 | 50 | TrackDAO& m_trackDao; | 55 | TrackDAO& m_trackDao; |
3799 | 51 | ConfigObject<ConfigValue>* m_pConfig; | 56 | ConfigObject<ConfigValue>* m_pConfig; |
3800 | 52 | TrackCollection* m_pTrackCollection; | ||
3801 | 53 | }; | 57 | }; |
3802 | 54 | 58 | ||
3803 | 55 | #endif /* MIXXXLIBRARYFEATURE_H */ | 59 | #endif /* MIXXXLIBRARYFEATURE_H */ |
3804 | 56 | 60 | ||
3805 | === modified file 'mixxx/src/library/playlistfeature.cpp' | |||
3806 | --- mixxx/src/library/playlistfeature.cpp 2013-05-12 22:17:32 +0000 | |||
3807 | +++ mixxx/src/library/playlistfeature.cpp 2013-05-18 16:32:26 +0000 | |||
3808 | @@ -22,11 +22,12 @@ | |||
3809 | 22 | PlaylistFeature::PlaylistFeature(QObject* parent, | 22 | PlaylistFeature::PlaylistFeature(QObject* parent, |
3810 | 23 | TrackCollection* pTrackCollection, | 23 | TrackCollection* pTrackCollection, |
3811 | 24 | ConfigObject<ConfigValue>* pConfig) | 24 | ConfigObject<ConfigValue>* pConfig) |
3814 | 25 | : BasePlaylistFeature(parent, pConfig, pTrackCollection, | 25 | : BasePlaylistFeature(parent, pConfig, pTrackCollection,"PLAYLISTHOME") { |
3813 | 26 | "PLAYLISTHOME") { | ||
3815 | 27 | m_pPlaylistTableModel = new PlaylistTableModel(this, pTrackCollection, | 26 | m_pPlaylistTableModel = new PlaylistTableModel(this, pTrackCollection, |
3818 | 28 | "mixxx.db.model.playlist"); | 27 | "mixxx.db.model.playlist", |
3819 | 29 | 28 | pConfig); | |
3820 | 29 | connect(this, SIGNAL(configChanged(QString,QString)), | ||
3821 | 30 | m_pPlaylistTableModel, SLOT(slotConfigChanged(QString,QString))); | ||
3822 | 30 | //construct child model | 31 | //construct child model |
3823 | 31 | TreeItem *rootItem = new TreeItem(); | 32 | TreeItem *rootItem = new TreeItem(); |
3824 | 32 | m_childModel.setRootItem(rootItem); | 33 | m_childModel.setRootItem(rootItem); |
3825 | @@ -179,7 +180,7 @@ | |||
3826 | 179 | 180 | ||
3827 | 180 | if (type != PlaylistDAO::PLHT_UNKNOWN) { | 181 | if (type != PlaylistDAO::PLHT_UNKNOWN) { |
3828 | 181 | // Switch the view to the playlist. | 182 | // Switch the view to the playlist. |
3830 | 182 | m_pPlaylistTableModel->setPlaylist(playlistId); | 183 | m_pPlaylistTableModel->setTableModel(playlistId); |
3831 | 183 | // Update selection | 184 | // Update selection |
3832 | 184 | emit(featureSelect(this, m_lastRightClickedIndex)); | 185 | emit(featureSelect(this, m_lastRightClickedIndex)); |
3833 | 185 | } | 186 | } |
3834 | 186 | 187 | ||
3835 | === modified file 'mixxx/src/library/playlistfeature.h' | |||
3836 | --- mixxx/src/library/playlistfeature.h 2013-05-18 16:23:08 +0000 | |||
3837 | +++ mixxx/src/library/playlistfeature.h 2013-05-18 16:32:26 +0000 | |||
3838 | @@ -15,7 +15,8 @@ | |||
3839 | 15 | class PlaylistFeature : public BasePlaylistFeature { | 15 | class PlaylistFeature : public BasePlaylistFeature { |
3840 | 16 | Q_OBJECT | 16 | Q_OBJECT |
3841 | 17 | public: | 17 | public: |
3843 | 18 | PlaylistFeature(QObject* parent, TrackCollection* pTrackCollection, | 18 | PlaylistFeature(QObject* parent, |
3844 | 19 | TrackCollection* pTrackCollection, | ||
3845 | 19 | ConfigObject<ConfigValue>* pConfig); | 20 | ConfigObject<ConfigValue>* pConfig); |
3846 | 20 | virtual ~PlaylistFeature(); | 21 | virtual ~PlaylistFeature(); |
3847 | 21 | 22 | ||
3848 | @@ -25,6 +26,9 @@ | |||
3849 | 25 | bool dropAcceptChild(const QModelIndex& index, QList<QUrl> urls, QWidget *pSource); | 26 | bool dropAcceptChild(const QModelIndex& index, QList<QUrl> urls, QWidget *pSource); |
3850 | 26 | bool dragMoveAcceptChild(const QModelIndex& index, QUrl url); | 27 | bool dragMoveAcceptChild(const QModelIndex& index, QUrl url); |
3851 | 27 | 28 | ||
3852 | 29 | signals: | ||
3853 | 30 | void configChanged(QString,QString); | ||
3854 | 31 | |||
3855 | 28 | public slots: | 32 | public slots: |
3856 | 29 | void onRightClick(const QPoint& globalPos); | 33 | void onRightClick(const QPoint& globalPos); |
3857 | 30 | void onRightClickChild(const QPoint& globalPos, QModelIndex index); | 34 | void onRightClickChild(const QPoint& globalPos, QModelIndex index); |
3858 | 31 | 35 | ||
3859 | === modified file 'mixxx/src/library/playlisttablemodel.cpp' | |||
3860 | --- mixxx/src/library/playlisttablemodel.cpp 2013-05-12 22:17:32 +0000 | |||
3861 | +++ mixxx/src/library/playlisttablemodel.cpp 2013-05-18 16:32:26 +0000 | |||
3862 | @@ -1,50 +1,56 @@ | |||
3863 | 1 | #include <QtCore> | ||
3864 | 2 | #include <QtGui> | ||
3865 | 3 | #include <QtSql> | ||
3866 | 4 | #include <QDateTime> | ||
3867 | 5 | #include "library/trackcollection.h" | ||
3868 | 6 | #include "library/playlisttablemodel.h" | 1 | #include "library/playlisttablemodel.h" |
3869 | 7 | #include "library/queryutil.h" | 2 | #include "library/queryutil.h" |
3870 | 8 | #include "mixxxutils.cpp" | 3 | #include "mixxxutils.cpp" |
3871 | 9 | #include "playermanager.h" | 4 | #include "playermanager.h" |
3872 | 10 | 5 | ||
3873 | 11 | PlaylistTableModel::PlaylistTableModel(QObject* parent, | 6 | PlaylistTableModel::PlaylistTableModel(QObject* parent, |
3887 | 12 | TrackCollection* pTrackCollection, | 7 | TrackCollection* pTrackCollection, |
3888 | 13 | QString settingsNamespace, | 8 | QString settingsNamespace, |
3889 | 14 | bool showAll) | 9 | ConfigObject<ConfigValue>* pConfig, |
3890 | 15 | : BaseSqlTableModel(parent, pTrackCollection, | 10 | bool showAll) |
3891 | 16 | pTrackCollection->getDatabase(), | 11 | : BaseSqlTableModel(parent, pTrackCollection, pConfig, settingsNamespace), |
3892 | 17 | settingsNamespace), | 12 | m_playlistDao(m_pTrackCollection->getPlaylistDAO()), |
3893 | 18 | m_pTrackCollection(pTrackCollection), | 13 | m_iPlaylistId(-1), |
3894 | 19 | m_playlistDao(m_pTrackCollection->getPlaylistDAO()), | 14 | m_showAll(showAll) { |
3882 | 20 | m_trackDao(m_pTrackCollection->getTrackDAO()), | ||
3883 | 21 | m_iPlaylistId(-1) { | ||
3884 | 22 | connect(this, SIGNAL(doSearch(const QString&)), | ||
3885 | 23 | this, SLOT(slotSearch(const QString&))); | ||
3886 | 24 | m_showAll = showAll; | ||
3895 | 25 | } | 15 | } |
3896 | 26 | 16 | ||
3897 | 27 | PlaylistTableModel::~PlaylistTableModel() { | 17 | PlaylistTableModel::~PlaylistTableModel() { |
3898 | 28 | } | 18 | } |
3899 | 29 | 19 | ||
3901 | 30 | void PlaylistTableModel::setPlaylist(int playlistId) { | 20 | void PlaylistTableModel::setTableModel(int playlistId) { |
3902 | 31 | //qDebug() << "PlaylistTableModel::setPlaylist" << playlistId; | 21 | //qDebug() << "PlaylistTableModel::setPlaylist" << playlistId; |
3903 | 32 | 22 | ||
3905 | 33 | if (m_iPlaylistId == playlistId) { | 23 | if (playlistId == m_iPlaylistId) { |
3906 | 34 | qDebug() << "Already focused on playlist " << playlistId; | 24 | qDebug() << "Already focused on playlist " << playlistId; |
3907 | 35 | return; | 25 | return; |
3908 | 26 | } else if (playlistId == -1) { | ||
3909 | 27 | // calls from parent class use -1 as id then just set the current playlist | ||
3910 | 28 | playlistId = m_iPlaylistId; | ||
3911 | 36 | } | 29 | } |
3912 | 37 | 30 | ||
3913 | 38 | m_iPlaylistId = playlistId; | 31 | m_iPlaylistId = playlistId; |
3915 | 39 | QString playlistTableName = "playlist_" + QString::number(m_iPlaylistId); | 32 | QString playlistTableName = "playlist_" + QString::number(m_iPlaylistId)+"_"; |
3916 | 33 | |||
3917 | 40 | QSqlQuery query(m_pTrackCollection->getDatabase()); | 34 | QSqlQuery query(m_pTrackCollection->getDatabase()); |
3918 | 41 | FieldEscaper escaper(m_pTrackCollection->getDatabase()); | 35 | FieldEscaper escaper(m_pTrackCollection->getDatabase()); |
3919 | 42 | 36 | ||
3920 | 43 | QStringList columns; | 37 | QStringList columns; |
3925 | 44 | columns << PLAYLISTTRACKSTABLE_TRACKID + " as " + LIBRARYTABLE_ID | 38 | QStringList tableColumns; |
3926 | 45 | << PLAYLISTTRACKSTABLE_POSITION | 39 | QString filter; |
3927 | 46 | << PLAYLISTTRACKSTABLE_DATETIMEADDED | 40 | columns << "PlaylistTracks."+PLAYLISTTRACKSTABLE_TRACKID + " as " + LIBRARYTABLE_ID |
3928 | 47 | << "'' as preview"; | 41 | << "PlaylistTracks."+PLAYLISTTRACKSTABLE_POSITION |
3929 | 42 | << "PlaylistTracks."+PLAYLISTTRACKSTABLE_DATETIMEADDED | ||
3930 | 43 | << "'' as preview"; | ||
3931 | 44 | tableColumns << PLAYLISTTRACKSTABLE_TRACKID | ||
3932 | 45 | << PLAYLISTTRACKSTABLE_POSITION | ||
3933 | 46 | << PLAYLISTTRACKSTABLE_DATETIMEADDED; | ||
3934 | 47 | bool showMissing = m_pConfig->getValueString(ConfigKey("[Library]","ShowMissingSongs"),"1").toInt(); | ||
3935 | 48 | if (showMissing) { | ||
3936 | 49 | filter = "library.mixxx_deleted=0"; | ||
3937 | 50 | playlistTableName.append("_missing"); | ||
3938 | 51 | } else { | ||
3939 | 52 | filter = "library.mixxx_deleted=0 AND track_locations.fs_deleted=0"; | ||
3940 | 53 | } | ||
3941 | 48 | 54 | ||
3942 | 49 | // We drop files that have been explicitly deleted from mixxx | 55 | // We drop files that have been explicitly deleted from mixxx |
3943 | 50 | // (mixxx_deleted=0) from the view. There was a bug in <= 1.9.0 where | 56 | // (mixxx_deleted=0) from the view. There was a bug in <= 1.9.0 where |
3944 | @@ -54,12 +60,13 @@ | |||
3945 | 54 | "CREATE TEMPORARY VIEW IF NOT EXISTS %1 AS " | 60 | "CREATE TEMPORARY VIEW IF NOT EXISTS %1 AS " |
3946 | 55 | "SELECT %2 FROM PlaylistTracks " | 61 | "SELECT %2 FROM PlaylistTracks " |
3947 | 56 | "INNER JOIN library ON library.id = PlaylistTracks.track_id " | 62 | "INNER JOIN library ON library.id = PlaylistTracks.track_id " |
3948 | 63 | "INNER JOIN track_locations ON track_locations.id=PlaylistTracks.track_id " | ||
3949 | 57 | "WHERE PlaylistTracks.playlist_id = %3") | 64 | "WHERE PlaylistTracks.playlist_id = %3") |
3950 | 58 | .arg(escaper.escapeString(playlistTableName), | 65 | .arg(escaper.escapeString(playlistTableName), |
3951 | 59 | columns.join(","), | 66 | columns.join(","), |
3952 | 60 | QString::number(playlistId)); | 67 | QString::number(playlistId)); |
3953 | 61 | if (!m_showAll) { | 68 | if (!m_showAll) { |
3955 | 62 | queryString.append(" AND library.mixxx_deleted = 0"); | 69 | queryString.append(" AND " + filter); |
3956 | 63 | } | 70 | } |
3957 | 64 | query.prepare(queryString); | 71 | query.prepare(queryString); |
3958 | 65 | if (!query.exec()) { | 72 | if (!query.exec()) { |
3959 | @@ -68,7 +75,7 @@ | |||
3960 | 68 | 75 | ||
3961 | 69 | columns[0] = LIBRARYTABLE_ID; | 76 | columns[0] = LIBRARYTABLE_ID; |
3962 | 70 | columns[3] = "preview"; | 77 | columns[3] = "preview"; |
3964 | 71 | setTable(playlistTableName, columns[0], columns, | 78 | setTable(playlistTableName, tableColumns[0], tableColumns, |
3965 | 72 | m_pTrackCollection->getTrackSource("default")); | 79 | m_pTrackCollection->getTrackSource("default")); |
3966 | 73 | initHeaderData(); | 80 | initHeaderData(); |
3967 | 74 | setSearch(""); | 81 | setSearch(""); |
3968 | @@ -76,45 +83,6 @@ | |||
3969 | 76 | setSort(defaultSortColumn(), defaultSortOrder()); | 83 | setSort(defaultSortColumn(), defaultSortOrder()); |
3970 | 77 | } | 84 | } |
3971 | 78 | 85 | ||
3972 | 79 | bool PlaylistTableModel::addTrack(const QModelIndex& index, QString location) { | ||
3973 | 80 | const int positionColumn = fieldIndex(PLAYLISTTRACKSTABLE_POSITION); | ||
3974 | 81 | int position = index.sibling(index.row(), positionColumn).data().toInt(); | ||
3975 | 82 | |||
3976 | 83 | // Handle weird cases like a drag-and-drop to an invalid index | ||
3977 | 84 | if (position <= 0) { | ||
3978 | 85 | position = rowCount() + 1; | ||
3979 | 86 | } | ||
3980 | 87 | |||
3981 | 88 | // If a track is dropped but it isn't in the library, then add it because | ||
3982 | 89 | // the user probably dropped a file from outside Mixxx into this playlist. | ||
3983 | 90 | QFileInfo fileInfo(location); | ||
3984 | 91 | |||
3985 | 92 | // Adds track, does not insert duplicates, handles unremoving logic. | ||
3986 | 93 | int trackId = m_trackDao.addTrack(fileInfo, true); | ||
3987 | 94 | |||
3988 | 95 | // Do nothing if the location still isn't in the database. | ||
3989 | 96 | if (trackId < 0) { | ||
3990 | 97 | return false; | ||
3991 | 98 | } | ||
3992 | 99 | |||
3993 | 100 | m_playlistDao.insertTrackIntoPlaylist(trackId, m_iPlaylistId, position); | ||
3994 | 101 | |||
3995 | 102 | // TODO(rryan) signal an add to the base, don't select | ||
3996 | 103 | select(); //Repopulate the data model. | ||
3997 | 104 | return true; | ||
3998 | 105 | } | ||
3999 | 106 | |||
4000 | 107 | bool PlaylistTableModel::appendTrack(int trackId) { | ||
4001 | 108 | if (trackId < 0) { | ||
4002 | 109 | return false; | ||
4003 | 110 | } | ||
4004 | 111 | |||
4005 | 112 | bool bSuccess = m_playlistDao.appendTrackToPlaylist(trackId, m_iPlaylistId); | ||
4006 | 113 | |||
4007 | 114 | select(); //Repopulate the data model. | ||
4008 | 115 | return bSuccess; | ||
4009 | 116 | } | ||
4010 | 117 | |||
4011 | 118 | int PlaylistTableModel::addTracks(const QModelIndex& index, QList<QString> locations) { | 86 | int PlaylistTableModel::addTracks(const QModelIndex& index, QList<QString> locations) { |
4012 | 119 | const int positionColumn = fieldIndex(PLAYLISTTRACKSTABLE_POSITION); | 87 | const int positionColumn = fieldIndex(PLAYLISTTRACKSTABLE_POSITION); |
4013 | 120 | int position = index.sibling(index.row(), positionColumn).data().toInt(); | 88 | int position = index.sibling(index.row(), positionColumn).data().toInt(); |
4014 | @@ -129,7 +97,7 @@ | |||
4015 | 129 | fileInfoList.append(QFileInfo(fileLocation)); | 97 | fileInfoList.append(QFileInfo(fileLocation)); |
4016 | 130 | } | 98 | } |
4017 | 131 | 99 | ||
4019 | 132 | QList<int> trackIds = m_trackDao.addTracks(fileInfoList, true); | 100 | QList<int> trackIds = m_trackDAO.addTracks(fileInfoList, true); |
4020 | 133 | 101 | ||
4021 | 134 | int tracksAdded = m_playlistDao.insertTracksIntoPlaylist( | 102 | int tracksAdded = m_playlistDao.insertTracksIntoPlaylist( |
4022 | 135 | trackIds, m_iPlaylistId, position); | 103 | trackIds, m_iPlaylistId, position); |
4023 | @@ -144,13 +112,15 @@ | |||
4024 | 144 | return tracksAdded; | 112 | return tracksAdded; |
4025 | 145 | } | 113 | } |
4026 | 146 | 114 | ||
4034 | 147 | TrackPointer PlaylistTableModel::getTrack(const QModelIndex& index) const { | 115 | bool PlaylistTableModel::appendTrack(int trackId) { |
4035 | 148 | //FIXME: use position instead of location for playlist tracks? | 116 | if (trackId < 0) { |
4036 | 149 | 117 | return false; | |
4037 | 150 | //const int locationColumnIndex = this->fieldIndex(LIBRARYTABLE_LOCATION); | 118 | } |
4038 | 151 | //QString location = index.sibling(index.row(), locationColumnIndex).data().toString(); | 119 | |
4039 | 152 | int trackId = getTrackId(index); | 120 | m_playlistDao.appendTrackToPlaylist(trackId, m_iPlaylistId); |
4040 | 153 | return m_trackDao.getTrack(trackId); | 121 | |
4041 | 122 | select(); //Repopulate the data model. | ||
4042 | 123 | return true; | ||
4043 | 154 | } | 124 | } |
4044 | 155 | 125 | ||
4045 | 156 | void PlaylistTableModel::removeTrack(const QModelIndex& index) { | 126 | void PlaylistTableModel::removeTrack(const QModelIndex& index) { |
4046 | @@ -226,18 +196,17 @@ | |||
4047 | 226 | 196 | ||
4048 | 227 | //Insert the song into the PlaylistTracks table | 197 | //Insert the song into the PlaylistTracks table |
4049 | 228 | 198 | ||
4056 | 229 | /** ALGORITHM for code below | 199 | // ALGORITHM for code below |
4057 | 230 | Case 1: destination < source (newPos < oldPos) | 200 | // Case 1: destination < source (newPos < oldPos) |
4058 | 231 | 1) Set position = -1 where pos=source -- Gives that track a dummy index to keep stuff simple. | 201 | // 1) Set position = -1 where pos=source -- Gives that track a dummy index to keep stuff simple. |
4059 | 232 | 2) Decrement position where pos > source | 202 | // 2) Decrement position where pos > source |
4060 | 233 | 3) increment position where pos > dest | 203 | // 3) increment position where pos > dest |
4061 | 234 | 4) Set position = dest where pos=-1 -- Move track from dummy pos to final destination. | 204 | // 4) Set position = dest where pos=-1 -- Move track from dummy pos to final destination. |
4062 | 235 | 205 | ||
4068 | 236 | Case 2: destination > source (newPos > oldPos) | 206 | // Case 2: destination > source (newPos > oldPos) |
4069 | 237 | 1) Set position=-1 where pos=source -- Give track a dummy index again. | 207 | // 1) Set position=-1 where pos=source -- Give track a dummy index again. |
4070 | 238 | 2) Decrement position where pos > source AND pos <= dest | 208 | // 2) Decrement position where pos > source AND pos <= dest |
4071 | 239 | 3) Set postion=dest where pos=-1 -- Move that track from dummy pos to final destination | 209 | // 3) Set postion=dest where pos=-1 -- Move that track from dummy pos to final destination |
4067 | 240 | */ | ||
4072 | 241 | 210 | ||
4073 | 242 | QString queryString; | 211 | QString queryString; |
4074 | 243 | if (newPosition < oldPosition) { | 212 | if (newPosition < oldPosition) { |
4075 | @@ -336,17 +305,6 @@ | |||
4076 | 336 | select(); | 305 | select(); |
4077 | 337 | } | 306 | } |
4078 | 338 | 307 | ||
4079 | 339 | void PlaylistTableModel::search(const QString& searchText) { | ||
4080 | 340 | // qDebug() << "PlaylistTableModel::search()" << searchText | ||
4081 | 341 | // << QThread::currentThread(); | ||
4082 | 342 | emit(doSearch(searchText)); | ||
4083 | 343 | } | ||
4084 | 344 | |||
4085 | 345 | void PlaylistTableModel::slotSearch(const QString& searchText) { | ||
4086 | 346 | BaseSqlTableModel::search( | ||
4087 | 347 | searchText, LibraryTableModel::DEFAULT_LIBRARYFILTER); | ||
4088 | 348 | } | ||
4089 | 349 | |||
4090 | 350 | bool PlaylistTableModel::isColumnInternal(int column) { | 308 | bool PlaylistTableModel::isColumnInternal(int column) { |
4091 | 351 | if (column == fieldIndex(LIBRARYTABLE_ID) || | 309 | if (column == fieldIndex(LIBRARYTABLE_ID) || |
4092 | 352 | column == fieldIndex(PLAYLISTTRACKSTABLE_TRACKID) || | 310 | column == fieldIndex(PLAYLISTTRACKSTABLE_TRACKID) || |
4093 | @@ -354,6 +312,7 @@ | |||
4094 | 354 | column == fieldIndex(LIBRARYTABLE_MIXXXDELETED) || | 312 | column == fieldIndex(LIBRARYTABLE_MIXXXDELETED) || |
4095 | 355 | column == fieldIndex(LIBRARYTABLE_BPM_LOCK) || | 313 | column == fieldIndex(LIBRARYTABLE_BPM_LOCK) || |
4096 | 356 | column == fieldIndex(TRACKLOCATIONSTABLE_FSDELETED) || | 314 | column == fieldIndex(TRACKLOCATIONSTABLE_FSDELETED) || |
4097 | 315 | column == fieldIndex(TRACKLOCATIONSTABLE_MAINDIRID) || | ||
4098 | 357 | (PlayerManager::numPreviewDecks() == 0 && column == fieldIndex("preview"))) { | 316 | (PlayerManager::numPreviewDecks() == 0 && column == fieldIndex("preview"))) { |
4099 | 358 | return true; | 317 | return true; |
4100 | 359 | } | 318 | } |
4101 | @@ -380,6 +339,7 @@ | |||
4102 | 380 | | TRACKMODELCAPS_LOADTOSAMPLER | 339 | | TRACKMODELCAPS_LOADTOSAMPLER |
4103 | 381 | | TRACKMODELCAPS_LOADTOPREVIEWDECK | 340 | | TRACKMODELCAPS_LOADTOPREVIEWDECK |
4104 | 382 | | TRACKMODELCAPS_REMOVE | 341 | | TRACKMODELCAPS_REMOVE |
4105 | 342 | | TRACKMODELCAPS_RELOCATE | ||
4106 | 383 | | TRACKMODELCAPS_BPMLOCK | 343 | | TRACKMODELCAPS_BPMLOCK |
4107 | 384 | | TRACKMODELCAPS_CLEAR_BEATS | 344 | | TRACKMODELCAPS_CLEAR_BEATS |
4108 | 385 | | TRACKMODELCAPS_RESETPLAYED; | 345 | | TRACKMODELCAPS_RESETPLAYED; |
4109 | 386 | 346 | ||
4110 | === modified file 'mixxx/src/library/playlisttablemodel.h' | |||
4111 | --- mixxx/src/library/playlisttablemodel.h 2012-08-10 15:03:46 +0000 | |||
4112 | +++ mixxx/src/library/playlisttablemodel.h 2013-05-18 16:32:26 +0000 | |||
4113 | @@ -1,54 +1,38 @@ | |||
4114 | 1 | #ifndef PLAYLISTTABLEMODEL_H | 1 | #ifndef PLAYLISTTABLEMODEL_H |
4115 | 2 | #define PLAYLISTTABLEMODEL_H | 2 | #define PLAYLISTTABLEMODEL_H |
4116 | 3 | 3 | ||
4117 | 4 | #include <QtSql> | ||
4118 | 5 | #include <QItemDelegate> | ||
4119 | 6 | #include <QtCore> | ||
4120 | 7 | |||
4121 | 8 | #include "library/basesqltablemodel.h" | 4 | #include "library/basesqltablemodel.h" |
4122 | 9 | #include "library/dao/playlistdao.h" | 5 | #include "library/dao/playlistdao.h" |
4123 | 10 | #include "library/dao/trackdao.h" | ||
4124 | 11 | #include "library/librarytablemodel.h" | ||
4125 | 12 | |||
4126 | 13 | class TrackCollection; | ||
4127 | 14 | 6 | ||
4128 | 15 | class PlaylistTableModel : public BaseSqlTableModel { | 7 | class PlaylistTableModel : public BaseSqlTableModel { |
4129 | 16 | Q_OBJECT | 8 | Q_OBJECT |
4130 | 17 | public: | 9 | public: |
4131 | 18 | PlaylistTableModel(QObject* parent, TrackCollection* pTrackCollection, | 10 | PlaylistTableModel(QObject* parent, TrackCollection* pTrackCollection, |
4133 | 19 | QString settingsNamespace,bool showAll=false); | 11 | QString settingsNamespace, |
4134 | 12 | ConfigObject<ConfigValue>* pConfig, | ||
4135 | 13 | bool showAll=false); | ||
4136 | 20 | virtual ~PlaylistTableModel(); | 14 | virtual ~PlaylistTableModel(); |
4138 | 21 | void setPlaylist(int playlistId); | 15 | void setTableModel(int playlistId = -1); |
4139 | 16 | |||
4140 | 22 | int getPlaylist() const { | 17 | int getPlaylist() const { |
4141 | 23 | return m_iPlaylistId; | 18 | return m_iPlaylistId; |
4142 | 24 | } | 19 | } |
4143 | 25 | virtual TrackPointer getTrack(const QModelIndex& index) const; | ||
4144 | 26 | 20 | ||
4152 | 27 | virtual void search(const QString& searchText); | 21 | bool isColumnInternal(int column); |
4153 | 28 | virtual bool isColumnInternal(int column); | 22 | bool isColumnHiddenByDefault(int column); |
4154 | 29 | virtual bool isColumnHiddenByDefault(int column); | 23 | void removeTrack(const QModelIndex& index); |
4155 | 30 | virtual void removeTrack(const QModelIndex& index); | 24 | void removeTracks(const QModelIndexList& indices); |
4149 | 31 | virtual void removeTracks(const QModelIndexList& indices); | ||
4150 | 32 | virtual bool addTrack(const QModelIndex& index, QString location); | ||
4151 | 33 | virtual bool appendTrack(int trackId); | ||
4156 | 34 | // Adding multiple tracks at one to a playlist. Returns the number of | 25 | // Adding multiple tracks at one to a playlist. Returns the number of |
4157 | 35 | // successful additions. | 26 | // successful additions. |
4162 | 36 | virtual int addTracks(const QModelIndex& index, QList<QString> locations); | 27 | int addTracks(const QModelIndex& index, QList<QString> locations); |
4163 | 37 | virtual void moveTrack(const QModelIndex& sourceIndex, const QModelIndex& destIndex); | 28 | bool appendTrack(int trackId); |
4164 | 38 | virtual void shuffleTracks(const QModelIndex& shuffleStartIndex); | 29 | void moveTrack(const QModelIndex& sourceIndex, |
4165 | 39 | 30 | const QModelIndex& destIndex); | |
4166 | 31 | void shuffleTracks(const QModelIndex& shuffleStartIndex); | ||
4167 | 40 | TrackModel::CapabilitiesFlags getCapabilities() const; | 32 | TrackModel::CapabilitiesFlags getCapabilities() const; |
4168 | 41 | 33 | ||
4169 | 42 | private slots: | ||
4170 | 43 | void slotSearch(const QString& searchText); | ||
4171 | 44 | |||
4172 | 45 | signals: | ||
4173 | 46 | void doSearch(const QString& searchText); | ||
4174 | 47 | |||
4175 | 48 | private: | 34 | private: |
4176 | 49 | TrackCollection* m_pTrackCollection; | ||
4177 | 50 | PlaylistDAO& m_playlistDao; | 35 | PlaylistDAO& m_playlistDao; |
4178 | 51 | TrackDAO& m_trackDao; | ||
4179 | 52 | int m_iPlaylistId; | 36 | int m_iPlaylistId; |
4180 | 53 | bool m_showAll; | 37 | bool m_showAll; |
4181 | 54 | }; | 38 | }; |
4182 | 55 | 39 | ||
4183 | === modified file 'mixxx/src/library/preparelibrarytablemodel.cpp' | |||
4184 | --- mixxx/src/library/preparelibrarytablemodel.cpp 2012-12-08 14:33:51 +0000 | |||
4185 | +++ mixxx/src/library/preparelibrarytablemodel.cpp 2013-05-18 16:32:26 +0000 | |||
4186 | @@ -2,34 +2,23 @@ | |||
4187 | 2 | 2 | ||
4188 | 3 | #include "preparelibrarytablemodel.h" | 3 | #include "preparelibrarytablemodel.h" |
4189 | 4 | #include "library/trackcollection.h" | 4 | #include "library/trackcollection.h" |
4190 | 5 | #include "configobject.h" | ||
4191 | 5 | 6 | ||
4192 | 6 | const QString RECENT_FILTER = "datetime_added > datetime('now', '-7 days')"; | 7 | const QString RECENT_FILTER = "datetime_added > datetime('now', '-7 days')"; |
4193 | 7 | 8 | ||
4194 | 8 | PrepareLibraryTableModel::PrepareLibraryTableModel(QObject* parent, | 9 | PrepareLibraryTableModel::PrepareLibraryTableModel(QObject* parent, |
4195 | 9 | TrackCollection* pTrackCollection) | 10 | TrackCollection* pTrackCollection) |
4197 | 10 | : LibraryTableModel(parent, pTrackCollection, | 11 | : LibraryTableModel(parent, pTrackCollection, NULL, |
4198 | 11 | "mixxx.db.model.prepare") { | 12 | "mixxx.db.model.prepare") { |
4199 | 12 | m_bShowRecentSongs = true; | 13 | m_bShowRecentSongs = true; |
4200 | 13 | setSearch("", RECENT_FILTER); | 14 | setSearch("", RECENT_FILTER); |
4201 | 14 | 15 | ||
4202 | 15 | connect(this, SIGNAL(doSearch(const QString&)), | ||
4203 | 16 | this, SLOT(slotSearch(const QString&))); | ||
4204 | 17 | } | 16 | } |
4205 | 18 | 17 | ||
4206 | 19 | 18 | ||
4207 | 20 | PrepareLibraryTableModel::~PrepareLibraryTableModel() { | 19 | PrepareLibraryTableModel::~PrepareLibraryTableModel() { |
4208 | 21 | } | 20 | } |
4209 | 22 | 21 | ||
4210 | 23 | void PrepareLibraryTableModel::search(const QString& searchText) { | ||
4211 | 24 | // qDebug() << "PrepareLibraryTableModel::search()" << searchText | ||
4212 | 25 | // << QThread::currentThread(); | ||
4213 | 26 | emit(doSearch(searchText)); | ||
4214 | 27 | } | ||
4215 | 28 | |||
4216 | 29 | void PrepareLibraryTableModel::slotSearch(const QString& searchText) { | ||
4217 | 30 | BaseSqlTableModel::search(searchText, | ||
4218 | 31 | m_bShowRecentSongs ? RECENT_FILTER : QString()); | ||
4219 | 32 | } | ||
4220 | 33 | 22 | ||
4221 | 34 | void PrepareLibraryTableModel::showRecentSongs() { | 23 | void PrepareLibraryTableModel::showRecentSongs() { |
4222 | 35 | m_bShowRecentSongs = true; | 24 | m_bShowRecentSongs = true; |
4223 | 36 | 25 | ||
4224 | === modified file 'mixxx/src/library/preparelibrarytablemodel.h' | |||
4225 | --- mixxx/src/library/preparelibrarytablemodel.h 2012-11-25 11:17:13 +0000 | |||
4226 | +++ mixxx/src/library/preparelibrarytablemodel.h 2013-05-18 16:32:26 +0000 | |||
4227 | @@ -8,18 +8,13 @@ | |||
4228 | 8 | { | 8 | { |
4229 | 9 | Q_OBJECT | 9 | Q_OBJECT |
4230 | 10 | public: | 10 | public: |
4232 | 11 | PrepareLibraryTableModel(QObject* parent, TrackCollection* pTrackCollection); | 11 | PrepareLibraryTableModel(QObject* parent, |
4233 | 12 | TrackCollection* pTrackCollection); | ||
4234 | 12 | virtual ~PrepareLibraryTableModel(); | 13 | virtual ~PrepareLibraryTableModel(); |
4235 | 13 | 14 | ||
4236 | 14 | virtual void search(const QString& searchText); | ||
4237 | 15 | |||
4238 | 16 | public slots: | 15 | public slots: |
4239 | 17 | void showRecentSongs(); | 16 | void showRecentSongs(); |
4240 | 18 | void showAllSongs(); | 17 | void showAllSongs(); |
4241 | 19 | private slots: | ||
4242 | 20 | void slotSearch(const QString& searchText); | ||
4243 | 21 | signals: | ||
4244 | 22 | void doSearch(const QString& searchText); | ||
4245 | 23 | private: | 18 | private: |
4246 | 24 | bool m_bShowRecentSongs; | 19 | bool m_bShowRecentSongs; |
4247 | 25 | }; | 20 | }; |
4248 | 26 | 21 | ||
4249 | === modified file 'mixxx/src/library/promotracksfeature.cpp' | |||
4250 | --- mixxx/src/library/promotracksfeature.cpp 2012-12-12 17:23:33 +0000 | |||
4251 | +++ mixxx/src/library/promotracksfeature.cpp 2013-05-18 16:32:26 +0000 | |||
4252 | @@ -46,7 +46,7 @@ | |||
4253 | 46 | m_pTrackCollection(pTrackCollection), | 46 | m_pTrackCollection(pTrackCollection), |
4254 | 47 | m_pFeaturedArtistsView(NULL), | 47 | m_pFeaturedArtistsView(NULL), |
4255 | 48 | m_pBundledSongsView(NULL), | 48 | m_pBundledSongsView(NULL), |
4257 | 49 | m_downloadsTableModel(this, pTrackCollection), | 49 | m_downloadsTableModel(this, pTrackCollection,config), |
4258 | 50 | m_bFirstRun(firstRun) { | 50 | m_bFirstRun(firstRun) { |
4259 | 51 | 51 | ||
4260 | 52 | m_sPromoRemoteHTMLLocation = QString("http://promo.mixxx.org/%1/index.html").arg(MIXXX_PROMO_VERSION); //m_pConfig->getConfigPath() + "/promo/promotracks.html"; | 52 | m_sPromoRemoteHTMLLocation = QString("http://promo.mixxx.org/%1/index.html").arg(MIXXX_PROMO_VERSION); //m_pConfig->getConfigPath() + "/promo/promotracks.html"; |
4261 | 53 | 53 | ||
4262 | === modified file 'mixxx/src/library/proxytrackmodel.cpp' | |||
4263 | --- mixxx/src/library/proxytrackmodel.cpp 2013-01-19 12:15:22 +0000 | |||
4264 | +++ mixxx/src/library/proxytrackmodel.cpp 2013-05-18 16:32:26 +0000 | |||
4265 | @@ -2,6 +2,7 @@ | |||
4266 | 2 | // Created 10/22/2009 by RJ Ryan (rryan@mit.edu) | 2 | // Created 10/22/2009 by RJ Ryan (rryan@mit.edu) |
4267 | 3 | 3 | ||
4268 | 4 | #include <QtCore> | 4 | #include <QtCore> |
4269 | 5 | #include <QMessageBox> | ||
4270 | 5 | #include <QVariant> | 6 | #include <QVariant> |
4271 | 6 | 7 | ||
4272 | 7 | #include "library/proxytrackmodel.h" | 8 | #include "library/proxytrackmodel.h" |
4273 | @@ -40,7 +41,8 @@ | |||
4274 | 40 | return m_pTrackModel->getTrackLocation(indexSource); | 41 | return m_pTrackModel->getTrackLocation(indexSource); |
4275 | 41 | } | 42 | } |
4276 | 42 | 43 | ||
4278 | 43 | void ProxyTrackModel::search(const QString& searchText) { | 44 | void ProxyTrackModel::search(const QString& searchText, const QString& extraFilter) { |
4279 | 45 | Q_UNUSED(extraFilter); | ||
4280 | 44 | if (m_bHandleSearches) { | 46 | if (m_bHandleSearches) { |
4281 | 45 | m_currentSearch = searchText; | 47 | m_currentSearch = searchText; |
4282 | 46 | setFilterFixedString(searchText); | 48 | setFilterFixedString(searchText); |
4283 | @@ -64,10 +66,6 @@ | |||
4284 | 64 | return m_pTrackModel->isColumnHiddenByDefault(column); | 66 | return m_pTrackModel->isColumnHiddenByDefault(column); |
4285 | 65 | } | 67 | } |
4286 | 66 | 68 | ||
4287 | 67 | void ProxyTrackModel::removeTrack(const QModelIndex& index) { | ||
4288 | 68 | QModelIndex indexSource = mapToSource(index); | ||
4289 | 69 | m_pTrackModel->removeTrack(indexSource); | ||
4290 | 70 | } | ||
4291 | 71 | 69 | ||
4292 | 72 | void ProxyTrackModel::removeTracks(const QModelIndexList& indices) { | 70 | void ProxyTrackModel::removeTracks(const QModelIndexList& indices) { |
4293 | 73 | QModelIndexList translatedList; | 71 | QModelIndexList translatedList; |
4294 | @@ -78,11 +76,6 @@ | |||
4295 | 78 | m_pTrackModel->removeTracks(translatedList); | 76 | m_pTrackModel->removeTracks(translatedList); |
4296 | 79 | } | 77 | } |
4297 | 80 | 78 | ||
4298 | 81 | bool ProxyTrackModel::addTrack(const QModelIndex& index, QString location) { | ||
4299 | 82 | QModelIndex indexSource = mapToSource(index); | ||
4300 | 83 | return m_pTrackModel->addTrack(indexSource, location); | ||
4301 | 84 | } | ||
4302 | 85 | |||
4303 | 86 | void ProxyTrackModel::moveTrack(const QModelIndex& sourceIndex, | 79 | void ProxyTrackModel::moveTrack(const QModelIndex& sourceIndex, |
4304 | 87 | const QModelIndex& destIndex) { | 80 | const QModelIndex& destIndex) { |
4305 | 88 | QModelIndex sourceIndexSource = mapToSource(sourceIndex); | 81 | QModelIndex sourceIndexSource = mapToSource(sourceIndex); |
4306 | @@ -95,7 +88,19 @@ | |||
4307 | 95 | } | 88 | } |
4308 | 96 | 89 | ||
4309 | 97 | TrackModel::CapabilitiesFlags ProxyTrackModel::getCapabilities() const { | 90 | TrackModel::CapabilitiesFlags ProxyTrackModel::getCapabilities() const { |
4311 | 98 | return m_pTrackModel->getCapabilities(); | 91 | return TRACKMODELCAPS_NONE |
4312 | 92 | | TRACKMODELCAPS_DELETEFS; | ||
4313 | 93 | } | ||
4314 | 94 | |||
4315 | 95 | void ProxyTrackModel::deleteTracks(const QModelIndexList& indices){ | ||
4316 | 96 | QMessageBox::StandardButton btn = QMessageBox::question( | ||
4317 | 97 | NULL, tr("Confirm Delete"), | ||
4318 | 98 | tr("Are you sure you want to delete these files?"), | ||
4319 | 99 | QMessageBox::Yes | QMessageBox::No, QMessageBox::No); | ||
4320 | 100 | if (btn == QMessageBox::No) { | ||
4321 | 101 | return ; | ||
4322 | 102 | } | ||
4323 | 103 | //TODO(kain88) ask rryan what the row of the location field is | ||
4324 | 99 | } | 104 | } |
4325 | 100 | 105 | ||
4326 | 101 | bool ProxyTrackModel::filterAcceptsRow(int sourceRow, | 106 | bool ProxyTrackModel::filterAcceptsRow(int sourceRow, |
4327 | 102 | 107 | ||
4328 | === modified file 'mixxx/src/library/proxytrackmodel.h' | |||
4329 | --- mixxx/src/library/proxytrackmodel.h 2012-11-25 09:33:00 +0000 | |||
4330 | +++ mixxx/src/library/proxytrackmodel.h 2013-05-18 16:32:26 +0000 | |||
4331 | @@ -16,7 +16,7 @@ | |||
4332 | 16 | // calling the composed TrackModel. If the bHandleSearches flag is set, the | 16 | // calling the composed TrackModel. If the bHandleSearches flag is set, the |
4333 | 17 | // TrackModel search calls will not be delivered to the composed TrackModel | 17 | // TrackModel search calls will not be delivered to the composed TrackModel |
4334 | 18 | // because filtering is handled by the QSortFilterProxyModel. | 18 | // because filtering is handled by the QSortFilterProxyModel. |
4336 | 19 | class ProxyTrackModel : public QSortFilterProxyModel, public virtual TrackModel { | 19 | class ProxyTrackModel : public QSortFilterProxyModel, public TrackModel { |
4337 | 20 | public: | 20 | public: |
4338 | 21 | // Construct a new ProxyTrackModel with pTrackModel as the TrackModel it | 21 | // Construct a new ProxyTrackModel with pTrackModel as the TrackModel it |
4339 | 22 | // composes. If bHandleSearches is true, then search signals will not be | 22 | // composes. If bHandleSearches is true, then search signals will not be |
4340 | @@ -29,15 +29,14 @@ | |||
4341 | 29 | virtual QString getTrackLocation(const QModelIndex& index) const; | 29 | virtual QString getTrackLocation(const QModelIndex& index) const; |
4342 | 30 | virtual int getTrackId(const QModelIndex& index) const; | 30 | virtual int getTrackId(const QModelIndex& index) const; |
4343 | 31 | virtual const QLinkedList<int> getTrackRows(int trackId) const; | 31 | virtual const QLinkedList<int> getTrackRows(int trackId) const; |
4345 | 32 | virtual void search(const QString& searchText); | 32 | virtual void search(const QString& searchText,const QString& extraFilter=QString()); |
4346 | 33 | virtual const QString currentSearch() const; | 33 | virtual const QString currentSearch() const; |
4347 | 34 | virtual bool isColumnInternal(int column); | 34 | virtual bool isColumnInternal(int column); |
4348 | 35 | virtual bool isColumnHiddenByDefault(int column); | 35 | virtual bool isColumnHiddenByDefault(int column); |
4349 | 36 | virtual void removeTrack(const QModelIndex& index); | ||
4350 | 37 | virtual void removeTracks(const QModelIndexList& indices); | 36 | virtual void removeTracks(const QModelIndexList& indices); |
4351 | 38 | virtual bool addTrack(const QModelIndex& index, QString location); | ||
4352 | 39 | virtual void moveTrack(const QModelIndex& sourceIndex, | 37 | virtual void moveTrack(const QModelIndex& sourceIndex, |
4353 | 40 | const QModelIndex& destIndex); | 38 | const QModelIndex& destIndex); |
4354 | 39 | void deleteTracks(const QModelIndexList& indices); | ||
4355 | 41 | virtual QAbstractItemDelegate* delegateForColumn(const int i, QObject* pParent); | 40 | virtual QAbstractItemDelegate* delegateForColumn(const int i, QObject* pParent); |
4356 | 42 | virtual TrackModel::CapabilitiesFlags getCapabilities() const; | 41 | virtual TrackModel::CapabilitiesFlags getCapabilities() const; |
4357 | 43 | 42 | ||
4358 | 44 | 43 | ||
4359 | === modified file 'mixxx/src/library/rhythmbox/rhythmboxfeature.cpp' | |||
4360 | --- mixxx/src/library/rhythmbox/rhythmboxfeature.cpp 2013-01-01 11:53:13 +0000 | |||
4361 | +++ mixxx/src/library/rhythmbox/rhythmboxfeature.cpp 2013-05-18 16:32:26 +0000 | |||
4362 | @@ -9,9 +9,11 @@ | |||
4363 | 9 | #include "library/treeitem.h" | 9 | #include "library/treeitem.h" |
4364 | 10 | #include "library/queryutil.h" | 10 | #include "library/queryutil.h" |
4365 | 11 | 11 | ||
4367 | 12 | RhythmboxFeature::RhythmboxFeature(QObject* parent, TrackCollection* pTrackCollection) | 12 | RhythmboxFeature::RhythmboxFeature(QObject* parent, TrackCollection* pTrackCollection, |
4368 | 13 | ConfigObject<ConfigValue> *pConfig) | ||
4369 | 13 | : BaseExternalLibraryFeature(parent, pTrackCollection), | 14 | : BaseExternalLibraryFeature(parent, pTrackCollection), |
4370 | 14 | m_pTrackCollection(pTrackCollection), | 15 | m_pTrackCollection(pTrackCollection), |
4371 | 16 | m_pConfig(pConfig), | ||
4372 | 15 | m_cancelImport(false) { | 17 | m_cancelImport(false) { |
4373 | 16 | QString tableName = "rhythmbox_library"; | 18 | QString tableName = "rhythmbox_library"; |
4374 | 17 | QString idColumn = "id"; | 19 | QString idColumn = "id"; |
4375 | @@ -37,13 +39,13 @@ | |||
4376 | 37 | this, m_pTrackCollection, | 39 | this, m_pTrackCollection, |
4377 | 38 | "mixxx.db.model.rhythmbox", | 40 | "mixxx.db.model.rhythmbox", |
4378 | 39 | "rhythmbox_library", | 41 | "rhythmbox_library", |
4380 | 40 | "rhythmbox"); | 42 | "rhythmbox",m_pConfig); |
4381 | 41 | m_pRhythmboxPlaylistModel = new BaseExternalPlaylistModel( | 43 | m_pRhythmboxPlaylistModel = new BaseExternalPlaylistModel( |
4382 | 42 | this, m_pTrackCollection, | 44 | this, m_pTrackCollection, |
4383 | 43 | "mixxx.db.model.rhythmbox_playlist", | 45 | "mixxx.db.model.rhythmbox_playlist", |
4384 | 44 | "rhythmbox_playlists", | 46 | "rhythmbox_playlists", |
4385 | 45 | "rhythmbox_playlist_tracks", | 47 | "rhythmbox_playlist_tracks", |
4387 | 46 | "rhythmbox"); | 48 | "rhythmbox",m_pConfig); |
4388 | 47 | 49 | ||
4389 | 48 | m_isActivated = false; | 50 | m_isActivated = false; |
4390 | 49 | m_title = tr("Rhythmbox"); | 51 | m_title = tr("Rhythmbox"); |
4391 | @@ -76,7 +78,7 @@ | |||
4392 | 76 | "mixxx.db.model.rhythmbox_playlist", | 78 | "mixxx.db.model.rhythmbox_playlist", |
4393 | 77 | "rhythmbox_playlists", | 79 | "rhythmbox_playlists", |
4394 | 78 | "rhythmbox_playlist_tracks", | 80 | "rhythmbox_playlist_tracks", |
4396 | 79 | "rhythmbox"); | 81 | "rhythmbox", m_pConfig); |
4397 | 80 | pModel->setPlaylist(playlist); | 82 | pModel->setPlaylist(playlist); |
4398 | 81 | return pModel; | 83 | return pModel; |
4399 | 82 | } | 84 | } |
4400 | 83 | 85 | ||
4401 | === modified file 'mixxx/src/library/rhythmbox/rhythmboxfeature.h' | |||
4402 | --- mixxx/src/library/rhythmbox/rhythmboxfeature.h 2013-01-01 11:53:13 +0000 | |||
4403 | +++ mixxx/src/library/rhythmbox/rhythmboxfeature.h 2013-05-18 16:32:26 +0000 | |||
4404 | @@ -14,6 +14,7 @@ | |||
4405 | 14 | #include "library/baseexternallibraryfeature.h" | 14 | #include "library/baseexternallibraryfeature.h" |
4406 | 15 | #include "library/treeitemmodel.h" | 15 | #include "library/treeitemmodel.h" |
4407 | 16 | #include "library/trackcollection.h" | 16 | #include "library/trackcollection.h" |
4408 | 17 | #include "configobject.h" | ||
4409 | 17 | 18 | ||
4410 | 18 | class BaseExternalTrackModel; | 19 | class BaseExternalTrackModel; |
4411 | 19 | class BaseExternalPlaylistModel; | 20 | class BaseExternalPlaylistModel; |
4412 | @@ -21,7 +22,8 @@ | |||
4413 | 21 | class RhythmboxFeature : public BaseExternalLibraryFeature { | 22 | class RhythmboxFeature : public BaseExternalLibraryFeature { |
4414 | 22 | Q_OBJECT | 23 | Q_OBJECT |
4415 | 23 | public: | 24 | public: |
4417 | 24 | RhythmboxFeature(QObject* parent, TrackCollection*); | 25 | RhythmboxFeature(QObject* parent, TrackCollection* pTrackCollection, |
4418 | 26 | ConfigObject<ConfigValue> *pConfig); | ||
4419 | 25 | virtual ~RhythmboxFeature(); | 27 | virtual ~RhythmboxFeature(); |
4420 | 26 | static bool isSupported(); | 28 | static bool isSupported(); |
4421 | 27 | 29 | ||
4422 | @@ -54,6 +56,7 @@ | |||
4423 | 54 | QFutureWatcher<TreeItem*> m_track_watcher; | 56 | QFutureWatcher<TreeItem*> m_track_watcher; |
4424 | 55 | QFuture<TreeItem*> m_track_future; | 57 | QFuture<TreeItem*> m_track_future; |
4425 | 56 | TreeItemModel m_childModel; | 58 | TreeItemModel m_childModel; |
4426 | 59 | ConfigObject<ConfigValue> *m_pConfig; | ||
4427 | 57 | bool m_cancelImport; | 60 | bool m_cancelImport; |
4428 | 58 | 61 | ||
4429 | 59 | // Removes all rows from a given table | 62 | // Removes all rows from a given table |
4430 | 60 | 63 | ||
4431 | === modified file 'mixxx/src/library/setlogfeature.cpp' | |||
4432 | --- mixxx/src/library/setlogfeature.cpp 2013-05-12 22:17:32 +0000 | |||
4433 | +++ mixxx/src/library/setlogfeature.cpp 2013-05-18 16:32:26 +0000 | |||
4434 | @@ -17,11 +17,10 @@ | |||
4435 | 17 | SetlogFeature::SetlogFeature(QObject* parent, | 17 | SetlogFeature::SetlogFeature(QObject* parent, |
4436 | 18 | ConfigObject<ConfigValue>* pConfig, | 18 | ConfigObject<ConfigValue>* pConfig, |
4437 | 19 | TrackCollection* pTrackCollection) | 19 | TrackCollection* pTrackCollection) |
4440 | 20 | : BasePlaylistFeature(parent, pConfig, pTrackCollection, | 20 | : BasePlaylistFeature(parent, pConfig, pTrackCollection, "SETLOGHOME") { |
4439 | 21 | "SETLOGHOME") { | ||
4441 | 22 | m_pPlaylistTableModel = new PlaylistTableModel(this, pTrackCollection, | 21 | m_pPlaylistTableModel = new PlaylistTableModel(this, pTrackCollection, |
4442 | 23 | "mixxx.db.model.setlog", | 22 | "mixxx.db.model.setlog", |
4444 | 24 | true);//show all tracks | 23 | pConfig, true); |
4445 | 25 | m_pJoinWithPreviousAction = new QAction(tr("Join with previous"), this); | 24 | m_pJoinWithPreviousAction = new QAction(tr("Join with previous"), this); |
4446 | 26 | connect(m_pJoinWithPreviousAction, SIGNAL(triggered()), | 25 | connect(m_pJoinWithPreviousAction, SIGNAL(triggered()), |
4447 | 27 | this, SLOT(slotJoinWithPrevious())); | 26 | this, SLOT(slotJoinWithPrevious())); |
4448 | @@ -181,7 +180,7 @@ | |||
4449 | 181 | int previousPlaylistId = m_playlistDao.getPreviousPlaylist(currentPlaylistId, PlaylistDAO::PLHT_SET_LOG); | 180 | int previousPlaylistId = m_playlistDao.getPreviousPlaylist(currentPlaylistId, PlaylistDAO::PLHT_SET_LOG); |
4450 | 182 | if (previousPlaylistId >= 0) { | 181 | if (previousPlaylistId >= 0) { |
4451 | 183 | 182 | ||
4453 | 184 | m_pPlaylistTableModel->setPlaylist(previousPlaylistId); | 183 | m_pPlaylistTableModel->setTableModel(previousPlaylistId); |
4454 | 185 | 184 | ||
4455 | 186 | if (currentPlaylistId == m_playlistId) { | 185 | if (currentPlaylistId == m_playlistId) { |
4456 | 187 | // mark all the Tracks in the previous Playlist as played | 186 | // mark all the Tracks in the previous Playlist as played |
4457 | @@ -252,6 +251,8 @@ | |||
4458 | 252 | return; | 251 | return; |
4459 | 253 | } | 252 | } |
4460 | 254 | 253 | ||
4461 | 254 | m_playlistDao.appendTrackToPlaylist(currentPlayingTrackId, | ||
4462 | 255 | m_playlistId); | ||
4463 | 255 | if (m_pPlaylistTableModel->getPlaylist() == m_playlistId) { | 256 | if (m_pPlaylistTableModel->getPlaylist() == m_playlistId) { |
4464 | 256 | // View needs a refresh | 257 | // View needs a refresh |
4465 | 257 | m_pPlaylistTableModel->appendTrack(currentPlayingTrackId); | 258 | m_pPlaylistTableModel->appendTrack(currentPlayingTrackId); |
4466 | @@ -277,7 +278,7 @@ | |||
4467 | 277 | 278 | ||
4468 | 278 | if (type != PlaylistDAO::PLHT_UNKNOWN) { | 279 | if (type != PlaylistDAO::PLHT_UNKNOWN) { |
4469 | 279 | // Switch the view to the playlist. | 280 | // Switch the view to the playlist. |
4471 | 280 | m_pPlaylistTableModel->setPlaylist(playlistId); | 281 | m_pPlaylistTableModel->setTableModel(playlistId); |
4472 | 281 | // Update selection | 282 | // Update selection |
4473 | 282 | emit(featureSelect(this, m_lastRightClickedIndex)); | 283 | emit(featureSelect(this, m_lastRightClickedIndex)); |
4474 | 283 | } | 284 | } |
4475 | 284 | 285 | ||
4476 | === modified file 'mixxx/src/library/stardelegate.cpp' | |||
4477 | --- mixxx/src/library/stardelegate.cpp 2012-11-30 09:17:37 +0000 | |||
4478 | +++ mixxx/src/library/stardelegate.cpp 2013-05-18 16:32:26 +0000 | |||
4479 | @@ -18,15 +18,19 @@ | |||
4480 | 18 | 18 | ||
4481 | 19 | #include <QtDebug> | 19 | #include <QtDebug> |
4482 | 20 | #include <QtGui> | 20 | #include <QtGui> |
4483 | 21 | #include <QTableView> | ||
4484 | 21 | 22 | ||
4485 | 22 | #include "stardelegate.h" | 23 | #include "stardelegate.h" |
4486 | 23 | #include "stareditor.h" | 24 | #include "stareditor.h" |
4487 | 24 | #include "starrating.h" | 25 | #include "starrating.h" |
4488 | 26 | #include "library/trackmodel.h" | ||
4489 | 27 | #include "library/dao/trackdao.h" | ||
4490 | 25 | 28 | ||
4491 | 26 | StarDelegate::StarDelegate(QObject *pParent) | 29 | StarDelegate::StarDelegate(QObject *pParent) |
4492 | 27 | : QStyledItemDelegate(pParent), | 30 | : QStyledItemDelegate(pParent), |
4493 | 28 | m_isOneCellInEditMode(false) { | 31 | m_isOneCellInEditMode(false) { |
4494 | 29 | m_pTableView = qobject_cast<QTableView *>(pParent); | 32 | m_pTableView = qobject_cast<QTableView *>(pParent); |
4495 | 33 | m_pTrackModel = dynamic_cast<TrackModel*>(m_pTableView->model()); | ||
4496 | 30 | connect(pParent, SIGNAL(entered(QModelIndex)), | 34 | connect(pParent, SIGNAL(entered(QModelIndex)), |
4497 | 31 | this, SLOT(cellEntered(QModelIndex))); | 35 | this, SLOT(cellEntered(QModelIndex))); |
4498 | 32 | } | 36 | } |
4499 | @@ -41,7 +45,8 @@ | |||
4500 | 41 | // Populate the correct colors based on the styling | 45 | // Populate the correct colors based on the styling |
4501 | 42 | QStyleOptionViewItem newOption = option; | 46 | QStyleOptionViewItem newOption = option; |
4502 | 43 | initStyleOption(&newOption, index); | 47 | initStyleOption(&newOption, index); |
4504 | 44 | 48 | bool fsDeleted=index.sibling(index.row(), | |
4505 | 49 | m_pTrackModel->fieldIndex(TRACKLOCATIONSTABLE_FSDELETED)).data().toInt(); | ||
4506 | 45 | // Set the palette appropriately based on whether the row is selected or | 50 | // Set the palette appropriately based on whether the row is selected or |
4507 | 46 | // not. We also have to check if it is inactive or not and use the | 51 | // not. We also have to check if it is inactive or not and use the |
4508 | 47 | // appropriate ColorGroup. | 52 | // appropriate ColorGroup. |
4509 | @@ -54,7 +59,11 @@ | |||
4510 | 54 | painter->setBrush(newOption.palette.color( | 59 | painter->setBrush(newOption.palette.color( |
4511 | 55 | colorGroup, QPalette::HighlightedText)); | 60 | colorGroup, QPalette::HighlightedText)); |
4512 | 56 | } else { | 61 | } else { |
4514 | 57 | painter->fillRect(newOption.rect, newOption.palette.base()); | 62 | if (fsDeleted) { |
4515 | 63 | painter->fillRect(newOption.rect, QColor(Qt::red)); | ||
4516 | 64 | } else { | ||
4517 | 65 | painter->fillRect(newOption.rect, newOption.palette.base()); | ||
4518 | 66 | } | ||
4519 | 58 | painter->setBrush(newOption.palette.text()); | 67 | painter->setBrush(newOption.palette.text()); |
4520 | 59 | } | 68 | } |
4521 | 60 | 69 | ||
4522 | @@ -123,4 +132,3 @@ | |||
4523 | 123 | m_currentEditedCellIndex = QModelIndex(); | 132 | m_currentEditedCellIndex = QModelIndex(); |
4524 | 124 | } | 133 | } |
4525 | 125 | } | 134 | } |
4526 | 126 | |||
4527 | 127 | 135 | ||
4528 | === modified file 'mixxx/src/library/stardelegate.h' | |||
4529 | --- mixxx/src/library/stardelegate.h 2012-06-03 14:37:44 +0000 | |||
4530 | +++ mixxx/src/library/stardelegate.h 2013-05-18 16:32:26 +0000 | |||
4531 | @@ -21,6 +21,7 @@ | |||
4532 | 21 | 21 | ||
4533 | 22 | #include <QStyledItemDelegate> | 22 | #include <QStyledItemDelegate> |
4534 | 23 | #include <QTableView> | 23 | #include <QTableView> |
4535 | 24 | #include "library/trackmodel.h" | ||
4536 | 24 | 25 | ||
4537 | 25 | /* | 26 | /* |
4538 | 26 | * When displaying data in a QListView, QTableView, or QTreeView, | 27 | * When displaying data in a QListView, QTableView, or QTreeView, |
4539 | @@ -57,6 +58,7 @@ | |||
4540 | 57 | QTableView *m_pTableView; | 58 | QTableView *m_pTableView; |
4541 | 58 | QPersistentModelIndex m_currentEditedCellIndex; | 59 | QPersistentModelIndex m_currentEditedCellIndex; |
4542 | 59 | bool m_isOneCellInEditMode; | 60 | bool m_isOneCellInEditMode; |
4543 | 61 | TrackModel* m_pTrackModel; | ||
4544 | 60 | }; | 62 | }; |
4545 | 61 | 63 | ||
4546 | 62 | #endif | 64 | #endif |
4547 | 63 | 65 | ||
4548 | === modified file 'mixxx/src/library/trackcollection.cpp' | |||
4549 | --- mixxx/src/library/trackcollection.cpp 2013-05-07 03:17:23 +0000 | |||
4550 | +++ mixxx/src/library/trackcollection.cpp 2013-05-18 16:32:26 +0000 | |||
4551 | @@ -18,9 +18,10 @@ | |||
4552 | 18 | m_playlistDao(m_db), | 18 | m_playlistDao(m_db), |
4553 | 19 | m_crateDao(m_db), | 19 | m_crateDao(m_db), |
4554 | 20 | m_cueDao(m_db), | 20 | m_cueDao(m_db), |
4555 | 21 | m_directoryDao(m_db), | ||
4556 | 21 | m_analysisDao(m_db, pConfig), | 22 | m_analysisDao(m_db, pConfig), |
4557 | 22 | m_trackDao(m_db, m_cueDao, m_playlistDao, m_crateDao, | 23 | m_trackDao(m_db, m_cueDao, m_playlistDao, m_crateDao, |
4559 | 23 | m_analysisDao, pConfig), | 24 | m_analysisDao, m_directoryDao, pConfig), |
4560 | 24 | m_supportedFileExtensionsRegex( | 25 | m_supportedFileExtensionsRegex( |
4561 | 25 | SoundSourceProxy::supportedFileExtensionsRegex(), | 26 | SoundSourceProxy::supportedFileExtensionsRegex(), |
4562 | 26 | Qt::CaseInsensitive) { | 27 | Qt::CaseInsensitive) { |
4563 | @@ -72,7 +73,7 @@ | |||
4564 | 72 | return false; | 73 | return false; |
4565 | 73 | } | 74 | } |
4566 | 74 | 75 | ||
4568 | 75 | int requiredSchemaVersion = 18; | 76 | int requiredSchemaVersion = 19; |
4569 | 76 | QString schemaFilename = m_pConfig->getResourcePath(); | 77 | QString schemaFilename = m_pConfig->getResourcePath(); |
4570 | 77 | schemaFilename.append("schema.xml"); | 78 | schemaFilename.append("schema.xml"); |
4571 | 78 | QString okToExit = tr("Click OK to exit."); | 79 | QString okToExit = tr("Click OK to exit."); |
4572 | @@ -116,12 +117,19 @@ | |||
4573 | 116 | return m_db; | 117 | return m_db; |
4574 | 117 | } | 118 | } |
4575 | 118 | 119 | ||
4580 | 119 | /** Do a non-recursive import of all the songs in a directory. Does NOT decend into subdirectories. | 120 | // Do a non-recursive import of all the songs in a directory. Does NOT |
4581 | 120 | @param trackDao The track data access object which provides a connection to the database. We use this parameter in order to make this function callable from separate threads. You need to use a different DB connection for each thread. | 121 | // decend into subdirectories. |
4582 | 121 | @return true if the scan completed without being cancelled. False if the scan was cancelled part-way through. | 122 | // @param trackDao The track data access object which provides a |
4583 | 122 | */ | 123 | // connection to the database. We use this parameter in order to make |
4584 | 124 | // this function callable from separate threads. You need to use a | ||
4585 | 125 | // different DB connection for each thread. | ||
4586 | 126 | // @return true if the scan completed without being cancelled. | ||
4587 | 127 | // False if the scan was cancelled part-way through. | ||
4588 | 123 | bool TrackCollection::importDirectory(QString directory, TrackDAO &trackDao, | 128 | bool TrackCollection::importDirectory(QString directory, TrackDAO &trackDao, |
4590 | 124 | const QStringList & nameFilters, volatile bool* cancel) { | 129 | const QStringList & nameFilters, |
4591 | 130 | QSet<int>& restoredTracks, | ||
4592 | 131 | const int dirId, | ||
4593 | 132 | volatile bool* cancel) { | ||
4594 | 125 | //qDebug() << "TrackCollection::importDirectory(" << directory<< ")"; | 133 | //qDebug() << "TrackCollection::importDirectory(" << directory<< ")"; |
4595 | 126 | 134 | ||
4596 | 127 | emit(startedLoading()); | 135 | emit(startedLoading()); |
4597 | @@ -149,15 +157,17 @@ | |||
4598 | 149 | // it. If it does exist in the database, then it is either in the | 157 | // it. If it does exist in the database, then it is either in the |
4599 | 150 | // user's library OR the user has "removed" the track via | 158 | // user's library OR the user has "removed" the track via |
4600 | 151 | // "Right-Click -> Remove". These tracks stay in the library, but | 159 | // "Right-Click -> Remove". These tracks stay in the library, but |
4603 | 152 | // their mixxx_deleted column is 1. | 160 | // their mixxx_deleted column is 1. It is also possible that the |
4604 | 153 | if (!trackDao.trackExistsInDatabase(absoluteFilePath)) { | 161 | // track was deleted and now restored, set these in restoredTracks |
4605 | 162 | if (trackDao.trackExistsInDatabase(absoluteFilePath)) { | ||
4606 | 163 | restoredTracks.insert(trackDao.getTrackId(absoluteFilePath)); | ||
4607 | 164 | } else { | ||
4608 | 154 | //qDebug() << "Loading" << it.fileName(); | 165 | //qDebug() << "Loading" << it.fileName(); |
4609 | 155 | emit(progressLoading(it.fileName())); | 166 | emit(progressLoading(it.fileName())); |
4610 | 156 | 167 | ||
4611 | 157 | TrackPointer pTrack = TrackPointer(new TrackInfoObject( | 168 | TrackPointer pTrack = TrackPointer(new TrackInfoObject( |
4612 | 158 | absoluteFilePath), &QObject::deleteLater); | 169 | absoluteFilePath), &QObject::deleteLater); |
4615 | 159 | 170 | if (trackDao.addTracksAdd(pTrack.data(), false,dirId)) { | |
4614 | 160 | if (trackDao.addTracksAdd(pTrack.data(), false)) { | ||
4616 | 161 | // Successful added | 171 | // Successful added |
4617 | 162 | // signal the main instance of TrackDao, that there is a | 172 | // signal the main instance of TrackDao, that there is a |
4618 | 163 | // new Track in the database | 173 | // new Track in the database |
4619 | @@ -183,13 +193,17 @@ | |||
4620 | 183 | return m_playlistDao; | 193 | return m_playlistDao; |
4621 | 184 | } | 194 | } |
4622 | 185 | 195 | ||
4623 | 196 | DirectoryDAO& TrackCollection::getDirectoryDAO() { | ||
4624 | 197 | return m_directoryDao; | ||
4625 | 198 | } | ||
4626 | 199 | |||
4627 | 186 | QSharedPointer<BaseTrackCache> TrackCollection::getTrackSource( | 200 | QSharedPointer<BaseTrackCache> TrackCollection::getTrackSource( |
4629 | 187 | const QString name) { | 201 | const QString name) { |
4630 | 188 | return m_trackSources.value(name, QSharedPointer<BaseTrackCache>()); | 202 | return m_trackSources.value(name, QSharedPointer<BaseTrackCache>()); |
4631 | 189 | } | 203 | } |
4632 | 190 | 204 | ||
4635 | 191 | void TrackCollection::addTrackSource( | 205 | void TrackCollection::addTrackSource(const QString name, |
4636 | 192 | const QString name, QSharedPointer<BaseTrackCache> trackSource) { | 206 | QSharedPointer<BaseTrackCache> trackSource) { |
4637 | 193 | Q_ASSERT(!m_trackSources.contains(name)); | 207 | Q_ASSERT(!m_trackSources.contains(name)); |
4638 | 194 | m_trackSources[name] = trackSource; | 208 | m_trackSources[name] = trackSource; |
4639 | 195 | } | 209 | } |
4640 | 196 | 210 | ||
4641 | === modified file 'mixxx/src/library/trackcollection.h' | |||
4642 | --- mixxx/src/library/trackcollection.h 2013-02-09 22:06:46 +0000 | |||
4643 | +++ mixxx/src/library/trackcollection.h 2013-05-18 16:32:26 +0000 | |||
4644 | @@ -31,6 +31,7 @@ | |||
4645 | 31 | #include "library/dao/cuedao.h" | 31 | #include "library/dao/cuedao.h" |
4646 | 32 | #include "library/dao/playlistdao.h" | 32 | #include "library/dao/playlistdao.h" |
4647 | 33 | #include "library/dao/analysisdao.h" | 33 | #include "library/dao/analysisdao.h" |
4648 | 34 | #include "library/dao/directorydao.h" | ||
4649 | 34 | 35 | ||
4650 | 35 | class TrackInfoObject; | 36 | class TrackInfoObject; |
4651 | 36 | 37 | ||
4652 | @@ -51,7 +52,10 @@ | |||
4653 | 51 | 52 | ||
4654 | 52 | /** Import the files in a given diretory, without recursing into subdirectories */ | 53 | /** Import the files in a given diretory, without recursing into subdirectories */ |
4655 | 53 | bool importDirectory(QString directory, TrackDAO &trackDao, | 54 | bool importDirectory(QString directory, TrackDAO &trackDao, |
4657 | 54 | const QStringList & nameFilters, volatile bool* cancel); | 55 | const QStringList & nameFilters, |
4658 | 56 | QSet<int>& restoredTracks, | ||
4659 | 57 | const int dirId, | ||
4660 | 58 | volatile bool* cancel); | ||
4661 | 55 | 59 | ||
4662 | 56 | void resetLibaryCancellation(); | 60 | void resetLibaryCancellation(); |
4663 | 57 | QSqlDatabase& getDatabase(); | 61 | QSqlDatabase& getDatabase(); |
4664 | @@ -59,6 +63,7 @@ | |||
4665 | 59 | CrateDAO& getCrateDAO(); | 63 | CrateDAO& getCrateDAO(); |
4666 | 60 | TrackDAO& getTrackDAO(); | 64 | TrackDAO& getTrackDAO(); |
4667 | 61 | PlaylistDAO& getPlaylistDAO(); | 65 | PlaylistDAO& getPlaylistDAO(); |
4668 | 66 | DirectoryDAO& getDirectoryDAO(); | ||
4669 | 62 | QSharedPointer<BaseTrackCache> getTrackSource(const QString name); | 67 | QSharedPointer<BaseTrackCache> getTrackSource(const QString name); |
4670 | 63 | void addTrackSource(const QString name, QSharedPointer<BaseTrackCache> trackSource); | 68 | void addTrackSource(const QString name, QSharedPointer<BaseTrackCache> trackSource); |
4671 | 64 | void cancelLibraryScan(); | 69 | void cancelLibraryScan(); |
4672 | @@ -81,7 +86,13 @@ | |||
4673 | 81 | CueDAO m_cueDao; | 86 | CueDAO m_cueDao; |
4674 | 82 | AnalysisDao m_analysisDao; | 87 | AnalysisDao m_analysisDao; |
4675 | 83 | TrackDAO m_trackDao; | 88 | TrackDAO m_trackDao; |
4676 | 89 | DirectoryDAO m_directoryDao; | ||
4677 | 84 | const QRegExp m_supportedFileExtensionsRegex; | 90 | const QRegExp m_supportedFileExtensionsRegex; |
4678 | 91 | // Flag to raise when library scan should be cancelled | ||
4679 | 92 | int bCancelLibraryScan; | ||
4680 | 93 | QMutex m_libraryScanMutex; | ||
4681 | 94 | |||
4682 | 95 | |||
4683 | 85 | }; | 96 | }; |
4684 | 86 | 97 | ||
4685 | 87 | #endif | 98 | #endif |
4686 | 88 | 99 | ||
4687 | === modified file 'mixxx/src/library/trackmodel.h' | |||
4688 | --- mixxx/src/library/trackmodel.h 2012-11-25 09:33:00 +0000 | |||
4689 | +++ mixxx/src/library/trackmodel.h 2013-05-18 16:32:26 +0000 | |||
4690 | @@ -43,7 +43,8 @@ | |||
4691 | 43 | TRACKMODELCAPS_RESETPLAYED = 0x04000, | 43 | TRACKMODELCAPS_RESETPLAYED = 0x04000, |
4692 | 44 | TRACKMODELCAPS_HIDE = 0x08000, | 44 | TRACKMODELCAPS_HIDE = 0x08000, |
4693 | 45 | TRACKMODELCAPS_UNHIDE = 0x10000, | 45 | TRACKMODELCAPS_UNHIDE = 0x10000, |
4695 | 46 | TRACKMODELCAPS_PURGE = 0x20000 | 46 | TRACKMODELCAPS_PURGE = 0x20000, |
4696 | 47 | TRACKMODELCAPS_DELETEFS = 0x40000 | ||
4697 | 47 | }; | 48 | }; |
4698 | 48 | 49 | ||
4699 | 49 | typedef int CapabilitiesFlags; /** Enables us to do ORing */ | 50 | typedef int CapabilitiesFlags; /** Enables us to do ORing */ |
4700 | @@ -63,7 +64,10 @@ | |||
4701 | 63 | virtual const QLinkedList<int> getTrackRows(int trackId) const = 0; | 64 | virtual const QLinkedList<int> getTrackRows(int trackId) const = 0; |
4702 | 64 | 65 | ||
4703 | 65 | bool isTrackModel() { return true;} | 66 | bool isTrackModel() { return true;} |
4705 | 66 | virtual void search(const QString& searchText) = 0; | 67 | virtual void search(const QString& searchText, const QString& extraFilter=QString()) { |
4706 | 68 | Q_UNUSED(searchText); | ||
4707 | 69 | Q_UNUSED(extraFilter); | ||
4708 | 70 | }; | ||
4709 | 67 | virtual const QString currentSearch() const = 0; | 71 | virtual const QString currentSearch() const = 0; |
4710 | 68 | virtual bool isColumnInternal(int column) = 0; | 72 | virtual bool isColumnInternal(int column) = 0; |
4711 | 69 | // if no header state exists, we may hide some columns so that the user can | 73 | // if no header state exists, we may hide some columns so that the user can |
4712 | @@ -71,9 +75,7 @@ | |||
4713 | 71 | virtual bool isColumnHiddenByDefault(int column) = 0; | 75 | virtual bool isColumnHiddenByDefault(int column) = 0; |
4714 | 72 | virtual const QList<int>& showableColumns() const { return m_emptyColumns; } | 76 | virtual const QList<int>& showableColumns() const { return m_emptyColumns; } |
4715 | 73 | virtual const QList<int>& searchColumns() const { return m_emptyColumns; } | 77 | virtual const QList<int>& searchColumns() const { return m_emptyColumns; } |
4719 | 74 | virtual void removeTrack(const QModelIndex& index) { | 78 | |
4717 | 75 | Q_UNUSED(index); | ||
4718 | 76 | } | ||
4720 | 77 | virtual void removeTracks(const QModelIndexList& indices) { | 79 | virtual void removeTracks(const QModelIndexList& indices) { |
4721 | 78 | Q_UNUSED(indices); | 80 | Q_UNUSED(indices); |
4722 | 79 | } | 81 | } |
4723 | @@ -83,14 +85,15 @@ | |||
4724 | 83 | virtual void unhideTracks(const QModelIndexList& indices) { | 85 | virtual void unhideTracks(const QModelIndexList& indices) { |
4725 | 84 | Q_UNUSED(indices); | 86 | Q_UNUSED(indices); |
4726 | 85 | } | 87 | } |
4727 | 88 | virtual void relocateTracks(const QModelIndexList& indices) { | ||
4728 | 89 | Q_UNUSED(indices); | ||
4729 | 90 | } | ||
4730 | 91 | virtual void deleteTracks(const QModelIndexList& indices) { | ||
4731 | 92 | Q_UNUSED(indices); | ||
4732 | 93 | } | ||
4733 | 86 | virtual void purgeTracks(const QModelIndexList& indices) { | 94 | virtual void purgeTracks(const QModelIndexList& indices) { |
4734 | 87 | Q_UNUSED(indices); | 95 | Q_UNUSED(indices); |
4735 | 88 | } | 96 | } |
4736 | 89 | virtual bool addTrack(const QModelIndex& index, QString location) { | ||
4737 | 90 | Q_UNUSED(index); | ||
4738 | 91 | Q_UNUSED(location); | ||
4739 | 92 | return false; | ||
4740 | 93 | } | ||
4741 | 94 | virtual int addTracks(const QModelIndex& index, QList<QString> locations) { | 97 | virtual int addTracks(const QModelIndex& index, QList<QString> locations) { |
4742 | 95 | Q_UNUSED(index); | 98 | Q_UNUSED(index); |
4743 | 96 | Q_UNUSED(locations); | 99 | Q_UNUSED(locations); |
4744 | @@ -133,10 +136,13 @@ | |||
4745 | 133 | m_iDefaultSortColumn = sortColumn; | 136 | m_iDefaultSortColumn = sortColumn; |
4746 | 134 | m_eDefaultSortOrder = sortOrder; | 137 | m_eDefaultSortOrder = sortOrder; |
4747 | 135 | } | 138 | } |
4749 | 136 | 139 | ||
4750 | 137 | virtual int fieldIndex(const QString& fieldName) const { | 140 | virtual int fieldIndex(const QString& fieldName) const { |
4751 | 138 | Q_UNUSED(fieldName); | 141 | Q_UNUSED(fieldName); |
4753 | 139 | return 0; | 142 | return -1; |
4754 | 143 | } | ||
4755 | 144 | |||
4756 | 145 | virtual void select() { | ||
4757 | 140 | } | 146 | } |
4758 | 141 | 147 | ||
4759 | 142 | private: | 148 | private: |
4760 | 143 | 149 | ||
4761 | === modified file 'mixxx/src/library/traktor/traktorfeature.cpp' | |||
4762 | --- mixxx/src/library/traktor/traktorfeature.cpp 2013-01-01 11:53:13 +0000 | |||
4763 | +++ mixxx/src/library/traktor/traktorfeature.cpp 2013-05-18 16:32:26 +0000 | |||
4764 | @@ -11,17 +11,17 @@ | |||
4765 | 11 | #include "library/traktor/traktorfeature.h" | 11 | #include "library/traktor/traktorfeature.h" |
4766 | 12 | 12 | ||
4767 | 13 | #include "library/librarytablemodel.h" | 13 | #include "library/librarytablemodel.h" |
4768 | 14 | #include "library/missingtablemodel.h" | ||
4769 | 15 | #include "library/queryutil.h" | 14 | #include "library/queryutil.h" |
4770 | 16 | #include "library/trackcollection.h" | 15 | #include "library/trackcollection.h" |
4771 | 17 | #include "library/treeitem.h" | 16 | #include "library/treeitem.h" |
4772 | 18 | 17 | ||
4773 | 19 | TraktorTrackModel::TraktorTrackModel(QObject* parent, | 18 | TraktorTrackModel::TraktorTrackModel(QObject* parent, |
4775 | 20 | TrackCollection* pTrackCollection) | 19 | TrackCollection* pTrackCollection, |
4776 | 20 | ConfigObject<ConfigValue> *pConfig) | ||
4777 | 21 | : BaseExternalTrackModel(parent, pTrackCollection, | 21 | : BaseExternalTrackModel(parent, pTrackCollection, |
4778 | 22 | "mixxx.db.model.traktor_tablemodel", | 22 | "mixxx.db.model.traktor_tablemodel", |
4779 | 23 | "traktor_library", | 23 | "traktor_library", |
4781 | 24 | "traktor") { | 24 | "traktor",pConfig) { |
4782 | 25 | } | 25 | } |
4783 | 26 | 26 | ||
4784 | 27 | bool TraktorTrackModel::isColumnHiddenByDefault(int column) { | 27 | bool TraktorTrackModel::isColumnHiddenByDefault(int column) { |
4785 | @@ -33,12 +33,13 @@ | |||
4786 | 33 | } | 33 | } |
4787 | 34 | 34 | ||
4788 | 35 | TraktorPlaylistModel::TraktorPlaylistModel(QObject* parent, | 35 | TraktorPlaylistModel::TraktorPlaylistModel(QObject* parent, |
4790 | 36 | TrackCollection* pTrackCollection) | 36 | TrackCollection* pTrackCollection, |
4791 | 37 | ConfigObject<ConfigValue> *pConfig) | ||
4792 | 37 | : BaseExternalPlaylistModel(parent, pTrackCollection, | 38 | : BaseExternalPlaylistModel(parent, pTrackCollection, |
4793 | 38 | "mixxx.db.model.traktor.playlistmodel", | 39 | "mixxx.db.model.traktor.playlistmodel", |
4794 | 39 | "traktor_playlists", | 40 | "traktor_playlists", |
4795 | 40 | "traktor_playlist_tracks", | 41 | "traktor_playlist_tracks", |
4797 | 41 | "traktor") { | 42 | "traktor", pConfig) { |
4798 | 42 | } | 43 | } |
4799 | 43 | 44 | ||
4800 | 44 | bool TraktorPlaylistModel::isColumnHiddenByDefault(int column) { | 45 | bool TraktorPlaylistModel::isColumnHiddenByDefault(int column) { |
4801 | @@ -49,10 +50,12 @@ | |||
4802 | 49 | return false; | 50 | return false; |
4803 | 50 | } | 51 | } |
4804 | 51 | 52 | ||
4806 | 52 | TraktorFeature::TraktorFeature(QObject* parent, TrackCollection* pTrackCollection) | 53 | TraktorFeature::TraktorFeature(QObject* parent, TrackCollection* pTrackCollection, |
4807 | 54 | ConfigObject<ConfigValue> *pConfig) | ||
4808 | 53 | : BaseExternalLibraryFeature(parent, pTrackCollection), | 55 | : BaseExternalLibraryFeature(parent, pTrackCollection), |
4809 | 54 | m_pTrackCollection(pTrackCollection), | 56 | m_pTrackCollection(pTrackCollection), |
4811 | 55 | m_cancelImport(false) { | 57 | m_cancelImport(false), |
4812 | 58 | m_pConfig(pConfig) { | ||
4813 | 56 | QString tableName = "traktor_library"; | 59 | QString tableName = "traktor_library"; |
4814 | 57 | QString idColumn = "id"; | 60 | QString idColumn = "id"; |
4815 | 58 | QStringList columns; | 61 | QStringList columns; |
4816 | @@ -75,8 +78,8 @@ | |||
4817 | 75 | columns, false))); | 78 | columns, false))); |
4818 | 76 | 79 | ||
4819 | 77 | m_isActivated = false; | 80 | m_isActivated = false; |
4822 | 78 | m_pTraktorTableModel = new TraktorTrackModel(this, m_pTrackCollection); | 81 | m_pTraktorTableModel = new TraktorTrackModel(this, m_pTrackCollection,pConfig); |
4823 | 79 | m_pTraktorPlaylistModel = new TraktorPlaylistModel(this, m_pTrackCollection); | 82 | m_pTraktorPlaylistModel = new TraktorPlaylistModel(this, m_pTrackCollection,pConfig); |
4824 | 80 | 83 | ||
4825 | 81 | m_title = tr("Traktor"); | 84 | m_title = tr("Traktor"); |
4826 | 82 | 85 | ||
4827 | @@ -101,7 +104,8 @@ | |||
4828 | 101 | } | 104 | } |
4829 | 102 | 105 | ||
4830 | 103 | BaseSqlTableModel* TraktorFeature::getPlaylistModelForPlaylist(QString playlist) { | 106 | BaseSqlTableModel* TraktorFeature::getPlaylistModelForPlaylist(QString playlist) { |
4832 | 104 | TraktorPlaylistModel* pModel = new TraktorPlaylistModel(this, m_pTrackCollection); | 107 | TraktorPlaylistModel* pModel = new TraktorPlaylistModel(this, m_pTrackCollection |
4833 | 108 | ,m_pConfig); | ||
4834 | 105 | pModel->setPlaylist(playlist); | 109 | pModel->setPlaylist(playlist); |
4835 | 106 | return pModel; | 110 | return pModel; |
4836 | 107 | } | 111 | } |
4837 | 108 | 112 | ||
4838 | === modified file 'mixxx/src/library/traktor/traktorfeature.h' | |||
4839 | --- mixxx/src/library/traktor/traktorfeature.h 2013-01-01 11:53:13 +0000 | |||
4840 | +++ mixxx/src/library/traktor/traktorfeature.h 2013-05-18 16:32:26 +0000 | |||
4841 | @@ -15,6 +15,7 @@ | |||
4842 | 15 | #include "library/baseexternaltrackmodel.h" | 15 | #include "library/baseexternaltrackmodel.h" |
4843 | 16 | #include "library/baseexternalplaylistmodel.h" | 16 | #include "library/baseexternalplaylistmodel.h" |
4844 | 17 | #include "library/treeitemmodel.h" | 17 | #include "library/treeitemmodel.h" |
4845 | 18 | #include "configobject.h" | ||
4846 | 18 | 19 | ||
4847 | 19 | class LibraryTableModel; | 20 | class LibraryTableModel; |
4848 | 20 | class MissingTableModel; | 21 | class MissingTableModel; |
4849 | @@ -24,21 +25,24 @@ | |||
4850 | 24 | class TraktorTrackModel : public BaseExternalTrackModel { | 25 | class TraktorTrackModel : public BaseExternalTrackModel { |
4851 | 25 | public: | 26 | public: |
4852 | 26 | TraktorTrackModel(QObject* parent, | 27 | TraktorTrackModel(QObject* parent, |
4854 | 27 | TrackCollection* pTrackCollection); | 28 | TrackCollection* pTrackCollection, |
4855 | 29 | ConfigObject<ConfigValue> *pConfig); | ||
4856 | 28 | virtual bool isColumnHiddenByDefault(int column); | 30 | virtual bool isColumnHiddenByDefault(int column); |
4857 | 29 | }; | 31 | }; |
4858 | 30 | 32 | ||
4859 | 31 | class TraktorPlaylistModel : public BaseExternalPlaylistModel { | 33 | class TraktorPlaylistModel : public BaseExternalPlaylistModel { |
4860 | 32 | public: | 34 | public: |
4861 | 33 | TraktorPlaylistModel(QObject* parent, | 35 | TraktorPlaylistModel(QObject* parent, |
4863 | 34 | TrackCollection* pTrackCollection); | 36 | TrackCollection* pTrackCollection, |
4864 | 37 | ConfigObject<ConfigValue> *pConfig); | ||
4865 | 35 | virtual bool isColumnHiddenByDefault(int column); | 38 | virtual bool isColumnHiddenByDefault(int column); |
4866 | 36 | }; | 39 | }; |
4867 | 37 | 40 | ||
4868 | 38 | class TraktorFeature : public BaseExternalLibraryFeature { | 41 | class TraktorFeature : public BaseExternalLibraryFeature { |
4869 | 39 | Q_OBJECT | 42 | Q_OBJECT |
4870 | 40 | public: | 43 | public: |
4872 | 41 | TraktorFeature(QObject* parent, TrackCollection*); | 44 | TraktorFeature(QObject* parent, TrackCollection*, |
4873 | 45 | ConfigObject<ConfigValue> *pConfig); | ||
4874 | 42 | virtual ~TraktorFeature(); | 46 | virtual ~TraktorFeature(); |
4875 | 43 | 47 | ||
4876 | 44 | QVariant title(); | 48 | QVariant title(); |
4877 | @@ -70,6 +74,7 @@ | |||
4878 | 70 | TrackCollection* m_pTrackCollection; | 74 | TrackCollection* m_pTrackCollection; |
4879 | 71 | // A separate db connection for the worker parsing thread | 75 | // A separate db connection for the worker parsing thread |
4880 | 72 | QSqlDatabase m_database; | 76 | QSqlDatabase m_database; |
4881 | 77 | ConfigObject<ConfigValue> *m_pConfig; | ||
4882 | 73 | TraktorTrackModel* m_pTraktorTableModel; | 78 | TraktorTrackModel* m_pTraktorTableModel; |
4883 | 74 | TraktorPlaylistModel* m_pTraktorPlaylistModel; | 79 | TraktorPlaylistModel* m_pTraktorPlaylistModel; |
4884 | 75 | 80 | ||
4885 | 76 | 81 | ||
4886 | === modified file 'mixxx/src/library/treeitem.cpp' | |||
4887 | --- mixxx/src/library/treeitem.cpp 2013-05-18 16:23:08 +0000 | |||
4888 | +++ mixxx/src/library/treeitem.cpp 2013-05-18 16:32:26 +0000 | |||
4889 | @@ -45,6 +45,12 @@ | |||
4890 | 45 | } | 45 | } |
4891 | 46 | 46 | ||
4892 | 47 | TreeItem::~TreeItem() { | 47 | TreeItem::~TreeItem() { |
4893 | 48 | qDebug() << "~TreeItem()"; | ||
4894 | 49 | //TODO(kain88) this causes a segfault during shutdown, no idea why | ||
4895 | 50 | qDebug() << m_childItems << " empty " << m_childItems.isEmpty(); | ||
4896 | 51 | if (m_childItems.isEmpty()) { | ||
4897 | 52 | return; | ||
4898 | 53 | } | ||
4899 | 48 | qDeleteAll(m_childItems); | 54 | qDeleteAll(m_childItems); |
4900 | 49 | } | 55 | } |
4901 | 50 | 56 | ||
4902 | 51 | 57 | ||
4903 | === modified file 'mixxx/src/mixxx.cpp' | |||
4904 | --- mixxx/src/mixxx.cpp 2013-05-16 00:14:12 +0000 | |||
4905 | +++ mixxx/src/mixxx.cpp 2013-05-18 16:32:26 +0000 | |||
4906 | @@ -298,30 +298,14 @@ | |||
4907 | 298 | m_pEngine->addChannel(pMicrophone); | 298 | m_pEngine->addChannel(pMicrophone); |
4908 | 299 | m_pSoundManager->registerInput(micInput, pMicrophone); | 299 | m_pSoundManager->registerInput(micInput, pMicrophone); |
4909 | 300 | 300 | ||
4933 | 301 | // Get Music dir | 301 | // library dies in seemingly unrelated qtsql error about not having a |
4934 | 302 | bool hasChanged_MusicDir = false; | 302 | // sqlite driver if this path doesn't exist. Normally config->Save() |
4935 | 303 | QDir dir(m_pConfig->getValueString(ConfigKey("[Playlist]","Directory"))); | 303 | // above would make it but if it doesn't get run for whatever reason |
4936 | 304 | if (m_pConfig->getValueString( | 304 | // we get hosed -- bkgood |
4937 | 305 | ConfigKey("[Playlist]","Directory")).length() < 1 || !dir.exists()) | 305 | if (!QDir(QDir::homePath().append("/").append(SETTINGS_PATH)).exists()) { |
4938 | 306 | { | 306 | QDir().mkpath(QDir::homePath().append("/").append(SETTINGS_PATH)); |
4916 | 307 | // TODO this needs to be smarter, we can't distinguish between an empty | ||
4917 | 308 | // path return value (not sure if this is normally possible, but it is | ||
4918 | 309 | // possible with the Windows 7 "Music" library, which is what | ||
4919 | 310 | // QDesktopServices::storageLocation(QDesktopServices::MusicLocation) | ||
4920 | 311 | // resolves to) and a user hitting 'cancel'. If we get a blank return | ||
4921 | 312 | // but the user didn't hit cancel, we need to know this and let the | ||
4922 | 313 | // user take some course of action -- bkgood | ||
4923 | 314 | QString fd = QFileDialog::getExistingDirectory( | ||
4924 | 315 | this, tr("Choose music library directory"), | ||
4925 | 316 | QDesktopServices::storageLocation(QDesktopServices::MusicLocation)); | ||
4926 | 317 | |||
4927 | 318 | if (fd != "") | ||
4928 | 319 | { | ||
4929 | 320 | m_pConfig->set(ConfigKey("[Playlist]","Directory"), fd); | ||
4930 | 321 | m_pConfig->Save(); | ||
4931 | 322 | hasChanged_MusicDir = true; | ||
4932 | 323 | } | ||
4939 | 324 | } | 307 | } |
4940 | 308 | |||
4941 | 325 | // Do not write meta data back to ID3 when meta data has changed | 309 | // Do not write meta data back to ID3 when meta data has changed |
4942 | 326 | // Because multiple TrackDao objects can exists for a particular track | 310 | // Because multiple TrackDao objects can exists for a particular track |
4943 | 327 | // writing meta data may ruine your MP3 file if done simultaneously. | 311 | // writing meta data may ruine your MP3 file if done simultaneously. |
4944 | @@ -375,6 +359,46 @@ | |||
4945 | 375 | bFirstRun || bUpgraded, | 359 | bFirstRun || bUpgraded, |
4946 | 376 | m_pRecordingManager); | 360 | m_pRecordingManager); |
4947 | 377 | m_pPlayerManager->bindToLibrary(m_pLibrary); | 361 | m_pPlayerManager->bindToLibrary(m_pLibrary); |
4948 | 362 | connect(this, SIGNAL(dirsChanged(QString,QString)), | ||
4949 | 363 | m_pLibrary, SLOT(slotDirsChanged(QString,QString))); | ||
4950 | 364 | |||
4951 | 365 | // Check if we update from an old db without relative library paths | ||
4952 | 366 | // getValueString will return "" if no value was set | ||
4953 | 367 | bool oldLibrary = m_pConfig->getValueString(ConfigKey("[Library]","newVersion"))==""; | ||
4954 | 368 | qDebug() << "kain88 status of library version" << oldLibrary; | ||
4955 | 369 | //TODO(kain88) mode this into update code | ||
4956 | 370 | if (oldLibrary) { | ||
4957 | 371 | QString dir = m_pConfig->getValueString(ConfigKey("[Playlist]","Directory")); | ||
4958 | 372 | // adds the current library path to the directories table and updates | ||
4959 | 373 | // track_locations for all tracks | ||
4960 | 374 | if (dir!="") { | ||
4961 | 375 | emit(dirsChanged("update",dir)); | ||
4962 | 376 | m_pConfig->set(ConfigKey("[Library]","newVersion"),ConfigValue((int)true)); | ||
4963 | 377 | m_pConfig->Save(); | ||
4964 | 378 | } | ||
4965 | 379 | } | ||
4966 | 380 | |||
4967 | 381 | // Get Music dir | ||
4968 | 382 | bool hasChanged_MusicDir = false; | ||
4969 | 383 | |||
4970 | 384 | QStringList dirs = m_pLibrary->getDirs(); | ||
4971 | 385 | if (dirs.size() < 1) { | ||
4972 | 386 | // TODO(XXX) this needs to be smarter, we can't distinguish between an empty | ||
4973 | 387 | // path return value (not sure if this is normally possible, but it is | ||
4974 | 388 | // possible with the Windows 7 "Music" library, which is what | ||
4975 | 389 | // QDesktopServices::storageLocation(QDesktopServices::MusicLocation) | ||
4976 | 390 | // resolves to) and a user hitting 'cancel'. If we get a blank return | ||
4977 | 391 | // but the user didn't hit cancel, we need to know this and let the | ||
4978 | 392 | // user take some course of action -- bkgood | ||
4979 | 393 | QString fd = QFileDialog::getExistingDirectory( | ||
4980 | 394 | this, tr("Choose music library directory"), | ||
4981 | 395 | QDesktopServices::storageLocation(QDesktopServices::MusicLocation)); | ||
4982 | 396 | if (fd != "") { | ||
4983 | 397 | //adds Folder to database | ||
4984 | 398 | emit(dirsChanged("added",fd)); | ||
4985 | 399 | hasChanged_MusicDir = true; | ||
4986 | 400 | } | ||
4987 | 401 | } | ||
4988 | 378 | 402 | ||
4989 | 379 | // Call inits to invoke all other construction parts | 403 | // Call inits to invoke all other construction parts |
4990 | 380 | 404 | ||
4991 | @@ -414,6 +438,11 @@ | |||
4992 | 414 | // Initialize preference dialog | 438 | // Initialize preference dialog |
4993 | 415 | m_pPrefDlg = new DlgPreferences(this, m_pSkinLoader, m_pSoundManager, m_pPlayerManager, | 439 | m_pPrefDlg = new DlgPreferences(this, m_pSkinLoader, m_pSoundManager, m_pPlayerManager, |
4994 | 416 | m_pControllerManager, m_pVCManager, m_pConfig); | 440 | m_pControllerManager, m_pVCManager, m_pConfig); |
4995 | 441 | connect(m_pPrefDlg, SIGNAL(configChanged(QString,QString)), | ||
4996 | 442 | m_pLibrary, SIGNAL(configChanged(QString,QString))); | ||
4997 | 443 | connect(m_pPrefDlg, SIGNAL(dirsChanged(QString,QString)), | ||
4998 | 444 | m_pLibrary, SLOT(slotDirsChanged(QString,QString))); | ||
4999 | 445 | |||
5000 | 417 | m_pPrefDlg->setWindowIcon(QIcon(":/images/ic_mixxx_window.png")); | 446 | m_pPrefDlg->setWindowIcon(QIcon(":/images/ic_mixxx_window.png")); |
Hey Max -- I know you aren't ready to merge this yet but I gave it a quick skim while getting chromaprint on the build server and thought I'd shoot you some comments:
* DlgPrefPlaylist
- SQL queries should not be done here -- need to be abstracted away by a DAO.
- Shouldn't rely on the default DB connection existing -- TrackCollection needs to get passed into DlgPreferences. (We could change the creation order in the future and this code would break -- better to have it enforced by code)
* BaseSqlTableMod el::relocateTra cks
- It would be cool if you could handle the use case where you select a whole album and hit relocate. Either maybe auto-magically detecting that the rest of the selected missing files are in the same directory as the first missing one relocated or maybe by letting the user pick a directory if it is clear that all the selected files were in the same directory originally. This would be a handy speedup.
* DirectoryDAO: :addDirectory -- I don't see multiple queries so I don't think it needs a transaction.
* DirectoryDAO: :relocateDirect ory -- the string arguments in these queries are untrusted and need escaping. Use QSqlQuery: :bindValue see TrackDAO: :updateTrack for an example.
* DirectoryDAO: :getDirIds, DirectoryDAO: :getDirId -- same comment RE: escaping.
* DirectoryDAO: :updateTrackLoc ations -- same comments re: escaping. Also this sets every track_locations entry to have the directory. Based on the calls to this function I'm not sure that was the intended functionality. What's this function supposed to do?
* TrackDAO: :deleteTracksFr omFS -- QMessageBox / GUI code shouldn't be in the DAO's (especially if all this code goes to its own thread eventually). Instead, have the caller pass in a list of stuff that you append un-removeable file paths to or something similar.
* TrackDAO -- some of your queries are using strings that need escaping .. you can only use string construction of the query for when you know the values are safe (i.e. a list of numeric IDs that you join together with commas.) or when you are using table names, column names, and other constants. Strings coming from user input (names, directories, paths, etc.) all need escaping.
* I'm scared of adding delete- on-filesystem code to Mixxx. Is it worth it to let the user do that? The cost of failure is huge in loss of user trust.
And now, about checksumming:
Checksumming every file when we add it to the library has to come with a huge performance hit to the library scanner. Have you noticed this? Albert and I considered checksums when we first wrote the SQLite library but didn't go with it because of this issue. I thought it would be a good compromise to do the checksums in the analyser queue (because it would be much less noticed there) and then only use the checksum for re-unification if it is present.
And now some comments about the checksum implementation itself:
* We should store version information about the checksum with it in a checksum_version column or with a unique string prefix to put on the front (I prefer a separate column since separators never end up being as unique as you thought they were).
* RE: md5 -- we probably don't need a c...