summaryrefslogtreecommitdiffstats
path: root/src/part/radialMap/segmentTip.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/part/radialMap/segmentTip.cpp')
-rw-r--r--src/part/radialMap/segmentTip.cpp186
1 files changed, 186 insertions, 0 deletions
diff --git a/src/part/radialMap/segmentTip.cpp b/src/part/radialMap/segmentTip.cpp
new file mode 100644
index 0000000..f73e845
--- /dev/null
+++ b/src/part/radialMap/segmentTip.cpp
@@ -0,0 +1,186 @@
+//Author: Max Howell <max.howell@methylblue.com>, (C) 2003-4
+//Copyright: See COPYING file that comes with this distribution
+
+#include "fileTree.h"
+#include "segmentTip.h"
+
+#include <cstdlib>
+#include <kapplication.h> //installing eventFilters
+#include <kglobal.h>
+#include <kglobalsettings.h>
+#include <klocale.h>
+#include <kpixmapeffect.h>
+#include <qpainter.h>
+#include <qtooltip.h> //for its palette
+
+
+
+namespace RadialMap {
+
+
+bool isBackingStoreActive()
+{
+ // # xdpyinfo | grep backing
+ // options: backing-store YES, save-unders YES
+
+ char buffer[4096];
+ FILE *xdpyinfo = popen( "xdpyinfo", "r" );
+ int const N = fread( (void*)buffer, sizeof(char), 4096, xdpyinfo );
+ buffer[ N ] = '\0';
+ pclose( xdpyinfo );
+
+ return QString::fromLocal8Bit( buffer ).contains( "backing-store YES" );
+}
+
+
+SegmentTip::SegmentTip( uint h )
+ : QWidget( 0, 0, WNoAutoErase | WStyle_Customize | WStyle_NoBorder | WStyle_Tool | WStyle_StaysOnTop | WX11BypassWM )
+ , m_cursorHeight( -h )
+ , m_backing_store( isBackingStoreActive() )
+{
+ setBackgroundMode( Qt::NoBackground );
+}
+
+void
+SegmentTip::moveTo( QPoint p, const QWidget &canvas, bool placeAbove )
+{
+ //**** this function is very slow and seems to be visibly influenced by operations like mapFromGlobal() (who knows why!)
+ // ** so any improvements are much desired
+
+ //TODO uints could improve the class
+ p.rx() -= rect().center().x();
+ p.ry() -= (placeAbove ? 8 + height() : m_cursorHeight - 8);
+
+ const QRect screen = KGlobalSettings::desktopGeometry( parentWidget() );
+
+ const int x = p.x();
+ const int y = p.y();
+ const int x2 = x + width();
+ const int y2 = y + height(); //how's it ever gunna get below screen height?! (well you never know I spose)
+ const int sw = screen.width();
+ const int sh = screen.height();
+
+ if( x < 0 ) p.setX( 0 );
+ if( y < 0 ) p.setY( 0 );
+ if( x2 > sw ) p.rx() -= x2 - sw;
+ if( y2 > sh ) p.ry() -= y2 - sh;
+
+
+ //I'm using this QPoint to determine where to offset the bitBlt in m_pixmap
+ QPoint offset = canvas.mapToGlobal( QPoint() ) - p;
+ if( offset.x() < 0 ) offset.setX( 0 );
+ if( offset.y() < 0 ) offset.setY( 0 );
+
+
+ const QRect alphaMaskRect( canvas.mapFromGlobal( p ), size() );
+ const QRect intersection( alphaMaskRect.intersect( canvas.rect() ) );
+
+ m_pixmap.resize( size() ); //move to updateTip once you are sure it can never be null
+ bitBlt( &m_pixmap, offset, &canvas, intersection, Qt::CopyROP );
+
+ QColor const c = QToolTip::palette().color( QPalette::Active, QColorGroup::Background );
+ if (!m_backing_store)
+ m_pixmap.fill( c );
+
+ QPainter paint( &m_pixmap );
+ paint.setPen( Qt::black );
+ paint.setBrush( Qt::NoBrush );
+ paint.drawRect( rect() );
+ paint.end();
+
+ if (m_backing_store)
+ m_pixmap = KPixmapEffect::fade( m_pixmap, 0.6, c );
+
+ paint.begin( &m_pixmap );
+ paint.drawText( rect(), AlignCenter, m_text );
+ paint.end();
+
+ p += screen.topLeft(); //for Xinerama users
+
+ move( x, y );
+ show();
+ update();
+}
+
+void
+SegmentTip::updateTip( const File* const file, const Directory* const root )
+{
+ const QString s1 = file->fullPath( root );
+ QString s2 = file->humanReadableSize();
+ KLocale *loc = KGlobal::locale();
+ const uint MARGIN = 3;
+ const uint pc = 100 * file->size() / root->size();
+ uint maxw = 0;
+ uint h = fontMetrics().height()*2 + 2*MARGIN;
+
+ if( pc > 0 ) s2 += QString( " (%1%)" ).arg( loc->formatNumber( pc, 0 ) );
+
+ m_text = s1;
+ m_text += '\n';
+ m_text += s2;
+
+ if( file->isDirectory() )
+ {
+ double files = static_cast<const Directory*>(file)->children();
+ const uint pc = uint((100 * files) / (double)root->children());
+ QString s3 = i18n( "Files: %1" ).arg( loc->formatNumber( files, 0 ) );
+
+ if( pc > 0 ) s3 += QString( " (%1%)" ).arg( loc->formatNumber( pc, 0 ) );
+
+ maxw = fontMetrics().width( s3 );
+ h += fontMetrics().height();
+ m_text += '\n';
+ m_text += s3;
+ }
+
+ uint
+ w = fontMetrics().width( s1 ); if( w > maxw ) maxw = w;
+ w = fontMetrics().width( s2 ); if( w > maxw ) maxw = w;
+
+ resize( maxw + 2 * MARGIN, h );
+}
+
+bool
+SegmentTip::event( QEvent *e )
+{
+ switch( e->type() )
+ {
+ case QEvent::Show:
+ kapp->installEventFilter( this );
+ break;
+ case QEvent::Hide:
+ kapp->removeEventFilter( this );
+ break;
+ case QEvent::Paint:
+ {
+ //QPainter( this ).drawPixmap( 0, 0, m_pixmap );
+ bitBlt( this, 0, 0, &m_pixmap );
+ return true;
+ }
+ default:
+ ;
+ }
+
+ return false/*QWidget::event( e )*/;
+}
+
+bool
+SegmentTip::eventFilter( QObject*, QEvent *e )
+{
+ switch ( e->type() )
+ {
+ case QEvent::Leave:
+// case QEvent::MouseButtonPress:
+// case QEvent::MouseButtonRelease:
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ case QEvent::FocusIn:
+ case QEvent::FocusOut:
+ case QEvent::Wheel:
+ hide(); //FALL THROUGH
+ default:
+ return false; //allow this event to passed to target
+ }
+}
+
+} //namespace RadialMap