Merge lp:~mixxxdevelopers/mixxx/features_library into lp:~mixxxdevelopers/mixxx/trunk
- features_library
- Merge into trunk
Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Merged at revision: | 2489 | ||||||||
Proposed branch: | lp:~mixxxdevelopers/mixxx/features_library | ||||||||
Merge into: | lp:~mixxxdevelopers/mixxx/trunk | ||||||||
Diff against target: |
2332 lines (+1056/-419) 32 files modified
mixxx/build/depends.py (+4/-1) mixxx/res/schema.xml (+18/-0) mixxx/src/library/basesqltablemodel.cpp (+227/-5) mixxx/src/library/basesqltablemodel.h (+10/-1) mixxx/src/library/cratetablemodel.cpp (+22/-66) mixxx/src/library/cratetablemodel.h (+0/-2) mixxx/src/library/dao/trackdao.cpp (+32/-9) mixxx/src/library/dao/trackdao.h (+4/-0) mixxx/src/library/legacylibraryimporter.cpp (+10/-3) mixxx/src/library/libraryscanner.cpp (+23/-13) mixxx/src/library/librarytablemodel.cpp (+31/-83) mixxx/src/library/librarytablemodel.h (+0/-2) mixxx/src/library/missingtablemodel.cpp (+7/-58) mixxx/src/library/missingtablemodel.h (+1/-1) mixxx/src/library/playlisttablemodel.cpp (+5/-62) mixxx/src/library/playlisttablemodel.h (+0/-51) mixxx/src/library/rhythmboxtrackmodel.cpp (+3/-0) mixxx/src/library/stardelegate.cpp (+114/-0) mixxx/src/library/stardelegate.h (+56/-0) mixxx/src/library/stareditor.cpp (+95/-0) mixxx/src/library/stareditor.h (+61/-0) mixxx/src/library/starrating.cpp (+74/-0) mixxx/src/library/starrating.h (+62/-0) mixxx/src/library/trackcollection.cpp (+4/-1) mixxx/src/mixxx.cpp (+2/-2) mixxx/src/player.cpp (+2/-0) mixxx/src/trackinfoobject.cpp (+74/-0) mixxx/src/trackinfoobject.h (+19/-0) mixxx/src/widget/wlibrarytableview.cpp (+8/-1) mixxx/src/widget/wstatuslight.cpp (+70/-39) mixxx/src/widget/wstatuslight.h (+10/-12) mixxx/src/widget/wtracktableview.cpp (+8/-7) |
||||||||
To merge this branch: | bzr merge lp:~mixxxdevelopers/mixxx/features_library | ||||||||
Related bugs: |
|
||||||||
Related blueprints: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Albert Santoni | Approve | ||
Review via email:
|
Commit message
Description of the change
This branch is the combination of both lp:~ywwg/mixxx/features_library and lp:~raffitea/mixxx/features_library.
The combined set of features added here by both Tobias and Owen are:
* Adding a times played column to the library
* Adding a rating column to the library
* Adding a played column to the library
* Version bump to schema version 6, clear all the headerstate so that the new columns show up
* Adding a checkbox widget to the times-played column which is shown next to the # of times the track was played in the library track table
* Adding a star-widget to the rating column in the library track table.
* Increase the play count of a track and set it played when it is successfully loaded to a player.
* Making search queries search based on individual terms instead of the whole phrase
* Search now searches album, location, comment, and title.
* Make artist, album, title, year, track number, genre, comment, BPM in the track table editable on a single click.
* Disable loading track by hitting enter to avoid accidental loads from editing
* Rewrite part of WStatusLight (Owen, can you describe what the change here was?)
* Test for the existence of the 1.7-library conversion file result and skip legacy import if it exists.
* Added some logic to record the creation date of a Track, but it isn't used anywhere as far as I can tell.
Thanks to Tobias and Owen for this great work!
- 2489. By RJ Skerry-Ryan
-
Clear the prepare and missing headers on upgarde to schema version 6.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
RAFFI TEA (raffitea) wrote : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Albert Santoni (gamegod) wrote : | # |
Yeeeeeeeeah Qt 4.7 on Ubuntu 10.10:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Albert Santoni (gamegod) wrote : | # |
I've reviewed your code and everything pretty much looks good to me.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Albert Santoni (gamegod) wrote : | # |
Actually, I lied. I think we should make the Key column hidden by default, since it'll probably be blank for most people, and we don't yet offer key analysis. What do you think?
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
RAFFI TEA (raffitea) wrote : | # |
It sounds reasonable. How can I archive such a behaviour?
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
RAFFI TEA (raffitea) wrote : | # |
Key columns are now hidden by default. Basically, I have extended TrackModel with a method 'isColumnHidden
Preview Diff
1 | === modified file 'mixxx/build/depends.py' |
2 | --- mixxx/build/depends.py 2010-10-19 00:05:55 +0000 |
3 | +++ mixxx/build/depends.py 2010-10-19 05:33:52 +0000 |
4 | @@ -454,6 +454,9 @@ |
5 | "library/featuredartistswebview.cpp", |
6 | "library/bundledsongswebview.cpp", |
7 | "library/songdownloader.cpp", |
8 | + "library/starrating.cpp", |
9 | + "library/stardelegate.cpp", |
10 | + "library/stareditor.cpp", |
11 | |
12 | "xmlparse.cpp", |
13 | "parser.cpp", |
14 | @@ -676,7 +679,7 @@ |
15 | build.env.Append(LINKFLAGS = ['/nodefaultlib:LIBCMT.lib', |
16 | '/nodefaultlib:LIBCMTd.lib', |
17 | '/entry:mainCRTStartup']) |
18 | - # Makes the program not launch a shell first |
19 | + # Makes the program not launch a shell first |
20 | if build.toolchain_is_msvs: |
21 | build.env.Append(LINKFLAGS = '/subsystem:windows') |
22 | elif build.toolchain_is_gnu: |
23 | |
24 | === modified file 'mixxx/res/schema.xml' |
25 | --- mixxx/res/schema.xml 2010-09-14 14:45:35 +0000 |
26 | +++ mixxx/res/schema.xml 2010-10-19 05:33:52 +0000 |
27 | @@ -146,4 +146,22 @@ |
28 | ALTER TABLE LibraryHashes ADD COLUMN needs_verification INTEGER DEFAULT 0; |
29 | </sql> |
30 | </revision> |
31 | + <revision version="6"> |
32 | + <description> |
33 | + Add timesplayed and rating column. Reset header state. |
34 | + </description> |
35 | + <sql> |
36 | + ALTER TABLE library ADD COLUMN timesplayed integer DEFAULT 0; |
37 | + ALTER TABLE library ADD COLUMN rating integer DEFAULT 0; |
38 | + |
39 | + UPDATE library SET timesplayed = played; |
40 | + UPDATE library SET played = 0; |
41 | + |
42 | + DELETE FROM settings WHERE name="mixxx.db.model.library.header_state"; |
43 | + DELETE FROM settings WHERE name="mixxx.db.model.playlist.header_state"; |
44 | + DELETE FROM settings WHERE name="mixxx.db.model.crate.header_state"; |
45 | + DELETE FROM settings WHERE name="mixxx.db.model.prepare.header_state"; |
46 | + DELETE FROM settings WHERE name="mixxx.db.model.missing.header_state"; |
47 | + </sql> |
48 | + </revision> |
49 | </schema> |
50 | |
51 | === modified file 'mixxx/src/library/basesqltablemodel.cpp' |
52 | --- mixxx/src/library/basesqltablemodel.cpp 2010-08-27 20:29:12 +0000 |
53 | +++ mixxx/src/library/basesqltablemodel.cpp 2010-10-19 05:33:52 +0000 |
54 | @@ -6,6 +6,9 @@ |
55 | #include "trackinfoobject.h" |
56 | #include "library/trackcollection.h" |
57 | #include "library/basesqltablemodel.h" |
58 | +#include "mixxxutils.cpp" |
59 | +#include "library/starrating.h" |
60 | + |
61 | |
62 | BaseSqlTableModel::BaseSqlTableModel(QObject* parent, |
63 | TrackCollection* pTrackCollection, |
64 | @@ -20,6 +23,44 @@ |
65 | } |
66 | |
67 | BaseSqlTableModel::~BaseSqlTableModel() { |
68 | + |
69 | +} |
70 | + |
71 | +void BaseSqlTableModel::initHeaderData() { |
72 | + //Set the column heading labels, rename them for translations and have |
73 | + //proper capitalization |
74 | + setHeaderData(fieldIndex(LIBRARYTABLE_TIMESPLAYED), |
75 | + Qt::Horizontal, tr("Played")); |
76 | + setHeaderData(fieldIndex(LIBRARYTABLE_ARTIST), |
77 | + Qt::Horizontal, tr("Artist")); |
78 | + setHeaderData(fieldIndex(LIBRARYTABLE_TITLE), |
79 | + Qt::Horizontal, tr("Title")); |
80 | + setHeaderData(fieldIndex(LIBRARYTABLE_ALBUM), |
81 | + Qt::Horizontal, tr("Album")); |
82 | + setHeaderData(fieldIndex(LIBRARYTABLE_GENRE), |
83 | + Qt::Horizontal, tr("Genre")); |
84 | + setHeaderData(fieldIndex(LIBRARYTABLE_YEAR), |
85 | + Qt::Horizontal, tr("Year")); |
86 | + setHeaderData(fieldIndex(LIBRARYTABLE_FILETYPE), |
87 | + Qt::Horizontal, tr("Type")); |
88 | + setHeaderData(fieldIndex(LIBRARYTABLE_LOCATION), |
89 | + Qt::Horizontal, tr("Location")); |
90 | + setHeaderData(fieldIndex(LIBRARYTABLE_COMMENT), |
91 | + Qt::Horizontal, tr("Comment")); |
92 | + setHeaderData(fieldIndex(LIBRARYTABLE_DURATION), |
93 | + Qt::Horizontal, tr("Duration")); |
94 | + setHeaderData(fieldIndex(LIBRARYTABLE_RATING), |
95 | + Qt::Horizontal, tr("Rating")); |
96 | + setHeaderData(fieldIndex(LIBRARYTABLE_BITRATE), |
97 | + Qt::Horizontal, tr("Bitrate")); |
98 | + setHeaderData(fieldIndex(LIBRARYTABLE_BPM), |
99 | + Qt::Horizontal, tr("BPM")); |
100 | + setHeaderData(fieldIndex(LIBRARYTABLE_TRACKNUMBER), |
101 | + Qt::Horizontal, tr("Track #")); |
102 | + setHeaderData(fieldIndex(LIBRARYTABLE_DATETIMEADDED), |
103 | + Qt::Horizontal, tr("Date Added")); |
104 | + setHeaderData(fieldIndex(PLAYLISTTRACKSTABLE_POSITION), |
105 | + Qt::Horizontal, tr("#")); |
106 | } |
107 | |
108 | bool BaseSqlTableModel::select() { |
109 | @@ -48,9 +89,10 @@ |
110 | return result; |
111 | } |
112 | |
113 | -QVariant BaseSqlTableModel::data(const QModelIndex& index, int role) const { |
114 | - if (!index.isValid()) |
115 | +QVariant BaseSqlTableModel::getBaseValue(const QModelIndex& index, int role) const { |
116 | + if (!index.isValid()) { |
117 | return QVariant(); |
118 | + } |
119 | |
120 | int row = index.row(); |
121 | int col = index.column(); |
122 | @@ -62,7 +104,12 @@ |
123 | |
124 | int trackId = m_rowToTrackId[row]; |
125 | |
126 | - if (role == Qt::DisplayRole && m_trackOverrides.contains(trackId)) { |
127 | + /* |
128 | + * The if-block below is only executed when a table item has been edited. |
129 | + * |
130 | + */ |
131 | + if ((role == Qt::DisplayRole || role == Qt::ToolTipRole || role == Qt::EditRole) && |
132 | + m_trackOverrides.contains(trackId)) { |
133 | //qDebug() << "Returning override for track" << trackId; |
134 | TrackPointer pTrack = m_trackDAO.getTrack(trackId); |
135 | |
136 | @@ -86,16 +133,146 @@ |
137 | } else if (fieldIndex(LIBRARYTABLE_COMMENT) == col) { |
138 | return QVariant(pTrack->getComment()); |
139 | } else if (fieldIndex(LIBRARYTABLE_DURATION) == col) { |
140 | - return QVariant(pTrack->getDuration()); |
141 | + return pTrack->getDuration(); |
142 | } else if (fieldIndex(LIBRARYTABLE_BITRATE) == col) { |
143 | return QVariant(pTrack->getBitrate()); |
144 | } else if (fieldIndex(LIBRARYTABLE_BPM) == col) { |
145 | return QVariant(pTrack->getBpm()); |
146 | + } else if (fieldIndex(LIBRARYTABLE_PLAYED) == col) { |
147 | + return QVariant(pTrack->getPlayed()); |
148 | + } else if (fieldIndex(LIBRARYTABLE_TIMESPLAYED) == col) { |
149 | + return QVariant(pTrack->getTimesPlayed()); |
150 | + } else if (fieldIndex(LIBRARYTABLE_RATING) == col) { |
151 | + return pTrack->getRating(); |
152 | } |
153 | } |
154 | + |
155 | + // If none of these work, hand off to the lower layer to deal with. The role |
156 | + // might not be Edit/Display/ToolTip, or we might have a bug. |
157 | return QSqlTableModel::data(index, role); |
158 | } |
159 | |
160 | + |
161 | +QVariant BaseSqlTableModel::data(const QModelIndex& index, int role) const { |
162 | + if (!index.isValid()) { |
163 | + return QVariant(); |
164 | + } |
165 | + |
166 | + int row = index.row(); |
167 | + int col = index.column(); |
168 | + |
169 | + //qDebug() << "BaseSqlTableModel::data() column:" << col << "role:" << role; |
170 | + |
171 | + // This value is the value in its most raw form. It was looked up either |
172 | + // from the SQL table or from the cached track layer. |
173 | + QVariant value = getBaseValue(index, role); |
174 | + |
175 | + // Format the value based on whether we are in a tooltip, display, or edit |
176 | + // role |
177 | + if (role == Qt::ToolTipRole || role == Qt::DisplayRole) { |
178 | + if (index.column() == fieldIndex(LIBRARYTABLE_DURATION)) { |
179 | + if (qVariantCanConvert<int>(value)) |
180 | + value = MixxxUtils::secondsToMinutes(qVariantValue<int>(value)); |
181 | + } else if (index.column() == fieldIndex(LIBRARYTABLE_RATING)) { |
182 | + if (qVariantCanConvert<int>(value)) |
183 | + value = qVariantFromValue(StarRating(value.toInt())); |
184 | + } else if (index.column() == fieldIndex(LIBRARYTABLE_TIMESPLAYED)) { |
185 | + if (qVariantCanConvert<int>(value)) |
186 | + value = QString("(%1)").arg(value.toInt()); |
187 | + } else if (index.column() == fieldIndex(LIBRARYTABLE_PLAYED)) { |
188 | + // Convert to a bool. Not really that useful since it gets converted |
189 | + // right back to a QVariant |
190 | + value = (value == "true") ? true : false; |
191 | + } |
192 | + } else if (role == Qt::EditRole) { |
193 | + if (index.column() == fieldIndex(LIBRARYTABLE_BPM)) { |
194 | + return value.toDouble(); |
195 | + } else if (index.column() == fieldIndex(LIBRARYTABLE_TIMESPLAYED)) { |
196 | + return index.sibling(index.row(), fieldIndex(LIBRARYTABLE_PLAYED)).data().toBool(); |
197 | + } else if (index.column() == fieldIndex(LIBRARYTABLE_RATING)) { |
198 | + if (qVariantCanConvert<int>(value)) |
199 | + value = qVariantFromValue(StarRating(value.toInt())); |
200 | + } |
201 | + } else if (role == Qt::CheckStateRole) { |
202 | + if (index.column() == fieldIndex(LIBRARYTABLE_TIMESPLAYED)) { |
203 | + bool played = index.sibling(index.row(), fieldIndex(LIBRARYTABLE_PLAYED)).data().toBool(); |
204 | + value = played ? Qt::Checked : Qt::Unchecked; |
205 | + } |
206 | + } |
207 | + |
208 | + return value; |
209 | +} |
210 | + |
211 | +bool BaseSqlTableModel::setData(const QModelIndex &index, const QVariant &value, int role) |
212 | +{ |
213 | + if (!index.isValid()) |
214 | + return false; |
215 | + |
216 | + int row = index.row(); |
217 | + int col = index.column(); |
218 | + |
219 | + //qDebug() << "BaseSqlTableModel::setData() column:" << col << "value:" << value << "role:" << role; |
220 | + |
221 | + // Over-ride sets to TIMESPLAYED and re-direct them to PLAYED |
222 | + if (role == Qt::CheckStateRole) { |
223 | + if (index.column() == fieldIndex(LIBRARYTABLE_TIMESPLAYED)) { |
224 | + QString val = value.toInt() > 0 ? QString("true") : QString("false"); |
225 | + QModelIndex playedIndex = index.sibling(index.row(), fieldIndex(LIBRARYTABLE_PLAYED)); |
226 | + return setData(playedIndex, val, Qt::EditRole); |
227 | + } |
228 | + } |
229 | + |
230 | + Q_ASSERT(m_rowToTrackId.contains(row)); |
231 | + if (!m_rowToTrackId.contains(row)) { |
232 | + return QSqlTableModel::setData(index, value, role); |
233 | + } |
234 | + |
235 | + int trackId = m_rowToTrackId[row]; |
236 | + TrackPointer pTrack = m_trackDAO.getTrack(trackId); |
237 | + |
238 | + // TODO(XXX) Qt properties could really help here. |
239 | + if (fieldIndex(LIBRARYTABLE_ARTIST) == col) { |
240 | + pTrack->setArtist(value.toString()); |
241 | + } else if (fieldIndex(LIBRARYTABLE_TITLE) == col) { |
242 | + pTrack->setTitle(value.toString()); |
243 | + } else if (fieldIndex(LIBRARYTABLE_ALBUM) == col) { |
244 | + pTrack->setAlbum(value.toString()); |
245 | + } else if (fieldIndex(LIBRARYTABLE_YEAR) == col) { |
246 | + pTrack->setYear(value.toString()); |
247 | + } else if (fieldIndex(LIBRARYTABLE_GENRE) == col) { |
248 | + pTrack->setGenre(value.toString()); |
249 | + } else if (fieldIndex(LIBRARYTABLE_FILETYPE) == col) { |
250 | + pTrack->setType(value.toString()); |
251 | + } else if (fieldIndex(LIBRARYTABLE_TRACKNUMBER) == col) { |
252 | + pTrack->setTrackNumber(value.toString()); |
253 | + } else if (fieldIndex(LIBRARYTABLE_LOCATION) == col) { |
254 | + pTrack->setLocation(value.toString()); |
255 | + } else if (fieldIndex(LIBRARYTABLE_COMMENT) == col) { |
256 | + pTrack->setComment(value.toString()); |
257 | + } else if (fieldIndex(LIBRARYTABLE_DURATION) == col) { |
258 | + pTrack->setDuration(value.toInt()); |
259 | + } else if (fieldIndex(LIBRARYTABLE_BITRATE) == col) { |
260 | + pTrack->setBitrate(value.toInt()); |
261 | + } else if (fieldIndex(LIBRARYTABLE_BPM) == col) { |
262 | + //QVariant::toFloat needs >= QT 4.6.x |
263 | + pTrack->setBpm((float) value.toDouble()); |
264 | + } else if (fieldIndex(LIBRARYTABLE_PLAYED) == col) { |
265 | + pTrack->setPlayed(value.toBool()); |
266 | + } else if (fieldIndex(LIBRARYTABLE_TIMESPLAYED) == col) { |
267 | + pTrack->setTimesPlayed(value.toInt()); |
268 | + } else if (fieldIndex(LIBRARYTABLE_RATING) == col) { |
269 | + StarRating starRating = qVariantValue<StarRating>(value); |
270 | + pTrack->setRating(starRating.starCount()); |
271 | + } |
272 | + |
273 | + // Do not save the track here. Changing the track dirties it and the caching |
274 | + // system will automatically save the track once it is unloaded from |
275 | + // memory. rryan 10/2010 |
276 | + //m_trackDAO.saveTrack(pTrack); |
277 | + |
278 | + return true; |
279 | +} |
280 | + |
281 | void BaseSqlTableModel::trackChanged(int trackId) { |
282 | m_trackOverrides.insert(trackId); |
283 | if (m_trackIdToRow.contains(trackId)) { |
284 | @@ -129,7 +306,7 @@ |
285 | |
286 | QString table = m_qTableName; |
287 | QString field = database().driver()->escapeIdentifier(f.name(), |
288 | - QSqlDriver::FieldName); |
289 | + QSqlDriver::FieldName); |
290 | s.append(QLatin1String("ORDER BY ")); |
291 | QString sort_field = QString("%1.%2").arg(table).arg(field); |
292 | |
293 | @@ -149,3 +326,48 @@ |
294 | s += m_eSortOrder == Qt::AscendingOrder ? QLatin1String(" ASC") : QLatin1String(" DESC"); |
295 | return s; |
296 | } |
297 | + |
298 | +Qt::ItemFlags BaseSqlTableModel::readWriteFlags(const QModelIndex &index) const |
299 | +{ |
300 | + Qt::ItemFlags defaultFlags = QAbstractItemModel::flags(index); |
301 | + if (!index.isValid()) |
302 | + return Qt::ItemIsEnabled; |
303 | + |
304 | + //Enable dragging songs from this data model to elsewhere (like the waveform |
305 | + //widget to load a track into a Player). |
306 | + defaultFlags |= Qt::ItemIsDragEnabled; |
307 | + |
308 | + if ( index.column() == fieldIndex(LIBRARYTABLE_FILETYPE) |
309 | + || index.column() == fieldIndex(LIBRARYTABLE_LOCATION) |
310 | + || index.column() == fieldIndex(LIBRARYTABLE_DURATION) |
311 | + || index.column() == fieldIndex(LIBRARYTABLE_BITRATE) |
312 | + || index.column() == fieldIndex(LIBRARYTABLE_DATETIMEADDED)) |
313 | + { |
314 | + return defaultFlags | QAbstractItemModel::flags(index); |
315 | + } |
316 | + else if (index.column() == fieldIndex(LIBRARYTABLE_TIMESPLAYED)) { |
317 | + return defaultFlags | QAbstractItemModel::flags(index) | Qt::ItemIsUserCheckable; |
318 | + } |
319 | + else { |
320 | + return defaultFlags | QAbstractItemModel::flags(index) | Qt::ItemIsEditable; |
321 | + } |
322 | +} |
323 | + |
324 | +Qt::ItemFlags BaseSqlTableModel::readOnlyFlags(const QModelIndex &index) const |
325 | +{ |
326 | + Qt::ItemFlags defaultFlags = QAbstractItemModel::flags(index); |
327 | + if (!index.isValid()) |
328 | + return Qt::ItemIsEnabled; |
329 | + |
330 | + //Enable dragging songs from this data model to elsewhere (like the waveform widget to |
331 | + //load a track into a Player). |
332 | + defaultFlags |= Qt::ItemIsDragEnabled; |
333 | + |
334 | + return defaultFlags; |
335 | + |
336 | +} |
337 | + |
338 | +Qt::ItemFlags BaseSqlTableModel::flags(const QModelIndex &index) const |
339 | +{ |
340 | + return readWriteFlags(index); |
341 | +} |
342 | |
343 | === modified file 'mixxx/src/library/basesqltablemodel.h' |
344 | --- mixxx/src/library/basesqltablemodel.h 2010-07-15 19:07:16 +0000 |
345 | +++ mixxx/src/library/basesqltablemodel.h 2010-10-19 05:33:52 +0000 |
346 | @@ -23,12 +23,21 @@ |
347 | virtual void setSort(int column, Qt::SortOrder order); |
348 | virtual bool select(); |
349 | virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; |
350 | - |
351 | + virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); |
352 | + /** Use this if you want a model that is read-only. */ |
353 | + virtual Qt::ItemFlags readOnlyFlags(const QModelIndex &index) const; |
354 | + /** Use this if you want a model that can be changed */ |
355 | + virtual Qt::ItemFlags readWriteFlags(const QModelIndex &index) const; |
356 | + /** calls readWriteFlags() by default */ |
357 | + virtual Qt::ItemFlags flags(const QModelIndex &index) const; |
358 | protected: |
359 | virtual QString orderByClause() const; |
360 | + virtual void initHeaderData(); |
361 | private slots: |
362 | void trackChanged(int trackId); |
363 | private: |
364 | + QVariant getBaseValue(const QModelIndex& index, int role = Qt::DisplayRole) const; |
365 | + |
366 | QString m_qTableName; |
367 | int m_iSortColumn; |
368 | Qt::SortOrder m_eSortOrder; |
369 | |
370 | === modified file 'mixxx/src/library/cratetablemodel.cpp' |
371 | --- mixxx/src/library/cratetablemodel.cpp 2010-09-14 20:32:32 +0000 |
372 | +++ mixxx/src/library/cratetablemodel.cpp 2010-10-19 05:33:52 +0000 |
373 | @@ -33,11 +33,14 @@ |
374 | QString queryString = QString("CREATE TEMPORARY VIEW IF NOT EXISTS %1 AS " |
375 | "SELECT " |
376 | "library." + LIBRARYTABLE_ID + "," + |
377 | + LIBRARYTABLE_PLAYED + "," + |
378 | + LIBRARYTABLE_TIMESPLAYED + "," + |
379 | LIBRARYTABLE_ARTIST + "," + |
380 | LIBRARYTABLE_TITLE + "," + |
381 | LIBRARYTABLE_ALBUM + "," + |
382 | LIBRARYTABLE_YEAR + "," + |
383 | LIBRARYTABLE_DURATION + "," + |
384 | + LIBRARYTABLE_RATING + "," + |
385 | LIBRARYTABLE_GENRE + "," + |
386 | LIBRARYTABLE_FILETYPE + "," + |
387 | LIBRARYTABLE_TRACKNUMBER + "," + |
388 | @@ -69,34 +72,8 @@ |
389 | |
390 | select(); |
391 | |
392 | - setHeaderData(fieldIndex(LIBRARYTABLE_ID), |
393 | - Qt::Horizontal, tr("ID")); |
394 | - setHeaderData(fieldIndex(LIBRARYTABLE_ARTIST), |
395 | - Qt::Horizontal, tr("Artist")); |
396 | - setHeaderData(fieldIndex(LIBRARYTABLE_TITLE), |
397 | - Qt::Horizontal, tr("Title")); |
398 | - setHeaderData(fieldIndex(LIBRARYTABLE_ALBUM), |
399 | - Qt::Horizontal, tr("Album")); |
400 | - setHeaderData(fieldIndex(LIBRARYTABLE_GENRE), |
401 | - Qt::Horizontal, tr("Genre")); |
402 | - setHeaderData(fieldIndex(LIBRARYTABLE_YEAR), |
403 | - Qt::Horizontal, tr("Year")); |
404 | - setHeaderData(fieldIndex(LIBRARYTABLE_FILETYPE), |
405 | - Qt::Horizontal, tr("Type")); |
406 | - setHeaderData(fieldIndex("location"), |
407 | - Qt::Horizontal, tr("Location")); |
408 | - setHeaderData(fieldIndex(LIBRARYTABLE_COMMENT), |
409 | - Qt::Horizontal, tr("Comment")); |
410 | - setHeaderData(fieldIndex(LIBRARYTABLE_DURATION), |
411 | - Qt::Horizontal, tr("Duration")); |
412 | - setHeaderData(fieldIndex(LIBRARYTABLE_TRACKNUMBER), |
413 | - Qt::Horizontal, tr("Track #")); |
414 | - setHeaderData(fieldIndex(LIBRARYTABLE_BITRATE), |
415 | - Qt::Horizontal, tr("Bitrate")); |
416 | - setHeaderData(fieldIndex(LIBRARYTABLE_BPM), |
417 | - Qt::Horizontal, tr("BPM")); |
418 | - setHeaderData(fieldIndex(LIBRARYTABLE_DATETIMEADDED), |
419 | - Qt::Horizontal, tr("Date Added")); |
420 | + // BaseSqlTableModel sets up the header names |
421 | + initHeaderData(); |
422 | } |
423 | |
424 | bool CrateTableModel::addTrack(const QModelIndex& index, QString location) { |
425 | @@ -186,12 +163,22 @@ |
426 | filter = "(" + LibraryTableModel::DEFAULT_LIBRARYFILTER + ")"; |
427 | else { |
428 | QSqlField search("search", QVariant::String); |
429 | - search.setValue("%" + searchText + "%"); |
430 | - QString escapedText = database().driver()->formatValue(search); |
431 | - filter = "(" + LibraryTableModel::DEFAULT_LIBRARYFILTER + " AND " + |
432 | - "(artist LIKE " + escapedText + " OR " + |
433 | - "album LIKE " + escapedText + " OR " + |
434 | - "title LIKE " + escapedText + "))"; |
435 | + |
436 | + |
437 | + filter = "(" + LibraryTableModel::DEFAULT_LIBRARYFILTER; |
438 | + |
439 | + foreach(QString term, searchText.split(" ")) |
440 | + { |
441 | + search.setValue("%" + term + "%"); |
442 | + QString escapedText = database().driver()->formatValue(search); |
443 | + filter += " AND (artist LIKE " + escapedText + " OR " + |
444 | + "album LIKE " + escapedText + " OR " + |
445 | + "location LIKE " + escapedText + " OR " + |
446 | + "comment LIKE " + escapedText + " OR " + |
447 | + "title LIKE " + escapedText + ")"; |
448 | + } |
449 | + |
450 | + filter += ")"; |
451 | } |
452 | |
453 | setFilter(filter); |
454 | @@ -203,6 +190,7 @@ |
455 | |
456 | bool CrateTableModel::isColumnInternal(int column) { |
457 | if (column == fieldIndex(LIBRARYTABLE_ID) || |
458 | + column == fieldIndex(LIBRARYTABLE_PLAYED) || |
459 | column == fieldIndex(LIBRARYTABLE_MIXXXDELETED) || |
460 | column == fieldIndex(TRACKLOCATIONSTABLE_FSDELETED)) { |
461 | return true; |
462 | @@ -235,42 +223,10 @@ |
463 | return mimeData; |
464 | } |
465 | |
466 | -Qt::ItemFlags CrateTableModel::flags(const QModelIndex& index) const { |
467 | - Qt::ItemFlags defaultFlags = QAbstractItemModel::flags(index); |
468 | - if (!index.isValid()) |
469 | - return Qt::ItemIsEnabled; |
470 | - |
471 | - //Enable dragging songs from this data model to elsewhere (like the waveform |
472 | - //widget to load a track into a Player). |
473 | - defaultFlags |= Qt::ItemIsDragEnabled; |
474 | - |
475 | - return defaultFlags; |
476 | -} |
477 | - |
478 | QItemDelegate* CrateTableModel::delegateForColumn(int i) { |
479 | return NULL; |
480 | } |
481 | |
482 | -QVariant CrateTableModel::data(const QModelIndex& item, int role) const { |
483 | - if (!item.isValid()) |
484 | - return QVariant(); |
485 | - |
486 | - QVariant value; |
487 | - |
488 | - if (role == Qt::ToolTipRole) |
489 | - value = BaseSqlTableModel::data(item, Qt::DisplayRole); |
490 | - else |
491 | - value = BaseSqlTableModel::data(item, role); |
492 | - |
493 | - if ((role == Qt::DisplayRole || role == Qt::ToolTipRole) && |
494 | - item.column() == fieldIndex(LIBRARYTABLE_DURATION)) { |
495 | - if (qVariantCanConvert<int>(value)) { |
496 | - value = MixxxUtils::secondsToMinutes(qVariantValue<int>(value)); |
497 | - } |
498 | - } |
499 | - return value; |
500 | -} |
501 | - |
502 | TrackModel::CapabilitiesFlags CrateTableModel::getCapabilities() const { |
503 | return TRACKMODELCAPS_RECEIVEDROPS | TRACKMODELCAPS_ADDTOPLAYLIST | |
504 | TRACKMODELCAPS_ADDTOCRATE | TRACKMODELCAPS_ADDTOAUTODJ; |
505 | |
506 | === modified file 'mixxx/src/library/cratetablemodel.h' |
507 | --- mixxx/src/library/cratetablemodel.h 2010-09-13 06:23:38 +0000 |
508 | +++ mixxx/src/library/cratetablemodel.h 2010-10-19 05:33:52 +0000 |
509 | @@ -20,9 +20,7 @@ |
510 | |
511 | void setCrate(int crateId); |
512 | |
513 | - virtual QVariant data(const QModelIndex& item, int role) const; |
514 | QMimeData* mimeData(const QModelIndexList &indexes) const; |
515 | - Qt::ItemFlags flags(const QModelIndex &index) const; |
516 | |
517 | // From TrackModel |
518 | virtual TrackPointer getTrack(const QModelIndex& index) const; |
519 | |
520 | === modified file 'mixxx/src/library/dao/trackdao.cpp' |
521 | --- mixxx/src/library/dao/trackdao.cpp 2010-09-17 04:15:33 +0000 |
522 | +++ mixxx/src/library/dao/trackdao.cpp 2010-10-19 05:33:52 +0000 |
523 | @@ -19,6 +19,18 @@ |
524 | |
525 | } |
526 | |
527 | +void TrackDAO::finish() |
528 | +{ |
529 | + //clear out played information on exit |
530 | + //crash prevention: if mixxx crashes, played information will be maintained |
531 | + qDebug() << "Clearing played information for this session"; |
532 | + QSqlQuery query(m_database); |
533 | + if (!query.exec("UPDATE library SET played=0")) |
534 | + { |
535 | + qDebug() << "Error clearing played value"; |
536 | + } |
537 | +} |
538 | + |
539 | TrackDAO::~TrackDAO() |
540 | { |
541 | } |
542 | @@ -187,13 +199,15 @@ |
543 | |
544 | void TrackDAO::prepareLibraryInsert(QSqlQuery& query) { |
545 | query.prepare("INSERT INTO library (artist, title, album, year, genre, tracknumber, " |
546 | - "filetype, location, comment, url, duration, " |
547 | + "filetype, location, comment, url, duration, rating, " |
548 | "bitrate, samplerate, cuepoint, bpm, wavesummaryhex, " |
549 | + "timesplayed, " |
550 | "channels, mixxx_deleted, header_parsed) " |
551 | "VALUES (:artist, " |
552 | ":title, :album, :year, :genre, :tracknumber, " |
553 | - ":filetype, :location, :comment, :url, :duration, " |
554 | + ":filetype, :location, :comment, :url, :duration, :rating," |
555 | ":bitrate, :samplerate, :cuepoint, :bpm, :wavesummaryhex, " |
556 | + ":timesplayed, " |
557 | ":channels, :mixxx_deleted, :header_parsed)"); |
558 | } |
559 | |
560 | @@ -209,6 +223,7 @@ |
561 | query.bindValue(":comment", pTrack->getComment()); |
562 | query.bindValue(":url", pTrack->getURL()); |
563 | query.bindValue(":duration", pTrack->getDuration()); |
564 | + query.bindValue(":rating", pTrack->getRating()); |
565 | query.bindValue(":bitrate", pTrack->getBitrate()); |
566 | query.bindValue(":samplerate", pTrack->getSampleRate()); |
567 | query.bindValue(":cuepoint", pTrack->getCuePoint()); |
568 | @@ -216,7 +231,7 @@ |
569 | const QByteArray* pWaveSummary = pTrack->getWaveSummary(); |
570 | if (pWaveSummary) //Avoid null pointer deref |
571 | query.bindValue(":wavesummaryhex", *pWaveSummary); |
572 | - //query.bindValue(":timesplayed", pTrack->getCuePoint()); |
573 | + query.bindValue(":timesplayed", pTrack->getTimesPlayed()); |
574 | //query.bindValue(":datetime_added", pTrack->getDateAdded()); |
575 | query.bindValue(":channels", pTrack->getChannels()); |
576 | query.bindValue(":mixxx_deleted", 0); |
577 | @@ -322,7 +337,7 @@ |
578 | time.start(); |
579 | |
580 | //qDebug() << "TrackDAO::addTrack" << QThread::currentThread() << m_database.connectionName(); |
581 | - //qDebug() << "TrackCollection::addTrack(), inserting into DB"; |
582 | + //qDebug() << "TrackCollection::addTrack(), inserting into DB"; |
583 | Q_ASSERT(pTrack); //Why you be giving me NULL pTracks |
584 | |
585 | //Start the transaction |
586 | @@ -500,12 +515,14 @@ |
587 | QString url = query.value(query.record().indexOf("url")).toString(); |
588 | int duration = query.value(query.record().indexOf("duration")).toInt(); |
589 | int bitrate = query.value(query.record().indexOf("bitrate")).toInt(); |
590 | + int rating = query.value(query.record().indexOf("rating")).toInt(); |
591 | int samplerate = query.value(query.record().indexOf("samplerate")).toInt(); |
592 | int cuepoint = query.value(query.record().indexOf("cuepoint")).toInt(); |
593 | QString bpm = query.value(query.record().indexOf("bpm")).toString(); |
594 | QByteArray* wavesummaryhex = new QByteArray( |
595 | query.value(query.record().indexOf("wavesummaryhex")).toByteArray()); |
596 | - //int timesplayed = query.value(query.record().indexOf("timesplayed")).toInt(); |
597 | + int timesplayed = query.value(query.record().indexOf("timesplayed")).toInt(); |
598 | + int played = query.value(query.record().indexOf("played")).toInt(); |
599 | int channels = query.value(query.record().indexOf("channels")).toInt(); |
600 | int filesize = query.value(query.record().indexOf("filesize")).toInt(); |
601 | QString filetype = query.value(query.record().indexOf("filetype")).toString(); |
602 | @@ -525,6 +542,7 @@ |
603 | track->setYear(year); |
604 | track->setGenre(genre); |
605 | track->setTrackNumber(tracknumber); |
606 | + track->setRating(rating); |
607 | |
608 | track->setComment(comment); |
609 | track->setURL(url); |
610 | @@ -535,7 +553,8 @@ |
611 | track->setBpm(bpm.toFloat()); |
612 | track->setWaveSummary(wavesummaryhex, false); |
613 | delete wavesummaryhex; |
614 | - //track->setTimesPlayed //Doesn't exist wtfbbq |
615 | + track->setTimesPlayed(timesplayed); |
616 | + track->setPlayed(played); |
617 | track->setChannels(channels); |
618 | track->setType(filetype); |
619 | track->setLocation(location); |
620 | @@ -607,7 +626,8 @@ |
621 | time.start(); |
622 | QSqlQuery query(m_database); |
623 | |
624 | - query.prepare("SELECT library.id, artist, title, album, year, genre, tracknumber, filetype, track_locations.location as location, track_locations.filesize as filesize, comment, url, duration, bitrate, samplerate, cuepoint, bpm, wavesummaryhex, channels, header_parsed FROM Library INNER JOIN track_locations ON library.location = track_locations.id WHERE library.id=" + QString("%1").arg(id)); |
625 | + query.prepare("SELECT library.id, artist, title, album, year, genre, tracknumber, filetype, rating, track_locations.location as location, track_locations.filesize as filesize, comment, url, duration, bitrate, samplerate, cuepoint, bpm, wavesummaryhex, channels, header_parsed, timesplayed, played FROM Library INNER JOIN track_locations ON library.location = track_locations.id WHERE library.id=" + QString("%1").arg(id)); |
626 | + |
627 | TrackPointer pTrack; |
628 | |
629 | if (query.exec()) { |
630 | @@ -641,9 +661,10 @@ |
631 | "SET artist=:artist, " |
632 | "title=:title, album=:album, year=:year, genre=:genre, " |
633 | "filetype=:filetype, tracknumber=:tracknumber, " |
634 | - "comment=:comment, url=:url, duration=:duration, " |
635 | + "comment=:comment, url=:url, duration=:duration, rating=:rating, " |
636 | "bitrate=:bitrate, samplerate=:samplerate, cuepoint=:cuepoint, " |
637 | "bpm=:bpm, wavesummaryhex=:wavesummaryhex, " |
638 | + "timesplayed=:timesplayed, played=:played, " |
639 | "channels=:channels, header_parsed=:header_parsed " |
640 | "WHERE id="+QString("%1").arg(trackId)); |
641 | query.bindValue(":artist", pTrack->getArtist()); |
642 | @@ -660,10 +681,12 @@ |
643 | query.bindValue(":samplerate", pTrack->getSampleRate()); |
644 | query.bindValue(":cuepoint", pTrack->getCuePoint()); |
645 | query.bindValue(":bpm", pTrack->getBpm()); |
646 | + query.bindValue(":rating", pTrack->getRating()); |
647 | const QByteArray* pWaveSummary = pTrack->getWaveSummary(); |
648 | if (pWaveSummary) //Avoid null pointer deref |
649 | query.bindValue(":wavesummaryhex", *pWaveSummary); |
650 | - //query.bindValue(":timesplayed", pTrack->getCuePoint()); |
651 | + query.bindValue(":timesplayed", pTrack->getTimesPlayed()); |
652 | + query.bindValue(":played", pTrack->getPlayed()); |
653 | query.bindValue(":channels", pTrack->getChannels()); |
654 | query.bindValue(":header_parsed", pTrack->getHeaderParsed() ? 1 : 0); |
655 | //query.bindValue(":location", pTrack->getLocation()); |
656 | |
657 | === modified file 'mixxx/src/library/dao/trackdao.h' |
658 | --- mixxx/src/library/dao/trackdao.h 2010-09-13 06:23:38 +0000 |
659 | +++ mixxx/src/library/dao/trackdao.h 2010-10-19 05:33:52 +0000 |
660 | @@ -38,6 +38,9 @@ |
661 | const QString LIBRARYTABLE_MIXXXDELETED = "mixxx_deleted"; |
662 | const QString LIBRARYTABLE_DATETIMEADDED = "datetime_added"; |
663 | const QString LIBRARYTABLE_HEADERPARSED = "header_parsed"; |
664 | +const QString LIBRARYTABLE_TIMESPLAYED = "timesplayed"; |
665 | +const QString LIBRARYTABLE_PLAYED = "played"; |
666 | +const QString LIBRARYTABLE_RATING = "rating"; |
667 | |
668 | const QString TRACKLOCATIONSTABLE_ID = "id"; |
669 | const QString TRACKLOCATIONSTABLE_LOCATION = "location"; |
670 | @@ -52,6 +55,7 @@ |
671 | public: |
672 | //TrackDAO() {}; |
673 | TrackDAO(QSqlDatabase& database, CueDAO& cueDao); |
674 | + void finish(); |
675 | virtual ~TrackDAO(); |
676 | void setDatabase(QSqlDatabase& database) { m_database = database; }; |
677 | |
678 | |
679 | === modified file 'mixxx/src/library/legacylibraryimporter.cpp' |
680 | --- mixxx/src/library/legacylibraryimporter.cpp 2010-09-11 08:15:14 +0000 |
681 | +++ mixxx/src/library/legacylibraryimporter.cpp 2010-10-19 05:33:52 +0000 |
682 | @@ -174,9 +174,16 @@ |
683 | } |
684 | } |
685 | |
686 | - //now change the file to mixxxtrack.bak so that its not readded next time program loads |
687 | - file.copy(QDir::homePath().append("/").append(SETTINGS_PATH).append("mixxxtrack.bak")); |
688 | - file.remove(); |
689 | + QString upgrade_filename = QDir::homePath().append("/").append(SETTINGS_PATH).append("DBUPGRADED"); |
690 | + //now create stub so that the library is not readded next time program loads |
691 | + QFile upgradefile(upgrade_filename); |
692 | + if (!upgradefile.open(QIODevice::WriteOnly | QIODevice::Text)) |
693 | + qDebug() << "Couldn't open" << upgrade_filename << "for writing"; |
694 | + else |
695 | + { |
696 | + file.write("",0); |
697 | + file.close(); |
698 | + } |
699 | } else { |
700 | qDebug() << errorMsg << " line: " << errorLine << " column: " << errorColumn; |
701 | } |
702 | |
703 | === modified file 'mixxx/src/library/libraryscanner.cpp' |
704 | --- mixxx/src/library/libraryscanner.cpp 2010-09-18 19:30:15 +0000 |
705 | +++ mixxx/src/library/libraryscanner.cpp 2010-10-19 05:33:52 +0000 |
706 | @@ -55,10 +55,10 @@ |
707 | */ |
708 | QString iTunesArtFolder = ""; |
709 | #if defined(__WINDOWS__) |
710 | - iTunesArtFolder = QDesktopServices::storageLocation(QDesktopServices::MusicLocation) + "\\iTunes\\Album Artwork"; |
711 | - iTunesArtFolder.replace(QString("\\"), QString("/")); |
712 | + iTunesArtFolder = QDesktopServices::storageLocation(QDesktopServices::MusicLocation) + "\\iTunes\\Album Artwork"; |
713 | + iTunesArtFolder.replace(QString("\\"), QString("/")); |
714 | #elif defined(__APPLE__) |
715 | - iTunesArtFolder = QDesktopServices::storageLocation(QDesktopServices::MusicLocation) + "/iTunes/Album Artwork"; |
716 | + iTunesArtFolder = QDesktopServices::storageLocation(QDesktopServices::MusicLocation) + "/iTunes/Album Artwork"; |
717 | #endif |
718 | m_directoriesBlacklist << iTunesArtFolder; |
719 | qDebug() << "iTunes Album Art path is:" << iTunesArtFolder; |
720 | @@ -109,7 +109,7 @@ |
721 | |
722 | //Print out any SQL error, if there was one. |
723 | if (query.lastError().isValid()) { |
724 | - qDebug() << query.lastError(); |
725 | + qDebug() << query.lastError(); |
726 | } |
727 | |
728 | QString dir; |
729 | @@ -167,15 +167,25 @@ |
730 | |
731 | QTime t2; |
732 | t2.start(); |
733 | - //Try to upgrade the library from 1.7 (XML) to 1.8+ (DB) if needed |
734 | - LegacyLibraryImporter libImport(m_trackDao, m_playlistDao); |
735 | - connect(&libImport, SIGNAL(progress(QString)), |
736 | - m_pProgress, SLOT(slotUpdate(QString)), |
737 | - Qt::BlockingQueuedConnection); |
738 | - m_database.transaction(); |
739 | - libImport.import(); |
740 | - m_database.commit(); |
741 | - qDebug("Legacy importer took %d ms", t2.elapsed()); |
742 | + |
743 | + //Try to upgrade the library from 1.7 (XML) to 1.8+ (DB) if needed. If the |
744 | + //upgrade_filename already exists, then do not try to upgrade since we have |
745 | + //already done it. |
746 | + QString upgrade_filename = QDir::homePath().append("/").append(SETTINGS_PATH).append("DBUPGRADED"); |
747 | + qDebug() << "upgrade filename is " << upgrade_filename; |
748 | + QFile upgradefile(upgrade_filename); |
749 | + if (!upgradefile.exists()) |
750 | + { |
751 | + LegacyLibraryImporter libImport(m_trackDao, m_playlistDao); |
752 | + connect(&libImport, SIGNAL(progress(QString)), |
753 | + m_pProgress, SLOT(slotUpdate(QString)), |
754 | + Qt::BlockingQueuedConnection); |
755 | + m_database.transaction(); |
756 | + libImport.import(); |
757 | + m_database.commit(); |
758 | + qDebug("Legacy importer took %d ms", t2.elapsed()); |
759 | + |
760 | + } |
761 | |
762 | //Refresh the name filters in case we loaded new |
763 | //SoundSource plugins. |
764 | |
765 | === modified file 'mixxx/src/library/librarytablemodel.cpp' |
766 | --- mixxx/src/library/librarytablemodel.cpp 2010-09-14 20:32:32 +0000 |
767 | +++ mixxx/src/library/librarytablemodel.cpp 2010-10-19 05:33:52 +0000 |
768 | @@ -20,11 +20,14 @@ |
769 | query.prepare("CREATE TEMPORARY VIEW IF NOT EXISTS library_view AS " |
770 | "SELECT " |
771 | "library." + LIBRARYTABLE_ID + "," + |
772 | + "library." + LIBRARYTABLE_PLAYED + "," + |
773 | + "library." + LIBRARYTABLE_TIMESPLAYED + "," + |
774 | "library." + LIBRARYTABLE_ARTIST + "," + |
775 | "library." + LIBRARYTABLE_TITLE + "," + |
776 | "library." + LIBRARYTABLE_ALBUM + "," + |
777 | "library." + LIBRARYTABLE_YEAR + "," + |
778 | "library." + LIBRARYTABLE_DURATION + "," + |
779 | + "library." + LIBRARYTABLE_RATING + "," + |
780 | "library." + LIBRARYTABLE_GENRE + "," + |
781 | "library." + LIBRARYTABLE_FILETYPE + "," + |
782 | "library." + LIBRARYTABLE_TRACKNUMBER + "," + |
783 | @@ -43,7 +46,7 @@ |
784 | |
785 | //Print out any SQL error, if there was one. |
786 | if (query.lastError().isValid()) { |
787 | - qDebug() << __FILE__ << __LINE__ << query.lastError(); |
788 | + qDebug() << __FILE__ << __LINE__ << query.lastError(); |
789 | } |
790 | |
791 | //setTable("library"); |
792 | @@ -56,34 +59,9 @@ |
793 | //and shows it... |
794 | //setRelation(fieldIndex(LIBRARYTABLE_LOCATION), QSqlRelation("track_locations", "id", "location")); |
795 | |
796 | - //Set the column heading labels, rename them for translations and have |
797 | - //proper capitalization |
798 | - setHeaderData(fieldIndex(LIBRARYTABLE_ARTIST), |
799 | - Qt::Horizontal, tr("Artist")); |
800 | - setHeaderData(fieldIndex(LIBRARYTABLE_TITLE), |
801 | - Qt::Horizontal, tr("Title")); |
802 | - setHeaderData(fieldIndex(LIBRARYTABLE_ALBUM), |
803 | - Qt::Horizontal, tr("Album")); |
804 | - setHeaderData(fieldIndex(LIBRARYTABLE_GENRE), |
805 | - Qt::Horizontal, tr("Genre")); |
806 | - setHeaderData(fieldIndex(LIBRARYTABLE_YEAR), |
807 | - Qt::Horizontal, tr("Year")); |
808 | - setHeaderData(fieldIndex(LIBRARYTABLE_FILETYPE), |
809 | - Qt::Horizontal, tr("Type")); |
810 | - setHeaderData(fieldIndex(LIBRARYTABLE_LOCATION), |
811 | - Qt::Horizontal, tr("Location")); |
812 | - setHeaderData(fieldIndex(LIBRARYTABLE_COMMENT), |
813 | - Qt::Horizontal, tr("Comment")); |
814 | - setHeaderData(fieldIndex(LIBRARYTABLE_DURATION), |
815 | - Qt::Horizontal, tr("Duration")); |
816 | - setHeaderData(fieldIndex(LIBRARYTABLE_BITRATE), |
817 | - Qt::Horizontal, tr("Bitrate")); |
818 | - setHeaderData(fieldIndex(LIBRARYTABLE_BPM), |
819 | - Qt::Horizontal, tr("BPM")); |
820 | - setHeaderData(fieldIndex(LIBRARYTABLE_TRACKNUMBER), |
821 | - Qt::Horizontal, tr("Track #")); |
822 | - setHeaderData(fieldIndex(LIBRARYTABLE_DATETIMEADDED), |
823 | - Qt::Horizontal, tr("Date Added")); |
824 | + |
825 | + // BaseSqlTabelModel will setup the header info |
826 | + initHeaderData(); |
827 | |
828 | //Sets up the table filter so that we don't show "deleted" tracks (only show mixxx_deleted=0). |
829 | slotSearch(""); |
830 | @@ -126,15 +104,15 @@ |
831 | |
832 | TrackPointer LibraryTableModel::getTrack(const QModelIndex& index) const |
833 | { |
834 | - int trackId = index.sibling(index.row(), fieldIndex(LIBRARYTABLE_ID)).data().toInt(); |
835 | - return m_trackDao.getTrack(trackId); |
836 | + int trackId = index.sibling(index.row(), fieldIndex(LIBRARYTABLE_ID)).data().toInt(); |
837 | + return m_trackDao.getTrack(trackId); |
838 | } |
839 | |
840 | QString LibraryTableModel::getTrackLocation(const QModelIndex& index) const |
841 | { |
842 | - const int locationColumnIndex = fieldIndex(LIBRARYTABLE_LOCATION); |
843 | - QString location = index.sibling(index.row(), locationColumnIndex).data().toString(); |
844 | - return location; |
845 | + const int locationColumnIndex = fieldIndex(LIBRARYTABLE_LOCATION); |
846 | + QString location = index.sibling(index.row(), locationColumnIndex).data().toString(); |
847 | + return location; |
848 | } |
849 | |
850 | void LibraryTableModel::removeTracks(const QModelIndexList& indices) { |
851 | @@ -152,9 +130,9 @@ |
852 | |
853 | void LibraryTableModel::removeTrack(const QModelIndex& index) |
854 | { |
855 | - int trackId = index.sibling(index.row(), fieldIndex(LIBRARYTABLE_ID)).data().toInt(); |
856 | - m_trackDao.removeTrack(trackId); |
857 | - select(); //Repopulate the data model. |
858 | + int trackId = index.sibling(index.row(), fieldIndex(LIBRARYTABLE_ID)).data().toInt(); |
859 | + m_trackDao.removeTrack(trackId); |
860 | + select(); //Repopulate the data model. |
861 | } |
862 | |
863 | void LibraryTableModel::moveTrack(const QModelIndex& sourceIndex, const QModelIndex& destIndex) |
864 | @@ -181,12 +159,21 @@ |
865 | filter = "(" + LibraryTableModel::DEFAULT_LIBRARYFILTER + ")"; |
866 | else { |
867 | QSqlField search("search", QVariant::String); |
868 | - search.setValue("%" + searchText + "%"); |
869 | - QString escapedText = database().driver()->formatValue(search); |
870 | - filter = "(" + LibraryTableModel::DEFAULT_LIBRARYFILTER + " AND " + |
871 | - "(artist LIKE " + escapedText + " OR " + |
872 | - "album LIKE " + escapedText + " OR " + |
873 | - "title LIKE " + escapedText + "))"; |
874 | + |
875 | + filter = "(" + LibraryTableModel::DEFAULT_LIBRARYFILTER; |
876 | + |
877 | + foreach(QString term, searchText.split(" ")) |
878 | + { |
879 | + search.setValue("%" + term + "%"); |
880 | + QString escapedText = database().driver()->formatValue(search); |
881 | + filter += " AND (artist LIKE " + escapedText + " OR " + |
882 | + "album LIKE " + escapedText + " OR " + |
883 | + "location LIKE " + escapedText + " OR " + |
884 | + "comment LIKE " + escapedText + " OR " + |
885 | + "title LIKE " + escapedText + ")"; |
886 | + } |
887 | + |
888 | + filter += ")"; |
889 | } |
890 | setFilter(filter); |
891 | } |
892 | @@ -205,6 +192,7 @@ |
893 | (column == fieldIndex(LIBRARYTABLE_SAMPLERATE)) || |
894 | (column == fieldIndex(LIBRARYTABLE_MIXXXDELETED)) || |
895 | (column == fieldIndex(LIBRARYTABLE_HEADERPARSED)) || |
896 | + (column == fieldIndex(LIBRARYTABLE_PLAYED)) || |
897 | (column == fieldIndex(LIBRARYTABLE_CHANNELS)) || |
898 | (column == fieldIndex(TRACKLOCATIONSTABLE_FSDELETED))) { |
899 | return true; |
900 | @@ -216,26 +204,6 @@ |
901 | return NULL; |
902 | } |
903 | |
904 | -QVariant LibraryTableModel::data(const QModelIndex& item, int role) const { |
905 | - if (!item.isValid()) |
906 | - return QVariant(); |
907 | - |
908 | - QVariant value; |
909 | - if (role == Qt::ToolTipRole) |
910 | - value = BaseSqlTableModel::data(item, Qt::DisplayRole); |
911 | - else |
912 | - value = BaseSqlTableModel::data(item, role); |
913 | - |
914 | - if ((role == Qt::DisplayRole || role == Qt::ToolTipRole) && |
915 | - item.column() == fieldIndex(LIBRARYTABLE_DURATION)) { |
916 | - if (qVariantCanConvert<int>(value)) { |
917 | - value = MixxxUtils::secondsToMinutes(qVariantValue<int>(value)); |
918 | - } |
919 | - } |
920 | - |
921 | - return value; |
922 | -} |
923 | - |
924 | QMimeData* LibraryTableModel::mimeData(const QModelIndexList &indexes) const { |
925 | QMimeData *mimeData = new QMimeData(); |
926 | QList<QUrl> urls; |
927 | @@ -263,26 +231,6 @@ |
928 | return mimeData; |
929 | } |
930 | |
931 | -Qt::ItemFlags LibraryTableModel::flags(const QModelIndex &index) const |
932 | -{ |
933 | - Qt::ItemFlags defaultFlags = QAbstractItemModel::flags(index); |
934 | - if (!index.isValid()) |
935 | - return Qt::ItemIsEnabled; |
936 | - |
937 | - //Enable dragging songs from this data model to elsewhere (like the waveform |
938 | - //widget to load a track into a Player). |
939 | - defaultFlags |= Qt::ItemIsDragEnabled; |
940 | - |
941 | - /** FIXME: This doesn't seem to work - Albert */ |
942 | - const int bpmColumnIndex = fieldIndex(LIBRARYTABLE_BPM); |
943 | - if (index.column() == bpmColumnIndex) |
944 | - { |
945 | - return defaultFlags | Qt::ItemIsEditable; |
946 | - } |
947 | - |
948 | - return defaultFlags; |
949 | -} |
950 | - |
951 | TrackModel::CapabilitiesFlags LibraryTableModel::getCapabilities() const |
952 | { |
953 | return TRACKMODELCAPS_RECEIVEDROPS | TRACKMODELCAPS_ADDTOPLAYLIST | |
954 | |
955 | === modified file 'mixxx/src/library/librarytablemodel.h' |
956 | --- mixxx/src/library/librarytablemodel.h 2010-09-13 06:23:38 +0000 |
957 | +++ mixxx/src/library/librarytablemodel.h 2010-10-19 05:33:52 +0000 |
958 | @@ -27,11 +27,9 @@ |
959 | virtual bool addTrack(const QModelIndex& index, QString location); |
960 | virtual void moveTrack(const QModelIndex& sourceIndex, |
961 | const QModelIndex& destIndex); |
962 | - virtual QVariant data(const QModelIndex& item, int role) const; |
963 | |
964 | |
965 | QMimeData* mimeData(const QModelIndexList &indexes) const; |
966 | - Qt::ItemFlags flags(const QModelIndex &index) const; |
967 | QItemDelegate* delegateForColumn(const int i); |
968 | TrackModel::CapabilitiesFlags getCapabilities() const; |
969 | static const QString DEFAULT_LIBRARYFILTER; |
970 | |
971 | === modified file 'mixxx/src/library/missingtablemodel.cpp' |
972 | --- mixxx/src/library/missingtablemodel.cpp 2010-09-14 20:32:32 +0000 |
973 | +++ mixxx/src/library/missingtablemodel.cpp 2010-10-19 05:33:52 +0000 |
974 | @@ -25,11 +25,14 @@ |
975 | query.prepare("CREATE TEMPORARY VIEW IF NOT EXISTS " + tableName + " AS " |
976 | "SELECT " + |
977 | "library." + LIBRARYTABLE_ID + "," + |
978 | + "library." + LIBRARYTABLE_PLAYED + "," + |
979 | + "library." + LIBRARYTABLE_TIMESPLAYED + "," + |
980 | "library." + LIBRARYTABLE_ARTIST + "," + |
981 | "library." + LIBRARYTABLE_TITLE + "," + |
982 | "library." + LIBRARYTABLE_ALBUM + "," + |
983 | "library." + LIBRARYTABLE_YEAR + "," + |
984 | "library." + LIBRARYTABLE_DURATION + "," + |
985 | + "library." + LIBRARYTABLE_RATING + "," + |
986 | "library." + LIBRARYTABLE_GENRE + "," + |
987 | "library." + LIBRARYTABLE_FILETYPE + "," + |
988 | "library." + LIBRARYTABLE_TRACKNUMBER + "," + |
989 | @@ -58,36 +61,7 @@ |
990 | |
991 | qDebug() << "Created MissingTracksModel!"; |
992 | |
993 | - //Set the column heading labels, rename them for translations and have |
994 | - //proper capitalization |
995 | - setHeaderData(fieldIndex("track_locations.location"), |
996 | - Qt::Horizontal, tr("Location")); |
997 | - setHeaderData(fieldIndex(LIBRARYTABLE_ARTIST), |
998 | - Qt::Horizontal, tr("Artist")); |
999 | - setHeaderData(fieldIndex(LIBRARYTABLE_TITLE), |
1000 | - Qt::Horizontal, tr("Title")); |
1001 | - setHeaderData(fieldIndex(LIBRARYTABLE_ALBUM), |
1002 | - Qt::Horizontal, tr("Album")); |
1003 | - setHeaderData(fieldIndex(LIBRARYTABLE_GENRE), |
1004 | - Qt::Horizontal, tr("Genre")); |
1005 | - setHeaderData(fieldIndex(LIBRARYTABLE_YEAR), |
1006 | - Qt::Horizontal, tr("Year")); |
1007 | - setHeaderData(fieldIndex(LIBRARYTABLE_FILETYPE), |
1008 | - Qt::Horizontal, tr("Type")); |
1009 | - setHeaderData(fieldIndex(LIBRARYTABLE_LOCATION), |
1010 | - Qt::Horizontal, tr("Location")); |
1011 | - setHeaderData(fieldIndex(LIBRARYTABLE_COMMENT), |
1012 | - Qt::Horizontal, tr("Comment")); |
1013 | - setHeaderData(fieldIndex(LIBRARYTABLE_DURATION), |
1014 | - Qt::Horizontal, tr("Duration")); |
1015 | - setHeaderData(fieldIndex(LIBRARYTABLE_TRACKNUMBER), |
1016 | - Qt::Horizontal, tr("Track #")); |
1017 | - setHeaderData(fieldIndex(LIBRARYTABLE_BITRATE), |
1018 | - Qt::Horizontal, tr("Bitrate")); |
1019 | - setHeaderData(fieldIndex(LIBRARYTABLE_BPM), |
1020 | - Qt::Horizontal, tr("BPM")); |
1021 | - setHeaderData(fieldIndex(LIBRARYTABLE_DATETIMEADDED), |
1022 | - Qt::Horizontal, tr("Date Added")); |
1023 | + initHeaderData(); //derived from BaseSqlModel |
1024 | |
1025 | slotSearch(""); |
1026 | |
1027 | @@ -168,6 +142,7 @@ |
1028 | |
1029 | bool MissingTableModel::isColumnInternal(int column) { |
1030 | if (column == fieldIndex(LIBRARYTABLE_ID) || |
1031 | + column == fieldIndex(LIBRARYTABLE_PLAYED) || |
1032 | column == fieldIndex(LIBRARYTABLE_MIXXXDELETED) || |
1033 | column == fieldIndex(TRACKLOCATIONSTABLE_FSDELETED)) |
1034 | return true; |
1035 | @@ -200,42 +175,16 @@ |
1036 | return mimeData; |
1037 | } |
1038 | |
1039 | +/** Override flags from BaseSqlModel since we don't want edit this model */ |
1040 | Qt::ItemFlags MissingTableModel::flags(const QModelIndex &index) const |
1041 | { |
1042 | - Qt::ItemFlags defaultFlags = QAbstractItemModel::flags(index); |
1043 | - if (!index.isValid()) |
1044 | - return Qt::ItemIsEnabled; |
1045 | - |
1046 | - //defaultFlags |= Qt::ItemIsDragEnabled; |
1047 | - //defaultFlags = 0; |
1048 | - |
1049 | - return defaultFlags; |
1050 | + return readOnlyFlags(index); |
1051 | } |
1052 | |
1053 | QItemDelegate* MissingTableModel::delegateForColumn(const int i) { |
1054 | return NULL; |
1055 | } |
1056 | |
1057 | -QVariant MissingTableModel::data(const QModelIndex& item, int role) const { |
1058 | - if (!item.isValid()) |
1059 | - return QVariant(); |
1060 | - |
1061 | - QVariant value; |
1062 | - |
1063 | - if (role == Qt::ToolTipRole) |
1064 | - value = BaseSqlTableModel::data(item, Qt::DisplayRole); |
1065 | - else |
1066 | - value = BaseSqlTableModel::data(item, role); |
1067 | - |
1068 | - if ((role == Qt::DisplayRole || role == Qt::ToolTipRole) && |
1069 | - item.column() == fieldIndex(LIBRARYTABLE_DURATION)) { |
1070 | - if (qVariantCanConvert<int>(value)) { |
1071 | - value = MixxxUtils::secondsToMinutes(qVariantValue<int>(value)); |
1072 | - } |
1073 | - } |
1074 | - return value; |
1075 | -} |
1076 | - |
1077 | TrackModel::CapabilitiesFlags MissingTableModel::getCapabilities() const |
1078 | { |
1079 | return 0; |
1080 | |
1081 | === modified file 'mixxx/src/library/missingtablemodel.h' |
1082 | --- mixxx/src/library/missingtablemodel.h 2010-09-13 06:23:38 +0000 |
1083 | +++ mixxx/src/library/missingtablemodel.h 2010-10-19 05:33:52 +0000 |
1084 | @@ -26,7 +26,7 @@ |
1085 | virtual void removeTracks(const QModelIndexList& indices); |
1086 | virtual bool addTrack(const QModelIndex& index, QString location); |
1087 | virtual void moveTrack(const QModelIndex& sourceIndex, const QModelIndex& destIndex); |
1088 | - virtual QVariant data(const QModelIndex& item, int role) const; |
1089 | + |
1090 | QMimeData* mimeData(const QModelIndexList &indexes) const; |
1091 | Qt::ItemFlags flags(const QModelIndex &index) const; |
1092 | QItemDelegate* delegateForColumn(const int i); |
1093 | |
1094 | === modified file 'mixxx/src/library/playlisttablemodel.cpp' |
1095 | --- mixxx/src/library/playlisttablemodel.cpp 2010-09-14 20:32:32 +0000 |
1096 | +++ mixxx/src/library/playlisttablemodel.cpp 2010-10-19 05:33:52 +0000 |
1097 | @@ -44,11 +44,14 @@ |
1098 | "PlaylistTracks." + PLAYLISTTRACKSTABLE_POSITION + "," + |
1099 | //"playlist_id, " + //DEBUG |
1100 | "library." + LIBRARYTABLE_ID + "," + |
1101 | + "library." + LIBRARYTABLE_PLAYED + "," + |
1102 | + "library." + LIBRARYTABLE_TIMESPLAYED + "," + |
1103 | "library." + LIBRARYTABLE_ARTIST + "," + |
1104 | "library." + LIBRARYTABLE_TITLE + "," + |
1105 | "library." + LIBRARYTABLE_ALBUM + "," + |
1106 | "library." + LIBRARYTABLE_YEAR + "," + |
1107 | "library." + LIBRARYTABLE_DURATION + "," + |
1108 | + "library." + LIBRARYTABLE_RATING + "," + |
1109 | "library." + LIBRARYTABLE_GENRE + "," + |
1110 | "library." + LIBRARYTABLE_FILETYPE + "," + |
1111 | "library." + LIBRARYTABLE_TRACKNUMBER + "," + |
1112 | @@ -79,36 +82,7 @@ |
1113 | |
1114 | setTable(playlistTableName); |
1115 | |
1116 | - //Set the column heading labels, rename them for translations and have |
1117 | - //proper capitalization |
1118 | - setHeaderData(fieldIndex(PLAYLISTTRACKSTABLE_POSITION), |
1119 | - Qt::Horizontal, tr("#")); |
1120 | - setHeaderData(fieldIndex(LIBRARYTABLE_ARTIST), |
1121 | - Qt::Horizontal, tr("Artist")); |
1122 | - setHeaderData(fieldIndex(LIBRARYTABLE_TITLE), |
1123 | - Qt::Horizontal, tr("Title")); |
1124 | - setHeaderData(fieldIndex(LIBRARYTABLE_ALBUM), |
1125 | - Qt::Horizontal, tr("Album")); |
1126 | - setHeaderData(fieldIndex(LIBRARYTABLE_GENRE), |
1127 | - Qt::Horizontal, tr("Genre")); |
1128 | - setHeaderData(fieldIndex(LIBRARYTABLE_YEAR), |
1129 | - Qt::Horizontal, tr("Year")); |
1130 | - setHeaderData(fieldIndex(LIBRARYTABLE_FILETYPE), |
1131 | - Qt::Horizontal, tr("Type")); |
1132 | - setHeaderData(fieldIndex("location"), |
1133 | - Qt::Horizontal, tr("Location")); |
1134 | - setHeaderData(fieldIndex(LIBRARYTABLE_COMMENT), |
1135 | - Qt::Horizontal, tr("Comment")); |
1136 | - setHeaderData(fieldIndex(LIBRARYTABLE_DURATION), |
1137 | - Qt::Horizontal, tr("Duration")); |
1138 | - setHeaderData(fieldIndex(LIBRARYTABLE_TRACKNUMBER), |
1139 | - Qt::Horizontal, tr("Track #")); |
1140 | - setHeaderData(fieldIndex(LIBRARYTABLE_BITRATE), |
1141 | - Qt::Horizontal, tr("Bitrate")); |
1142 | - setHeaderData(fieldIndex(LIBRARYTABLE_DATETIMEADDED), |
1143 | - Qt::Horizontal, tr("Date Added")); |
1144 | - setHeaderData(fieldIndex(LIBRARYTABLE_BPM), |
1145 | - Qt::Horizontal, tr("BPM")); |
1146 | + initHeaderData(); //derived from BaseSqlModel |
1147 | |
1148 | slotSearch(""); |
1149 | |
1150 | @@ -323,6 +297,7 @@ |
1151 | |
1152 | bool PlaylistTableModel::isColumnInternal(int column) { |
1153 | if (column == fieldIndex(LIBRARYTABLE_ID) || |
1154 | + column == fieldIndex(LIBRARYTABLE_PLAYED) || |
1155 | column == fieldIndex(LIBRARYTABLE_MIXXXDELETED) || |
1156 | column == fieldIndex(TRACKLOCATIONSTABLE_FSDELETED)) |
1157 | return true; |
1158 | @@ -354,43 +329,11 @@ |
1159 | return mimeData; |
1160 | } |
1161 | |
1162 | -Qt::ItemFlags PlaylistTableModel::flags(const QModelIndex &index) const |
1163 | -{ |
1164 | - Qt::ItemFlags defaultFlags = QAbstractItemModel::flags(index); |
1165 | - if (!index.isValid()) |
1166 | - return Qt::ItemIsEnabled; |
1167 | - |
1168 | - //Enable dragging songs from this data model to elsewhere (like the waveform widget to |
1169 | - //load a track into a Player). |
1170 | - defaultFlags |= Qt::ItemIsDragEnabled; |
1171 | - |
1172 | - return defaultFlags; |
1173 | -} |
1174 | |
1175 | QItemDelegate* PlaylistTableModel::delegateForColumn(const int i) { |
1176 | return NULL; |
1177 | } |
1178 | |
1179 | -QVariant PlaylistTableModel::data(const QModelIndex& item, int role) const { |
1180 | - if (!item.isValid()) |
1181 | - return QVariant(); |
1182 | - |
1183 | - QVariant value; |
1184 | - |
1185 | - if (role == Qt::ToolTipRole) |
1186 | - value = BaseSqlTableModel::data(item, Qt::DisplayRole); |
1187 | - else |
1188 | - value = BaseSqlTableModel::data(item, role); |
1189 | - |
1190 | - if ((role == Qt::DisplayRole || role == Qt::ToolTipRole) && |
1191 | - item.column() == fieldIndex(LIBRARYTABLE_DURATION)) { |
1192 | - if (qVariantCanConvert<int>(value)) { |
1193 | - value = MixxxUtils::secondsToMinutes(qVariantValue<int>(value)); |
1194 | - } |
1195 | - } |
1196 | - return value; |
1197 | -} |
1198 | - |
1199 | TrackModel::CapabilitiesFlags PlaylistTableModel::getCapabilities() const |
1200 | { |
1201 | TrackModel::CapabilitiesFlags caps = TRACKMODELCAPS_RECEIVEDROPS | TRACKMODELCAPS_REORDER | TRACKMODELCAPS_ADDTOCRATE | TRACKMODELCAPS_ADDTOPLAYLIST; |
1202 | |
1203 | === added file 'mixxx/src/library/playlisttablemodel.h' |
1204 | --- mixxx/src/library/playlisttablemodel.h 1970-01-01 00:00:00 +0000 |
1205 | +++ mixxx/src/library/playlisttablemodel.h 2010-10-19 05:33:52 +0000 |
1206 | @@ -0,0 +1,51 @@ |
1207 | +#ifndef PLAYLISTTABLEMODEL_H |
1208 | +#define PLAYLISTTABLEMODEL_H |
1209 | + |
1210 | +#include <QtSql> |
1211 | +#include <QItemDelegate> |
1212 | +#include <QtCore> |
1213 | +#include "trackmodel.h" |
1214 | +#include "library/basesqltablemodel.h" |
1215 | +#include "library/librarytablemodel.h" |
1216 | +#include "library/dao/playlistdao.h" |
1217 | +#include "library/dao/trackdao.h" |
1218 | + |
1219 | +class TrackCollection; |
1220 | + |
1221 | +class PlaylistTableModel : public BaseSqlTableModel, public virtual TrackModel |
1222 | +{ |
1223 | + Q_OBJECT |
1224 | + public: |
1225 | + PlaylistTableModel(QObject* parent, TrackCollection* pTrackCollection); |
1226 | + virtual ~PlaylistTableModel(); |
1227 | + void setPlaylist(int playlistId); |
1228 | + virtual TrackPointer getTrack(const QModelIndex& index) const; |
1229 | + virtual QString getTrackLocation(const QModelIndex& index) const; |
1230 | + virtual void search(const QString& searchText); |
1231 | + virtual const QString currentSearch(); |
1232 | + virtual bool isColumnInternal(int column); |
1233 | + virtual void removeTrack(const QModelIndex& index); |
1234 | + virtual void removeTracks(const QModelIndexList& indices); |
1235 | + virtual bool addTrack(const QModelIndex& index, QString location); |
1236 | + virtual void moveTrack(const QModelIndex& sourceIndex, const QModelIndex& destIndex); |
1237 | + |
1238 | + QMimeData* mimeData(const QModelIndexList &indexes) const; |
1239 | + |
1240 | + QItemDelegate* delegateForColumn(const int i); |
1241 | + TrackModel::CapabilitiesFlags getCapabilities() const; |
1242 | + |
1243 | + private slots: |
1244 | + void slotSearch(const QString& searchText); |
1245 | + |
1246 | + signals: |
1247 | + void doSearch(const QString& searchText); |
1248 | + |
1249 | + private: |
1250 | + TrackCollection* m_pTrackCollection; |
1251 | + PlaylistDAO& m_playlistDao; |
1252 | + TrackDAO& m_trackDao; |
1253 | + int m_iPlaylistId; |
1254 | + QString m_currentSearch; |
1255 | +}; |
1256 | + |
1257 | +#endif |
1258 | |
1259 | === removed file 'mixxx/src/library/playlisttablemodel.h' |
1260 | --- mixxx/src/library/playlisttablemodel.h 2010-09-13 06:23:38 +0000 |
1261 | +++ mixxx/src/library/playlisttablemodel.h 1970-01-01 00:00:00 +0000 |
1262 | @@ -1,51 +0,0 @@ |
1263 | -#ifndef PLAYLISTTABLEMODEL_H |
1264 | -#define PLAYLISTTABLEMODEL_H |
1265 | - |
1266 | -#include <QtSql> |
1267 | -#include <QItemDelegate> |
1268 | -#include <QtCore> |
1269 | -#include "trackmodel.h" |
1270 | -#include "library/basesqltablemodel.h" |
1271 | -#include "library/librarytablemodel.h" |
1272 | -#include "library/dao/playlistdao.h" |
1273 | -#include "library/dao/trackdao.h" |
1274 | - |
1275 | -class TrackCollection; |
1276 | - |
1277 | -class PlaylistTableModel : public BaseSqlTableModel, public virtual TrackModel |
1278 | -{ |
1279 | - Q_OBJECT |
1280 | - public: |
1281 | - PlaylistTableModel(QObject* parent, TrackCollection* pTrackCollection); |
1282 | - virtual ~PlaylistTableModel(); |
1283 | - void setPlaylist(int playlistId); |
1284 | - virtual TrackPointer getTrack(const QModelIndex& index) const; |
1285 | - virtual QString getTrackLocation(const QModelIndex& index) const; |
1286 | - virtual void search(const QString& searchText); |
1287 | - virtual const QString currentSearch(); |
1288 | - virtual bool isColumnInternal(int column); |
1289 | - virtual void removeTrack(const QModelIndex& index); |
1290 | - virtual void removeTracks(const QModelIndexList& indices); |
1291 | - virtual bool addTrack(const QModelIndex& index, QString location); |
1292 | - virtual void moveTrack(const QModelIndex& sourceIndex, const QModelIndex& destIndex); |
1293 | - virtual QVariant data(const QModelIndex& item, int role) const; |
1294 | - QMimeData* mimeData(const QModelIndexList &indexes) const; |
1295 | - Qt::ItemFlags flags(const QModelIndex &index) const; |
1296 | - QItemDelegate* delegateForColumn(const int i); |
1297 | - TrackModel::CapabilitiesFlags getCapabilities() const; |
1298 | - |
1299 | - private slots: |
1300 | - void slotSearch(const QString& searchText); |
1301 | - |
1302 | - signals: |
1303 | - void doSearch(const QString& searchText); |
1304 | - |
1305 | - private: |
1306 | - TrackCollection* m_pTrackCollection; |
1307 | - PlaylistDAO& m_playlistDao; |
1308 | - TrackDAO& m_trackDao; |
1309 | - int m_iPlaylistId; |
1310 | - QString m_currentSearch; |
1311 | -}; |
1312 | - |
1313 | -#endif |
1314 | |
1315 | === modified file 'mixxx/src/library/rhythmboxtrackmodel.cpp' |
1316 | --- mixxx/src/library/rhythmboxtrackmodel.cpp 2010-10-15 21:17:06 +0000 |
1317 | +++ mixxx/src/library/rhythmboxtrackmodel.cpp 2010-10-19 05:33:52 +0000 |
1318 | @@ -160,6 +160,9 @@ |
1319 | pTrack->setGenre(songNode.firstChildElement("genre").text()); |
1320 | pTrack->setDuration(songNode.firstChildElement("duration").text().toUInt()); |
1321 | |
1322 | + // TODO(ywwg) why was this added? constructor above does the same -- rryan |
1323 | + pTrack->setLocation(trackLocation); |
1324 | + |
1325 | // Have QObject handle deleting this track |
1326 | return TrackPointer(pTrack, &QObject::deleteLater); |
1327 | } |
1328 | |
1329 | === added file 'mixxx/src/library/stardelegate.cpp' |
1330 | --- mixxx/src/library/stardelegate.cpp 1970-01-01 00:00:00 +0000 |
1331 | +++ mixxx/src/library/stardelegate.cpp 2010-10-19 05:33:52 +0000 |
1332 | @@ -0,0 +1,114 @@ |
1333 | +/*************************************************************************** |
1334 | + stardelegate.cpp |
1335 | + ------------------- |
1336 | + copyright : (C) 2010 Tobias Rafreider |
1337 | + copyright : (C) 2009 Nokia Corporation |
1338 | + |
1339 | +***************************************************************************/ |
1340 | + |
1341 | +/*************************************************************************** |
1342 | + * * |
1343 | + * This program is free software; you can redistribute it and/or modify * |
1344 | + * it under the terms of the GNU General Public License as published by * |
1345 | + * the Free Software Foundation; either version 2 of the License, or * |
1346 | + * (at your option) any later version. * |
1347 | + * * |
1348 | + ***************************************************************************/ |
1349 | + |
1350 | + |
1351 | +#include <QtDebug> |
1352 | +#include <QtGui> |
1353 | + |
1354 | +#include "stardelegate.h" |
1355 | +#include "stareditor.h" |
1356 | +#include "starrating.h" |
1357 | + |
1358 | +/* |
1359 | + * The function is invoked once for each item, represented by a QModelIndex object from the model. |
1360 | + * If the data stored in the item is a StarRating, we paint it use a star editor for displaying; |
1361 | + * otherwise, we let QItemDelegate paint it for us. |
1362 | + * This ensures that the StarDelegate can handle the most common data types. |
1363 | + */ |
1364 | +void StarDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const |
1365 | +{ |
1366 | + // Populate the correct colors based on the styling |
1367 | + QStyleOptionViewItem newOption = option; |
1368 | + initStyleOption(&newOption, index); |
1369 | + |
1370 | + // Set the palette appropriately based on whether the row is selected or not |
1371 | + if (newOption.state & QStyle::State_Selected) { |
1372 | + painter->fillRect(newOption.rect, newOption.palette.highlight()); |
1373 | + painter->setBrush(newOption.palette.highlightedText()); |
1374 | + } else { |
1375 | + painter->fillRect(newOption.rect, newOption.palette.base()); |
1376 | + painter->setBrush(newOption.palette.text()); |
1377 | + } |
1378 | + |
1379 | + if (qVariantCanConvert<StarRating>(index.data())) { |
1380 | + StarRating starRating = qVariantValue<StarRating>(index.data()); |
1381 | + starRating.paint(painter, newOption.rect, newOption.palette, StarRating::ReadOnly); |
1382 | + } else { |
1383 | + QStyledItemDelegate::paint(painter, newOption, index); |
1384 | + } |
1385 | +} |
1386 | + |
1387 | +QSize StarDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const |
1388 | +{ |
1389 | + if (qVariantCanConvert<StarRating>(index.data())) { |
1390 | + StarRating starRating = qVariantValue<StarRating>(index.data()); |
1391 | + return starRating.sizeHint(); |
1392 | + } else { |
1393 | + return QStyledItemDelegate::sizeHint(option, index); |
1394 | + } |
1395 | +} |
1396 | +/* |
1397 | + * If the item is a StarRating, we create a StarEditor and connect |
1398 | + * its editingFinished() signal to our commitAndCloseEditor() slot, |
1399 | + * so we can update the model when the editor closes. |
1400 | + */ |
1401 | +QWidget *StarDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option,const QModelIndex &index) const |
1402 | +{ |
1403 | + // Populate the correct colors based on the styling |
1404 | + QStyleOptionViewItem newOption = option; |
1405 | + initStyleOption(&newOption, index); |
1406 | + |
1407 | + if (qVariantCanConvert<StarRating>(index.data())) { |
1408 | + StarEditor *editor = new StarEditor(parent, newOption); |
1409 | + connect(editor, SIGNAL(editingFinished()), |
1410 | + this, SLOT(commitAndCloseEditor())); |
1411 | + return editor; |
1412 | + } else { |
1413 | + return QStyledItemDelegate::createEditor(parent, newOption, index); |
1414 | + } |
1415 | +} |
1416 | + |
1417 | +void StarDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const |
1418 | +{ |
1419 | + if (qVariantCanConvert<StarRating>(index.data())) { |
1420 | + StarRating starRating = qVariantValue<StarRating>(index.data()); |
1421 | + StarEditor *starEditor = qobject_cast<StarEditor *>(editor); |
1422 | + starEditor->setStarRating(starRating); |
1423 | + } else { |
1424 | + QStyledItemDelegate::setEditorData(editor, index); |
1425 | + } |
1426 | +} |
1427 | + |
1428 | +void StarDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const |
1429 | +{ |
1430 | + if (qVariantCanConvert<StarRating>(index.data())) { |
1431 | + StarEditor *starEditor = qobject_cast<StarEditor *>(editor); |
1432 | + model->setData(index, qVariantFromValue(starEditor->starRating())); |
1433 | + } else { |
1434 | + QStyledItemDelegate::setModelData(editor, model, index); |
1435 | + } |
1436 | +} |
1437 | +/* |
1438 | + * When the user is done editing, we emit commitData() and closeEditor() (both declared in QAbstractItemDelegate), |
1439 | + * to tell the model that there is edited data and to inform the view that the editor is no longer needed. |
1440 | + */ |
1441 | +void StarDelegate::commitAndCloseEditor() |
1442 | +{ |
1443 | + StarEditor *editor = qobject_cast<StarEditor *>(sender()); |
1444 | + emit commitData(editor); |
1445 | + emit closeEditor(editor); |
1446 | +} |
1447 | |
1448 | === added file 'mixxx/src/library/stardelegate.h' |
1449 | --- mixxx/src/library/stardelegate.h 1970-01-01 00:00:00 +0000 |
1450 | +++ mixxx/src/library/stardelegate.h 2010-10-19 05:33:52 +0000 |
1451 | @@ -0,0 +1,56 @@ |
1452 | +/*************************************************************************** |
1453 | + stardelegate.h |
1454 | + ------------------- |
1455 | + copyright : (C) 2010 Tobias Rafreider |
1456 | + copyright : (C) 2009 Nokia Corporation |
1457 | + |
1458 | +***************************************************************************/ |
1459 | + |
1460 | +/*************************************************************************** |
1461 | + * * |
1462 | + * This program is free software; you can redistribute it and/or modify * |
1463 | + * it under the terms of the GNU General Public License as published by * |
1464 | + * the Free Software Foundation; either version 2 of the License, or * |
1465 | + * (at your option) any later version. * |
1466 | + * * |
1467 | + ***************************************************************************/ |
1468 | + |
1469 | + |
1470 | +#ifndef STARDELEGATE_H |
1471 | +#define STARDELEGATE_H |
1472 | + |
1473 | +#include <QStyledItemDelegate> |
1474 | + |
1475 | +/* |
1476 | + * When displaying data in a QListView, QTableView, or QTreeView, |
1477 | + * the individual items are drawn by a delegate. |
1478 | + * Also, when the user starts editing an item (e.g., by double-clicking the item), |
1479 | + * the delegate provides an editor widget that is placed on top of the item while editing takes place. |
1480 | + * |
1481 | + * By default a QListView, QTableView, or QTreeView has a QItemDelegate attached, |
1482 | + * which inherits QAbstractItemDelegate and handles the most common data types (notably int and QString). |
1483 | + * If we need to support custom data types, or want to customize the rendering or the editing for |
1484 | + * existing data types, we can subclass QAbstractItemDelegate or QItemDelegate or QStyledItemDelegate |
1485 | + */ |
1486 | +class StarDelegate : public QStyledItemDelegate |
1487 | +{ |
1488 | + Q_OBJECT |
1489 | + |
1490 | +public: |
1491 | + StarDelegate(QWidget *parent = 0) : QStyledItemDelegate(parent) {} |
1492 | + /** reimplemented from QItemDelegate and is called whenever the view needs to repaint an item **/ |
1493 | + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; |
1494 | + /** eturns an item's preferred size **/ |
1495 | + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; |
1496 | + /** called when the user starts editing an item: **/ |
1497 | + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,const QModelIndex &index) const; |
1498 | + /** called when an editor is created to initialize it with data from the model: **/ |
1499 | + void setEditorData(QWidget *editor, const QModelIndex &index) const; |
1500 | + /** called when editing is finished, to commit data from the editor to the model: **/ |
1501 | + void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const; |
1502 | + |
1503 | +private slots: |
1504 | + void commitAndCloseEditor(); |
1505 | +}; |
1506 | + |
1507 | +#endif |
1508 | |
1509 | === added file 'mixxx/src/library/stareditor.cpp' |
1510 | --- mixxx/src/library/stareditor.cpp 1970-01-01 00:00:00 +0000 |
1511 | +++ mixxx/src/library/stareditor.cpp 2010-10-19 05:33:52 +0000 |
1512 | @@ -0,0 +1,95 @@ |
1513 | +/*************************************************************************** |
1514 | + stareditor.cpp |
1515 | + ------------------- |
1516 | + copyright : (C) 2010 Tobias Rafreider |
1517 | + copyright : (C) 2009 Nokia Corporation |
1518 | + |
1519 | +***************************************************************************/ |
1520 | + |
1521 | +/*************************************************************************** |
1522 | + * * |
1523 | + * This program is free software; you can redistribute it and/or modify * |
1524 | + * it under the terms of the GNU General Public License as published by * |
1525 | + * the Free Software Foundation; either version 2 of the License, or * |
1526 | + * (at your option) any later version. * |
1527 | + * * |
1528 | + ***************************************************************************/ |
1529 | + |
1530 | +/*************************************************************************** |
1531 | + * * |
1532 | + * StarEditor inherits QWidget and is used by StarDelegate to let the user * |
1533 | + * edit a star rating in the library using the mouse. * |
1534 | + * * |
1535 | + * The class has been adapted from the official "Star Delegate Example", * |
1536 | + * see http://doc.trolltech.com/4.5/itemviews-stardelegate.html * |
1537 | + ***************************************************************************/ |
1538 | + |
1539 | + #include <QtGui> |
1540 | + |
1541 | + #include "stareditor.h" |
1542 | + #include "starrating.h" |
1543 | + |
1544 | +/* |
1545 | + * We enable mouse tracking on the widget so we can follow the cursor even |
1546 | + * when the user doesn't hold down any mouse button. We also turn on |
1547 | + * QWidget's auto-fill background feature to obtain an opaque background. |
1548 | + * (Without the call, the view's background would shine through the editor.) |
1549 | + */ |
1550 | +StarEditor::StarEditor(QWidget *parent, const QStyleOptionViewItem &option) |
1551 | + : QWidget(parent) |
1552 | +{ |
1553 | + setPalette(option.palette); |
1554 | + setMouseTracking(true); |
1555 | + setAutoFillBackground(true); |
1556 | +} |
1557 | + |
1558 | +QSize StarEditor::sizeHint() const |
1559 | + { |
1560 | + return m_starRating.sizeHint(); |
1561 | + } |
1562 | +/* |
1563 | + * We simply call StarRating::paint() to draw the stars, |
1564 | + * just like we did when implementing StarDelegate |
1565 | + */ |
1566 | +void StarEditor::paintEvent(QPaintEvent *) |
1567 | + { |
1568 | + QPainter painter(this); |
1569 | + m_starRating.paint(&painter, rect(), palette(), StarRating::Editable); |
1570 | + } |
1571 | +/* |
1572 | + * In the mouse event handler, we call setStarCount() on |
1573 | + * the private data member m_starRating to reflect the current cursor position, |
1574 | + * and we call QWidget::update() to force a repaint. |
1575 | + */ |
1576 | + void StarEditor::mouseMoveEvent(QMouseEvent *event) |
1577 | + { |
1578 | + int star = starAtPosition(event->x()); |
1579 | + |
1580 | + if (star != m_starRating.starCount() && star != -1) { |
1581 | + m_starRating.setStarCount(star); |
1582 | + update(); |
1583 | + } |
1584 | + } |
1585 | +/* |
1586 | + * When the user releases a mouse button, we simply emit the editingFinished() signal. |
1587 | + */ |
1588 | + void StarEditor::mouseReleaseEvent(QMouseEvent * /* event */) |
1589 | + { |
1590 | + emit editingFinished(); |
1591 | + } |
1592 | +/* |
1593 | + * The method uses basic linear algebra to find out which star is under the cursor. |
1594 | + */ |
1595 | + int StarEditor::starAtPosition(int x) |
1596 | + { |
1597 | + // If the mouse is very close to the left edge, set 0 stars. |
1598 | + if (x < m_starRating.sizeHint().width() * 0.05) { |
1599 | + return 0; |
1600 | + } |
1601 | + int star = (x / (m_starRating.sizeHint().width() / m_starRating.maxStarCount())) + 1; |
1602 | + |
1603 | + if (star <= 0 || star > m_starRating.maxStarCount()) |
1604 | + return 0; |
1605 | + |
1606 | + return star; |
1607 | + } |
1608 | |
1609 | === added file 'mixxx/src/library/stareditor.h' |
1610 | --- mixxx/src/library/stareditor.h 1970-01-01 00:00:00 +0000 |
1611 | +++ mixxx/src/library/stareditor.h 2010-10-19 05:33:52 +0000 |
1612 | @@ -0,0 +1,61 @@ |
1613 | +/*************************************************************************** |
1614 | + stareditor.h |
1615 | + ------------------- |
1616 | + copyright : (C) 2010 Tobias Rafreider |
1617 | + copyright : (C) 2009 Nokia Corporation |
1618 | + |
1619 | +***************************************************************************/ |
1620 | + |
1621 | +/*************************************************************************** |
1622 | + * * |
1623 | + * This program is free software; you can redistribute it and/or modify * |
1624 | + * it under the terms of the GNU General Public License as published by * |
1625 | + * the Free Software Foundation; either version 2 of the License, or * |
1626 | + * (at your option) any later version. * |
1627 | + * * |
1628 | + ***************************************************************************/ |
1629 | + |
1630 | +/*************************************************************************** |
1631 | + * * |
1632 | + * StarEditor inherits QWidget and is used by StarDelegate to let the user * |
1633 | + * edit a star rating in the library using the mouse. * |
1634 | + * * |
1635 | + * The class has been adapted from the official "Star Delegate Example", * |
1636 | + * see http://doc.trolltech.com/4.5/itemviews-stardelegate.html * |
1637 | + ***************************************************************************/ |
1638 | + |
1639 | +#ifndef STAREDITOR_H |
1640 | +#define STAREDITOR_H |
1641 | + |
1642 | +#include <QWidget> |
1643 | + |
1644 | +#include "starrating.h" |
1645 | + |
1646 | +class StarEditor : public QWidget |
1647 | +{ |
1648 | + Q_OBJECT |
1649 | + |
1650 | +public: |
1651 | + StarEditor(QWidget *parent, const QStyleOptionViewItem& option); |
1652 | + |
1653 | + QSize sizeHint() const; |
1654 | + void setStarRating(const StarRating &starRating) { |
1655 | + m_starRating = starRating; |
1656 | + } |
1657 | + StarRating starRating() { return m_starRating; } |
1658 | + |
1659 | +signals: |
1660 | + void editingFinished(); |
1661 | + |
1662 | +protected: |
1663 | + void paintEvent(QPaintEvent *event); |
1664 | + void mouseMoveEvent(QMouseEvent *event); |
1665 | + void mouseReleaseEvent(QMouseEvent *event); |
1666 | + |
1667 | +private: |
1668 | + int starAtPosition(int x); |
1669 | + |
1670 | + StarRating m_starRating; |
1671 | +}; |
1672 | + |
1673 | +#endif |
1674 | |
1675 | === added file 'mixxx/src/library/starrating.cpp' |
1676 | --- mixxx/src/library/starrating.cpp 1970-01-01 00:00:00 +0000 |
1677 | +++ mixxx/src/library/starrating.cpp 2010-10-19 05:33:52 +0000 |
1678 | @@ -0,0 +1,74 @@ |
1679 | +/*************************************************************************** |
1680 | + starrating.cpp |
1681 | + ------------------- |
1682 | + copyright : (C) 2010 Tobias Rafreider |
1683 | + copyright : (C) 2009 Nokia Corporation |
1684 | + |
1685 | +***************************************************************************/ |
1686 | + |
1687 | +/*************************************************************************** |
1688 | + * * |
1689 | + * This program is free software; you can redistribute it and/or modify * |
1690 | + * it under the terms of the GNU General Public License as published by * |
1691 | + * the Free Software Foundation; either version 2 of the License, or * |
1692 | + * (at your option) any later version. * |
1693 | + * * |
1694 | + ***************************************************************************/ |
1695 | + |
1696 | + |
1697 | +#include <QtGui> |
1698 | +#include <math.h> |
1699 | + |
1700 | +#include "starrating.h" |
1701 | + |
1702 | +const int PaintingScaleFactor = 20; |
1703 | + |
1704 | + |
1705 | + |
1706 | +StarRating::StarRating(int starCount, int maxStarCount) |
1707 | +{ |
1708 | + m_myStarCount = starCount; |
1709 | + m_myMaxStarCount = maxStarCount; |
1710 | + |
1711 | + m_starPolygon << QPointF(1.0, 0.5); |
1712 | + for (int i = 1; i < 5; ++i) |
1713 | + m_starPolygon << QPointF(0.5 + 0.5 * cos(0.8 * i * 3.14), 0.5 + 0.5 * sin(0.8 * i * 3.14)); m_diamondPolygon << QPointF(0.4, 0.5) << QPointF(0.5, 0.4) << QPointF(0.6, 0.5) << QPointF(0.5, 0.6) << QPointF(0.4, 0.5); |
1714 | +} |
1715 | + |
1716 | +QSize StarRating::sizeHint() const |
1717 | +{ |
1718 | + return PaintingScaleFactor * QSize(m_myMaxStarCount, 1); |
1719 | +} |
1720 | + |
1721 | +/* |
1722 | + * function paints the stars in this StarRating object on a paint device |
1723 | + */ |
1724 | +void StarRating::paint(QPainter *painter, const QRect &rect, const QPalette &palette, EditMode mode) const |
1725 | +{ |
1726 | + painter->save(); |
1727 | + |
1728 | + painter->setRenderHint(QPainter::Antialiasing, true); |
1729 | + painter->setPen(Qt::NoPen); |
1730 | + |
1731 | + // Workaround for painting issue. If we are editable, assume we are |
1732 | + // selected, so use the highlight and hightlightedText colors. |
1733 | + if (mode == Editable) { |
1734 | + painter->fillRect(rect, palette.highlight()); |
1735 | + painter->setBrush(palette.highlightedText()); |
1736 | + } |
1737 | + |
1738 | + int yOffset = (rect.height() - PaintingScaleFactor) / 2; |
1739 | + painter->translate(rect.x(), rect.y() + yOffset); |
1740 | + painter->scale(PaintingScaleFactor, PaintingScaleFactor); |
1741 | + |
1742 | + for (int i = 0; i < m_myMaxStarCount; ++i) { |
1743 | + if (i < m_myStarCount) { |
1744 | + painter->drawPolygon(m_starPolygon, Qt::WindingFill); |
1745 | + } else { |
1746 | + painter->drawPolygon(m_diamondPolygon, Qt::WindingFill); |
1747 | + } |
1748 | + painter->translate(1.0, 0.0); |
1749 | + } |
1750 | + |
1751 | + painter->restore(); |
1752 | +} |
1753 | |
1754 | === added file 'mixxx/src/library/starrating.h' |
1755 | --- mixxx/src/library/starrating.h 1970-01-01 00:00:00 +0000 |
1756 | +++ mixxx/src/library/starrating.h 2010-10-19 05:33:52 +0000 |
1757 | @@ -0,0 +1,62 @@ |
1758 | +/*************************************************************************** |
1759 | + starrating.h |
1760 | + ------------------- |
1761 | + copyright : (C) 2010 Tobias Rafreider |
1762 | + copyright : (C) 2009 Nokia Corporation |
1763 | + |
1764 | +***************************************************************************/ |
1765 | + |
1766 | +/*************************************************************************** |
1767 | + * * |
1768 | + * This program is free software; you can redistribute it and/or modify * |
1769 | + * it under the terms of the GNU General Public License as published by * |
1770 | + * the Free Software Foundation; either version 2 of the License, or * |
1771 | + * (at your option) any later version. * |
1772 | + * * |
1773 | + ***************************************************************************/ |
1774 | + |
1775 | + |
1776 | +#ifndef STARRATING_H |
1777 | +#define STARRATING_H |
1778 | + |
1779 | +#include <QMetaType> |
1780 | +#include <QPointF> |
1781 | +#include <QVector> |
1782 | +#include <QPainter> |
1783 | +#include <QStyledItemDelegate> |
1784 | + |
1785 | +/* |
1786 | + * The StarRating class represents a rating as a number of stars. |
1787 | + * In addition to holding the data, it is also capable of painting the stars on a QPaintDevice, |
1788 | + * which in this example is either a view or an editor. |
1789 | + * The myStarCount member variable stores the current rating, and myMaxStarCount stores |
1790 | + * the highest possible rating (typically 5). |
1791 | + */ |
1792 | +class StarRating |
1793 | +{ |
1794 | + public: |
1795 | + enum EditMode { Editable, ReadOnly }; |
1796 | + |
1797 | + |
1798 | + StarRating(int starCount = 1, int maxStarCount = 5); |
1799 | + |
1800 | + void paint(QPainter *painter, const QRect &rect, const QPalette &palette, EditMode mode) const; |
1801 | + QSize sizeHint() const; |
1802 | + |
1803 | + int starCount() const { return m_myStarCount; } |
1804 | + int maxStarCount() const { return m_myMaxStarCount; } |
1805 | + void setStarCount(int starCount) { m_myStarCount = starCount; } |
1806 | + void setMaxStarCount(int maxStarCount) { m_myMaxStarCount = maxStarCount; } |
1807 | + |
1808 | + |
1809 | +private: |
1810 | + QPolygonF m_starPolygon; |
1811 | + QPolygonF m_diamondPolygon; |
1812 | + int m_myStarCount; |
1813 | + int m_myMaxStarCount; |
1814 | + |
1815 | +}; |
1816 | + |
1817 | +Q_DECLARE_METATYPE(StarRating) |
1818 | + |
1819 | +#endif |
1820 | |
1821 | === modified file 'mixxx/src/library/trackcollection.cpp' |
1822 | --- mixxx/src/library/trackcollection.cpp 2010-10-07 03:05:48 +0000 |
1823 | +++ mixxx/src/library/trackcollection.cpp 2010-10-19 05:33:52 +0000 |
1824 | @@ -44,6 +44,9 @@ |
1825 | { |
1826 | // Save all tracks that haven't been saved yet. |
1827 | m_trackDao.saveDirtyTracks(); |
1828 | + // TODO(XXX) Maybe fold saveDirtyTracks into TrackDAO::finish now that it |
1829 | + // exists? -- rryan 10/2010 |
1830 | + m_trackDao.finish(); |
1831 | |
1832 | Q_ASSERT(!m_db.rollback()); //Rollback any uncommitted transaction |
1833 | //The above is an ASSERT because there should never be an outstanding |
1834 | @@ -65,7 +68,7 @@ |
1835 | return false; |
1836 | } |
1837 | |
1838 | - int requiredSchemaVersion = 5; |
1839 | + int requiredSchemaVersion = 6; |
1840 | if (!SchemaManager::upgradeToSchemaVersion(m_pConfig, m_db, |
1841 | requiredSchemaVersion)) { |
1842 | QMessageBox::warning(0, qApp->tr("Cannot upgrade database schema"), |
1843 | |
1844 | === modified file 'mixxx/src/mixxx.cpp' |
1845 | --- mixxx/src/mixxx.cpp 2010-10-18 21:55:09 +0000 |
1846 | +++ mixxx/src/mixxx.cpp 2010-10-19 05:33:52 +0000 |
1847 | @@ -185,10 +185,10 @@ |
1848 | QDir dir(config->getValueString(ConfigKey("[Playlist]","Directory"))); |
1849 | if ((config->getValueString(ConfigKey("[Playlist]","Directory")).length()<1) || (!dir.exists())) |
1850 | { |
1851 | - QString fd = QFileDialog::getExistingDirectory(this, |
1852 | + QString fd = QFileDialog::getExistingDirectory(this, |
1853 | tr("Choose music library directory"), |
1854 | QDesktopServices::storageLocation(QDesktopServices::MusicLocation)); |
1855 | - |
1856 | + |
1857 | if (fd != "") |
1858 | { |
1859 | config->set(ConfigKey("[Playlist]","Directory"), fd); |
1860 | |
1861 | === modified file 'mixxx/src/player.cpp' |
1862 | --- mixxx/src/player.cpp 2010-10-07 09:03:35 +0000 |
1863 | +++ mixxx/src/player.cpp 2010-10-19 05:33:52 +0000 |
1864 | @@ -178,6 +178,8 @@ |
1865 | if(!m_pLoadedTrack->getHeaderParsed()) |
1866 | SoundSourceProxy::ParseHeader(m_pLoadedTrack.data()); |
1867 | |
1868 | + m_pLoadedTrack->incTimesPlayed(); |
1869 | + |
1870 | // Generate waveform summary |
1871 | //TODO: Consider reworking this visual resample stuff... need to ask rryan about this -- Albert. |
1872 | // TODO(rryan) : fix this crap -- the waveform renderers should be owned by |
1873 | |
1874 | === modified file 'mixxx/src/trackinfoobject.cpp' |
1875 | --- mixxx/src/trackinfoobject.cpp 2010-10-07 03:05:48 +0000 |
1876 | +++ mixxx/src/trackinfoobject.cpp 2010-10-19 05:33:52 +0000 |
1877 | @@ -48,6 +48,7 @@ |
1878 | : m_qMutex(QMutex::Recursive) { |
1879 | m_sFilename = XmlParse::selectNodeQString(nodeHeader, "Filename"); |
1880 | m_sLocation = XmlParse::selectNodeQString(nodeHeader, "Filepath") + "/" + m_sFilename; |
1881 | + QString create_date; |
1882 | |
1883 | // We don't call initialize() here because it would end up calling parse() |
1884 | // on the file. Plus those initializations weren't done before, so it might |
1885 | @@ -72,6 +73,11 @@ |
1886 | m_bBpmConfirm = XmlParse::selectNodeQString(nodeHeader, "BpmConfirm").toInt(); |
1887 | m_fBeatFirst = XmlParse::selectNodeQString(nodeHeader, "BeatFirst").toFloat(); |
1888 | m_bHeaderParsed = false; |
1889 | + create_date = XmlParse::selectNodeQString(nodeHeader, "CreateDate"); |
1890 | + if (create_date == "") |
1891 | + m_dCreateDate = fileInfo.created(); |
1892 | + else |
1893 | + m_dCreateDate = QDateTime::fromString(create_date); |
1894 | |
1895 | // Mixxx <1.8 recorded track IDs in mixxxtrack.xml, but we are going to |
1896 | // ignore those. Tracks will get a new ID from the database. |
1897 | @@ -79,6 +85,7 @@ |
1898 | m_iId = -1; |
1899 | |
1900 | m_fCuePoint = XmlParse::selectNodeQString(nodeHeader, "CuePoint").toFloat(); |
1901 | + m_bPlayed = false; |
1902 | |
1903 | m_pVisualWave = 0; |
1904 | m_dVisualResampleRate = 0; |
1905 | @@ -112,6 +119,7 @@ |
1906 | m_iDuration = 0; |
1907 | m_iBitrate = 0; |
1908 | m_iTimesPlayed = 0; |
1909 | + m_bPlayed = false; |
1910 | m_fBpm = 0.; |
1911 | m_bBpmConfirm = false; |
1912 | m_bIsValid = false; |
1913 | @@ -123,6 +131,8 @@ |
1914 | m_iChannels = 0; |
1915 | m_fCuePoint = 0.0f; |
1916 | m_dVisualResampleRate = 0; |
1917 | + m_dCreateDate = QDateTime::currentDateTime(); |
1918 | + m_Rating = 0; |
1919 | |
1920 | // parse() parses the metadata from file. This is not a quick operation! |
1921 | if (parseHeader) |
1922 | @@ -148,6 +158,7 @@ |
1923 | { |
1924 | QMutexLocker lock(&m_qMutex); |
1925 | |
1926 | + QString create_date; |
1927 | XmlParse::addElement( doc, header, "Filename", m_sFilename ); |
1928 | //XmlParse::addElement( doc, header, "Filepath", m_sFilepath ); |
1929 | XmlParse::addElement( doc, header, "Title", m_sTitle ); |
1930 | @@ -165,6 +176,7 @@ |
1931 | XmlParse::addElement( doc, header, "BeatFirst", QString("%1").arg(m_fBeatFirst) ); |
1932 | XmlParse::addElement( doc, header, "Id", QString("%1").arg(m_iId) ); |
1933 | XmlParse::addElement( doc, header, "CuePoint", QString::number(m_fCuePoint) ); |
1934 | + XmlParse::addElement( doc, header, "CreateDate", m_dCreateDate.toString() ); |
1935 | //if (m_pWave) { |
1936 | //XmlParse::addHexElement(doc, header, "WaveSummaryHex", m_pWave); |
1937 | //} |
1938 | @@ -255,6 +267,13 @@ |
1939 | return m_sFilename; |
1940 | } |
1941 | |
1942 | +QDateTime TrackInfoObject::getCreateDate() const |
1943 | +{ |
1944 | + QMutexLocker lock(&m_qMutex); |
1945 | + QDateTime create_date = QDateTime(m_dCreateDate); |
1946 | + return create_date; |
1947 | +} |
1948 | + |
1949 | bool TrackInfoObject::exists() const |
1950 | { |
1951 | QMutexLocker lock(&m_qMutex); |
1952 | @@ -439,13 +458,53 @@ |
1953 | return m_iTimesPlayed; |
1954 | } |
1955 | |
1956 | +void TrackInfoObject::setTimesPlayed(int t) |
1957 | +{ |
1958 | + QMutexLocker lock(&m_qMutex); |
1959 | + bool dirty = t != m_iTimesPlayed; |
1960 | + m_iTimesPlayed = t; |
1961 | + if (dirty) |
1962 | + setDirty(true); |
1963 | +} |
1964 | + |
1965 | void TrackInfoObject::incTimesPlayed() |
1966 | { |
1967 | QMutexLocker lock(&m_qMutex); |
1968 | + std::cout << "Track Played:" << m_sArtist.toStdString() << " - " << m_sTitle.toStdString(); |
1969 | + qDebug() << "Track Played:" << m_sArtist << " - " << m_sTitle; |
1970 | + m_bPlayed = true; |
1971 | ++m_iTimesPlayed; |
1972 | setDirty(true); |
1973 | } |
1974 | |
1975 | +bool TrackInfoObject::getPlayed() const |
1976 | +{ |
1977 | + QMutexLocker lock(&m_qMutex); |
1978 | + bool bPlayed = m_bPlayed; |
1979 | + return bPlayed; |
1980 | +} |
1981 | + |
1982 | +void TrackInfoObject::setPlayed(bool bPlayed) |
1983 | +{ |
1984 | + QMutexLocker lock(&m_qMutex); |
1985 | + bool dirty = bPlayed != m_bPlayed; |
1986 | + m_bPlayed = bPlayed; |
1987 | + if (dirty) |
1988 | + { |
1989 | + if (bPlayed) |
1990 | + { |
1991 | + std::cout << "Track Played:" << m_sArtist.toStdString() << " - " << m_sTitle.toStdString(); |
1992 | + qDebug() << "Track Played:" << m_sArtist << " - " << m_sTitle; |
1993 | + } |
1994 | + else |
1995 | + { |
1996 | + std::cout << "Track Unplayed:" << m_sArtist.toStdString() << " - " << m_sTitle.toStdString(); |
1997 | + qDebug() << "Track Unplayed:" << m_sArtist << " - " << m_sTitle; |
1998 | + } |
1999 | + setDirty(true); |
2000 | + } |
2001 | +} |
2002 | + |
2003 | QString TrackInfoObject::getComment() const |
2004 | { |
2005 | QMutexLocker lock(&m_qMutex); |
2006 | @@ -721,3 +780,18 @@ |
2007 | QMutexLocker lock(&m_qMutex); |
2008 | return m_bLocationChanged; |
2009 | } |
2010 | +/** Returns the rating */ |
2011 | +int TrackInfoObject::getRating() const{ |
2012 | + QMutexLocker lock(&m_qMutex); |
2013 | + |
2014 | + return m_Rating; |
2015 | +} |
2016 | + /** Set rating */ |
2017 | +void TrackInfoObject::setRating (int rating){ |
2018 | + QMutexLocker lock(&m_qMutex); |
2019 | + |
2020 | + bool dirty = rating != m_Rating; |
2021 | + m_Rating = rating; |
2022 | + if (dirty) |
2023 | + setDirty(true); |
2024 | +} |
2025 | |
2026 | === modified file 'mixxx/src/trackinfoobject.h' |
2027 | --- mixxx/src/trackinfoobject.h 2010-10-07 03:05:48 +0000 |
2028 | +++ mixxx/src/trackinfoobject.h 2010-10-19 05:33:52 +0000 |
2029 | @@ -19,6 +19,7 @@ |
2030 | #define TRACKINFOOBJECT_H |
2031 | |
2032 | #include <QList> |
2033 | +#include <QDateTime> |
2034 | #include <QObject> |
2035 | #include <QFileInfo> |
2036 | #include <QMutex> |
2037 | @@ -76,6 +77,8 @@ |
2038 | QString getDirectory() const; |
2039 | // Returns the filename of the file. |
2040 | QString getFilename() const; |
2041 | + // Returns file creation date |
2042 | + QDateTime getCreateDate() const; |
2043 | // Returns the length of the file in bytes |
2044 | int getLength() const; |
2045 | // Returns whether the file exists on disk or not. Updated as of the time |
2046 | @@ -152,11 +155,21 @@ |
2047 | void setTrackNumber(QString); |
2048 | /** Return number of times the track has been played */ |
2049 | int getTimesPlayed() const; |
2050 | + /** Set number of times the track has been played */ |
2051 | + void setTimesPlayed(int t); |
2052 | /** Increment times played with one */ |
2053 | void incTimesPlayed(); |
2054 | + /** Returns true if track has been played this instance*/ |
2055 | + bool getPlayed() const; |
2056 | + /** Set Played status*/ |
2057 | + void setPlayed(bool); |
2058 | |
2059 | int getId() const; |
2060 | |
2061 | + /** Returns rating */ |
2062 | + int getRating() const; |
2063 | + /** Sets rating */ |
2064 | + void setRating(int); |
2065 | |
2066 | /** Get URL for track */ |
2067 | QString getURL(); |
2068 | @@ -282,10 +295,14 @@ |
2069 | int m_iSampleRate; |
2070 | /** Number of channels */ |
2071 | int m_iChannels; |
2072 | + /**Track rating */ |
2073 | + int m_Rating;; |
2074 | /** Bitrate, number of kilobits per second of audio in the track*/ |
2075 | int m_iBitrate; |
2076 | /** Number of times the track has been played */ |
2077 | int m_iTimesPlayed; |
2078 | + /** Has this track been played this sessions? */ |
2079 | + bool m_bPlayed; |
2080 | /** Beat per minutes (BPM) */ |
2081 | float m_fBpm; |
2082 | /** Minimum BPM range. If this is 0.0, then the config min BPM will be used */ |
2083 | @@ -302,6 +319,8 @@ |
2084 | int m_iId; |
2085 | /** Cue point in samples or something */ |
2086 | float m_fCuePoint; |
2087 | + /** Date. creation date of file */ |
2088 | + QDateTime m_dCreateDate; |
2089 | |
2090 | // The list of cue points for the track |
2091 | QList<Cue*> m_cuePoints; |
2092 | |
2093 | === modified file 'mixxx/src/widget/wlibrarytableview.cpp' |
2094 | --- mixxx/src/widget/wlibrarytableview.cpp 2010-09-19 22:08:15 +0000 |
2095 | +++ mixxx/src/widget/wlibrarytableview.cpp 2010-10-19 05:33:52 +0000 |
2096 | @@ -8,6 +8,7 @@ |
2097 | #include "widget/wwidget.h" |
2098 | #include "widget/wskincolor.h" |
2099 | #include "widget/wlibrarytableview.h" |
2100 | +#include "../library/stardelegate.h" |
2101 | |
2102 | WLibraryTableView::WLibraryTableView(QWidget* parent, |
2103 | ConfigObject<ConfigValue>* pConfig, |
2104 | @@ -16,7 +17,13 @@ |
2105 | m_pConfig(pConfig), |
2106 | m_vScrollBarPosKey(vScrollBarPosKey) { |
2107 | |
2108 | - //Setup properties for table |
2109 | + // Setup properties for table |
2110 | + |
2111 | + // Editing starts when clicking on an already selected item. |
2112 | + setEditTriggers(QAbstractItemView::SelectedClicked); |
2113 | + |
2114 | + // This is to support rating of tracks |
2115 | + setItemDelegate(new StarDelegate()); |
2116 | |
2117 | //Enable selection by rows and extended selection (ctrl/shift click) |
2118 | setSelectionBehavior(QAbstractItemView::SelectRows); |
2119 | |
2120 | === modified file 'mixxx/src/widget/wstatuslight.cpp' |
2121 | --- mixxx/src/widget/wstatuslight.cpp 2009-03-05 15:14:48 +0000 |
2122 | +++ mixxx/src/widget/wstatuslight.cpp 2010-10-19 05:33:52 +0000 |
2123 | @@ -26,59 +26,90 @@ |
2124 | |
2125 | WStatusLight::WStatusLight(QWidget * parent) : WWidget(parent) |
2126 | { |
2127 | - m_pPixmapBack = 0; |
2128 | - m_pPixmapSL = 0; |
2129 | + m_pPixmapSLs = 0; |
2130 | + m_iNoPos = 0; |
2131 | + m_iPos = 0; |
2132 | + |
2133 | + setNoPos(0); |
2134 | } |
2135 | |
2136 | WStatusLight::~WStatusLight() |
2137 | { |
2138 | - resetPositions(); |
2139 | + for (int i = 0; i < m_iNoPos; i++) { |
2140 | + WPixmapStore::deletePixmap(m_pPixmapSLs[i]); |
2141 | + } |
2142 | +} |
2143 | + |
2144 | +void WStatusLight::setNoPos(int iNoPos) |
2145 | +{ |
2146 | + m_iNoPos = iNoPos; |
2147 | + m_fValue = 0.; |
2148 | + |
2149 | + // If pixmap array is already allocated, delete it |
2150 | + if (m_pPixmapSLs) |
2151 | + delete [] m_pPixmapSLs; |
2152 | + |
2153 | + if (m_iNoPos>0) |
2154 | + { |
2155 | + m_pPixmapSLs = new QPixmap*[m_iNoPos]; |
2156 | + for (int i=0; i<m_iNoPos; ++i) |
2157 | + m_pPixmapSLs[i] = 0; |
2158 | + } |
2159 | } |
2160 | |
2161 | void WStatusLight::setup(QDomNode node) |
2162 | { |
2163 | WWidget::setup(node); |
2164 | - |
2165 | - // Set pixmaps |
2166 | - bool bHorizontal = false; |
2167 | - if (!selectNode(node, "Horizontal").isNull() && selectNodeQString(node, "Horizontal")=="true") |
2168 | - bHorizontal = true; |
2169 | - setPixmaps(getPath(selectNodeQString(node, "PathBack")), getPath(selectNodeQString(node, "PathStatusLight")), bHorizontal); |
2170 | -} |
2171 | - |
2172 | -void WStatusLight::resetPositions() |
2173 | -{ |
2174 | - if (m_pPixmapBack) |
2175 | - { |
2176 | - WPixmapStore::deletePixmap(m_pPixmapBack); |
2177 | - m_pPixmapBack = 0; |
2178 | - WPixmapStore::deletePixmap(m_pPixmapSL); |
2179 | - m_pPixmapSL = 0; |
2180 | - } |
2181 | -} |
2182 | - |
2183 | -void WStatusLight::setPixmaps(const QString &backFilename, const QString &vuFilename, bool bHorizontal) |
2184 | -{ |
2185 | - m_pPixmapBack = WPixmapStore::getPixmap(backFilename); |
2186 | - if (!m_pPixmapBack || m_pPixmapBack->size()==QSize(0,0)) |
2187 | - qDebug() << "WStatusLight: Error loading back pixmap" << backFilename; |
2188 | - m_pPixmapSL = WPixmapStore::getPixmap(vuFilename); |
2189 | - if (!m_pPixmapSL || m_pPixmapSL->size()==QSize(0,0)) |
2190 | - qDebug() << "WStatusLight: Error loading statuslight pixmap" << vuFilename; |
2191 | - |
2192 | - setFixedSize(m_pPixmapBack->size()); |
2193 | - m_bHorizontal = bHorizontal; |
2194 | + // Number of states |
2195 | + m_iNoPos = selectNodeInt(node, "NumberPos") + 1; |
2196 | + setNoPos(m_iNoPos); |
2197 | + |
2198 | + for (int i=0; i<m_iNoPos; i++) |
2199 | + { |
2200 | + switch(i) |
2201 | + { |
2202 | + case 0: |
2203 | + // Set background pixmap if available |
2204 | + if (!selectNode(node, "BackPath").isNull()) |
2205 | + setPixmap(0, getPath(selectNodeQString(node, "BackPath"))); |
2206 | + else |
2207 | + m_pPixmapSLs[0] = 0; |
2208 | + break; |
2209 | + case 1: |
2210 | + setPixmap(1, getPath(selectNodeQString(node, "PathStatusLight"))); |
2211 | + break; |
2212 | + default: |
2213 | + setPixmap(i, getPath(selectNodeQString(node, QString("PathStatusLight%1").arg(i)))); |
2214 | + } |
2215 | + } |
2216 | +} |
2217 | + |
2218 | +void WStatusLight::setPixmap(int iState, const QString &filename) |
2219 | +{ |
2220 | + int pixIdx = iState; |
2221 | + m_pPixmapSLs[pixIdx] = WPixmapStore::getPixmap(filename); |
2222 | + if (!m_pPixmapSLs[pixIdx]) |
2223 | + qDebug() << "WPushButton: Error loading pixmap:" << filename << iState; |
2224 | + |
2225 | + // Set size of widget equal to pixmap size |
2226 | + setFixedSize(m_pPixmapSLs[pixIdx]->size()); |
2227 | +} |
2228 | + |
2229 | +void WStatusLight::setValue(double v) |
2230 | +{ |
2231 | + if (m_iPos != (int)v) |
2232 | + { |
2233 | + m_iPos = (int)v; |
2234 | + update(); |
2235 | + } |
2236 | } |
2237 | |
2238 | void WStatusLight::paintEvent(QPaintEvent *) |
2239 | { |
2240 | - if (m_pPixmapBack!=0 && m_pPixmapSL!=0) |
2241 | + if (m_pPixmapSLs[m_iPos]) |
2242 | { |
2243 | QPainter p(this); |
2244 | - |
2245 | - if(m_fValue == 0) |
2246 | - p.drawPixmap(0, 0, *m_pPixmapBack); |
2247 | - else |
2248 | - p.drawPixmap(0, 0, *m_pPixmapSL); |
2249 | + if(m_iPos != 0 && m_pPixmapSLs[0]) p.drawPixmap(0, 0, *m_pPixmapSLs[0]); |
2250 | + p.drawPixmap(0, 0, *m_pPixmapSLs[m_iPos]); |
2251 | } |
2252 | } |
2253 | |
2254 | === modified file 'mixxx/src/widget/wstatuslight.h' |
2255 | --- mixxx/src/widget/wstatuslight.h 2009-03-05 15:45:39 +0000 |
2256 | +++ mixxx/src/widget/wstatuslight.h 2010-10-19 05:33:52 +0000 |
2257 | @@ -31,26 +31,24 @@ |
2258 | */ |
2259 | |
2260 | class WStatusLight : public WWidget { |
2261 | - Q_OBJECT |
2262 | -public: |
2263 | + Q_OBJECT |
2264 | + public: |
2265 | WStatusLight(QWidget *parent=0); |
2266 | - ~WStatusLight(); |
2267 | + virtual ~WStatusLight(); |
2268 | void setup(QDomNode node); |
2269 | - void setPixmaps(const QString &backFilename, const QString &vuFilename, bool bHorizontal=false); |
2270 | - |
2271 | -private: |
2272 | - /** Set position number to zero and deallocate pixmaps */ |
2273 | - void resetPositions(); |
2274 | + void setPixmap(int iState, const QString &filename); |
2275 | + void setNoPos(int iNoPos); |
2276 | + public slots: |
2277 | + void setValue(double v); |
2278 | + private: |
2279 | void paintEvent(QPaintEvent *); |
2280 | |
2281 | /** Current position */ |
2282 | int m_iPos; |
2283 | - /** Number of positions associated with this knob */ |
2284 | + /** Number of positions associated with this light */ |
2285 | int m_iNoPos; |
2286 | /** Associated pixmaps */ |
2287 | - QPixmap *m_pPixmapBack, *m_pPixmapSL; |
2288 | - /** True if it's a horizontal vu meter */ |
2289 | - bool m_bHorizontal; |
2290 | + QPixmap **m_pPixmapSLs; |
2291 | }; |
2292 | |
2293 | #endif |
2294 | |
2295 | === modified file 'mixxx/src/widget/wtracktableview.cpp' |
2296 | --- mixxx/src/widget/wtracktableview.cpp 2010-09-17 06:09:27 +0000 |
2297 | +++ mixxx/src/widget/wtracktableview.cpp 2010-10-19 05:33:52 +0000 |
2298 | @@ -31,12 +31,11 @@ |
2299 | this, SLOT(slotPrevTrackInfo())); |
2300 | |
2301 | m_pMenu = new QMenu(this); |
2302 | + |
2303 | m_pPlaylistMenu = new QMenu(this); |
2304 | m_pPlaylistMenu->setTitle(tr("Add to Playlist")); |
2305 | m_pCrateMenu = new QMenu(this); |
2306 | m_pCrateMenu->setTitle(tr("Add to Crate")); |
2307 | - //Disable editing |
2308 | - //setEditTriggers(QAbstractItemView::NoEditTriggers); |
2309 | |
2310 | //Create all the context m_pMenu->actions (stuff that shows up when you |
2311 | //right-click) |
2312 | @@ -614,13 +613,15 @@ |
2313 | |
2314 | void WTrackTableView::keyPressEvent(QKeyEvent* event) |
2315 | { |
2316 | - m_selectedIndices = this->selectionModel()->selectedRows(); |
2317 | + |
2318 | if (event->key() == Qt::Key_Return) |
2319 | { |
2320 | - if (m_selectedIndices.size() > 0) { |
2321 | - QModelIndex index = m_selectedIndices.at(0); |
2322 | - slotMouseDoubleClicked(index); |
2323 | - } |
2324 | + /* |
2325 | + * It is not a good idea if 'key_return' |
2326 | + * causes a track to load since we allow in-line editing |
2327 | + * of table items in general |
2328 | + */ |
2329 | + return; |
2330 | } |
2331 | else if (event->key() == Qt::Key_BracketLeft) |
2332 | { |
Please note that Jus requested a way to specify the rating colour via skins. I have not found a good solution to that since star rating editors are created from delegates and I do not know how to read from skin.xml there :-( A singleton 'SkinManager' would be great.
BTW: Star ratings look good on Windows and Ubuntu 9.04. On Ubuntu 10.10 is does not look nice anymore (maybe QT 7.0 related)