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.
367 lines
9.7 KiB
367 lines
9.7 KiB
/***************************************************************************
|
|
sq_slideshowwidget.cpp - description
|
|
-------------------
|
|
begin : ??? Mar 30 2007
|
|
copyright : (C) 2007 by Baryshev Dmitry
|
|
email : ksquirrel.iv@gmail.com
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#include <tqimage.h>
|
|
#include <tqpainter.h>
|
|
#include <tqtimer.h>
|
|
#include <tqtoolbutton.h>
|
|
#include <tqhbox.h>
|
|
#include <tqfileinfo.h>
|
|
#include <tqfont.h>
|
|
#include <tqlabel.h>
|
|
#include <tqwhatsthis.h>
|
|
|
|
#include <kcursor.h>
|
|
#include <tdelocale.h>
|
|
#include <tdeio/global.h>
|
|
#include <tdeglobalsettings.h>
|
|
|
|
#include <ksquirrel-libs/fmt_defs.h>
|
|
|
|
#include "ksquirrel.h"
|
|
#include "sq_slideshowwidget.h"
|
|
#include "sq_imageloader.h"
|
|
#include "sq_iconloader.h"
|
|
#include "sq_config.h"
|
|
#include "sq_utils.h"
|
|
|
|
#ifdef SQ_HAVE_KEXIF
|
|
#include <libkexif/kexifdata.h>
|
|
#include <algorithm>
|
|
#endif
|
|
|
|
SQ_SlideShowWidget * SQ_SlideShowWidget::m_inst = 0;
|
|
|
|
SQ_SlideShowWidget::SQ_SlideShowWidget(TQWidget *parent, const char *name)
|
|
: TQWidget(parent,name, TQt::WStyle_Customize | TQt::WStyle_NoBorder | TQt::WStyle_StaysOnTop | TQt::WNoAutoErase)
|
|
{
|
|
m_inst = this;
|
|
|
|
timerHide = new TQTimer(this);
|
|
|
|
message = new TQLabel(this);
|
|
|
|
TQFont f = message->font();
|
|
f.setPointSize(12);
|
|
f.setBold(true);
|
|
message->setFont(f);
|
|
message->setMargin(4);
|
|
message->setFrameShape(TQFrame::NoFrame);
|
|
|
|
connect(timerHide, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotHide()));
|
|
|
|
options = new TQHBox(this, "kde toolbar widget");
|
|
options->setSpacing(0);
|
|
options->setMargin(1);
|
|
options->move(0, 0);
|
|
options->hide();
|
|
message->hide();
|
|
|
|
int is = TDEIcon::SizeMedium;
|
|
|
|
TQToolButton *b = new TQToolButton(options);
|
|
b->setIconSet(SQ_IconLoader::instance()->loadIcon("previous", TDEIcon::Desktop, is));
|
|
connect(b, TQT_SIGNAL(clicked()), this, TQT_SIGNAL(previous()));
|
|
connect(b, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotResetPause()));
|
|
|
|
b = new TQToolButton(options);
|
|
b->setIconSet(SQ_IconLoader::instance()->loadIcon("next", TDEIcon::Desktop, is));
|
|
connect(b, TQT_SIGNAL(clicked()), this, TQT_SIGNAL(next()));
|
|
connect(b, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotResetPause()));
|
|
|
|
buttonPause = new TQToolButton(options);
|
|
buttonPause->setToggleButton(true);
|
|
buttonPause->setIconSet(SQ_IconLoader::instance()->loadIcon("player_pause", TDEIcon::Desktop, is));
|
|
connect(buttonPause, TQT_SIGNAL(clicked()), this, TQT_SIGNAL(pause()));
|
|
|
|
b = new TQToolButton(options);
|
|
b->setIconSet(SQ_IconLoader::instance()->loadIcon("help", TDEIcon::Desktop, is));
|
|
connect(b, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotShowHelp()));
|
|
|
|
b = new TQToolButton(options);
|
|
b->setIconSet(SQ_IconLoader::instance()->loadIcon("cancel", TDEIcon::Desktop, is));
|
|
connect(b, TQT_SIGNAL(clicked()), this, TQT_SIGNAL(stopSlideShow()));
|
|
|
|
options->adjustSize();
|
|
message->setFixedHeight(options->height());
|
|
|
|
options->installEventFilter(this);
|
|
|
|
KCursor::setAutoHideCursor(this, true);
|
|
KCursor::setHideCursorDelay(2500);
|
|
}
|
|
|
|
SQ_SlideShowWidget::~SQ_SlideShowWidget()
|
|
{}
|
|
|
|
void SQ_SlideShowWidget::beginSlideShow(int totl)
|
|
{
|
|
total = totl;
|
|
|
|
SQ_Config::instance()->setGroup("Slideshow");
|
|
|
|
bgcolor.setNamedColor(SQ_Config::instance()->readEntry("background", "#4e4e4e"));
|
|
|
|
messages = SQ_Config::instance()->readBoolEntry("messages", true);
|
|
mes_pos = SQ_Config::instance()->readBoolEntry("messages_pos", true);
|
|
mes_name = SQ_Config::instance()->readBoolEntry("messages_name", true);
|
|
mes_size = SQ_Config::instance()->readBoolEntry("messages_size", false);
|
|
tcolor.setNamedColor(SQ_Config::instance()->readEntry("message_text", "#ffffff"));
|
|
|
|
// fake transparency
|
|
message->setPaletteForegroundColor(tcolor);
|
|
message->setPaletteBackgroundColor(bgcolor);
|
|
|
|
show();
|
|
setGeometry(TDEGlobalSettings::desktopGeometry(KSquirrel::app()));
|
|
|
|
message->hide();
|
|
options->hide();
|
|
|
|
if(messages)
|
|
{
|
|
message->move(0, 0);
|
|
message->show();
|
|
}
|
|
|
|
path = "";
|
|
current = 0;
|
|
buttonPause->setOn(false);
|
|
|
|
setFocus();
|
|
}
|
|
|
|
void SQ_SlideShowWidget::endSlideShow()
|
|
{
|
|
options->hide();
|
|
message->hide();
|
|
hide();
|
|
|
|
pixmap = TQPixmap();
|
|
}
|
|
|
|
void SQ_SlideShowWidget::loadImage(const TQString &_path, int _current)
|
|
{
|
|
fmt_info *finfo;
|
|
RGBA *bits;
|
|
|
|
// load first page
|
|
bool b = SQ_ImageLoader::instance()->loadImage(_path, SQ_CodecSettings::ImageViewer);
|
|
|
|
finfo = SQ_ImageLoader::instance()->info();
|
|
bits = SQ_ImageLoader::instance()->bits();
|
|
|
|
// memory allocation failed in SQ_ImageLoader::loadImage()
|
|
if(!b || !bits || !finfo->image.size())
|
|
return;
|
|
|
|
path = _path;
|
|
current = _current;
|
|
|
|
constructMessage();
|
|
|
|
pixmap = TQPixmap();
|
|
|
|
int w = finfo->image[0].w;
|
|
int h = finfo->image[0].h;
|
|
TQImage *all = 0, *small = 0;
|
|
|
|
all = new TQImage((uchar *)bits, w, h, 32, 0, 0, TQImage::LittleEndian);
|
|
all->setAlphaBuffer(true);
|
|
|
|
// scale down to fit into window
|
|
if(w > width() || h > height())
|
|
{
|
|
small = new TQImage();
|
|
*small = SQ_Utils::scale(*all, width(), height(), SQ_Utils::SMOOTH_FAST, TQ_ScaleMin);
|
|
|
|
delete all;
|
|
all = 0;
|
|
|
|
if(small->isNull())
|
|
{
|
|
SQ_ImageLoader::instance()->cleanup();
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
small = all;
|
|
|
|
const int wh = small->width() * small->height();
|
|
unsigned char t;
|
|
RGBA *sk = reinterpret_cast<RGBA *>(small->bits());
|
|
|
|
// swap R and B components - TQPixmap need it
|
|
for(int i = 0;i < wh;i++)
|
|
{
|
|
t = (sk+i)->r;
|
|
(sk+i)->r = (sk+i)->b;
|
|
(sk+i)->b = t;
|
|
}
|
|
|
|
#ifdef SQ_HAVE_KEXIF
|
|
KExifData data;
|
|
data.readFromFile(_path);
|
|
int O = data.getImageQt::Orientation();
|
|
|
|
if(O != KExifData::UNSPECIFIED && O != KExifData::NORMAL)
|
|
{
|
|
// copy original image
|
|
TQImage img = *small;
|
|
|
|
// rotate image
|
|
SQ_Utils::exifRotate(TQString(), img, O);
|
|
|
|
// transfer back
|
|
*small = img;
|
|
}
|
|
#endif
|
|
|
|
pixmap.convertFromImage(*small);
|
|
|
|
// finally clean all memory buffers
|
|
SQ_ImageLoader::instance()->cleanup();
|
|
|
|
delete small;
|
|
|
|
// show loaded image
|
|
update();
|
|
}
|
|
|
|
void SQ_SlideShowWidget::paintEvent(TQPaintEvent *e)
|
|
{
|
|
TQPainter p(this);
|
|
|
|
p.setClipRect(e->rect());
|
|
p.fillRect(e->rect(), bgcolor);
|
|
|
|
if(!pixmap.isNull())
|
|
p.drawPixmap((width() - pixmap.width()) / 2, (height() - pixmap.height()) / 2, pixmap);
|
|
}
|
|
|
|
void SQ_SlideShowWidget::closeEvent(TQCloseEvent *e)
|
|
{
|
|
emit stopSlideShow();
|
|
|
|
e->ignore();
|
|
}
|
|
|
|
void SQ_SlideShowWidget::keyPressEvent(TQKeyEvent *e)
|
|
{
|
|
if(e->key() == TQt::Key_Enter || e->key() == TQt::Key_Escape || e->key() == TQt::Key_Return)
|
|
close();
|
|
else if(e->key() == TQt::Key_Pause || e->key() == TQt::Key_Space)
|
|
{
|
|
buttonPause->toggle();
|
|
emit pause();
|
|
}
|
|
else if(e->key() == TQt::Key_PageUp)
|
|
emit previous();
|
|
else if(e->key() == TQt::Key_PageDown)
|
|
emit next();
|
|
else if(e->key() == TQt::Key_M)
|
|
{
|
|
SQ_Config::instance()->setGroup("Slideshow");
|
|
|
|
messages = SQ_Config::instance()->readBoolEntry("messages", true);
|
|
messages = !messages;
|
|
SQ_Config::instance()->writeEntry("messages", messages);
|
|
|
|
if(options->isVisible() && messages)
|
|
message->move(options->width()+1, 0);
|
|
|
|
constructMessage();
|
|
|
|
message->setShown(messages);
|
|
}
|
|
|
|
e->accept();
|
|
}
|
|
|
|
void SQ_SlideShowWidget::mouseMoveEvent(TQMouseEvent *)
|
|
{
|
|
if(!options->isVisible())
|
|
{
|
|
options->show();
|
|
if(messages) message->move(options->width()+1, 0);
|
|
}
|
|
|
|
timerHide->start(1500, true);
|
|
}
|
|
|
|
void SQ_SlideShowWidget::slotHide()
|
|
{
|
|
options->hide();
|
|
|
|
if(messages) message->move(0, 0);
|
|
}
|
|
|
|
bool SQ_SlideShowWidget::eventFilter(TQObject *, TQEvent *e)
|
|
{
|
|
if(e->type() == TQEvent::Enter)
|
|
{
|
|
timerHide->stop();
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void SQ_SlideShowWidget::slotShowHelp()
|
|
{
|
|
TQWhatsThis::display(i18n(
|
|
"<table cellspacing=0>"
|
|
"<tr><td><b>Enter, Escape, Return</b></td><td>stop slideshow</td></tr>"
|
|
"<tr><td><b>Pause, Space</b></td><td>pause/unpause slideshow</td></tr>"
|
|
"<tr><td><b>Page Up</b></td><td>previous image</td></tr>"
|
|
"<tr><td><b>Page Down</b></td><td>next image</td></tr>"
|
|
"<tr><td><b>M</b></td><td>show/hide onscreen messages</td></tr>"
|
|
"</table>"
|
|
));
|
|
}
|
|
|
|
void SQ_SlideShowWidget::constructMessage()
|
|
{
|
|
// construct onscreen message
|
|
if(messages)
|
|
{
|
|
TQFileInfo fm(path);
|
|
TQString s_message;
|
|
|
|
if(mes_pos) s_message = TQString::fromLatin1("[%1/%2] ").arg(current+1).arg(total);
|
|
|
|
if(mes_name) s_message += fm.fileName();
|
|
|
|
if(mes_size)
|
|
s_message = (mes_name || mes_pos) ? (s_message + " (" + TDEIO::convertSize(fm.size()) + ')') : TDEIO::convertSize(fm.size());
|
|
|
|
message->setText(s_message);
|
|
message->adjustSize();
|
|
}
|
|
}
|
|
|
|
void SQ_SlideShowWidget::slotResetPause()
|
|
{
|
|
buttonPause->setOn(false);
|
|
}
|
|
|
|
#include "sq_slideshowwidget.moc"
|