Don't recreate and destroy the tooltip widget on each show/hide operation, just use set the widget visible/invisible and update the content instead

svn path=/trunk/KDE/kdebase/apps/; revision=1107992
This commit is contained in:
Peter Penz 2010-03-27 13:08:46 +00:00
parent dd743f9d98
commit 47e80ef6b9
8 changed files with 219 additions and 321 deletions

View file

@ -43,8 +43,7 @@ set(dolphinprivate_LIB_SRCS
settings/filemetadataconfigurationdialog.cpp
settings/viewpropertiesdialog.cpp
settings/viewpropsprogressinfo.cpp
tooltips/ktooltip.cpp
tooltips/ktooltipwindow.cpp
tooltips/filemetadatatooltip.cpp
tooltips/tooltipmanager.cpp
versioncontrol/pendingthreadsmaintainer.cpp
versioncontrol/updateitemstatesthread.cpp

View file

@ -0,0 +1,161 @@
/***************************************************************************
* Copyright (C) 2010 by Peter Penz <peter.penz@gmx.at> *
* Copyright (C) 2008 by Fredrik Höglund <fredrik@kde.org> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#include "filemetadatatooltip.h"
#include <kcolorscheme.h>
#include <kfilemetadatawidget.h>
#include <kseparator.h>
#include <kwindowsystem.h>
#include <QLabel>
#include <QPainter>
#include <QVBoxLayout>
FileMetaDataToolTip::FileMetaDataToolTip(QWidget* parent) :
QWidget(parent),
m_preview(0),
m_name(0),
m_fileMetaDataWidget(0)
{
setAttribute(Qt::WA_TranslucentBackground);
setWindowFlags(Qt::ToolTip | Qt::FramelessWindowHint);
// Create widget for file preview
m_preview = new QLabel(this);
// Create widget for file name
m_name = new QLabel(this);
m_name->setWordWrap(true);
QFont font = m_name->font();
font.setBold(true);
m_name->setFont(font);
m_name->setAlignment(Qt::AlignHCenter);
m_name->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
// Create widget for the meta data
m_fileMetaDataWidget = new KFileMetaDataWidget();
m_fileMetaDataWidget->setForegroundRole(QPalette::ToolTipText);
m_fileMetaDataWidget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
m_fileMetaDataWidget->setReadOnly(true);
// The stretchwidget allows the metadata widget to be top aligned and fills
// the remaining vertical space
QWidget* stretchWidget = new QWidget(this);
stretchWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
QWidget* textContainer = new QWidget(this);
QVBoxLayout* textLayout = new QVBoxLayout(textContainer);
textLayout->addWidget(m_name);
textLayout->addWidget(new KSeparator());
textLayout->addWidget(m_fileMetaDataWidget);
textLayout->addWidget(stretchWidget);
QHBoxLayout* tipLayout = new QHBoxLayout(this);
tipLayout->addWidget(m_preview);
tipLayout->addWidget(textContainer);
}
FileMetaDataToolTip::~FileMetaDataToolTip()
{
}
void FileMetaDataToolTip::setPreview(const QPixmap& pixmap)
{
m_preview->setPixmap(pixmap);
m_preview->setFixedSize(pixmap.size());
}
const QPixmap* FileMetaDataToolTip::preview() const
{
return m_preview->pixmap();
}
void FileMetaDataToolTip::setName(const QString& name)
{
m_name->setText(name);
}
QString FileMetaDataToolTip::name() const
{
return m_name->text();
}
void FileMetaDataToolTip::setItems(const KFileItemList& items)
{
m_fileMetaDataWidget->setItems(items);
}
KFileItemList FileMetaDataToolTip::items() const
{
return m_fileMetaDataWidget->items();
}
void FileMetaDataToolTip::paintEvent(QPaintEvent* event)
{
Q_UNUSED(event);
QPainter painter(this);
QColor toColor = palette().brush(QPalette::ToolTipBase).color();
QColor fromColor = KColorScheme::shade(toColor, KColorScheme::LightShade, 0.2);
const bool haveAlphaChannel = KWindowSystem::compositingActive();
if (haveAlphaChannel) {
painter.setRenderHint(QPainter::Antialiasing);
painter.translate(0.5, 0.5);
toColor.setAlpha(220);
fromColor.setAlpha(220);
}
QLinearGradient gradient(QPointF(0.0, 0.0), QPointF(0.0, height()));
gradient.setColorAt(0.0, fromColor);
gradient.setColorAt(1.0, toColor);
painter.setPen(Qt::NoPen);
painter.setBrush(gradient);
const QRect rect(0, 0, width(), height());
if (haveAlphaChannel) {
const qreal radius = 5.0;
QPainterPath path;
path.moveTo(rect.left(), rect.top() + radius);
arc(path, rect.left() + radius, rect.top() + radius, radius, 180, -90);
arc(path, rect.right() - radius, rect.top() + radius, radius, 90, -90);
arc(path, rect.right() - radius, rect.bottom() - radius, radius, 0, -90);
arc(path, rect.left() + radius, rect.bottom() - radius, radius, 270, -90);
path.closeSubpath();
painter.drawPath(path);
} else {
painter.drawRect(rect);
}
}
void FileMetaDataToolTip::arc(QPainterPath& path,
qreal cx, qreal cy,
qreal radius, qreal angle,
qreal sweepLength)
{
path.arcTo(cx-radius, cy-radius, radius * 2, radius * 2, angle, sweepLength);
}
#include "filemetadatatooltip.moc"

View file

@ -1,5 +1,6 @@
/***************************************************************************
* Copyright (C) 2009 by Peter Penz <peter.penz@gmx.at> *
* Copyright (C) 2010 by Peter Penz <peter.penz@gmx.at> *
* Copyright (C) 2008 by Fredrik Höglund <fredrik@kde.org> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
@ -17,29 +18,53 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#ifndef KTOOLTIPWINDOW_H
#define KTOOLTIPWINDOW_H
#ifndef DOLPHINCONTROLLER_H
#define DOLPHINCONTROLLER_H
#include <QWidget>
class QPaintEvent;
class KToolTipWindow : public QWidget
class KFileItemList;
class KFileMetaDataWidget;
class QLabel;
/**
* @brief Tooltip, that shows the meta information and a preview of one
* or more files.
*/
class FileMetaDataToolTip : public QWidget
{
Q_OBJECT
public:
explicit KToolTipWindow(QWidget* content);
virtual ~KToolTipWindow();
FileMetaDataToolTip(QWidget* parent = 0);
virtual ~FileMetaDataToolTip();
void setPreview(const QPixmap& pixmap);
const QPixmap* preview() const;
void setName(const QString& name);
QString name() const;
void setItems(const KFileItemList& items);
KFileItemList items() const;
protected:
virtual void paintEvent(QPaintEvent* event);
private:
/**
* Helper method for KToolTipWindow::paintEvent() to adjust the painter path \p path
* Helper method for FileMetaDataToolTip::paintEvent() to adjust the painter path \p path
* by rounded corners.
*/
static void arc(QPainterPath& path, qreal cx, qreal cy, qreal radius, qreal angle, qreal sweeplength);
static void arc(QPainterPath& path,
qreal cx, qreal cy,
qreal radius, qreal angle,
qreal sweepLength);
private:
QLabel* m_preview;
QLabel* m_name;
KFileMetaDataWidget* m_fileMetaDataWidget;
};
#endif

View file

@ -1,102 +0,0 @@
/***************************************************************************
* Copyright (C) 2008 by Fredrik Höglund <fredrik@kde.org> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#include "ktooltip.h"
#include "ktooltipwindow_p.h"
#include <QLabel>
#include <QPoint>
#include <QWidget>
class KToolTipManager
{
public:
~KToolTipManager();
static KToolTipManager* instance();
void showTip(const QPoint& pos, QWidget* content);
void hideTip();
private:
KToolTipManager();
KToolTipWindow* m_window;
static KToolTipManager *s_instance;
};
KToolTipManager *KToolTipManager::s_instance = 0;
KToolTipManager::KToolTipManager() :
m_window(0)
{
}
KToolTipManager::~KToolTipManager()
{
delete m_window;
m_window = 0;
}
KToolTipManager* KToolTipManager::instance()
{
if (s_instance == 0) {
s_instance = new KToolTipManager();
}
return s_instance;
}
void KToolTipManager::showTip(const QPoint& pos, QWidget* content)
{
hideTip();
Q_ASSERT(m_window == 0);
m_window = new KToolTipWindow(content);
m_window->move(pos);
m_window->show();
}
void KToolTipManager::hideTip()
{
if (m_window != 0) {
m_window->hide();
m_window->deleteLater();
m_window = 0;
}
}
namespace KToolTip
{
void showText(const QPoint& pos, const QString& text)
{
QLabel* label = new QLabel(text);
label->setForegroundRole(QPalette::ToolTipText);
showTip(pos, label);
}
void showTip(const QPoint& pos, QWidget* content)
{
KToolTipManager::instance()->showTip(pos, content);
}
void hideTip()
{
KToolTipManager::instance()->hideTip();
}
}

View file

@ -1,46 +0,0 @@
/***************************************************************************
* Copyright (C) 2008 by Fredrik Höglund <fredrik@kde.org> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#ifndef KTOOLTIP_H
#define KTOOLTIP_H
class QPoint;
class QString;
class QWidget;
/**
* Allows to show tooltips having a widget as content.
*/
namespace KToolTip
{
void showText(const QPoint& pos, const QString& text);
/**
* Shows the tip @p content at the global position indicated by @p pos.
*
* Ownership of the content widget is transferred to KToolTip. The widget will be deleted
* automatically when it is hidden.
*
* The tip is shown immediately when this function is called.
*/
void showTip(const QPoint& pos, QWidget* content);
void hideTip();
}
#endif

View file

@ -1,90 +0,0 @@
/*******************************************************************************
* Copyright (C) 2008 by Fredrik Höglund <fredrik@kde.org> *
* Copyright (C) 2008 by Konstantin Heil <konst.heil@stud.uni-heidelberg.de> *
* Copyright (C) 2009 by Peter Penz <peter.penz@gmx.at> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
*******************************************************************************/
#include "ktooltipwindow_p.h"
#include <kcolorscheme.h>
#include <kwindowsystem.h>
#include <QPainter>
#include <QVBoxLayout>
KToolTipWindow::KToolTipWindow(QWidget* content) :
QWidget(0)
{
setAttribute(Qt::WA_TranslucentBackground);
setWindowFlags(Qt::ToolTip | Qt::FramelessWindowHint);
QVBoxLayout* layout = new QVBoxLayout(this);
layout->addWidget(content);
}
KToolTipWindow::~KToolTipWindow()
{
}
void KToolTipWindow::paintEvent(QPaintEvent* event)
{
Q_UNUSED(event);
QPainter painter(this);
QColor toColor = palette().brush(QPalette::ToolTipBase).color();
QColor fromColor = KColorScheme::shade(toColor, KColorScheme::LightShade, 0.2);
const bool haveAlphaChannel = KWindowSystem::compositingActive();
if (haveAlphaChannel) {
painter.setRenderHint(QPainter::Antialiasing);
painter.translate(0.5, 0.5);
toColor.setAlpha(220);
fromColor.setAlpha(220);
}
QLinearGradient gradient(QPointF(0.0, 0.0), QPointF(0.0, height()));
gradient.setColorAt(0.0, fromColor);
gradient.setColorAt(1.0, toColor);
painter.setPen(Qt::NoPen);
painter.setBrush(gradient);
const QRect rect(0, 0, width(), height());
if (haveAlphaChannel) {
const qreal radius = 5.0;
QPainterPath path;
path.moveTo(rect.left(), rect.top() + radius);
arc(path, rect.left() + radius, rect.top() + radius, radius, 180, -90);
arc(path, rect.right() - radius, rect.top() + radius, radius, 90, -90);
arc(path, rect.right() - radius, rect.bottom() - radius, radius, 0, -90);
arc(path, rect.left() + radius, rect.bottom() - radius, radius, 270, -90);
path.closeSubpath();
painter.drawPath(path);
} else {
painter.drawRect(rect);
}
}
void KToolTipWindow::arc(QPainterPath& path, qreal cx, qreal cy, qreal radius, qreal angle, qreal sweeplength)
{
path.arcTo(cx-radius, cy-radius, radius * 2, radius * 2, angle, sweeplength);
}
#include "ktooltipwindow_p.moc"

View file

@ -22,21 +22,15 @@
#include "dolphinmodel.h"
#include "dolphinsortfilterproxymodel.h"
#include <kfilemetadatawidget.h>
#include "filemetadatatooltip.h"
#include <kicon.h>
#include <kio/previewjob.h>
#include <kseparator.h>
#include "tooltips/ktooltip.h"
#include <QApplication>
#include <QDesktopWidget>
#include <QHBoxLayout>
#include <QLabel>
#include <QScrollArea>
#include <QScrollBar>
#include <QTimer>
#include <QVBoxLayout>
ToolTipManager::ToolTipManager(QAbstractItemView* parent,
DolphinSortFilterProxyModel* model) :
@ -47,6 +41,7 @@ ToolTipManager::ToolTipManager(QAbstractItemView* parent,
m_timer(0),
m_previewTimer(0),
m_waitOnPreviewTimer(0),
m_fileMetaDataToolTip(0),
m_item(),
m_itemRect(),
m_generatingPreview(false),
@ -84,6 +79,8 @@ ToolTipManager::ToolTipManager(QAbstractItemView* parent,
m_view->viewport()->installEventFilter(this);
m_view->installEventFilter(this);
m_fileMetaDataToolTip = new FileMetaDataToolTip(parent);
}
ToolTipManager::~ToolTipManager()
@ -115,11 +112,11 @@ bool ToolTipManager::eventFilter(QObject* watched, QEvent* event)
void ToolTipManager::requestToolTip(const QModelIndex& index)
{
// only request a tooltip for the name column and when no selection or
// Only request a tooltip for the name column and when no selection or
// drag & drop operation is done (indicated by the left mouse button)
if ((index.column() == DolphinModel::Name) && !(QApplication::mouseButtons() & Qt::LeftButton)) {
m_waitOnPreviewTimer->stop();
KToolTip::hideTip();
m_fileMetaDataToolTip->hide();
m_itemRect = m_view->visualRect(index);
const QPoint pos = m_view->viewport()->mapToGlobal(m_itemRect.topLeft());
@ -128,8 +125,8 @@ void ToolTipManager::requestToolTip(const QModelIndex& index)
const QModelIndex dirIndex = m_proxyModel->mapToSource(index);
m_item = m_dolphinModel->itemForIndex(dirIndex);
// only start the previewJob when the mouse has been over this item for 200 milliseconds,
// this prevents a lot of useless preview jobs when passing rapidly over a lot of items
// Only start the previewJob when the mouse has been over this item for 200 milliseconds.
// This prevents a lot of useless preview jobs when passing rapidly over a lot of items.
m_previewTimer->start(200);
m_previewPixmap = QPixmap();
m_hasDefaultIcon = false;
@ -145,7 +142,8 @@ void ToolTipManager::hideToolTip()
m_timer->stop();
m_previewTimer->stop();
m_waitOnPreviewTimer->stop();
KToolTip::hideTip();
m_fileMetaDataToolTip->hide();
}
void ToolTipManager::prepareToolTip()
@ -179,7 +177,7 @@ void ToolTipManager::setPreviewPix(const KFileItem& item,
const QPixmap& pixmap)
{
if ((m_item.url() != item.url()) || pixmap.isNull()) {
// an old preview or an invalid preview has been received
// An old preview or an invalid preview has been received
previewFailed();
} else {
m_previewPixmap = pixmap;
@ -199,10 +197,12 @@ void ToolTipManager::showToolTip(const QPixmap& pixmap)
return;
}
QWidget* tip = createTipContent(pixmap);
m_fileMetaDataToolTip->setPreview(pixmap);
m_fileMetaDataToolTip->setName(m_item.text());
m_fileMetaDataToolTip->setItems(KFileItemList() << m_item);
// calculate the x- and y-position of the tooltip
const QSize size = tip->sizeHint();
// Calculate the x- and y-position of the tooltip
const QSize size = m_fileMetaDataToolTip->sizeHint();
const QRect desktop = QApplication::desktop()->screenGeometry(m_itemRect.bottomRight());
// m_itemRect defines the area of the item, where the tooltip should be
@ -215,8 +215,6 @@ void ToolTipManager::showToolTip(const QPixmap& pixmap)
const bool hasRoomAbove = (m_itemRect.top() - size.height() >= desktop.top());
const bool hasRoomBelow = (m_itemRect.bottom() + size.height() <= desktop.bottom());
if (!hasRoomAbove && !hasRoomBelow && !hasRoomToLeft && !hasRoomToRight) {
delete tip;
tip = 0;
return;
}
@ -237,54 +235,8 @@ void ToolTipManager::showToolTip(const QPixmap& pixmap)
y = desktop.bottom() - size.height();
}
// the ownership of tip is transferred to KToolTip
KToolTip::showTip(QPoint(x, y), tip);
}
QWidget* ToolTipManager::createTipContent(const QPixmap& pixmap) const
{
QWidget* tipContent = new QWidget();
// add pixmap
QLabel* pixmapLabel = new QLabel(tipContent);
pixmapLabel->setPixmap(pixmap);
pixmapLabel->setFixedSize(pixmap.size());
// add item name
QLabel* nameLabel = new QLabel(tipContent);
nameLabel->setText(m_item.text());
nameLabel->setWordWrap(true);
QFont font = nameLabel->font();
font.setBold(true);
nameLabel->setFont(font);
nameLabel->setAlignment(Qt::AlignHCenter);
nameLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
// add meta data
KFileMetaDataWidget* metaDataWidget = new KFileMetaDataWidget(tipContent);
metaDataWidget->setForegroundRole(QPalette::ToolTipText);
metaDataWidget->setItems(KFileItemList() << m_item);
metaDataWidget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
metaDataWidget->setReadOnly(true);
// the stretchwidget allows the metadata widget to be top aligned and fills
// the remaining vertical space
QWidget* stretchWidget = new QWidget(tipContent);
stretchWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
QWidget* textContainer = new QWidget(tipContent);
QVBoxLayout* textLayout = new QVBoxLayout(textContainer);
textLayout->addWidget(nameLabel);
textLayout->addWidget(new KSeparator());
textLayout->addWidget(metaDataWidget);
textLayout->addWidget(stretchWidget);
QHBoxLayout* tipLayout = new QHBoxLayout(tipContent);
tipLayout->setMargin(0);
tipLayout->addWidget(pixmapLabel);
tipLayout->addWidget(textContainer);
return tipContent;
m_fileMetaDataToolTip->move(x, y);
m_fileMetaDataToolTip->show();
}
#include "tooltipmanager.moc"

View file

@ -27,6 +27,7 @@
class DolphinModel;
class DolphinSortFilterProxyModel;
class FileMetaDataToolTip;
class QAbstractItemView;
class QModelIndex;
class QTimer;
@ -69,12 +70,7 @@ private slots:
private:
void showToolTip(const QPixmap& pixmap);
/**
* Creates widget that represents the tip content having
* an icon and the meta data information.
*/
QWidget* createTipContent(const QPixmap& pixmap) const;
private:
QAbstractItemView* m_view;
DolphinModel* m_dolphinModel;
DolphinSortFilterProxyModel* m_proxyModel;
@ -82,6 +78,9 @@ private:
QTimer* m_timer;
QTimer* m_previewTimer;
QTimer* m_waitOnPreviewTimer;
FileMetaDataToolTip* m_fileMetaDataToolTip;
KFileItem m_item;
QRect m_itemRect;
bool m_generatingPreview;