[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