[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    extragear/network/kmldonkey/kmldonkey
From:       Aleksey Markelov <markelovai () gmail ! com>
Date:       2009-07-15 6:08:41
Message-ID: 1247638121.916481.23752.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 996882 by amarkelov:

availability render remake to use with upcoming downloadmodel

 M  +145 -109  availability.cpp  
 M  +11 -2     availability.h  
 M  +18 -16    kmldonkey.cpp  
 M  +1 -1      kmldonkey.h  


--- trunk/extragear/network/kmldonkey/kmldonkey/availability.cpp #996881:996882
@@ -4,6 +4,7 @@
  *
  * Copyright (C) 2003 Petter Stokke <ummo@hellokitty.com>
  * Copyright (C) 2003,2004,2007 Sebastian Sauer <mail@dipe.org>
+ * Copyright (C) 2009 Aleksey Markelov <markelovai@gmail.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -23,6 +24,7 @@
 
 #include "availability.h"
 #include "kmldonkey.h"
+#include <clientinfo.h>
 #include "network.h"
 
 #include <kglobal.h>
@@ -33,9 +35,113 @@
 #include <QPixmapCache>
 #include <QImage>
 #include <QPaintEvent>
+#include <QApplication>
 
-static int hits = 0;
 
+inline QColor blend_availability(int avail, int threshold)
+{
+    if (!avail) return KMLDonkey::App->colorNoSources;
+    --avail;
+    if (avail >= threshold) return KMLDonkey::App->colorManySources;
+
+    QColor dark = KMLDonkey::App->colorFewSources;
+    QColor light = KMLDonkey::App->colorManySources;
+
+    int rdiff = light.red() - dark.red(),
+        gdiff = light.green() - dark.green(),
+        bdiff = light.blue() - dark.blue();
+    return QColor(dark.red() + (rdiff * avail) / threshold,
+            dark.green() + (gdiff * avail) / threshold,
+            dark.blue() + (bdiff * avail) / threshold);
+}
+
+QPixmap AvailabilityRenderer::paint(const FileInfo *fi, const ClientInfo *ci, \
QString *cacheKey) +{
+    static const int pmHeight = 40;
+    int chunks = fi->fileChunks().size();
+    QPixmap pm(chunks ? chunks : pmHeight, pmHeight);
+    if (!chunks) {
+        pm.fill(Qt::transparent);
+        if (cacheKey) {
+            *cacheKey = QString();
+        }
+        return pm;
+    }
+
+    QByteArray availability;
+    if (KMLDonkey::App->donkey->findNetworkNo(fi->fileNetwork())->networkName() == \
"Donkey") { +        availability = fi->fileAvailability().value(fi->fileNetwork());
+    } else {//other networks report '0' availability, fill with 0x01
+        availability = QByteArray(chunks, '\1');
+    }
+
+    QByteArray download;
+    if (ci) {
+        const QHash<int, QByteArray> &cc = fi->fileSources();
+        download = cc.value(ci->clientNo());
+        if (download.isNull()) download = QByteArray(chunks, '0');
+    } else {
+        download = fi->fileChunks();
+    }
+    if (download.size() < availability.size()) {
+        download += QByteArray(availability.size() - download.size(), '0');
+    }
+    Q_ASSERT(download.size() == availability.size());
+
+    int threshold = KMLDonkey::App->availabilityThreshold;
+    bool shading = KMLDonkey::App->availabilityShading;
+    int shadingDepth = KMLDonkey::App->availabilityShadingDepth;
+
+    QString key = QString("avail:%1:%2:%3:%4")
+        .arg(QString(availability.toHex()))
+        .arg(QString(download))
+        .arg(threshold)
+        .arg(shading ? shadingDepth : 0);
+    if (cacheKey) {
+        *cacheKey = key;
+    }
+    if (QPixmapCache::find(key, pm)) return pm;
+
+    QPainter p(&pm);
+    QColor top, bottom;
+    //TODO:here we can combine chunks that should be painted with same colors
+    for (int i = 0; i < chunks; ++i) {
+        top = blend_availability(availability.at(i), threshold);
+        char dv = download.at(i);
+        if (QChar(dv).digitValue() > 0 && dv != '0') {
+            bottom = KMLDonkey::App->colorComplete;
+            if (dv != '1' || ci) {
+                top = bottom;
+            }
+        } else {
+            bottom = top;
+        }
+        p.setPen(top);
+        if (top == bottom) {
+            p.drawLine(i, 0, i, pmHeight);
+        } else {
+            p.drawLine(i, 0, i, pmHeight/2);
+            p.setPen(bottom);
+            p.drawLine(i, pmHeight/2, i, pmHeight);
+        }
+    }
+
+    if (shading) {
+        QColor c(0,0,0,0);
+        //XXX: use kconfig_update to reduce shadingDepth for lower versions?
+        QColor d(0,0,0,shadingDepth);
+        QLinearGradient gradient(0, 0, 0, pm.height());
+        gradient.setColorAt(0.0, d);
+        gradient.setColorAt(0.5, c);
+        gradient.setColorAt(1.0, d);
+        p.setPen(Qt::NoPen);
+        p.setBrush(gradient);
+        p.drawRect(pm.rect());
+    }
+    QPixmapCache::insert(key, pm);
+    return pm;
+}
+
 AvailabilityRenderer::AvailabilityRenderer(int file)
 {
     rfileno = file;
@@ -68,122 +174,19 @@
     return chunkNo;
 }
 
-void AvailabilityRenderer::paintSection(QPainter& p, QRect& r, QColor& c, int depth, \
                bool isTop)
-{
-    QString cacheKey = \
QString("%1:%2:%3:%4:%5").arg(r.width()).arg(r.height()).arg(depth).arg(isTop).arg(c.name());
                
-    QPixmap pm;
-    if (! QPixmapCache::find(cacheKey,pm)) {
-        QColor d(c.dark(depth));
-        pm = QPixmap(r.size());
-        QPainter p(&pm);
-        p.setPen(Qt::NoPen);
-        QLinearGradient gradient(0, 0, 0, pm.height());
-        gradient.setColorAt(0.0, isTop ? d : c);
-        gradient.setColorAt(1.0, isTop ? c : d);
-        p.setBrush(gradient);
-        p.drawRect(pm.rect());
-        QPixmapCache::insert(cacheKey, pm);
-    } else hits++;
-    p.drawPixmap(r, pm);
-}
-
-void AvailabilityRenderer::paintChunk(QPainter& p, QRect& r, int chunk)
-{
-    FileInfo* fi = fileInfo();
-    if (!fi) return;
-
-    QPalette& cg = KMLDonkey::App->availabilityColours;
-    int threshold = KMLDonkey::App->availabilityThreshold,
-    shadingDepth = KMLDonkey::App->availabilityShadingDepth;
-    bool shading = KMLDonkey::App->availabilityShading;
-
-    QColor top, bottom;
-
-    if (KMLDonkey::App->donkey->findNetworkNo(fi->fileNetwork())->networkName() == \
                "Donkey") {
-        // Only the Donkey network currently supports chunk availability.
-        int avail = (int)fi->fileAvailability()[fi->fileNetwork()][chunk];
-
-        if (!avail)
-            top = cg.window().color();
-        else {
-            avail--;
-            if (avail > threshold) avail = threshold;
-            int rdiff = cg.light().color().red() - cg.dark().color().red(),
-            gdiff = cg.light().color().green() - cg.dark().color().green(),
-            bdiff = cg.light().color().blue() - cg.dark().color().blue();
-            top = QColor(cg.dark().color().red() + ((rdiff * avail) / threshold),
-                cg.dark().color().green() + ((gdiff * avail) / threshold),
-                cg.dark().color().blue() + ((bdiff * avail) / threshold));
-        }
-    } else {
-        // Other networks seem to report ascii '0' as availability,
-        // we just render it as a single source.
-        top = cg.dark();
-    }
-
-    QChar dv;
-    if (isClientRenderer) {
-        const QHash<int,QByteArray>& cc = fi->fileSources();
-        if (cc.contains(clno)) {
-            const QString s = cc[clno];
-            dv = (chunk >= 0 && chunk < s.size()) ? s[chunk] : '0';
-        }
-        else
-            dv = '0';
-    } else {
-        dv = fi->fileChunks()[chunk];
-    }
-    if (dv.digitValue() > 0 && dv != '0') {
-        bottom = cg.foreground();
-        if (dv != '1' || isClientRenderer)
-            top = bottom;
-    } else
-        bottom = top;
-
-    QRect d = r;
-    d.setBottom(d.center().y());
-    if (!shading) p.setPen(Qt::NoPen);
-    if (shading)
-        paintSection(p, d, top, shadingDepth, true);
-    else {
-        p.setBrush(top);
-        p.drawRect(d);
-    }
-    d = r;
-    d.setTop(d.center().y());
-    if (shading)
-        paintSection(p, d, bottom, shadingDepth, false);
-    else {
-        p.setBrush(bottom);
-        p.drawRect(d);
-    }
-}
-
 void AvailabilityRenderer::paintAvailability(QPainter& p, QRect& g)
 {
     if (m_cache.isNull() || m_cache.size() != g.size()) {
-        hits = 0;
-        m_cache.resize(g.size());
-        updateFileInfo();
-        QPainter cp(&m_cache);
-        int c = chunkNo, s = -1, l, i, r;
-        for (i = 0; i < c; i++) {
-            l = (i * m_cache.width()) / c;
-            if (l > s) {
-            r = (((i+1) * g.width()) / c) - l;
-            if (!r) r = 1;
-            QRect d(l, 0, r, m_cache.height());
-            paintChunk(cp, d, i);
-            s = l;
-            }
-        }
+        ClientInfo *ci = isClientRenderer ? \
KMLDonkey::App->donkey->findClientNo(clno) : 0; +        FileInfo *fi = fileInfo();
+        m_cache = AvailabilityRenderer::paint(fi,ci).scaled(g.size());
     }
     p.drawPixmap(g, m_cache);
 }
 
 void AvailabilityRenderer::loseCache()
 {
-    m_cache.resize(0, 0);
+    m_cache = QPixmap();
 }
 
 
@@ -196,7 +199,6 @@
     if (frame)
         setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
     setMinimumSize(minimumSizeHint());
-    setBackgroundMode(Qt::NoBackground);
 }
 
 void AvailabilityWidget::paintEvent(QPaintEvent* e)
@@ -237,4 +239,38 @@
     return QSize((chunkNo > 300) ? 300 : chunkNo, QFontMetrics(font()).height() + 4 \
+ (frameWidth() * 2));  }
 
+void AvailabilityDelegate::paint(QPainter *painter, const QStyleOptionViewItem \
&option,  +        const QModelIndex &index) const
+{
+    QPixmap pm = index.data(Qt::UserRole + 2).value<QPixmap>();
+    QString key = index.data(Qt::UserRole + 3).toString();
+    Q_ASSERT(!pm.isNull());
+
+    const QStyleOptionViewItemV3 *optV3 = qstyleoption_cast<const \
QStyleOptionViewItemV3*>(&option); +    QStyle *style = optV3 && optV3->widget ? \
optV3->widget->style() : QApplication::style(); +    \
style->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter); +
+    bool selected = option.state & QStyle::State_Selected;
+    bool hover = option.state & QStyle::State_MouseOver;
+
+    QString cacheKey = QString("%1:%2:%3").arg(key, option.rect.width(), \
option.rect.height()); +    if (!QPixmapCache::find(cacheKey, pm)) {
+        pm = pm.scaled(option.rect.size());
+        QPixmapCache::insert(cacheKey, pm);
+    }
+    if (!selected && !hover) {
+        painter->drawPixmap(option.rect, pm);
+        return;
+    }
+
+    QPainter p;
+    p.begin(&pm);
+    p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
+    int opacity = selected ? (hover ? 130 : 155) : 180;
+    p.fillRect(pm.rect(), QColor(0, 0, 0, opacity));
+    p.end();
+
+    painter->drawPixmap(option.rect.adjusted(0,2,0,-2), pm, \
pm.rect().adjusted(0,2,0,-2)); +}
+
 #include "availability.moc"
