2006-12-27 23:56:38 +00:00
|
|
|
/***************************************************************************
|
2007-12-24 00:54:21 +00:00
|
|
|
* Copyright (C) 2006-2007 by Pino Toscano <pino@kde.org> *
|
2006-12-27 23:56:38 +00:00
|
|
|
* *
|
|
|
|
* 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. *
|
|
|
|
***************************************************************************/
|
|
|
|
|
2007-12-24 00:54:21 +00:00
|
|
|
#include "guiutils.h"
|
2007-04-19 18:30:20 +00:00
|
|
|
|
2006-12-27 23:56:38 +00:00
|
|
|
// qt/kde includes
|
2008-09-19 22:43:41 +00:00
|
|
|
#include <qpainter.h>
|
|
|
|
#include <qsvgrenderer.h>
|
2008-04-03 09:52:05 +00:00
|
|
|
#include <qtextdocument.h>
|
2008-04-14 22:31:28 +00:00
|
|
|
#include <kfiledialog.h>
|
2007-12-24 15:02:32 +00:00
|
|
|
#include <kglobal.h>
|
|
|
|
#include <kiconloader.h>
|
2006-12-27 23:56:38 +00:00
|
|
|
#include <klocale.h>
|
2008-04-14 22:31:28 +00:00
|
|
|
#include <kmessagebox.h>
|
2008-09-19 22:43:41 +00:00
|
|
|
#include <kstandarddirs.h>
|
2006-12-27 23:56:38 +00:00
|
|
|
|
|
|
|
// local includes
|
2012-09-27 12:14:03 +00:00
|
|
|
#include "core/action.h"
|
2006-12-27 23:56:38 +00:00
|
|
|
#include "core/annotations.h"
|
2008-04-14 22:31:28 +00:00
|
|
|
#include "core/document.h"
|
2006-12-27 23:56:38 +00:00
|
|
|
|
2008-11-15 23:27:27 +00:00
|
|
|
#include <memory>
|
|
|
|
|
2007-12-24 15:02:32 +00:00
|
|
|
struct GuiUtilsHelper
|
|
|
|
{
|
|
|
|
GuiUtilsHelper()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2008-11-15 23:27:27 +00:00
|
|
|
QSvgRenderer* svgStamps();
|
|
|
|
|
2010-03-17 19:37:52 +00:00
|
|
|
QList<KIconLoader *> il;
|
2008-11-15 23:27:27 +00:00
|
|
|
std::auto_ptr< QSvgRenderer > svgStampFile;
|
2007-12-24 15:02:32 +00:00
|
|
|
};
|
|
|
|
|
2008-11-15 23:27:27 +00:00
|
|
|
QSvgRenderer* GuiUtilsHelper::svgStamps()
|
|
|
|
{
|
|
|
|
if ( !svgStampFile.get() )
|
|
|
|
{
|
|
|
|
const QString stampFile = KStandardDirs::locate( "data", "okular/pics/stamps.svg" );
|
|
|
|
if ( !stampFile.isEmpty() )
|
|
|
|
{
|
|
|
|
svgStampFile.reset( new QSvgRenderer( stampFile ) );
|
|
|
|
if ( !svgStampFile->isValid() )
|
|
|
|
{
|
|
|
|
svgStampFile.reset();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return svgStampFile.get();
|
|
|
|
}
|
|
|
|
|
2007-12-24 15:02:32 +00:00
|
|
|
K_GLOBAL_STATIC( GuiUtilsHelper, s_data )
|
|
|
|
|
2007-12-24 00:54:21 +00:00
|
|
|
namespace GuiUtils {
|
2007-09-08 14:44:21 +00:00
|
|
|
|
|
|
|
QString captionForAnnotation( const Okular::Annotation * ann )
|
2006-12-27 23:56:38 +00:00
|
|
|
{
|
2007-10-03 22:53:27 +00:00
|
|
|
Q_ASSERT( ann );
|
2006-12-27 23:56:38 +00:00
|
|
|
|
|
|
|
QString ret;
|
|
|
|
switch( ann->subType() )
|
|
|
|
{
|
|
|
|
case Okular::Annotation::AText:
|
|
|
|
if( ( (Okular::TextAnnotation*)ann )->textType() == Okular::TextAnnotation::Linked )
|
|
|
|
ret = i18n( "Note" );
|
|
|
|
else
|
2007-08-19 16:15:55 +00:00
|
|
|
ret = i18n( "Inline Note" );
|
2006-12-27 23:56:38 +00:00
|
|
|
break;
|
|
|
|
case Okular::Annotation::ALine:
|
2013-04-19 19:12:34 +00:00
|
|
|
if( ( (Okular::LineAnnotation*)ann )->linePoints().count() == 2 )
|
|
|
|
ret = i18n( "Straight Line" );
|
|
|
|
else
|
|
|
|
ret = i18n( "Polygon" );
|
2006-12-27 23:56:38 +00:00
|
|
|
break;
|
|
|
|
case Okular::Annotation::AGeom:
|
2007-08-19 16:15:55 +00:00
|
|
|
ret = i18n( "Geometry" );
|
2006-12-27 23:56:38 +00:00
|
|
|
break;
|
|
|
|
case Okular::Annotation::AHighlight:
|
2013-04-20 08:53:04 +00:00
|
|
|
switch ( ( (Okular::HighlightAnnotation*)ann )->highlightType() )
|
|
|
|
{
|
|
|
|
case Okular::HighlightAnnotation::Highlight:
|
|
|
|
ret = i18n( "Highlight" );
|
|
|
|
break;
|
|
|
|
case Okular::HighlightAnnotation::Squiggly:
|
|
|
|
ret = i18n( "Squiggle" );
|
|
|
|
break;
|
|
|
|
case Okular::HighlightAnnotation::Underline:
|
|
|
|
ret = i18n( "Underline" );
|
|
|
|
break;
|
|
|
|
case Okular::HighlightAnnotation::StrikeOut:
|
|
|
|
ret = i18n( "Strike Out" );
|
|
|
|
break;
|
|
|
|
}
|
2006-12-27 23:56:38 +00:00
|
|
|
break;
|
|
|
|
case Okular::Annotation::AStamp:
|
|
|
|
ret = i18n( "Stamp" );
|
|
|
|
break;
|
|
|
|
case Okular::Annotation::AInk:
|
2013-04-19 19:11:42 +00:00
|
|
|
ret = i18n( "Freehand Line" );
|
2006-12-27 23:56:38 +00:00
|
|
|
break;
|
2008-04-13 16:42:14 +00:00
|
|
|
case Okular::Annotation::ACaret:
|
|
|
|
ret = i18n( "Caret" );
|
|
|
|
break;
|
|
|
|
case Okular::Annotation::AFileAttachment:
|
|
|
|
ret = i18n( "File Attachment" );
|
|
|
|
break;
|
2008-04-13 20:04:08 +00:00
|
|
|
case Okular::Annotation::ASound:
|
|
|
|
ret = i18n( "Sound" );
|
|
|
|
break;
|
2008-08-23 00:09:59 +00:00
|
|
|
case Okular::Annotation::AMovie:
|
|
|
|
ret = i18n( "Movie" );
|
|
|
|
break;
|
2012-08-16 09:53:58 +00:00
|
|
|
case Okular::Annotation::AScreen:
|
|
|
|
ret = i18nc( "Caption for a screen annotation", "Screen" );
|
|
|
|
break;
|
|
|
|
case Okular::Annotation::AWidget:
|
|
|
|
ret = i18nc( "Caption for a widget annotation", "Widget" );
|
|
|
|
break;
|
2006-12-27 23:56:38 +00:00
|
|
|
case Okular::Annotation::A_BASE:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2007-09-08 14:44:21 +00:00
|
|
|
QString authorForAnnotation( const Okular::Annotation * ann )
|
2007-09-08 14:41:40 +00:00
|
|
|
{
|
2007-10-03 22:53:27 +00:00
|
|
|
Q_ASSERT( ann );
|
2007-09-08 14:41:40 +00:00
|
|
|
|
|
|
|
return !ann->author().isEmpty() ? ann->author() : i18nc( "Unknown author", "Unknown" );
|
|
|
|
}
|
|
|
|
|
2007-09-08 14:44:21 +00:00
|
|
|
QString contentsHtml( const Okular::Annotation * ann )
|
2006-12-28 00:40:09 +00:00
|
|
|
{
|
2013-04-05 22:22:48 +00:00
|
|
|
QString text = Qt::escape( ann->contents() );
|
2010-04-02 19:07:36 +00:00
|
|
|
text.replace( '\n', "<br>" );
|
2008-04-03 09:52:05 +00:00
|
|
|
return text;
|
2006-12-28 00:40:09 +00:00
|
|
|
}
|
|
|
|
|
2007-09-08 14:44:21 +00:00
|
|
|
QString prettyToolTip( const Okular::Annotation * ann )
|
2007-09-08 14:41:40 +00:00
|
|
|
{
|
2007-10-03 22:53:27 +00:00
|
|
|
Q_ASSERT( ann );
|
2007-09-08 14:41:40 +00:00
|
|
|
|
|
|
|
QString author = authorForAnnotation( ann );
|
|
|
|
QString contents = contentsHtml( ann );
|
|
|
|
|
|
|
|
QString tooltip = QString( "<qt><b>" ) + i18n( "Author: %1", author ) + QString( "</b>" );
|
|
|
|
if ( !contents.isEmpty() )
|
2007-10-03 22:45:20 +00:00
|
|
|
tooltip += QString( "<div style=\"font-size: 4px;\"><hr /></div>" ) + contents;
|
2007-09-08 14:41:40 +00:00
|
|
|
|
|
|
|
tooltip += "</qt>";
|
|
|
|
|
|
|
|
return tooltip;
|
|
|
|
}
|
|
|
|
|
2008-09-19 22:43:41 +00:00
|
|
|
QPixmap loadStamp( const QString& _name, const QSize& size, int iconSize )
|
2008-09-19 20:21:57 +00:00
|
|
|
{
|
|
|
|
const QString name = _name.toLower();
|
2008-11-16 00:06:29 +00:00
|
|
|
QSvgRenderer * r = 0;
|
|
|
|
if ( ( r = s_data->svgStamps() ) && r->elementExists( name ) )
|
2008-09-19 22:43:41 +00:00
|
|
|
{
|
2008-11-16 00:06:29 +00:00
|
|
|
const QRectF stampElemRect = r->boundsOnElement( name );
|
|
|
|
const QRectF stampRect( size.isValid() ? QRectF( QPointF( 0, 0 ), size ) : stampElemRect );
|
|
|
|
QPixmap pixmap( stampRect.size().toSize() );
|
|
|
|
pixmap.fill( Qt::transparent );
|
|
|
|
QPainter p( &pixmap );
|
|
|
|
r->render( &p, name );
|
|
|
|
p.end();
|
|
|
|
return pixmap;
|
2008-09-19 22:43:41 +00:00
|
|
|
}
|
2008-09-19 20:21:57 +00:00
|
|
|
QPixmap pixmap;
|
|
|
|
const KIconLoader * il = iconLoader();
|
|
|
|
QString path;
|
2008-09-19 22:43:41 +00:00
|
|
|
const int minSize = iconSize > 0 ? iconSize : qMin( size.width(), size.height() );
|
2008-09-19 20:21:57 +00:00
|
|
|
pixmap = il->loadIcon( name, KIconLoader::User, minSize, KIconLoader::DefaultState, QStringList(), &path, true );
|
|
|
|
if ( path.isEmpty() )
|
|
|
|
pixmap = il->loadIcon( name, KIconLoader::NoGroup, minSize );
|
|
|
|
return pixmap;
|
|
|
|
}
|
|
|
|
|
2010-03-17 19:37:52 +00:00
|
|
|
void addIconLoader( KIconLoader * loader )
|
2007-12-24 15:02:32 +00:00
|
|
|
{
|
2010-03-17 19:37:52 +00:00
|
|
|
s_data->il.append( loader );
|
|
|
|
}
|
|
|
|
|
|
|
|
void removeIconLoader( KIconLoader * loader )
|
|
|
|
{
|
|
|
|
s_data->il.removeAll( loader );
|
2007-12-24 15:02:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
KIconLoader* iconLoader()
|
|
|
|
{
|
2010-03-17 19:37:52 +00:00
|
|
|
return s_data->il.isEmpty() ? KIconLoader::global() : s_data->il.back();
|
2007-12-24 15:02:32 +00:00
|
|
|
}
|
|
|
|
|
2008-04-14 22:31:28 +00:00
|
|
|
void saveEmbeddedFile( Okular::EmbeddedFile *ef, QWidget *parent )
|
|
|
|
{
|
|
|
|
const QString caption = i18n( "Where do you want to save %1?", ef->name() );
|
2009-12-26 20:47:58 +00:00
|
|
|
const QString path = KFileDialog::getSaveFileName( ef->name(), QString(), parent, caption,
|
|
|
|
KFileDialog::ConfirmOverwrite );
|
2008-04-14 22:31:28 +00:00
|
|
|
if ( path.isEmpty() )
|
|
|
|
return;
|
|
|
|
|
|
|
|
QFile f( path );
|
2009-12-26 20:47:58 +00:00
|
|
|
if ( !f.open( QIODevice::WriteOnly ) )
|
2008-04-14 22:31:28 +00:00
|
|
|
{
|
2009-12-26 20:47:58 +00:00
|
|
|
KMessageBox::error( parent, i18n( "Could not open \"%1\" for writing. File was not saved.", path ) );
|
|
|
|
return;
|
2008-04-14 22:31:28 +00:00
|
|
|
}
|
2009-12-26 20:47:58 +00:00
|
|
|
f.write( ef->data() );
|
|
|
|
f.close();
|
2008-04-14 22:31:28 +00:00
|
|
|
}
|
|
|
|
|
2012-09-27 12:14:03 +00:00
|
|
|
Okular::Movie* renditionMovieFromScreenAnnotation( const Okular::ScreenAnnotation *annotation )
|
|
|
|
{
|
|
|
|
if ( !annotation )
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if ( annotation->action() && annotation->action()->actionType() == Okular::Action::Rendition )
|
|
|
|
{
|
|
|
|
Okular::RenditionAction *renditionAction = static_cast< Okular::RenditionAction * >( annotation->action() );
|
|
|
|
return renditionAction->movie();
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-06-12 10:19:21 +00:00
|
|
|
// from Arthur - qt4
|
|
|
|
inline int qt_div_255(int x) { return (x + (x>>8) + 0x80) >> 8; }
|
|
|
|
|
|
|
|
void colorizeImage( QImage & grayImage, const QColor & color, unsigned int destAlpha )
|
|
|
|
{
|
|
|
|
// Make sure that the image is Format_ARGB32_Premultiplied
|
|
|
|
if ( grayImage.format() != QImage::Format_ARGB32_Premultiplied )
|
|
|
|
grayImage = grayImage.convertToFormat( QImage::Format_ARGB32_Premultiplied );
|
|
|
|
|
|
|
|
// iterate over all pixels changing the alpha component value
|
|
|
|
unsigned int * data = (unsigned int *)grayImage.bits();
|
|
|
|
unsigned int pixels = grayImage.width() * grayImage.height();
|
|
|
|
int red = color.red(),
|
|
|
|
green = color.green(),
|
|
|
|
blue = color.blue();
|
|
|
|
|
|
|
|
int source, sourceSat, sourceAlpha;
|
|
|
|
for( register unsigned int i = 0; i < pixels; ++i )
|
|
|
|
{ // optimize this loop keeping byte order into account
|
|
|
|
source = data[i];
|
|
|
|
sourceSat = qRed( source );
|
|
|
|
int newR = qt_div_255( sourceSat * red ),
|
|
|
|
newG = qt_div_255( sourceSat * green ),
|
|
|
|
newB = qt_div_255( sourceSat * blue );
|
|
|
|
if ( (sourceAlpha = qAlpha( source )) == 255 )
|
|
|
|
{
|
|
|
|
// use destAlpha
|
|
|
|
data[i] = qRgba( newR, newG, newB, destAlpha );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// use destAlpha * sourceAlpha product
|
|
|
|
if ( destAlpha < 255 )
|
|
|
|
sourceAlpha = qt_div_255( destAlpha * sourceAlpha );
|
|
|
|
data[i] = qRgba( newR, newG, newB, sourceAlpha );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-09-08 14:44:21 +00:00
|
|
|
}
|