Warning, file /utilities/krusader/app/DiskUsage/radialMap/segmentTip.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 SPDX-FileCopyrightText: 2003-2004 Max Howell <max.howell@methylblue.com> 0003 SPDX-FileCopyrightText: 2004-2022 Krusader Krew <https://krusader.org> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "segmentTip.h" 0009 0010 // QtCore 0011 #include <QEvent> 0012 // QtGui 0013 #include <QPainter> 0014 // QtWidgets 0015 #include <QApplication> //installing eventFilters 0016 #include <QDesktopWidget> 0017 #include <QToolTip> //for its palette 0018 0019 #include <KI18n/KLocalizedString> 0020 0021 #include "../compat.h" 0022 #include "fileTree.h" 0023 0024 namespace RadialMap 0025 { 0026 0027 SegmentTip::SegmentTip(uint h) 0028 : QWidget(nullptr, Qt::FramelessWindowHint | Qt::Tool | Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint) 0029 , m_cursorHeight(-h) 0030 { 0031 setAttribute(Qt::WA_NoSystemBackground, true); 0032 } 0033 0034 void SegmentTip::moveto(QPoint p, QWidget &canvas, bool placeAbove) 0035 { 0036 //**** this function is very slow and seems to be visibly influenced by operations like mapFromGlobal() (who knows why!) 0037 // ** so any improvements are much desired 0038 0039 // TODO uints could improve the class 0040 p.rx() -= rect().center().x(); 0041 p.ry() -= (placeAbove ? 8 + height() : m_cursorHeight - 8); 0042 0043 const QRect screen = QApplication::desktop()->screenGeometry(parentWidget()); 0044 0045 const int x = p.x(); 0046 const int y = p.y(); 0047 const int x2 = x + width(); 0048 const int y2 = y + height(); // how's it ever gunna get below screen height?! (well you never know I spose) 0049 const int sw = screen.width(); 0050 const int sh = screen.height(); 0051 0052 if (x < 0) 0053 p.setX(0); 0054 if (y < 0) 0055 p.setY(0); 0056 if (x2 > sw) 0057 p.rx() -= x2 - sw; 0058 if (y2 > sh) 0059 p.ry() -= y2 - sh; 0060 0061 // I'm using this QPoint to determine where to offset the bitBlt in m_pixmap 0062 QPoint offset = canvas.mapToGlobal(QPoint()) - p; 0063 if (offset.x() < 0) 0064 offset.setX(0); 0065 if (offset.y() < 0) 0066 offset.setY(0); 0067 0068 const QRect alphaMaskRect(canvas.mapFromGlobal(p), size()); 0069 const QRect intersection(alphaMaskRect.intersected(canvas.rect())); 0070 0071 m_pixmap = QPixmap(size()); // move to updateTip once you are sure it can never be null 0072 // bitBlt( &m_pixmap, offset, &canvas, intersection, Qt::CopyROP ); 0073 QPainter(&m_pixmap).drawPixmap(offset, canvas.grab(intersection)); 0074 0075 QColor col = QToolTip::palette().color(QPalette::Active, QPalette::Window); 0076 col.setAlpha(153); // 0.6 0077 0078 QRect rct = rect(); 0079 if (rct.width()) 0080 rct.setWidth(rct.width() - 1); 0081 if (rct.height()) 0082 rct.setHeight(rct.height() - 1); 0083 0084 QPainter paint(&m_pixmap); 0085 paint.setPen(Qt::black); 0086 paint.setBrush(col); 0087 paint.drawRect(rct); 0088 paint.end(); 0089 0090 paint.begin(&m_pixmap); 0091 paint.drawText(rect(), Qt::AlignCenter, m_text); 0092 paint.end(); 0093 0094 p += screen.topLeft(); // for Xinerama users 0095 0096 move(x, y); 0097 show(); 0098 repaint(); 0099 } 0100 0101 void SegmentTip::updateTip(const File *const file, const Directory *const root) 0102 { 0103 const QString s1 = file->fullPath(root); 0104 QString s2 = file->humanReadableSize(); 0105 QLocale loc; 0106 const uint MARGIN = 3; 0107 const FileSize pc = 100 * file->size() / root->size(); 0108 uint maxw = 0; 0109 uint h = fontMetrics().height() * 2 + 2 * MARGIN; 0110 0111 if (pc > 0) 0112 s2 += QString(" (%1%)").arg(loc.toString(pc)); 0113 0114 m_text = s1; 0115 m_text += '\n'; 0116 m_text += s2; 0117 0118 if (file->isDir()) { 0119 double files = dynamic_cast<const Directory *>(file)->fileCount(); 0120 const auto pc = uint((100 * files) / (double)root->fileCount()); 0121 QString s3 = i18n("Files: %1", loc.toString(files, 'f', 0)); 0122 0123 if (pc > 0) 0124 s3 += QString(" (%1%)").arg(loc.toString(pc)); 0125 0126 maxw = fontMetrics().horizontalAdvance(s3); 0127 h += fontMetrics().height(); 0128 m_text += '\n'; 0129 m_text += s3; 0130 } 0131 0132 uint w = fontMetrics().horizontalAdvance(s1); 0133 if (w > maxw) 0134 maxw = w; 0135 w = fontMetrics().horizontalAdvance(s2); 0136 if (w > maxw) 0137 maxw = w; 0138 0139 resize(maxw + 2 * MARGIN, h); 0140 } 0141 0142 bool SegmentTip::event(QEvent *e) 0143 { 0144 switch (e->type()) { 0145 case QEvent::Show: 0146 qApp->installEventFilter(this); 0147 break; 0148 case QEvent::Hide: 0149 qApp->removeEventFilter(this); 0150 break; 0151 case QEvent::Paint: { 0152 // bitBlt( this, 0, 0, &m_pixmap ); 0153 QPainter(this).drawPixmap(0, 0, m_pixmap); 0154 return true; 0155 } 0156 default:; 0157 } 0158 0159 return false /*QWidget::event( e )*/; 0160 } 0161 0162 bool SegmentTip::eventFilter(QObject *, QEvent *e) 0163 { 0164 switch (e->type()) { 0165 case QEvent::Leave: 0166 // case QEvent::MouseButtonPress: 0167 // case QEvent::MouseButtonRelease: 0168 case QEvent::KeyPress: 0169 case QEvent::KeyRelease: 0170 case QEvent::FocusIn: 0171 case QEvent::FocusOut: 0172 case QEvent::Wheel: 0173 hide(); // FALL THROUGH 0174 default: 0175 return false; // allow this event to passed to target 0176 } 0177 } 0178 0179 } // namespace RadialMap