You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
basket/src/kiconcanvas.cpp

244 lines
6.4 KiB

/*
*
* This file is part of the KDE project, module tdefile.
* Copyright (C) 2006 Luke Sandell <lasandell@gmail.com>
* (C) 2002 Carsten Pfeiffer <pfeiffer@kde.org>
* (C) 2000 Geert Jansen <jansen@kde.org>
* (C) 2000 Kurt Granroth <granroth@kde.org>
* (C) 1997 Christoph Neerfeld <chris@kde.org>
*
* This is free software; it comes under the GNU Library General
* Public License, version 2. See the file "COPYING.LIB" for the
* exact licensing terms.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "kiconcanvas.h"
#include "kicondialog.h"
#include <kiconviewsearchline.h>
#include <tdeapplication.h>
#include <kdebug.h>
#include <tdelocale.h>
#include <tdeglobal.h>
#include <kstandarddirs.h>
#include <kiconloader.h>
#include <kimagefilepreview.h>
#include <kurldrag.h>
#include <tdemultipledrag.h>
#include <tqimage.h>
#include <tqpixmap.h>
#include <tqtimer.h>
#include <tqfileinfo.h>
#include <tqdragobject.h>
#include <cmath>
#include <math.h>
#include <algorithm>
#ifdef HAVE_LIBART
#include <ksvgiconengine.h>
#endif
class TDEIconCanvasItem : public TQIconViewItem
{
public:
TDEIconCanvasItem ( TQIconView * parent, const TQString & key, const TQPixmap & pixmap )
: TQIconViewItem(parent)
{
setText(TQFileInfo(key).baseName());
setKey(key);
setPixmap(pixmap);
setDragEnabled(true);
setDropEnabled(false);
}
int compare(TQIconViewItem *rhs) const
{
return TQString::localeAwareCompare(text().lower(), rhs->text().lower());
}
};
class TDEIconCanvas::TDEIconCanvasPrivate
{
public:
TDEIconCanvasPrivate()
{
m_bLoading = false;
mSize = 0;
}
~TDEIconCanvasPrivate()
{
}
bool m_bLoading;
TQString mSetCurrent;
int mSize;
#ifdef HAVE_LIBART
KSVGIconEngine mSvgEngine;
#endif
bool mStrictIconSize;
};
/*
* TDEIconCanvas: Iconview for the iconloader dialog.
*/
TDEIconCanvas::TDEIconCanvas(TQWidget *parent, const char *name)
: TDEIconView(parent, name)
{
d = new TDEIconCanvasPrivate;
mpLoader = TDEGlobal::iconLoader();
mpTimer = new TQTimer(this);
connect(mpTimer, TQ_SIGNAL(timeout()), TQ_SLOT(slotLoadFiles()));
connect(this, TQ_SIGNAL(currentChanged(TQIconViewItem *)),
TQ_SLOT(slotCurrentChanged(TQIconViewItem *)));
setAcceptDrops(false);
setShowToolTips(true);
setStrictIconSize(false);
}
TDEIconCanvas::~TDEIconCanvas()
{
delete mpTimer;
delete d;
}
void TDEIconCanvas::setIconLoader(TDEIconLoader *loader)
{
mpLoader = loader;
}
void TDEIconCanvas::loadIcon(const TQString &name)
{
TQImage img;
TQString path = mpLoader->iconPath(name,-d->mSize);
// Use the extension as the format. Works for XPM and PNG, but not for SVG
TQString ext = path.right(3).upper();
int maxSize = std::min(d->mSize, 60);
if (ext != "SVG" && ext != "VGZ")
img.load(path);
#ifdef HAVE_LIBART
else
if (d->mSvgEngine.load(maxSize, maxSize, path))
img = *d->mSvgEngine.image();
#endif
if (img.isNull())
return;
// For non-KDE icons
if (d->mStrictIconSize && (img.width() != d->mSize || img.height() != d->mSize))
return;
if (img.width() > maxSize || img.height() > maxSize)
{
if (img.width() > img.height()) {
int height = (int) ((float(maxSize) / img.width()) * img.height());
img = img.smoothScale(maxSize, height);
} else {
int width = (int) ((float(maxSize) / img.height()) * img.width());
img = img.smoothScale(width, maxSize);
}
}
TQPixmap pm;
pm.convertFromImage(img);
(void) new TDEIconCanvasItem(this, name, pm);
}
void TDEIconCanvas::loadFiles(const TQStringList& files)
{
clear();
mFiles = files;
emit startLoading(mFiles.count());
mpTimer->start(10, true); // #86680
d->m_bLoading = false;
}
void TDEIconCanvas::slotLoadFiles()
{
setResizeMode(Fixed);
TQApplication::setOverrideCursor(waitCursor);
// disable updates to not trigger paint events when adding child items
setUpdatesEnabled( false );
d->m_bLoading = true;
int count;
TQStringList::ConstIterator it;
TQStringList::ConstIterator end(mFiles.end());
for (it=mFiles.begin(), count=0; it!=end; ++it, count++)
{
loadIcon(*it);
// Calling kapp->processEvents() makes the iconview flicker like hell
// (it's being repainted once for every new item), so we don't do this.
// Instead, we directly repaint the progress bar without going through
// the event-loop. We do that just once for every 10th item so that
// the progress bar doesn't flicker in turn. (pfeiffer)
// FIXME: TQt4 will have double buffering
if ( count % 10 == 0) {
emit progress(count);
}
if ( !d->m_bLoading ) // user clicked on a button that will load another set of icons
break;
}
// enable updates since we have to draw the whole view now
sort();
d->m_bLoading = false;
setUpdatesEnabled( true );
TQApplication::restoreOverrideCursor();
emit finished();
setResizeMode(Adjust);
}
TQString TDEIconCanvas::getCurrent() const
{
return currentItem() ? currentItem()->key() : TQString();
}
void TDEIconCanvas::stopLoading()
{
d->m_bLoading = false;
}
void TDEIconCanvas::slotCurrentChanged(TQIconViewItem *item)
{
emit nameChanged((item != 0L) ? item->text() : TQString());
}
void TDEIconCanvas::setGroupOrSize( int groupOrSize )
{
d->mSize = ((int)groupOrSize >= 0) ?
mpLoader->currentSize((TDEIcon::Group)groupOrSize) :
-groupOrSize;
}
void TDEIconCanvas::setStrictIconSize( bool strictIconSize )
{
d->mStrictIconSize = strictIconSize;
}
TQDragObject *TDEIconCanvas::dragObject()
{
// We use TQImageDrag rather than KURLDrag so that the user can't drag an icon out of the theme!
// TODO: support SVG?
TQPixmap *pixmap = currentItem()->pixmap();
TQPoint pos = viewportToContents( viewport()->mapFromGlobal( TQCursor::pos() ) );
TQPoint hot;
hot.setX(pos.x() - currentItem()->pos().x() - (currentItem()->width() - pixmap->width()) / 2);
hot.setY(pos.y() - currentItem()->pos().y() - (currentItem()->height() - pixmap->height()) / 2);
TQImageDrag *drag = new TQImageDrag( pixmap->convertToImage(), this );
drag->setPixmap(*pixmap, hot);
return drag;
}
#include "kiconcanvas.moc"