#include "tooltipmanager.h"
+#include "dolphintooltip.h"
#include "dolphinmodel.h"
#include "dolphinsortfilterproxymodel.h"
-#include <kformattedballoontipdelegate.h>
#include <kicon.h>
#include <ktooltip.h>
+#include <QApplication>
+#include <QDesktopWidget>
#include <QTimer>
+#include <QToolTip>
-K_GLOBAL_STATIC(KFormattedBalloonTipDelegate, g_delegate);
+K_GLOBAL_STATIC(DolphinBalloonTooltipDelegate, g_delegate)
ToolTipManager::ToolTipManager(QAbstractItemView* parent,
DolphinSortFilterProxyModel* model) :
m_proxyModel(model),
m_timer(0),
m_item(),
- m_pos()
+ m_itemRect()
{
KToolTip::setToolTipDelegate(g_delegate);
void ToolTipManager::requestToolTip(const QModelIndex& index)
{
- KToolTip::hideTip();
+ if (index.column() == DolphinModel::Name) {
+ KToolTip::hideTip();
- const QRect rect = m_view->visualRect(index);
- m_pos = m_view->viewport()->mapToGlobal(rect.bottomRight());
+ m_itemRect = m_view->visualRect(index);
+ const QPoint pos = m_view->viewport()->mapToGlobal(m_itemRect.topLeft());
+ m_itemRect.moveTo(pos);
- const QModelIndex dirIndex = m_proxyModel->mapToSource(index);
- m_item = m_dolphinModel->itemForIndex(dirIndex);
+ const QModelIndex dirIndex = m_proxyModel->mapToSource(index);
+ m_item = m_dolphinModel->itemForIndex(dirIndex);
- m_timer->start(500);
+ m_timer->start(500);
+ } else {
+ hideToolTip();
+ }
}
void ToolTipManager::hideToolTip()
void ToolTipManager::showToolTip()
{
- KToolTipItem* tip = new KToolTipItem(KIcon(m_item.iconName()), m_item.getToolTipText());
- KToolTip::showTip(m_pos, tip);
+ // TODO - create tip during requestTip(...) - this makes it more likely that the previews
+ // job will have completed by the time the tooltip is shown, resulting in less flicker.
+ // The memory management will be more intricate, though.
+ DolphinToolTipItem *tip = new DolphinToolTipItem(m_item);
+
+ KStyleOptionToolTip option;
+ // TODO: get option content from KToolTip or add KToolTip::sizeHint() method
+ option.direction = QApplication::layoutDirection();
+ option.fontMetrics = QFontMetrics(QToolTip::font());
+ option.activeCorner = KStyleOptionToolTip::TopLeftCorner;
+ option.palette = QToolTip::palette();
+ option.font = QToolTip::font();
+ option.rect = QRect();
+ option.state = QStyle::State_None;
+ option.decorationSize = QSize(32, 32);
+
+ const QSize size = g_delegate->sizeHint(&option, tip);
+ const QRect desktop = QApplication::desktop()->screenGeometry(m_itemRect.bottomRight());
+
+ // m_itemRect defines the area of the item, where the tooltip should be
+ // shown. Per default the tooltip is shown in the bottom right corner.
+ // If the tooltip content exceeds the desktop borders, it must be assured that:
+ // - the content is fully visible
+ // - the content is not drawn inside m_itemRect
+ 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());
+ if (!hasRoomAbove && !hasRoomBelow && !hasRoomToLeft && !hasRoomToRight) {
+ delete tip;
+ tip = 0;
+ return;
+ }
+
+ 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) {
+ y = hasRoomBelow ? m_itemRect.bottom() : m_itemRect.top() - size.height();
+ } else {
+ // 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();
+ }
+
+ KToolTip::showTip(QPoint(x, y), tip);
}
#include "tooltipmanager.moc"