#include <QApplication>
#include <QDesktopWidget>
+#include <QScrollBar>
#include <QTimer>
#include <QToolTip>
connect(m_waitOnPreviewTimer, SIGNAL(timeout()),
this, SLOT(prepareToolTip()));
+ // When the mousewheel is used, the items don't get a hovered indication
+ // (Qt-issue #200665). To assure that the tooltip still gets hidden,
+ // the scrollbars are observed.
+ connect(parent->horizontalScrollBar(), SIGNAL(valueChanged(int)),
+ this, SLOT(hideTip()));
+ connect(parent->verticalScrollBar(), SIGNAL(valueChanged(int)),
+ this, SLOT(hideTip()));
+
m_view->viewport()->installEventFilter(this);
}
void ToolTipManager::requestToolTip(const QModelIndex& index)
{
- if (index.column() == DolphinModel::Name) {
+ // 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();
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 200msec,
- // this prevents a lot of useless previewJobs (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);
- // reset these variables
m_preview = false;
m_previewIsLate = false;
m_previewPass = 0;
m_emptyRenderedKToolTipItem = toolTip; // make toolTip accessible everywhere
showToolTip(toolTip);
}
-
+
++m_previewPass;
m_waitOnPreviewTimer->start(250);
} else {
if (m_preview && m_previewIsLate) {
// We got a preview, but it is late, the tooltip has already been shown.
// So update the tooltip directly.
- m_emptyRenderedKToolTipItem->setData(Qt::DecorationRole, KIcon(m_pix));
+ if (m_emptyRenderedKToolTipItem != 0) {
+ m_emptyRenderedKToolTipItem->setData(Qt::DecorationRole, KIcon(m_pix));
+ }
return;
}
void ToolTipManager::showToolTip(KToolTipItem* tip)
{
+ if (QApplication::mouseButtons() & Qt::LeftButton) {
+ delete tip;
+ tip = 0;
+ // m_emptyRenderedKToolTipItem is an alias for tip.
+ m_emptyRenderedKToolTipItem = 0;
+ return;
+ }
+
KStyleOptionToolTip option;
// TODO: get option content from KToolTip or add KToolTip::sizeHint() method
option.direction = QApplication::layoutDirection();
const bool hasRoomToLeft = (m_itemRect.left() - size.width() >= desktop.left());
const bool hasRoomToRight = (m_itemRect.right() + size.width() <= desktop.right());
const bool hasRoomAbove = (m_itemRect.top() - size.height() >= desktop.top());
- const bool hasRoomBelow = (m_itemRect.bottom() + size.height() <= desktop.bottom());
+ const bool hasRoomBelow = (m_itemRect.bottom() + size.height() <= desktop.bottom());
if (!hasRoomAbove && !hasRoomBelow && !hasRoomToLeft && !hasRoomToRight) {
delete tip;
tip = 0;
}
int x = 0;
- if (hasRoomToLeft || hasRoomToRight) {
- x = hasRoomToRight ? m_itemRect.right() : m_itemRect.left() - size.width();
- } else {
- // Put the tooltip at the far right of the screen. The item will be overlapped
- // horizontally, but the y-coordinate will be adjusted afterwards so that no overlapping
- // occurs vertically.
- x = desktop.right() - size.width();
- }
-
int y = 0;
if (hasRoomBelow || hasRoomAbove) {
+ x = QCursor::pos().x() + 16; // TODO: use mouse pointer width instead of the magic value of 16
+ if (x + size.width() >= desktop.right()) {
+ x = desktop.right() - size.width();
+ }
y = hasRoomBelow ? m_itemRect.bottom() : m_itemRect.top() - size.height();
} else {
+ Q_ASSERT(hasRoomToLeft || hasRoomToRight);
+ x = hasRoomToRight ? m_itemRect.right() : m_itemRect.left() - size.width();
+
// Put the tooltip at the bottom of the screen. The x-coordinate has already
// been adjusted, so that no overlapping with m_itemRect occurs.
y = desktop.bottom() - size.height();
m_generatingPreview = false;
return;
}
-
- QPixmap icon = pixmap;
- // only paint borders if the pixmap is opaque
- if (!icon.hasAlphaChannel()) {
- // TODO: Make code from IconManager for drawing a border accessible for
- // other classes (the following code has been adapted from IconManager).
- // The frame is painted on top of the pixmap, this is needed to keep
- // the text preview visually nice (the previewer adds ugly borders).
- QPainter painter;
- // make a buffer pixmap, tends to crash when 'icon' is directly painted ...
- QPixmap framedIcon(icon.size().width(), pixmap.size().height());
- framedIcon.fill();
- const int width = framedIcon.width() - 1;
- const int height = framedIcon.height() - 1;
-
- // draw the pixmap
- painter.begin(&framedIcon);
- painter.drawPixmap(0,0, icon);
-
- // draw the frame
- painter.setRenderHint(QPainter::Antialiasing, false);
- painter.setPen(QColor(0, 0, 0));
- painter.drawRect(0, 0, width - 0, height - 1);
- painter.drawRect(1, 1, width - 2, height - 2);
- painter.setPen(QColor(255, 255, 255));
- painter.drawRect(2, 2, width - 4, height - 4);
-
- painter.end();
- icon = framedIcon;
-
- // provide an alpha channel for the frame
- QPixmap alphaChannel(icon.size());
- alphaChannel.fill();
-
- QPainter alphaPainter(&alphaChannel);
- alphaPainter.setBrush(Qt::NoBrush);
- alphaPainter.setRenderHint(QPainter::Antialiasing, false);
- alphaPainter.setPen(QColor(32, 32, 32));
- alphaPainter.drawRect(0, 0, width, height);
- alphaPainter.setPen(QColor(64, 64, 64));
- alphaPainter.drawRect(1, 1, width - 2, height - 2);
-
- icon.setAlphaChannel(alphaChannel);
- }
if (m_previewIsLate) {
// always use the maximal width
- QPixmap paddedImage(QSize(PREVIEW_WIDTH, icon.height()));
+ QPixmap paddedImage(QSize(PREVIEW_WIDTH, pixmap.height()));
paddedImage.fill(Qt::transparent);
QPainter painter(&paddedImage);
- painter.drawPixmap((PREVIEW_WIDTH - icon.width()) / 2, 0, icon);
+ painter.drawPixmap((PREVIEW_WIDTH - pixmap.width()) / 2, 0, pixmap);
m_pix = paddedImage;
} else {
- m_pix = icon;
+ m_pix = pixmap;
}
m_preview = true;
m_generatingPreview = false;