class KDesktopIcon : public QObject
{
Q_OBJECT
public:
KDesktopIcon( const char* _url, int _x, int _y );
virtual ~KDesktopIcon();
/**
* Updates the pixmap and the tool tip ( if required ).
* This function is usually called from KRootWidget::update().
*/
virtual void init();
virtual void updatePixmap();
const char* url() { return m_strURL.data(); }
QString path();
KMimeType* mimeType() { return m_pMimeType; }
int width() { return m_iWidth; }
int height() { return m_iHeight; }
int x() { return m_iX; }
int y() { return m_iY; }
void move( int _x, int _y ) { m_iX = _x; m_iY = _y; }
QRect geometry() { QRect r( m_iX, m_iY, m_iWidth, m_iHeight ); return r; }
void setGeometry( int _x, int _y, int _width, int _height ) { m_iX = _x; m_iY = _y; m_iWidth = _width; m_iHeight = _height; }
/**
* Call this to reinit/redraw the icon (e.g. if the iconstyle
* has changed)
*/
void update();
/**
* Selects/Unselects the icon.
*/
void select( bool _select );
/**
* @return TRUE if the icon is selected ( highlighted )
*/
bool isSelected() { return m_bSelected; }
void setCookie( bool _cookie ) { m_bCookie = _cookie; }
bool cookie() { return m_bCookie; }
bool isBeingMoved() { return m_beingMoved; }
void startMove() { m_beingMoved = true; }
void endMove() { m_beingMoved = false; }
int gridX() { return m_gridX; }
int gridY() { return m_gridY; }
void setGridX( int _x ) { m_gridX = _x; }
void setGridY( int _y ) { m_gridY = _y; }
virtual void paintEvent( QPainter *_painter );
public slots:
void slotFontChanged();
protected:
/**
* This is the URL of the file represented by this icon.
*/
QString m_strURL;
/**
* This is only the filename with no path in front of it.
*/
QString m_strFileName;
/**
* help function to find out filename for a directory
*/
void initFilename();
/**
* Dont delete this pixmap. It is cached in @ref KMimeType::pixmapCache
*/
QPixmap *m_pPixmap;
int m_pixmapXOffset;
int m_pixmapYOffset;
int m_textYOffset;
int m_textXOffset;
bool m_pressed;
QPoint m_pressPos;
int m_iWidth;
int m_iHeight;
int m_iX;
int m_iY;
/**
* Tells us wether this icon is currently selected.
*
* @see #select
*/
bool m_bSelected;
QStrList m_lstDropURLs;
QPopupMenu *m_pPopupMenu;
int m_gridX;
int m_gridY;
/*
* whether the icon currently occupies space or is in a state where a
* new position for it is to be calculated
*/
bool m_beingMoved;
/**
* Tells, wether this icons represents a link in the UNIX sense of
* a link. If yes, then we have to draw the label with an italic font.
*/
bool m_bIsLink;
KMimeType* m_pMimeType;
bool m_bCookie;
static QPixmap *link_pixmap;
static QPixmap *ro_pixmap;
};
KDesktopIcon::KDesktopIcon( const char *_url, int _x, int _y )
{
m_bCookie = false;
m_gridX = -1;
m_gridY = -1;
m_iX = _x;
m_iY = _y;
m_beingMoved = false;
m_bSelected = false;
m_pPopupMenu = new QPopupMenu();
m_strURL = _url;
K2URL u( m_strURL );
m_pMimeType = KMimeType::findByURL( u, 0, true );
cout << "The mimetype is " << m_pMimeType->mimeType() << endl;
m_pPixmap = KPixmapCache::pixmapForMimeType( m_pMimeType, u, true, false );
assert( m_pPixmap );
init();
connect( kapp, SIGNAL( kdisplayFontChanged() ), this, SLOT( slotFontChanged() ) );
if ( !link_pixmap || !ro_pixmap )
{
link_pixmap = new QPixmap;
*link_pixmap = DesktopIcon("link");
ro_pixmap = new QPixmap;
*ro_pixmap = DesktopIcon("readonly");
}
}
void KDesktopIcon::initFilename()
{
K2URL u( m_strURL );
string p = u.path( 0 );
QString path = p.c_str();
// first calculate the default
m_strFileName = path.mid( path.findRev( "/" ) + 1, path.length() );
// Strip extension
if ( m_strFileName.right(8) == ".desktop"
|| m_strFileName.right(7) == ".kdelnk")
m_strFileName.truncate(m_strFileName.findRev('.'));
// This changes "%2f" to "/"
// Just for a nicer display
decodeFileName( m_strFileName );
QDir dir( path ); // no static method available
if ( dir.exists() ) // a directoy
{
path += "/.directory";
QFile f( path );
if ( !f.open( IO_ReadOnly ) )
return;
f.close();
KConfig sc( path );
sc.setGroup("KDE Desktop Entry");
m_strFileName = sc.readEntry( "Name", m_strFileName );
}
}
void KDesktopIcon::init()
{
initFilename();
QPainter p;
p.begin( pdesktop );
m_bIsLink = false;
// Select font
QFont myfont( pdesktop->font() );
K2URL u( m_strURL );
if ( !u.isMalformed() && u.isLocalFile() )
{
struct stat lbuff;
lstat( u.path(), &lbuff );
if ( S_ISLNK( lbuff.st_mode ) )
{
myfont.setItalic( TRUE );
p.setFont( myfont );
m_bIsLink = TRUE;
}
}
int iAscent = p.fontMetrics().ascent();
int iDescent = p.fontMetrics().descent();
int iWidth = p.fontMetrics().width( m_strFileName );
int w = iWidth;
if ( m_pPixmap->width() > w )
{
w = m_pPixmap->width() + 8;
m_textXOffset = ( w - iWidth ) / 2;
m_pixmapXOffset = 4;
}
else
{
w += 8;
m_textXOffset = 4;
m_pixmapXOffset = ( w - m_pPixmap->width() ) / 2;
}
m_pixmapYOffset = 2;
m_textYOffset = m_pPixmap->height() + 5 + iAscent + 2;
p.end();
/* if ( m_bSelected )
setBackgroundColor( black );
else
setBackgroundColor( pdesktop->iconBackground() ); */
m_iWidth = w;
m_iHeight = m_pPixmap->height() + 5 + iAscent + iDescent + 4;
}
void KDesktopIcon::paintEvent( QPainter *p )
{
if ( m_bSelected )
{
QPixmap pix( *m_pPixmap );
QPainter painter;
painter.begin( &pix );
QBrush b( kapp->selectColor, Dense4Pattern );
painter.fillRect( 0, 0, pix.width(), pix.height(), b );
painter.end();
p->drawPixmap( x() + m_pixmapXOffset, y() + m_pixmapYOffset, pix );
}
else
p->drawPixmap( x() + m_pixmapXOffset, y() + m_pixmapYOffset, *m_pPixmap );
if ( m_bIsLink && link_pixmap )
bitBlt( pdesktop, x() + m_pixmapXOffset, y() + m_pixmapYOffset, link_pixmap );
int ascent = p->fontMetrics().ascent();
int descent = p->fontMetrics().descent();
int iWidth = p->fontMetrics().width( m_strFileName );
QColor fillColor;
if ( m_bSelected )
fillColor = kapp->selectColor;
else
fillColor = pdesktop->iconBackground();
p->fillRect( x() + m_textXOffset - 1, y() + m_textYOffset - ascent - 1, iWidth + 2, ascent + descent + 2, fillColor );
if ( m_bSelected )
p->setPen( kapp->selectTextColor );
else
p->setPen( pdesktop->labelForeground() );
QFont myfont( pdesktop->font() );
if ( m_bIsLink )
{
myfont.setItalic( true );
p->setFont( myfont );
}
p->drawText( x() + m_textXOffset, y() + m_textYOffset, m_strFileName );
}
void KDesktopIcon::updatePixmap()
{
QPixmap *tmp = m_pPixmap;
K2URL u( m_strURL );
m_pPixmap = KPixmapCache::pixmapForMimeType( m_pMimeType, u, true, false );
if ( m_pPixmap == tmp )
return;
init();
setGeometry( x(), y(), m_iWidth, m_iHeight );
// Torben: Ohhh, this could lead to flickering. Have to investigate further
// resizeEvent( 0L ); // <-- Added by Lars ( 04/06/98 ): fixes bug when changing icon
// TODO: Make it better!
pdesktop->repaint();
}
void KDesktopIcon::select( bool _select )
{
if ( m_bSelected == _select )
return;
m_bSelected = _select;
update();
}
void KDesktopIcon::update()
{
init();
QPainter p;
p.begin( pdesktop );
paintEvent( &p );
p.end();
}
void KDesktopIcon::slotFontChanged()
{
update();
}
QString KDesktopIcon::path()
{
K2URL u( m_strURL );
return QString( u.path() );
}
KDesktopIcon::~KDesktopIcon()
{
if ( m_pPopupMenu )
delete m_pPopupMenu;
}