kpresenter

KPrTransEffectDia.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2002 Ariya Hidayat <ariya@kde.org>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include "KPrTransEffectDia.h"
00021 
00022 #include "global.h"
00023 #include "KPrBackground.h"
00024 #include "KPrObject.h"
00025 #include "KPrTextObject.h"
00026 #include "KPrView.h"
00027 #include "KPrDocument.h"
00028 #include "KPrCanvas.h"
00029 #include "KPrPage.h"
00030 #include "KPrPageEffects.h"
00031 #include "KPrSoundPlayer.h"
00032 
00033 #include <qsplitter.h>
00034 #include <qheader.h>
00035 #include <qwmatrix.h>
00036 #include <qvbox.h>
00037 #include <qlayout.h>
00038 #include <qimage.h>
00039 #include <qpushbutton.h>
00040 #include <qcheckbox.h>
00041 #include <qslider.h>
00042 #include <qtooltip.h>
00043 #include <qwhatsthis.h>
00044 #include <qframe.h>
00045 #include <qlabel.h>
00046 #include <qcombobox.h>
00047 
00048 #include <kdebug.h>
00049 #include <kurlrequester.h>
00050 #include <klocale.h>
00051 #include <knuminput.h>
00052 #include <kiconloader.h>
00053 #include <kurl.h>
00054 #include <kstandarddirs.h>
00055 #include <kfiledialog.h>
00056 
00057 
00058 KPrEffectPreview::KPrEffectPreview( QWidget *parent, KPrDocument *_doc, KPrView *_view )
00059     : QLabel( parent ), doc( _doc ), view( _view ), m_pageEffect( 0 )
00060 {
00061     setFrameStyle( StyledPanel | Sunken );
00062 }
00063 
00064 void KPrEffectPreview::setPixmap( const QPixmap& pixmap )
00065 {
00066     // find the right size
00067     QRect rect = pixmap.rect();
00068     int w = rect.width();
00069     int h = rect.height();
00070     if ( w > h ) {
00071         w = 297;
00072         h = 210;
00073     }
00074     else if ( w < h ) {
00075         w = 210;
00076         h = 297;
00077     }
00078     else if ( w == h ) {
00079         w = 297;
00080         h = 297;
00081     }
00082 
00083     setMinimumSize( w, h );
00084 
00085     // create smaller pixmap for preview
00086     const QImage img( pixmap.convertToImage().smoothScale( w, h, QImage::ScaleFree ) );
00087     m_pixmap.convertFromImage( img );
00088 
00089     QLabel::setPixmap( m_pixmap );
00090 }
00091 
00092 void KPrEffectPreview::run( PageEffect effect, EffectSpeed speed )
00093 {
00094     QRect rect = m_pixmap.rect();
00095     m_target.resize( rect.size() );
00096     m_target.fill( Qt::black );
00097 
00098     //kPchangePages( this, m_pixmap, m_target, effect, speed );
00099     if ( m_pageEffect )
00100     {
00101         m_pageEffectTimer.stop();
00102         QObject::disconnect( &m_pageEffectTimer, SIGNAL( timeout() ), this, SLOT( slotDoPageEffect() ) );
00103 
00104         m_pageEffect->finish();
00105 
00106         delete m_pageEffect;
00107         m_pageEffect = 0;
00108         QLabel::repaint();
00109     }
00110 
00111     m_pageEffect = new KPrPageEffects( this, m_target, effect, speed );
00112     if ( m_pageEffect->doEffect() )
00113     {
00114         delete m_pageEffect;
00115         m_pageEffect = 0;
00116         QLabel::update();
00117     }
00118     else
00119     {
00120         connect( &m_pageEffectTimer, SIGNAL( timeout() ), SLOT( slotDoPageEffect() ) );
00121         m_pageEffectTimer.start( 50, true );
00122     }
00123 
00124     //QLabel::update();
00125 }
00126 
00127 
00128 void KPrEffectPreview::slotDoPageEffect()
00129 {
00130     if ( m_pageEffect->doEffect() )
00131     {
00132         m_pageEffectTimer.stop();
00133         QObject::disconnect( &m_pageEffectTimer, SIGNAL( timeout() ), this, SLOT( slotDoPageEffect() ) );
00134         delete m_pageEffect;
00135         m_pageEffect = 0;
00136         QLabel::update();
00137     }
00138     else
00139     {
00140         m_pageEffectTimer.start( 50, true );
00141     }
00142 }
00143 
00144 
00145 KPrTransEffectDia::KPrTransEffectDia( QWidget *parent, const char *name,
00146                                     KPrDocument *_doc, KPrView *_view )
00147     : KDialogBase( parent, name, true, "", KDialogBase::User1|Ok|Cancel ),
00148       doc( _doc ), view( _view ), soundPlayer( 0 )
00149 {
00150     enableButtonSeparator( true );
00151 
00152     QWidget *page = new QWidget( this );
00153     setMainWidget(page);
00154 
00155     QBoxLayout *topLayout = new QHBoxLayout( page, KDialog::marginHint(), KDialog::spacingHint() );
00156     QWidget* leftpart = new QWidget( page );
00157     topLayout->addWidget( leftpart );
00158     QWidget* rightpart = new QWidget( page );
00159     topLayout->addWidget( rightpart );
00160 
00161     // right-side of the dialog, for showing effect preview
00162 
00163     QVBoxLayout *rightlayout = new QVBoxLayout( rightpart, KDialog::marginHint(), KDialog::spacingHint() );
00164     rightlayout->setAutoAdd( true );
00165 
00166     effectPreview = new KPrEffectPreview( rightpart, doc, view );
00167 
00168     int pgnum = view->getCurrPgNum() - 1;  // getCurrPgNum() is 1-based
00169     KPrPage* pg = doc->pageList().at( pgnum );
00170 
00171     // pixmap for effect preview
00172     QRect rect= pg->getZoomPageRect();
00173     QPixmap pix( rect.size() );
00174     pix.fill( Qt::white );
00175     view->getCanvas()->drawPageInPix( pix, pgnum, 100 );
00176     effectPreview->setPixmap( pix );
00177 
00178     pageEffect = pg->getPageEffect();
00179     speed = pg->getPageEffectSpeed();
00180 
00181     QVBoxLayout *leftlayout = new QVBoxLayout( leftpart, KDialog::marginHint(), KDialog::spacingHint() );
00182     leftlayout->setAutoAdd( true );
00183 
00184     new QLabel( i18n("Effect:"), leftpart );
00185 
00186     effectList = new QListBox( leftpart );
00187     effectList->insertItem( i18n( "No Effect" ) );
00188     effectList->insertItem( i18n( "Close Horizontal" ) );
00189     effectList->insertItem( i18n( "Close Vertical" ) );
00190     effectList->insertItem( i18n( "Close From All Directions" ) );
00191     effectList->insertItem( i18n( "Open Horizontal" ) );
00192     effectList->insertItem( i18n( "Open Vertical" ) );
00193     effectList->insertItem( i18n( "Open From All Directions" ) );
00194     effectList->insertItem( i18n( "Interlocking Horizontal 1" ) );
00195     effectList->insertItem( i18n( "Interlocking Horizontal 2" ) );
00196     effectList->insertItem( i18n( "Interlocking Vertical 1" ) );
00197     effectList->insertItem( i18n( "Interlocking Vertical 2" ) );
00198     effectList->insertItem( i18n( "Surround 1" ) );
00199     effectList->insertItem( i18n( "Fly Away 1" ) );
00200     effectList->insertItem( i18n( "Blinds Horizontal" ) );
00201     effectList->insertItem( i18n( "Blinds Vertical" ) );
00202     effectList->insertItem( i18n( "Box In" ) );
00203     effectList->insertItem( i18n( "Box Out" ) );
00204     effectList->insertItem( i18n( "Checkerboard Across" ) );
00205     effectList->insertItem( i18n( "Checkerboard Down" ) );
00206     effectList->insertItem( i18n( "Cover Down" ) );
00207     effectList->insertItem( i18n( "Uncover Down" ) );
00208     effectList->insertItem( i18n( "Cover Up" ) );
00209     effectList->insertItem( i18n( "Uncover Up" ) );
00210     effectList->insertItem( i18n( "Cover Left" ) );
00211     effectList->insertItem( i18n( "Uncover Left" ) );
00212     effectList->insertItem( i18n( "Cover Right" ) );
00213     effectList->insertItem( i18n( "Uncover Right" ) );
00214     effectList->insertItem( i18n( "Cover Left-Up" ) );
00215     effectList->insertItem( i18n( "Uncover Left-Up" ) );
00216     effectList->insertItem( i18n( "Cover Left-Down" ) );
00217     effectList->insertItem( i18n( "Uncover Left-Down" ) );
00218     effectList->insertItem( i18n( "Cover Right-Up" ) );
00219     effectList->insertItem( i18n( "Uncover Right-Up" ) );
00220     effectList->insertItem( i18n( "Cover Right-Bottom" ) );
00221     effectList->insertItem( i18n( "Uncover Right-Bottom" ) );
00222     effectList->insertItem( i18n( "Dissolve" ) );
00223     effectList->insertItem( i18n( "Strips Left-Up" ) );
00224     effectList->insertItem( i18n( "Strips Left-Down" ) );
00225     effectList->insertItem( i18n( "Strips Right-Up" ) );
00226     effectList->insertItem( i18n( "Strips Right-Down" ) );
00227     effectList->insertItem( i18n( "Melting" ) );
00228     effectList->insertItem( i18n( "Random Transition" ) );
00229     effectList->setCurrentItem( static_cast<int>( pageEffect ) );
00230 
00231     // workaround, because Random Effect is always negative
00232     if( pageEffect == PEF_RANDOM )
00233         effectList->setCurrentItem( effectList->count()-1 );
00234 
00235     connect( effectList, SIGNAL(highlighted(int)), this, SLOT(effectChanged(int)) );
00236     connect( effectList, SIGNAL( doubleClicked ( QListBoxItem *) ), this, SLOT( effectChanged()) );
00237 
00238     new QLabel( i18n("Speed:"), leftpart );
00239 
00240     QWidget* sp = new QWidget( leftpart );
00241     QBoxLayout* speedLayout = new QHBoxLayout( sp, KDialog::marginHint(), KDialog::spacingHint() );
00242     speedLayout->setAutoAdd( true );
00243 
00244     speedCombo = new QComboBox( sp );
00245     speedCombo->insertItem(i18n("Slow") );
00246     speedCombo->insertItem(i18n("Medium") );
00247     speedCombo->insertItem(i18n("Fast") );
00248 
00249 
00250     speedCombo->setCurrentItem( speed );
00251 
00252     connect( speedCombo, SIGNAL(activated(int)), this, SLOT(speedChanged(int)) );
00253 
00254 
00255     QWidget* previewgrp = new QWidget( leftpart );
00256     QBoxLayout* previewLayout = new QHBoxLayout( previewgrp, KDialog::marginHint(), KDialog::spacingHint() );
00257     previewLayout->setAutoAdd( true );
00258 
00259     automaticPreview = new QCheckBox( i18n( "Automatic preview" ), previewgrp );
00260     automaticPreview->setChecked( true );
00261 
00262     QWidget* previewspacer = new QWidget( previewgrp );
00263     previewspacer->setSizePolicy( QSizePolicy( QSizePolicy::Expanding,
00264                                                QSizePolicy::Expanding ) );
00265 
00266     previewButton = new QPushButton( previewgrp );
00267     previewButton->setText( i18n("Preview") );
00268     connect( previewButton, SIGNAL(clicked()), this, SLOT(preview()) );
00269 
00270     QFrame* line = new QFrame( leftpart );
00271     line->setFrameStyle( QFrame::HLine | QFrame::Sunken );
00272 
00273     soundFileName = pg->getPageSoundFileName();
00274     soundEffect = pg->getPageSoundEffect();
00275 
00276     checkSoundEffect = new QCheckBox( i18n( "Sound effect" ), leftpart );
00277     checkSoundEffect->setChecked( soundEffect );
00278     connect( checkSoundEffect, SIGNAL( clicked() ), this, SLOT( soundEffectChanged() ) );
00279 
00280     QWidget* soundgrp = new QWidget( leftpart );
00281     QBoxLayout* soundLayout = new QHBoxLayout( soundgrp, KDialog::marginHint(), KDialog::spacingHint() );
00282     soundLayout->setAutoAdd( true );
00283 
00284     lSoundEffect = new QLabel( i18n( "File name:" ), soundgrp );
00285     requester = new KURLRequester( soundgrp );
00286     requester->setURL( soundFileName );
00287     connect( requester, SIGNAL( openFileDialog( KURLRequester * ) ),
00288              this, SLOT( slotRequesterClicked( KURLRequester * ) ) );
00289     connect( requester, SIGNAL( textChanged( const QString& ) ),
00290              this, SLOT( slotSoundFileChanged( const QString& ) ) );
00291 
00292     buttonTestPlaySoundEffect = new QPushButton( soundgrp );
00293     buttonTestPlaySoundEffect->setPixmap( BarIcon("1rightarrow", KIcon::SizeSmall) );
00294     QToolTip::add( buttonTestPlaySoundEffect, i18n("Play") );
00295 
00296     connect( buttonTestPlaySoundEffect, SIGNAL( clicked() ), this, SLOT( playSound() ) );
00297 
00298     buttonTestStopSoundEffect = new QPushButton( soundgrp );
00299     buttonTestStopSoundEffect->setPixmap( BarIcon("player_stop", KIcon::SizeSmall) );
00300     QToolTip::add( buttonTestStopSoundEffect, i18n("Stop") );
00301 
00302     connect( buttonTestStopSoundEffect, SIGNAL( clicked() ), this, SLOT( stopSound() ) );
00303 
00304     soundEffect = pg->getPageSoundEffect();
00305     setButtonText(KDialogBase::User1,i18n( "Apply &Global" ));
00306 
00307     slideTime = pg->getPageTimer();
00308 
00309     new QLabel( i18n("Automatically advance to the next slide after:"), rightpart );
00310 
00311     timeSlider = new KIntNumInput( slideTime, rightpart );
00312     timeSlider->setRange( 1, 600, 1 );
00313     timeSlider->setSuffix( i18n( " seconds" ) );
00314     connect( timeSlider, SIGNAL(valueChanged(int)), this, SLOT(timeChanged(int)) );
00315 
00316     QWidget* rspacer = new QWidget( rightpart );
00317     rspacer->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Expanding ) );
00318 
00319     QWidget* lspacer = new QWidget( leftpart );
00320     lspacer->setMinimumSize( 10, spacingHint() );
00321 
00322     soundEffectChanged();
00323 }
00324 
00325 void KPrTransEffectDia::preview()
00326 {
00327     if( pageEffect==PEF_NONE)
00328         return;
00329     effectPreview->run( pageEffect, speed );
00330 }
00331 
00332 void KPrTransEffectDia::effectChanged()
00333 {
00334     effectChanged( effectList->currentItem() );
00335 }
00336 
00337 void KPrTransEffectDia::effectChanged( int index )
00338 {
00339     if( effectList->currentText() == i18n( "Random Transition" ) )
00340         pageEffect = PEF_RANDOM;
00341     else
00342         pageEffect =  static_cast<PageEffect>( index );
00343 
00344     if( automaticPreview->isChecked() ) preview();
00345 }
00346 
00347 void KPrTransEffectDia::speedChanged( int value )
00348 {
00349     speed = static_cast<EffectSpeed>(value);
00350 }
00351 
00352 void KPrTransEffectDia::timeChanged( int value )
00353 {
00354     if( value <= 0 ) value = 1;
00355     slideTime = value;
00356 }
00357 
00358 void KPrTransEffectDia::soundEffectChanged()
00359 {
00360     soundEffect = checkSoundEffect->isChecked();
00361 
00362     lSoundEffect->setEnabled( checkSoundEffect->isChecked() );
00363     requester->setEnabled( checkSoundEffect->isChecked() );
00364 
00365     if ( !requester->url().isEmpty() ) {
00366         buttonTestPlaySoundEffect->setEnabled( checkSoundEffect->isChecked() );
00367         buttonTestStopSoundEffect->setEnabled( checkSoundEffect->isChecked() );
00368     }
00369     else {
00370         buttonTestPlaySoundEffect->setEnabled( false );
00371         buttonTestStopSoundEffect->setEnabled( false );
00372     }
00373 }
00374 
00375 static QString getSoundFileFilter()
00376 {
00377     QStringList fileList;
00378     fileList << "wav" << "au" << "mp3" << "mp1" << "mp2" << "mpg" << "dat"
00379              << "mpeg" << "ogg" << "cdda" << "cda " << "vcd" << "null";
00380     fileList.sort();
00381 
00382     bool comma = false;
00383     QString full, str;
00384     QStringList::ConstIterator end( fileList.end() );
00385     for ( QStringList::ConstIterator it = fileList.begin(); it != end; ++it ) {
00386         if ( comma )
00387             str += '\n';
00388         comma = true;
00389         str += QString( i18n( "*.%1|%2 Files" ) ).arg( *it ).arg( (*it).upper() );
00390 
00391         full += QString( "*.") + (*it) + ' ';
00392     }
00393 
00394     str = full + '|' + i18n( "All Supported Files" ) + '\n' + str;
00395     str += "\n*|" + i18n( "All Files" );
00396 
00397     return str;
00398 }
00399 
00400 void KPrTransEffectDia::slotRequesterClicked( KURLRequester * )
00401 {
00402     QString filter = getSoundFileFilter();
00403     requester->fileDialog()->setFilter( filter );
00404 
00405     // find the first "sound"-resource that contains files
00406     QStringList soundDirs = KGlobal::dirs()->resourceDirs( "sound" );
00407     if ( !soundDirs.isEmpty() ) {
00408         KURL soundURL;
00409         QDir dir;
00410         dir.setFilter( QDir::Files | QDir::Readable );
00411         QStringList::ConstIterator it = soundDirs.begin();
00412         while ( it != soundDirs.end() ) {
00413             dir = *it;
00414             if ( dir.isReadable() && dir.count() > 2 ) {
00415                 soundURL.setPath( *it );
00416                 requester->fileDialog()->setURL( soundURL );
00417                 break;
00418             }
00419             ++it;
00420         }
00421     }
00422 }
00423 
00424 void KPrTransEffectDia::slotSoundFileChanged( const QString& text )
00425 {
00426     soundFileName = text;
00427 
00428     buttonTestPlaySoundEffect->setEnabled( !text.isEmpty() );
00429     buttonTestStopSoundEffect->setEnabled( !text.isEmpty() );
00430 }
00431 
00432 void KPrTransEffectDia::playSound()
00433 {
00434     delete soundPlayer;
00435     soundPlayer = new KPrSoundPlayer( requester->url() );
00436     soundPlayer->play();
00437 
00438     buttonTestPlaySoundEffect->setEnabled( false );
00439     buttonTestStopSoundEffect->setEnabled( true );
00440 }
00441 
00442 void KPrTransEffectDia::stopSound()
00443 {
00444     if ( soundPlayer ) {
00445         soundPlayer->stop();
00446         delete soundPlayer;
00447         soundPlayer = 0;
00448 
00449         buttonTestPlaySoundEffect->setEnabled( true );
00450         buttonTestStopSoundEffect->setEnabled( false );
00451     }
00452 }
00453 
00454 void KPrTransEffectDia::slotOk()
00455 {
00456     // TODO: only if changed. And pass flags for which settings changed
00457     emit apply( false );
00458 }
00459 
00460 void KPrTransEffectDia::slotUser1()
00461 {
00462     // TODO: only if changed. And pass flags for which settings changed
00463     emit apply( true );
00464 }
00465 
00466 #include "KPrTransEffectDia.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys