diff --git a/kdevplatform/vcs/models/vcsannotationmodel.cpp b/kdevplatform/vcs/models/vcsannotationmodel.cpp --- a/kdevplatform/vcs/models/vcsannotationmodel.cpp +++ b/kdevplatform/vcs/models/vcsannotationmodel.cpp @@ -45,12 +45,30 @@ public: explicit VcsAnnotationModelPrivate( VcsAnnotationModel* q_ ) : q(q_) {} KDevelop::VcsAnnotation m_annotation; - QHash m_brushes; + mutable QHash m_brushes; VcsAnnotationModel* q; VcsJob* job; QColor foreground; QColor background; + const QBrush& brush(const VcsRevision& revision) const + { + auto brushIt = m_brushes.find(revision); + if (brushIt == m_brushes.end()) { + const int background_y = background.red()*0.299 + 0.587*background.green() + + 0.114*background.blue(); + // get random, but reproducable 8-bit values from last two bytes of the revision hash + const uint revisionHash = qHash(revision); + const int u = static_cast((0xFF & revisionHash)); + const int v = static_cast((0xFF00 & revisionHash) >> 8); + const int r = qRound(qMin(255.0, qMax(0.0, background_y + 1.402*(v-128)))); + const int g = qRound(qMin(255.0, qMax(0.0, background_y - 0.344*(u-128) - 0.714*(v-128)))); + const int b = qRound(qMin(255.0, qMax(0.0, background_y + 1.772*(u-128)))); + brushIt = m_brushes.insert(revision, QBrush(QColor(r, g, b))); + } + return brushIt.value(); + } + void addLines( KDevelop::VcsJob* job ) { if( job == this->job ) @@ -60,17 +78,6 @@ if( v.canConvert() ) { VcsAnnotationLine l = v.value(); - if( !m_brushes.contains( l.revision() ) ) - { - const int background_y = background.red()*0.299 + 0.587*background.green() - + 0.114*background.blue(); - int u = ( float(qrand()) / RAND_MAX ) * 255; - int v = ( float(qrand()) / RAND_MAX ) * 255; - float r = qMin(255.0, qMax(0.0, background_y + 1.402*(v-128))); - float g = qMin(255.0, qMax(0.0, background_y - 0.344*(u-128) - 0.714*(v-128))); - float b = qMin(255.0, qMax(0.0, background_y + 1.772*(u-128))); - m_brushes.insert( l.revision(), QBrush( QColor( r, g, b ) ) ); - } m_annotation.insertLine( l.lineNumber(), l ); emit q->lineChanged( l.lineNumber() ); } @@ -149,7 +156,7 @@ } if( role == Qt::BackgroundRole ) { - return QVariant( d->m_brushes[aline.revision()] ); + return QVariant(d->brush(aline.revision())); } else if( role == Qt::DisplayRole ) { return QVariant( QStringLiteral("%1 ").arg(aline.date().date().year()) + abbreviateLastName(aline.author()) ); diff --git a/kdevplatform/vcs/vcsrevision.cpp b/kdevplatform/vcs/vcsrevision.cpp --- a/kdevplatform/vcs/vcsrevision.cpp +++ b/kdevplatform/vcs/vcsrevision.cpp @@ -168,6 +168,23 @@ uint KDevelop::qHash( const KDevelop::VcsRevision& rev) { - return rev.revisionValue().toULongLong(); + const auto revisionValue = rev.revisionValue(); + switch (rev.revisionType()) { + case VcsRevision::GlobalNumber: + case VcsRevision::FileNumber: + return (revisionValue.type() == QVariant::String ? + ::qHash(revisionValue.toString()) : + ::qHash(revisionValue.toULongLong())); + break; + case VcsRevision::Special: + return ::qHash(static_cast(revisionValue.value())); + break; + case VcsRevision::Date: + return ::qHash(revisionValue.toDateTime()); + break; + default: + break; + } + return ::qHash(revisionValue.toString()); }