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.
395 lines
10 KiB
395 lines
10 KiB
// vim: set tabstop=4 shiftwidth=4 noexpandtab:
|
|
/* Gwenview - A simple image viewer for TDE
|
|
Copyright 2000-2004 Aurélien Gâteau
|
|
This class is based on the TDEIconViewItem class from KDE libs.
|
|
Original copyright follows.
|
|
*/
|
|
/* This file is part of the KDE libraries
|
|
Copyright (C) 1999 Torben Weis <weis@kde.org>
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Library General Public
|
|
License version 2 as published by the Free Software Foundation.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
Boston, MA 02110-1301, USA.
|
|
*/
|
|
// TQt includes
|
|
#include <tqapplication.h>
|
|
#include <tqcolor.h>
|
|
#include <tqpainter.h>
|
|
#include <tqpen.h>
|
|
#include <tqpixmap.h>
|
|
|
|
// KDE includes
|
|
#include <kdebug.h>
|
|
#include <kwordwrap.h>
|
|
#include <kurldrag.h>
|
|
|
|
// Our includes
|
|
#include "archive.h"
|
|
#include "filethumbnailview.h"
|
|
#include "filethumbnailviewitem.h"
|
|
#include "fileviewconfig.h"
|
|
#include "timeutils.h"
|
|
|
|
namespace Gwenview {
|
|
|
|
const int SHOWN_ITEM_INDICATOR_SIZE = 8;
|
|
|
|
#if 0
|
|
static void printRect(const TQString& txt,const TQRect& rect) {
|
|
kdWarning() << txt << " : " << rect.x() << "x" << rect.y() << " " << rect.width() << "x" << rect.height() << endl;
|
|
}
|
|
#endif
|
|
|
|
|
|
/**
|
|
* An helper class to handle a caption line and help drawing it
|
|
*/
|
|
class FileThumbnailViewItem::Line {
|
|
protected:
|
|
const TQIconViewItem* mItem;
|
|
TQString mTxt;
|
|
int mWidth;
|
|
public:
|
|
Line(const TQIconViewItem* item, const TQString& txt)
|
|
: mItem(item)
|
|
, mTxt(txt)
|
|
, mWidth(-1) {
|
|
}
|
|
virtual ~Line() {}
|
|
|
|
virtual void setWidth(int width) {
|
|
mWidth=width;
|
|
}
|
|
|
|
virtual int height() const=0;
|
|
|
|
void paint(TQPainter* p, int textX, int textY, int align) const {
|
|
Q_ASSERT(mWidth!=-1);
|
|
int length=fontMetrics().width(mTxt);
|
|
if (length<=mWidth ) {
|
|
p->drawText(
|
|
textX,
|
|
textY,
|
|
mWidth,
|
|
fontMetrics().height(),
|
|
align,
|
|
mTxt);
|
|
} else {
|
|
p->save();
|
|
complexPaint(p, textX, textY, align);
|
|
p->restore();
|
|
}
|
|
};
|
|
|
|
protected:
|
|
const FileThumbnailView* view() const {
|
|
return static_cast<const FileThumbnailView*>(mItem->iconView());
|
|
}
|
|
|
|
TQFontMetrics fontMetrics() const {
|
|
return view()->fontMetrics();
|
|
}
|
|
|
|
/**
|
|
* Called when the text won't fit the available space
|
|
*/
|
|
virtual void complexPaint(TQPainter* p, int textX, int textY, int align) const=0;
|
|
};
|
|
|
|
|
|
/**
|
|
* A line which will get cropped if necessary
|
|
*/
|
|
class FileThumbnailViewItem::CroppedLine : public FileThumbnailViewItem::Line {
|
|
public:
|
|
CroppedLine(const TQIconViewItem* item, const TQString& txt)
|
|
: Line(item, txt) {}
|
|
|
|
int height() const {
|
|
return fontMetrics().height();
|
|
}
|
|
|
|
void complexPaint(TQPainter* p, int textX, int textY, int /*align*/) const {
|
|
KWordWrap::drawFadeoutText(p,
|
|
textX,
|
|
textY + fontMetrics().ascent(),
|
|
mWidth,
|
|
mTxt);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* A line which will get wrapped if necessary
|
|
*/
|
|
|
|
class FileThumbnailViewItem::WrappedLine : public FileThumbnailViewItem::Line {
|
|
KWordWrap* mWordWrap;
|
|
public:
|
|
WrappedLine(const TQIconViewItem* item, const TQString& txt)
|
|
: Line(item, txt)
|
|
, mWordWrap(0) {}
|
|
|
|
~WrappedLine() {
|
|
delete mWordWrap;
|
|
}
|
|
|
|
int height() const {
|
|
Q_ASSERT(mWordWrap);
|
|
if (!mWordWrap) return 0;
|
|
return mWordWrap->boundingRect().height();
|
|
}
|
|
|
|
/**
|
|
* Regenerates mWordWrap if the width has changed
|
|
*/
|
|
void setWidth(int width) {
|
|
if (width==mWidth) return;
|
|
mWidth=width;
|
|
delete mWordWrap;
|
|
TQFontMetrics fm=fontMetrics();
|
|
mWordWrap=KWordWrap::formatText(fm,
|
|
TQRect(0, 0, mWidth, fm.height()*3),
|
|
0 /*flags*/,
|
|
mTxt);
|
|
}
|
|
|
|
void complexPaint(TQPainter* p, int textX, int textY, int align) const {
|
|
Q_ASSERT(mWordWrap);
|
|
if (!mWordWrap) return;
|
|
|
|
int xpos=0;
|
|
if (align & AlignHCenter) {
|
|
xpos=( mWidth - mWordWrap->boundingRect().width() ) / 2;
|
|
}
|
|
|
|
mWordWrap->drawText(p,
|
|
textX + xpos,
|
|
textY,
|
|
align);
|
|
}
|
|
};
|
|
|
|
|
|
FileThumbnailViewItem::FileThumbnailViewItem(TQIconView* view,const TQString& text,const TQPixmap& icon, KFileItem* fileItem)
|
|
: TQIconViewItem(view,text,icon), mFileItem(fileItem) {
|
|
updateLines();
|
|
calcRect();
|
|
}
|
|
|
|
|
|
FileThumbnailViewItem::~FileThumbnailViewItem() {
|
|
TQValueVector<Line*>::ConstIterator it=mLines.begin();
|
|
TQValueVector<Line*>::ConstIterator itEnd=mLines.end();
|
|
for (;it!=itEnd; ++it) {
|
|
delete *it;
|
|
}
|
|
}
|
|
|
|
|
|
void FileThumbnailViewItem::updateLines() {
|
|
TQValueVector<Line*>::ConstIterator it=mLines.begin();
|
|
TQValueVector<Line*>::ConstIterator itEnd=mLines.end();
|
|
for (;it!=itEnd; ++it) {
|
|
delete *it;
|
|
}
|
|
mLines.clear();
|
|
if (!mFileItem) return;
|
|
|
|
bool isDir=mFileItem->isDir();
|
|
if (iconView()->itemTextPos()==TQIconView::Right) {
|
|
// Text is on the right, show everything
|
|
|
|
time_t time = TimeUtils::getTime(mFileItem);
|
|
mLines.append( new WrappedLine(this, mFileItem->name()) );
|
|
mLines.append( new CroppedLine(this, TimeUtils::formatTime(time)) );
|
|
if (mImageSize.isValid()) {
|
|
TQString txt=TQString::number(mImageSize.width())+"x"+TQString::number(mImageSize.height());
|
|
mLines.append( new CroppedLine(this, txt) );
|
|
}
|
|
if (!isDir) {
|
|
mLines.append( new CroppedLine(this, TDEIO::convertSize(mFileItem->size())) );
|
|
}
|
|
|
|
} else {
|
|
// Text is below the icon, only show details selected in
|
|
// view->itemDetails()
|
|
FileThumbnailView *view=static_cast<FileThumbnailView*>(iconView());
|
|
int details=view->itemDetails();
|
|
bool isImage=!Archive::fileItemIsDirOrArchive(mFileItem);
|
|
|
|
if (!isImage || (details & FileThumbnailView::FILENAME)) {
|
|
mLines.append( new WrappedLine(this, mFileItem->name()) );
|
|
}
|
|
if (details & FileThumbnailView::FILEDATE) {
|
|
time_t time = TimeUtils::getTime(mFileItem);
|
|
mLines.append( new CroppedLine(this, TimeUtils::formatTime(time)) );
|
|
}
|
|
if (details & FileThumbnailView::IMAGESIZE) {
|
|
TQString txt;
|
|
if (mImageSize.isValid()) {
|
|
txt=TQString::number(mImageSize.width())+"x"+TQString::number(mImageSize.height());
|
|
}
|
|
mLines.append( new CroppedLine(this, txt) );
|
|
}
|
|
if (!isDir && (details & FileThumbnailView::FILESIZE)) {
|
|
mLines.append( new CroppedLine(this, TDEIO::convertSize(mFileItem->size())) );
|
|
}
|
|
|
|
}
|
|
|
|
calcRect();
|
|
}
|
|
|
|
|
|
void FileThumbnailViewItem::calcRect(const TQString&) {
|
|
FileThumbnailView *view=static_cast<FileThumbnailView*>(iconView());
|
|
bool isRight=view->itemTextPos()==TQIconView::Right;
|
|
|
|
int textW=view->gridX();
|
|
int thumbnailSize=FileViewConfig::thumbnailSize();
|
|
if (isRight) {
|
|
textW-=PADDING * 3 + thumbnailSize;
|
|
} else {
|
|
textW-=PADDING * 2;
|
|
}
|
|
|
|
int textH=0;
|
|
TQValueVector<Line*>::ConstIterator it=mLines.begin();
|
|
TQValueVector<Line*>::ConstIterator itEnd=mLines.end();
|
|
for (;it!=itEnd; ++it) {
|
|
(*it)->setWidth(textW);
|
|
textH+=(*it)->height();
|
|
}
|
|
|
|
TQRect itemRect(x(), y(), view->gridX(), 0);
|
|
TQRect itemPixmapRect(PADDING, PADDING, thumbnailSize, thumbnailSize);
|
|
TQRect itemTextRect(0, 0, textW, textH);
|
|
if (isRight) {
|
|
itemRect.setHeight( TQMAX(thumbnailSize + PADDING*2, textH) );
|
|
itemTextRect.moveLeft(thumbnailSize + PADDING * 2 );
|
|
itemTextRect.moveTop((itemRect.height() - textH)/2);
|
|
} else {
|
|
itemPixmapRect.moveLeft( (itemRect.width() - itemPixmapRect.width()) / 2 );
|
|
itemRect.setHeight(thumbnailSize + PADDING*3 + textH);
|
|
itemTextRect.moveLeft(PADDING);
|
|
itemTextRect.moveTop(thumbnailSize + PADDING * 2);
|
|
}
|
|
|
|
// Update rects
|
|
if ( itemPixmapRect != pixmapRect() ) {
|
|
setPixmapRect( itemPixmapRect );
|
|
}
|
|
if ( itemTextRect != textRect() ) {
|
|
setTextRect( itemTextRect );
|
|
}
|
|
if ( itemRect != rect() ) {
|
|
setItemRect( itemRect );
|
|
}
|
|
}
|
|
|
|
|
|
void FileThumbnailViewItem::paintItem(TQPainter *p, const TQColorGroup &cg) {
|
|
FileThumbnailView *view=static_cast<FileThumbnailView*>(iconView());
|
|
Q_ASSERT(view);
|
|
if (!view) return;
|
|
|
|
bool isRight=view->itemTextPos()==TQIconView::Right;
|
|
bool isShownItem=view->shownFileItem() && view->shownFileItem()->extraData(view)==this;
|
|
bool isImage=!Archive::fileItemIsDirOrArchive(mFileItem);
|
|
int textX, textY, textW, textH;
|
|
int thumbnailSize=FileViewConfig::thumbnailSize();
|
|
|
|
textX=textRect(false).x();
|
|
textY=textRect(false).y();
|
|
textW=textRect(false).width();
|
|
textH=textRect(false).height();
|
|
|
|
// Draw pixmap
|
|
TQRect pRect = pixmapRect(false);
|
|
int pixX = pRect.left() + ( thumbnailSize - pixmap()->width() ) / 2;
|
|
int pixY = pRect.top() + ( thumbnailSize - pixmap()->height() ) / 2;
|
|
p->drawPixmap( pixX, pixY, *pixmap() );
|
|
|
|
TQColor bg;
|
|
if ( isSelected() ) {
|
|
bg=cg.highlight();
|
|
} else {
|
|
bg=cg.mid();
|
|
}
|
|
|
|
// Draw shown item indicator
|
|
if (isShownItem) {
|
|
TQPointArray pa(3);
|
|
pa[0] = pixmapRect(false).bottomLeft();
|
|
pa[0].rx() += pixmapRect(false).width() / 2;
|
|
pa[0].ry() += PADDING - 1;
|
|
pa[0].ry() -= SHOWN_ITEM_INDICATOR_SIZE;
|
|
|
|
pa[1] = pa[0];
|
|
pa[1].rx() -= SHOWN_ITEM_INDICATOR_SIZE;
|
|
pa[1].ry() += SHOWN_ITEM_INDICATOR_SIZE;
|
|
|
|
pa[2] = pa[1];
|
|
pa[2].rx() += SHOWN_ITEM_INDICATOR_SIZE * 2;
|
|
|
|
p->setBrush(cg.highlight());
|
|
p->setPen(cg.base());
|
|
p->drawPolygon(pa);
|
|
}
|
|
|
|
if (isImage || isSelected()) {
|
|
// Draw frame
|
|
TQRect frmRect=pixmapRect(false);
|
|
frmRect.addCoords(-PADDING, -PADDING, PADDING, PADDING);
|
|
|
|
p->setBrush(TQBrush());
|
|
p->setPen(bg);
|
|
p->drawRect(frmRect);
|
|
if (isSelected()) {
|
|
frmRect.addCoords(1, 1, -1, -1);
|
|
p->drawRect(frmRect);
|
|
}
|
|
}
|
|
|
|
// Draw text
|
|
p->setPen(cg.text());
|
|
p->setBackgroundColor(cg.base());
|
|
int align = (isRight ? AlignAuto : AlignHCenter) | AlignTop;
|
|
|
|
TQValueVector<Line*>::ConstIterator it=mLines.begin();
|
|
TQValueVector<Line*>::ConstIterator itEnd=mLines.end();
|
|
for (;it!=itEnd; ++it) {
|
|
const Line* line=*it;
|
|
line->paint(p, textX, textY, align);
|
|
textY+=line->height();
|
|
}
|
|
}
|
|
|
|
|
|
bool FileThumbnailViewItem::acceptDrop(const TQMimeSource* source) const {
|
|
return KURLDrag::canDecode(source);
|
|
}
|
|
|
|
|
|
void FileThumbnailViewItem::dropped(TQDropEvent* event, const TQValueList<TQIconDragItem>&) {
|
|
FileThumbnailView *view=static_cast<FileThumbnailView*>(iconView());
|
|
emit view->dropped(event,mFileItem);
|
|
}
|
|
|
|
void FileThumbnailViewItem::setImageSize(const TQSize& size) {
|
|
mImageSize=size;
|
|
updateLines();
|
|
}
|
|
|
|
} // namespace
|