--- trunk/extragear/network/kmldonkey/kmldonkey/availability.h #996881:996882
@@ -28,6 +28,7 @@
 #include <QColor>
 #include <QPixmap>
 #include <QPaintEvent>
+#include <QStyledItemDelegate>
 
 #include <donkeyprotocol.h>
 
@@ -40,19 +41,27 @@
     int chunks() const;
     void loseCache();
 
+    static QPixmap paint(const FileInfo *fi, const ClientInfo *ci = 0, QString \
*cacheKey = 0);  protected:
     void paintAvailability(QPainter& p, QRect& r);
     int rfileno, clno, chunkNo;
     bool isClientRenderer;
 
 private:
-    void paintSection(QPainter& p, QRect& r, QColor& c, int depth, bool isTop);
-    void paintChunk(QPainter& p, QRect& r, int chunk);
     void updateFileInfo();
     
     QPixmap m_cache;
 };
 
+class AvailabilityDelegate : public QStyledItemDelegate
+{
+    Q_OBJECT
+public:
+    AvailabilityDelegate(QObject *parent = 0) : QStyledItemDelegate(parent) {}
+    void paint(QPainter *painter, const QStyleOptionViewItem &option, 
+            const QModelIndex &index) const;
+};
+
 class AvailabilityWidget : public QFrame, public AvailabilityRenderer
 {
     Q_OBJECT
--- trunk/extragear/network/kmldonkey/kmldonkey/kmldonkey.cpp #996881:996882
@@ -578,10 +578,10 @@
     colorDownloadNotAvailable = colorsgroup.readEntry("NotAvailable", QColor(0xFF, \
                0x00, 0x00));
     colorDownloadQueued = colorsgroup.readEntry("Queued", QColor(0x00, 0x00, 0x00));
 
-    availabilityColours.setColor(QColorGroup::Background, \
                colorsgroup.readEntry("NoSources", QColor(Qt::red)));
-    availabilityColours.setColor(QColorGroup::Foreground, \
                colorsgroup.readEntry("Complete", QColor(Qt::green)));
-    availabilityColours.setColor(QColorGroup::Dark, \
                colorsgroup.readEntry("FewSources", QColor(240, 255, 128, \
                QColor::Hsv)));
-    availabilityColours.setColor(QColorGroup::Light, \
colorsgroup.readEntry("ManySources", QColor(240, 128, 255, QColor::Hsv))); +    \
colorNoSources  = colorsgroup.readEntry("NoSources", QColor(Qt::red)); +    \
colorComplete = colorsgroup.readEntry("Complete", QColor(Qt::green)); +    \
colorFewSources = colorsgroup.readEntry("FewSources", QColor(240, 255, 128, \
QColor::Hsv)); +    colorManySources = colorsgroup.readEntry("ManySources", \
QColor(240, 128, 255, QColor::Hsv));  
     availabilityThreshold = colorsgroup.readEntry("Threshold", 25);
     availabilityShadingDepth = colorsgroup.readEntry("ShadingDepth", 250);
@@ -820,10 +820,11 @@
     prefs->colorPage->notavailableColorSelect->setColor(colorDownloadNotAvailable);
     prefs->colorPage->queuedColorSelect->setColor(colorDownloadQueued);
 
-    prefs->colorPage->noSourcesColorSelect->setColor(availabilityColours.window().color());
                
-    prefs->colorPage->fewSourcesColorSelect->setColor(availabilityColours.dark().color());
                
-    prefs->colorPage->manySourcesColorSelect->setColor(availabilityColours.light().color());
                
-    prefs->colorPage->completeColorSelect->setColor(availabilityColours.foreground());
 +    prefs->colorPage->noSourcesColorSelect->setColor(colorNoSources);
+    prefs->colorPage->fewSourcesColorSelect->setColor(colorFewSources);
+    prefs->colorPage->manySourcesColorSelect->setColor(colorManySources);
+    prefs->colorPage->completeColorSelect->setColor(colorComplete);
+
     prefs->colorPage->availabilityThresholdSlider->setValue(availabilityThreshold);
     prefs->colorPage->availabilityShadingSlider->setValue(availabilityShadingDepth);
     prefs->colorPage->availabilityShadingCheckbox->setChecked(availabilityShading);
@@ -922,17 +923,18 @@
         colorsgroup.writeEntry("NotAvailable", colorDownloadNotAvailable);
         colorsgroup.writeEntry("Queued", colorDownloadQueued);
 
-        availabilityColours.setColor(QColorGroup::Background, \
                prefs->colorPage->noSourcesColorSelect->color());
-        availabilityColours.setColor(QColorGroup::Dark, \
                prefs->colorPage->fewSourcesColorSelect->color());
-        availabilityColours.setColor(QColorGroup::Light, \
                prefs->colorPage->manySourcesColorSelect->color());
-        availabilityColours.setColor(QColorGroup::Foreground, \
prefs->colorPage->completeColorSelect->color()); +        colorNoSources = \
prefs->colorPage->noSourcesColorSelect->color(); +        colorFewSources = \
prefs->colorPage->fewSourcesColorSelect->color(); +        colorManySources = \
prefs->colorPage->manySourcesColorSelect->color(); +        colorComplete = \
prefs->colorPage->completeColorSelect->color(); +
         availabilityThreshold = \
                prefs->colorPage->availabilityThresholdSlider->value();
         availabilityShadingDepth = \
                prefs->colorPage->availabilityShadingSlider->value();
         availabilityShading = \
                prefs->colorPage->availabilityShadingCheckbox->isChecked();
-        colorsgroup.writeEntry("NoSources", availabilityColours.window().color());
-        colorsgroup.writeEntry("FewSources", availabilityColours.dark().color());
-        colorsgroup.writeEntry("ManySources", availabilityColours.light().color());
-        colorsgroup.writeEntry("Complete", \
availabilityColours.windowText().color()); +        \
colorsgroup.writeEntry("NoSources", colorNoSources); +        \
colorsgroup.writeEntry("FewSources", colorFewSources); +        \
colorsgroup.writeEntry("ManySources", colorManySources); +        \
colorsgroup.writeEntry("Complete", colorComplete);  \
colorsgroup.writeEntry("Threshold", availabilityThreshold);  \
colorsgroup.writeEntry("ShadingDepth", availabilityShadingDepth);  \
                colorsgroup.writeEntry("Shading", availabilityShading);
--- trunk/extragear/network/kmldonkey/kmldonkey/kmldonkey.h #996881:996882
@@ -93,7 +93,7 @@
         QColor colorSearchFewSources, colorSearchManySources, \
colorSearchAlreadyDone;  int searchThreshold;
         QColor colorDownloadDownloading, colorDownloadPaused, colorDownloadLooking, \
                colorDownloadNotAvailable, colorDownloadQueued;
-        QPalette availabilityColours;
+        QColor colorNoSources, colorComplete, colorFewSources, colorManySources;
         int availabilityThreshold, availabilityShadingDepth;
         bool availabilityShading;
         QColor colorSourceNotConnected, colorSourceBlacklisted, \
colorSourceConnecting, colorSourceQueued, colorSourceDownloading;


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic