summaryrefslogtreecommitdiffstats
path: root/kdeprint/posterpreview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kdeprint/posterpreview.cpp')
-rw-r--r--kdeprint/posterpreview.cpp294
1 files changed, 294 insertions, 0 deletions
diff --git a/kdeprint/posterpreview.cpp b/kdeprint/posterpreview.cpp
new file mode 100644
index 000000000..1a89ee8f3
--- /dev/null
+++ b/kdeprint/posterpreview.cpp
@@ -0,0 +1,294 @@
+/*
+ * This file is part of the KDE libraries
+ * Copyright (c) 2001-2002 Michael Goffioul <kdeprint@swing.be>
+ *
+ * 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.
+ **/
+
+#include "posterpreview.h"
+
+#include <kprocess.h>
+#include <qpainter.h>
+#include <qsimplerichtext.h>
+#include <qtimer.h>
+#include <qpixmap.h>
+#include <kprinter.h>
+#include <klocale.h>
+#include <kcursor.h>
+#include <kglobalsettings.h>
+
+PosterPreview::PosterPreview( QWidget *parent, const char *name )
+ : QFrame( parent, name )
+{
+ m_postersize = m_mediasize = "A4";
+ m_cutmargin = 5;
+ init();
+}
+
+PosterPreview::PosterPreview( const QString& postersize, const QString& mediasize, QWidget *parent, const char *name )
+ : QFrame( parent, name )
+{
+ m_postersize = postersize;
+ m_mediasize = mediasize;
+ m_cutmargin = 5;
+ init();
+}
+
+PosterPreview::~PosterPreview()
+{
+ delete m_process;
+}
+
+void PosterPreview::init()
+{
+ m_process = new KProcess;
+ connect( m_process, SIGNAL( receivedStderr( KProcess*, char*, int ) ), SLOT( slotProcessStderr( KProcess*, char*, int ) ) );
+ connect( m_process, SIGNAL( processExited( KProcess* ) ), SLOT( slotProcessExited( KProcess* ) ) );
+
+ m_cols = m_rows = m_pw = m_ph = m_mw = m_mh = 0;
+ m_dirty = false;
+ setDirty();
+ setMouseTracking( true );
+ setBackgroundMode( Qt::NoBackground );
+}
+
+void PosterPreview::parseBuffer()
+{
+ int rotate;
+ float pw, ph, mw, mh;
+ float x1, x2, y1, y2;
+ sscanf( m_buffer.ascii(), "%d %d %d %g %g %g %g %g %g %g %g", &m_rows, &m_cols, &rotate,
+ &pw, &ph, &mw, &mh, &x1, &y1, &x2, &y2 );
+ m_pw = ( int )( rotate ? ph : pw );
+ m_ph = ( int )( rotate ? pw : ph );
+ m_mw = ( int )( rotate ? mh : mw );
+ m_mh = ( int )( rotate ? mw : mh );
+ m_posterbb.setCoords( ( int )x1, ( int )y1, ( int )x2, ( int )y2 );
+}
+
+void PosterPreview::setDirty()
+{
+ if ( !m_dirty )
+ {
+ m_dirty = true;
+ QTimer::singleShot( 1, this, SLOT( updatePoster() ) );
+ }
+}
+
+void PosterPreview::updatePoster()
+{
+ m_buffer = "";
+ m_process->clearArguments();
+ *m_process << "poster" << "-F" << "-m" + m_mediasize << "-p" + m_postersize
+ << "-c" + QString::number( m_cutmargin ) + "%";
+ if ( !m_process->start( KProcess::NotifyOnExit, KProcess::Stderr ) )
+ {
+ m_rows = m_cols = 0;
+ m_dirty = false;
+ update();
+ }
+}
+
+void PosterPreview::drawContents( QPainter *painter )
+{
+ QPixmap pix( width(), height() );
+ QPainter *p = new QPainter( &pix );
+
+ p->fillRect( 0, 0, width(), height(), colorGroup().background() );
+
+ if ( isEnabled() )
+ {
+ if ( m_rows <= 0 || m_cols <= 0 || m_pw <= 0 || m_ph <= 0 )
+ {
+ QString txt = i18n( "Poster preview not available. Either the <b>poster</b> "
+ "executable is not properly installed, or you don't have "
+ "the required version; available at http://printing.kde.org/downloads/." );
+ QSimpleRichText richtext( ( m_buffer.isEmpty() ? txt : m_buffer.prepend( "<pre>" ).append( "</pre>" ) ), p->font() );
+ richtext.adjustSize();
+ int x = ( width()-richtext.widthUsed() )/2, y = ( height()-richtext.height() )/2;
+ x = QMAX( x, 0 );
+ y = QMAX( y, 0 );
+ richtext.draw( p, x, y, QRect( x, y, richtext.widthUsed(), richtext.height() ), colorGroup() );
+ m_boundingrect = QRect();
+ }
+ else
+ {
+ int totalx = m_cols*m_pw, totaly = m_rows*m_ph;
+ float scale = QMIN( float( width()-1 )/totalx, float( height()-1 )/totaly );
+ p->translate( 0, height()-1 );
+ p->scale( scale, -scale );
+ int x = ( int )( width()/scale-totalx )/2, y = ( int )( height()/scale-totaly )/2;
+ p->translate( x, y );
+ m_boundingrect = p->xForm( QRect( 0, 0, totalx, totaly ) );
+
+ x = y = 0;
+ int px = m_posterbb.x(), py = m_posterbb.y(), pw = m_posterbb.width(), ph = m_posterbb.height();
+ for ( int i=0; i<m_rows; i++, y+=m_ph, x=0 )
+ {
+ for ( int j=0; j<m_cols; j++, x+=m_pw )
+ {
+ bool selected = ( m_selectedpages.find( i*m_cols+j+1 ) != m_selectedpages.end() );
+ p->fillRect( x+1, y+1, m_pw-2, m_ph-2, ( selected ? KGlobalSettings::highlightColor() : white ) );
+ p->drawRect( x, y, m_pw, m_ph );
+ if ( pw > 0 && ph > 0 )
+ p->fillRect( x+m_mw+px, y+m_mh+py, QMIN( pw, m_pw-2*m_mw-px ), QMIN( ph, m_ph-2*m_mh-py ),
+ ( selected ? KGlobalSettings::highlightColor().dark( 160 ) : lightGray ) );
+ p->setPen( Qt::DotLine );
+ p->drawRect( x+m_mw, y+m_mh, m_pw-2*m_mw, m_ph-2*m_mh );
+ p->setPen( Qt::SolidLine );
+
+ pw -= m_pw-2*m_mw-px;
+ px = 0;
+ }
+
+ px = m_posterbb.x();
+ ph -= m_ph-2*m_mh-py;
+ py = 0;
+ pw = m_posterbb.width();
+ }
+ }
+ }
+
+ delete p;
+ painter->drawPixmap( 0, 0, pix );
+}
+
+void PosterPreview::mouseMoveEvent( QMouseEvent *e )
+{
+ if ( m_boundingrect.isValid() )
+ {
+ if ( m_boundingrect.contains( e->pos() ) )
+ setCursor( KCursor::handCursor() );
+ else
+ setCursor( KCursor::arrowCursor() );
+ }
+}
+
+void PosterPreview::mousePressEvent( QMouseEvent *e )
+{
+ if ( e->button() == Qt::LeftButton && m_boundingrect.isValid() )
+ {
+ if ( m_boundingrect.contains( e->pos() ) )
+ {
+ int c, r;
+ c = ( e->pos().x()-m_boundingrect.x() )/( m_boundingrect.width()/m_cols ) + 1;
+ r = m_rows - ( e->pos().y()-m_boundingrect.y() )/( m_boundingrect.height()/m_rows );
+ int pagenum = ( r-1 )*m_cols+c;
+
+ if ( m_selectedpages.find( pagenum ) == m_selectedpages.end() ||
+ !( e->state() & Qt::ShiftButton ) )
+ {
+ if ( !( e->state() & Qt::ShiftButton ) )
+ m_selectedpages.clear();
+ m_selectedpages.append( pagenum );
+ update();
+ emitSelectedPages();
+ }
+ }
+ else if ( m_selectedpages.count() > 0 )
+ {
+ m_selectedpages.clear();
+ update();
+ emitSelectedPages();
+ }
+ }
+}
+
+void PosterPreview::slotProcessStderr( KProcess*, char *buf, int len )
+{
+ m_buffer.append( QCString( buf, len ) );
+}
+
+void PosterPreview::slotProcessExited( KProcess* )
+{
+ if ( m_process->normalExit() && m_process->exitStatus() == 0 )
+ parseBuffer();
+ else
+ m_rows = m_cols = 0;
+
+ m_dirty = false;
+ update();
+}
+
+void PosterPreview::setPosterSize( int s )
+{
+ setPosterSize( pageSizeToPageName( KPrinter::PageSize( s ) ) );
+}
+
+void PosterPreview::setPosterSize( const QString& s )
+{
+ if ( m_postersize != s )
+ {
+ m_selectedpages.clear();
+ m_postersize = s;
+ setDirty();
+ emitSelectedPages();
+ }
+}
+
+void PosterPreview::setMediaSize( int s )
+{
+ setMediaSize( pageSizeToPageName( ( KPrinter::PageSize )s ) );
+}
+
+void PosterPreview::setMediaSize( const QString& s )
+{
+ if ( m_mediasize != s )
+ {
+ m_selectedpages.clear();
+ m_mediasize = s;
+ setDirty();
+ emitSelectedPages();
+ }
+}
+
+void PosterPreview::setCutMargin( int value )
+{
+ m_cutmargin = value;
+ setDirty();
+}
+
+void PosterPreview::setSelectedPages( const QString& s )
+{
+ QStringList l = QStringList::split( ",", s, false );
+ m_selectedpages.clear();
+ for ( QStringList::ConstIterator it=l.begin(); it!=l.end(); ++it )
+ {
+ int p;
+ if ( ( p = ( *it ).find( '-' ) ) == -1 )
+ m_selectedpages.append( ( *it ).toInt() );
+ else
+ {
+ int p1 = ( *it ).left( p ).toInt(), p2 = ( *it ).mid( p+1 ).toInt();
+ for ( int i=p1; i<=p2; i++ )
+ m_selectedpages.append( i );
+ }
+ }
+ update();
+}
+
+void PosterPreview::emitSelectedPages()
+{
+ QString s;
+ if ( m_selectedpages.count() > 0 )
+ {
+ for ( QValueList<int>::ConstIterator it=m_selectedpages.begin(); it!=m_selectedpages.end(); ++it )
+ s.append( QString::number( *it ) + "," );
+ s.truncate( s.length()-1 );
+ }
+ emit selectionChanged( s );
+}
+
+#include "posterpreview.moc"