I've just started DJing with Mixxx, and I'm having a blast. I've found
the library function somewhat limiting, though. I took a look at the
code and made some fairly minor tweaks:
1. I made the search function also searches on the path and filename of
each track, not just the tags.
2. You can search for more than one term by separating each term with a
space. The resulting list is an "AND" search of all the terms.
3. I added a "played" checkbox, so I won't accidentally play the same
track twice. When a track is loaded into a slot, it is marked as
"played".
The "played" checkbox is a fairly simple feature that just resets every
time the program is run (it is not based on the running total of plays
for each track). In the future I plan to add a menu item to optionally
reset the played status of all tracks. Users should also be able to
just click the box to flip the status.
The only bug I'm having trouble with is that when a track is loaded, the
checkbox doesn't repaint until the selected row is changed. I'm really
a GTK hacker so I don't know what incantation to give QT to make it
repaint properly.
Please let me know if there's anything I should do to improve the patch
or clean it up. I hope these features can be included in the trunk!
cheers,
Owen Williams
=== modified file 'mixxx/src/proxymodel.cpp'
--- mixxx/src/proxymodel.cpp 2009-03-05 15:14:48 +0000
+++ mixxx/src/proxymodel.cpp 2009-05-18 17:12:17 +0000
@@ -14,14 +14,24 @@
bool SortFilterProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex & sourceParent ) const
{
- QModelIndex index1 = sourceModel()->index(sourceRow, 0, sourceParent);
- QModelIndex index2 = sourceModel()->index(sourceRow, 1, sourceParent);
- QModelIndex index3 = sourceModel()->index(sourceRow, 6, sourceParent);
-
- return ( sourceModel()->data(index1).toString().contains(filterRegExp())
- || sourceModel()->data(index2).toString().contains(filterRegExp())
- || sourceModel()->data(index3).toString().contains(filterRegExp())
- );
+ QModelIndex index1 = sourceModel()->index(sourceRow, 0, sourceParent); //Artist
+ QModelIndex index2 = sourceModel()->index(sourceRow, 1, sourceParent); //Title
+ QModelIndex index3 = sourceModel()->index(sourceRow, 6, sourceParent); //Comment
+ QModelIndex index4 = sourceModel()->index(sourceRow, 7, sourceParent); //Filepath
+ QModelIndex index5 = sourceModel()->index(sourceRow, 8, sourceParent); //Filename
+
+ QString row_term = QString("%1 %2 %3 %4 %5").arg(sourceModel()->data(index1).toString())
+ .arg(sourceModel()->data(index2).toString())
+ .arg(sourceModel()->data(index3).toString())
+ .arg(sourceModel()->data(index4).toString())
+ .arg(sourceModel()->data(index5).toString());
+
+ foreach(QString i, filterRegExp().pattern().split(" "))
+ {
+ if (! row_term.contains(i, Qt::CaseInsensitive))
+ return false;
+ }
+ return true;
}
bool SortFilterProxyModel::lessThan( const QModelIndex &left, const QModelIndex &right ) const
=== modified file 'mixxx/src/track.cpp'
--- mixxx/src/track.cpp 2009-05-03 02:34:18 +0000
+++ mixxx/src/track.cpp 2009-05-18 23:08:17 +0000
@@ -289,6 +289,10 @@
double centa = m_pView->m_pTrackTableView->size().width()/100.;
qDebug() << "Adjusting column widths: tracktable width =" << m_pView->m_pTrackTableView->size().width() <<" 1% of that is:"<< centa << " FIXME: this should be done when initalizing the skin.";
m_pView->m_pTrackTableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ //m_pView->m_pTrackTableView->setColumnHidden(WTrackTableModel::TYPE, true);
+ //m_pView->m_pTrackTableView->setColumnHidden(WTrackTableModel::BITRATE, true);
+ m_pView->m_pTrackTableView->setColumnWidth(WTrackTableModel::PLAYED, 20/6. * centa);
+ m_pView->m_pTrackTableView->setColumnWidth(WTrackTableModel::FILENAME, 20 * centa);
m_pView->m_pTrackTableView->setColumnWidth(WTrackTableModel::ARTIST, 15 * centa);
m_pView->m_pTrackTableView->setColumnWidth(WTrackTableModel::TITLE, 40 * centa);
m_pView->m_pTrackTableView->setColumnWidth(WTrackTableModel::TYPE, (20/4.) * centa);
=== modified file 'mixxx/src/trackinfoobject.cpp'
--- mixxx/src/trackinfoobject.cpp 2009-03-06 00:20:56 +0000
+++ mixxx/src/trackinfoobject.cpp 2009-05-18 22:15:46 +0000
@@ -67,6 +67,7 @@
m_iSampleRate = 0;
m_iChannels = 0;
m_fCuePoint = 0.0f;
+ m_bPlayed = false;
m_dVisualResampleRate = 0;
@@ -119,6 +120,7 @@
m_fBeatFirst = XmlParse::selectNodeQString(nodeHeader, "BeatFirst").toFloat();
m_bHeaderParsed = false;
m_iScore = 0;
+ m_bPlayed = false;
m_iId = XmlParse::selectNodeQString(nodeHeader, "Id").toInt();
m_fCuePoint = XmlParse::selectNodeQString(nodeHeader, "CuePoint").toFloat();
@@ -611,13 +613,24 @@
void TrackInfoObject::incTimesPlayed()
{
+ qDebug() << "incrementing times played";
m_qMutex.lock();
++m_iTimesPlayed;
+ m_bPlayed = true;
if (m_iTimesPlayed>siMaxTimesPlayed)
siMaxTimesPlayed = m_iTimesPlayed;
m_qMutex.unlock();
}
+bool TrackInfoObject::getPlayed() const
+{
+ m_qMutex.lock();
+ bool bPlayed = m_bPlayed;
+ m_qMutex.unlock();
+
+ return bPlayed;
+}
+
void TrackInfoObject::setFilepath(QString s)
{
m_qMutex.lock();
=== modified file 'mixxx/src/trackinfoobject.h'
--- mixxx/src/trackinfoobject.h 2009-02-02 05:47:04 +0000
+++ mixxx/src/trackinfoobject.h 2009-05-18 22:07:52 +0000
@@ -139,6 +139,8 @@
int getTimesPlayed() const;
/** Increment times played with one */
void incTimesPlayed();
+ /** Returns true if track has been played this instance*/
+ bool getPlayed() const;
/** Sets the filepath */
void setFilepath(QString);
/** Returns the score */
@@ -224,6 +226,8 @@
int m_iBitrate;
/** Number of times the track has been played */
int m_iTimesPlayed;
+ /** Has track been played this run? */
+ int m_bPlayed;
/** Beat per minutes (BPM) */
float m_fBpm;
/** Bpm Correction Factors */
=== modified file 'mixxx/src/wtracktablemodel.cpp'
--- mixxx/src/wtracktablemodel.cpp 2009-03-06 00:20:56 +0000
+++ mixxx/src/wtracktablemodel.cpp 2009-05-18 23:10:29 +0000
@@ -14,6 +14,7 @@
m_pTrackPlaylist = NULL;
//setHeaderData(WTrackTableModel::SCORE,Qt::Horizontal, tr("**"));
+ setHeaderData(WTrackTableModel::PLAYED,Qt::Horizontal, tr("Played"));
setHeaderData(WTrackTableModel::TITLE,Qt::Horizontal, tr("Title"));
setHeaderData(WTrackTableModel::ARTIST,Qt::Horizontal, tr("Artist"));
setHeaderData(WTrackTableModel::TYPE,Qt::Horizontal, tr("Type"));
@@ -21,6 +22,8 @@
setHeaderData(WTrackTableModel::BITRATE,Qt::Horizontal, tr("kbit"));
setHeaderData(WTrackTableModel::BPM,Qt::Horizontal, tr("BPM"));
setHeaderData(WTrackTableModel::COMMENT,Qt::Horizontal, tr("Comment"));
+ setHeaderData(WTrackTableModel::FILEPATH,Qt::Horizontal, tr("Filepath"));
+ setHeaderData(WTrackTableModel::FILENAME,Qt::Horizontal, tr("Filename"));
}
WTrackTableModel::~WTrackTableModel()
@@ -55,23 +58,36 @@
{
switch(index.column())
{
- //case WTrackTableModel::SCORE: return m_pTrackInfo->getScoreStr();
- case WTrackTableModel::TITLE: return m_pTrackInfo->getTitle();
- case WTrackTableModel::ARTIST: return m_pTrackInfo->getArtist();
- case WTrackTableModel::TYPE: return m_pTrackInfo->getType();
- case WTrackTableModel::LENGTH: return m_pTrackInfo->getDurationStr();
- case WTrackTableModel::BITRATE: return m_pTrackInfo->getBitrateStr();
- case WTrackTableModel::BPM: return m_pTrackInfo->getBpmStr();
- case WTrackTableModel::COMMENT: return m_pTrackInfo->getComment();
- default:
- qDebug() << "index.column =" << index.column();
- Q_ASSERT(FALSE); //we should never get here
- return QVariant();
+ //case WTrackTableModel::SCORE: return m_pTrackInfo->getScoreStr();
+ case WTrackTableModel::TITLE: return m_pTrackInfo->getTitle();
+ case WTrackTableModel::ARTIST: return m_pTrackInfo->getArtist();
+ case WTrackTableModel::TYPE: return m_pTrackInfo->getType();
+ case WTrackTableModel::LENGTH: return m_pTrackInfo->getDurationStr();
+ case WTrackTableModel::BITRATE: return m_pTrackInfo->getBitrateStr();
+ case WTrackTableModel::BPM: return m_pTrackInfo->getBpmStr();
+ case WTrackTableModel::COMMENT: return m_pTrackInfo->getComment();
+ case WTrackTableModel::FILEPATH: return m_pTrackInfo->getFilepath();
+ case WTrackTableModel::FILENAME: return m_pTrackInfo->getFilename();
+ case WTrackTableModel::PLAYED: return "";
+ default:
+ qDebug() << "index.column =" << index.column();
+ Q_ASSERT(FALSE); //we should never get here
+ return QVariant();
}
}
-
- else
- return QVariant();
+ else if (role == Qt::CheckStateRole)
+ {
+ if (index.column() == WTrackTableModel::PLAYED)
+ {
+ if (m_pTrackInfo->getPlayed())
+ {
+ return Qt::Checked;
+ }
+ return Qt::Unchecked;
+ }
+ }
+
+ return QVariant();
}
QVariant WTrackTableModel::headerData(int section, Qt::Orientation orientation, int role) const
@@ -99,6 +115,12 @@
return QString("BPM");
case WTrackTableModel::COMMENT:
return QString("Comment");
+ case WTrackTableModel::FILEPATH:
+ return QString("Filepath");
+ case WTrackTableModel::FILENAME:
+ return QString("Filename");
+ case WTrackTableModel::PLAYED:
+ return QString("Played");
default:
//this is a nasty error for the user to see, but its better than a crash and should help with debugging
return QString("ERROR: WTrackTableModel::headerData Invalid section parameter");
@@ -138,6 +160,12 @@
emit dataChanged(index, index);
return true;
}
+/* else if (index.isValid() && role == Qt::CheckStateRole)
+ {
+ qDebug() << "got checkbox update";
+ emit dataChanged(index, index);
+ return true;
+ }*/
return false;
}
=== modified file 'mixxx/src/wtracktablemodel.h'
--- mixxx/src/wtracktablemodel.h 2009-03-06 00:20:56 +0000
+++ mixxx/src/wtracktablemodel.h 2009-05-18 21:54:22 +0000
@@ -34,6 +34,8 @@
DISABLED = -1,
SCORE = DISABLED,
// Note: all disabled items must be set to disabled and must appear before the first non-disabled item.
+ PLAYED,
+ FILENAME,
ARTIST ,
TITLE ,
TYPE ,
@@ -41,6 +43,7 @@
BITRATE ,
BPM ,
COMMENT ,
+ FILEPATH,
COLUMN_COUNT // Note: COLUMN_COUNT must remain the last entry.
} TABLE_COLUMNS;
=== modified file 'mixxx/src/wtracktableview.cpp'
--- mixxx/src/wtracktableview.cpp 2009-04-18 16:32:23 +0000
+++ mixxx/src/wtracktableview.cpp 2009-05-18 23:01:49 +0000
@@ -766,14 +766,21 @@
if (m_iTableMode == TABLE_MODE_BROWSE) //Browse mode
m_pTrack->slotLoadPlayer1(m_selectedDirTrackNames.at(0));
else //Library mode
+ {
m_pTrack->slotLoadPlayer1(m_selectedTrackInfoObjects.at(0));
+ qDebug() << "TODO: trigger paint so checkbox appears checked";
+ }
}
+
void WTrackTableView::slotLoadPlayer2()
{
if (m_iTableMode == TABLE_MODE_BROWSE) //Browse mode
m_pTrack->slotLoadPlayer2(m_selectedDirTrackNames.at(0));
- else //Library mode
+ else //Library mode
+ {
m_pTrack->slotLoadPlayer2(m_selectedTrackInfoObjects.at(0));
+ qDebug() << "TODO: trigger paint so checkbox appears checked";
+ }
}
void WTrackTableView::slotSendToPlayqueue()
------------------------------------------------------------------------------
Crystal Reports - New Free Runtime and 30 Day Trial
Check out the new simplified licensing option that enables
unlimited royalty-free distribution of the report engine
for externally facing server and web deployment.
http://p.sf.net/sfu/businessobjects
_______________________________________________
Mixxx-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mixxx-devel