kpresenter

KPrTransEffectDia.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2002 Ariya Hidayat <ariya@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18*/
19
20#include "KPrTransEffectDia.h"
21
22#include "global.h"
23#include "KPrBackground.h"
24#include "KPrObject.h"
25#include "KPrTextObject.h"
26#include "KPrView.h"
27#include "KPrDocument.h"
28#include "KPrCanvas.h"
29#include "KPrPage.h"
30#include "KPrPageEffects.h"
31#include "KPrSoundPlayer.h"
32
33#include <tqsplitter.h>
34#include <tqheader.h>
35#include <tqwmatrix.h>
36#include <tqvbox.h>
37#include <tqlayout.h>
38#include <tqimage.h>
39#include <tqpushbutton.h>
40#include <tqcheckbox.h>
41#include <tqslider.h>
42#include <tqtooltip.h>
43#include <tqwhatsthis.h>
44#include <tqframe.h>
45#include <tqlabel.h>
46#include <tqcombobox.h>
47
48#include <kdebug.h>
49#include <kurlrequester.h>
50#include <tdelocale.h>
51#include <knuminput.h>
52#include <kiconloader.h>
53#include <kurl.h>
54#include <kstandarddirs.h>
55#include <tdefiledialog.h>
56
57
58KPrEffectPreview::KPrEffectPreview( TQWidget *parent, KPrDocument *_doc, KPrView *_view )
59 : TQLabel( parent ), doc( _doc ), view( _view ), m_pageEffect( 0 )
60{
61 setFrameStyle( StyledPanel | Sunken );
62}
63
64void KPrEffectPreview::setPixmap( const TQPixmap& pixmap )
65{
66 // find the right size
67 TQRect rect = pixmap.rect();
68 int w = rect.width();
69 int h = rect.height();
70 if ( w > h ) {
71 w = 297;
72 h = 210;
73 }
74 else if ( w < h ) {
75 w = 210;
76 h = 297;
77 }
78 else if ( w == h ) {
79 w = 297;
80 h = 297;
81 }
82
83 setMinimumSize( w, h );
84
85 // create smaller pixmap for preview
86 const TQImage img( pixmap.convertToImage().smoothScale( w, h, TQImage::ScaleFree ) );
87 m_pixmap.convertFromImage( img );
88
89 TQLabel::setPixmap( m_pixmap );
90}
91
92void KPrEffectPreview::run( PageEffect effect, EffectSpeed speed )
93{
94 TQRect rect = m_pixmap.rect();
95 m_target.resize( rect.size() );
96 m_target.fill( TQt::black );
97
98 //kPchangePages( this, m_pixmap, m_target, effect, speed );
99 if ( m_pageEffect )
100 {
101 m_pageEffectTimer.stop();
102 TQObject::disconnect( &m_pageEffectTimer, TQ_SIGNAL( timeout() ), this, TQ_SLOT( slotDoPageEffect() ) );
103
104 m_pageEffect->finish();
105
106 delete m_pageEffect;
107 m_pageEffect = 0;
108 TQLabel::repaint();
109 }
110
111 m_pageEffect = new KPrPageEffects( this, m_target, effect, speed );
112 if ( m_pageEffect->doEffect() )
113 {
114 delete m_pageEffect;
115 m_pageEffect = 0;
116 TQLabel::update();
117 }
118 else
119 {
120 connect( &m_pageEffectTimer, TQ_SIGNAL( timeout() ), TQ_SLOT( slotDoPageEffect() ) );
121 m_pageEffectTimer.start( 50, true );
122 }
123
124 //TQLabel::update();
125}
126
127
128void KPrEffectPreview::slotDoPageEffect()
129{
130 if ( m_pageEffect->doEffect() )
131 {
132 m_pageEffectTimer.stop();
133 TQObject::disconnect( &m_pageEffectTimer, TQ_SIGNAL( timeout() ), this, TQ_SLOT( slotDoPageEffect() ) );
134 delete m_pageEffect;
135 m_pageEffect = 0;
136 TQLabel::update();
137 }
138 else
139 {
140 m_pageEffectTimer.start( 50, true );
141 }
142}
143
144
145KPrTransEffectDia::KPrTransEffectDia( TQWidget *parent, const char *name,
146 KPrDocument *_doc, KPrView *_view )
147 : KDialogBase( parent, name, true, "", KDialogBase::User1|Ok|Cancel ),
148 doc( _doc ), view( _view ), soundPlayer( 0 )
149{
150 enableButtonSeparator( true );
151
152 TQWidget *page = new TQWidget( this );
153 setMainWidget(page);
154
155 TQBoxLayout *topLayout = new TQHBoxLayout( page, KDialog::marginHint(), KDialog::spacingHint() );
156 TQWidget* leftpart = new TQWidget( page );
157 topLayout->addWidget( leftpart );
158 TQWidget* rightpart = new TQWidget( page );
159 topLayout->addWidget( rightpart );
160
161 // right-side of the dialog, for showing effect preview
162
163 TQVBoxLayout *rightlayout = new TQVBoxLayout( rightpart, KDialog::marginHint(), KDialog::spacingHint() );
164 rightlayout->setAutoAdd( true );
165
166 effectPreview = new KPrEffectPreview( rightpart, doc, view );
167
168 int pgnum = view->getCurrPgNum() - 1; // getCurrPgNum() is 1-based
169 KPrPage* pg = doc->pageList().at( pgnum );
170
171 // pixmap for effect preview
172 TQRect rect= pg->getZoomPageRect();
173 TQPixmap pix( rect.size() );
174 pix.fill( TQt::white );
175 view->getCanvas()->drawPageInPix( pix, pgnum, 100 );
176 effectPreview->setPixmap( pix );
177
178 pageEffect = pg->getPageEffect();
179 speed = pg->getPageEffectSpeed();
180
181 TQVBoxLayout *leftlayout = new TQVBoxLayout( leftpart, KDialog::marginHint(), KDialog::spacingHint() );
182 leftlayout->setAutoAdd( true );
183
184 new TQLabel( i18n("Effect:"), leftpart );
185
186 effectList = new TQListBox( leftpart );
187 effectList->insertItem( i18n( "No Effect" ) );
188 effectList->insertItem( i18n( "Close Horizontal" ) );
189 effectList->insertItem( i18n( "Close Vertical" ) );
190 effectList->insertItem( i18n( "Close From All Directions" ) );
191 effectList->insertItem( i18n( "Open Horizontal" ) );
192 effectList->insertItem( i18n( "Open Vertical" ) );
193 effectList->insertItem( i18n( "Open From All Directions" ) );
194 effectList->insertItem( i18n( "Interlocking Horizontal 1" ) );
195 effectList->insertItem( i18n( "Interlocking Horizontal 2" ) );
196 effectList->insertItem( i18n( "Interlocking Vertical 1" ) );
197 effectList->insertItem( i18n( "Interlocking Vertical 2" ) );
198 effectList->insertItem( i18n( "Surround 1" ) );
199 effectList->insertItem( i18n( "Fly Away 1" ) );
200 effectList->insertItem( i18n( "Blinds Horizontal" ) );
201 effectList->insertItem( i18n( "Blinds Vertical" ) );
202 effectList->insertItem( i18n( "Box In" ) );
203 effectList->insertItem( i18n( "Box Out" ) );
204 effectList->insertItem( i18n( "Checkerboard Across" ) );
205 effectList->insertItem( i18n( "Checkerboard Down" ) );
206 effectList->insertItem( i18n( "Cover Down" ) );
207 effectList->insertItem( i18n( "Uncover Down" ) );
208 effectList->insertItem( i18n( "Cover Up" ) );
209 effectList->insertItem( i18n( "Uncover Up" ) );
210 effectList->insertItem( i18n( "Cover Left" ) );
211 effectList->insertItem( i18n( "Uncover Left" ) );
212 effectList->insertItem( i18n( "Cover Right" ) );
213 effectList->insertItem( i18n( "Uncover Right" ) );
214 effectList->insertItem( i18n( "Cover Left-Up" ) );
215 effectList->insertItem( i18n( "Uncover Left-Up" ) );
216 effectList->insertItem( i18n( "Cover Left-Down" ) );
217 effectList->insertItem( i18n( "Uncover Left-Down" ) );
218 effectList->insertItem( i18n( "Cover Right-Up" ) );
219 effectList->insertItem( i18n( "Uncover Right-Up" ) );
220 effectList->insertItem( i18n( "Cover Right-Bottom" ) );
221 effectList->insertItem( i18n( "Uncover Right-Bottom" ) );
222 effectList->insertItem( i18n( "Dissolve" ) );
223 effectList->insertItem( i18n( "Strips Left-Up" ) );
224 effectList->insertItem( i18n( "Strips Left-Down" ) );
225 effectList->insertItem( i18n( "Strips Right-Up" ) );
226 effectList->insertItem( i18n( "Strips Right-Down" ) );
227 effectList->insertItem( i18n( "Melting" ) );
228 effectList->insertItem( i18n( "Random Transition" ) );
229 effectList->setCurrentItem( static_cast<int>( pageEffect ) );
230
231 // workaround, because Random Effect is always negative
232 if( pageEffect == PEF_RANDOM )
233 effectList->setCurrentItem( effectList->count()-1 );
234
235 connect( effectList, TQ_SIGNAL(highlighted(int)), this, TQ_SLOT(effectChanged(int)) );
236 connect( effectList, TQ_SIGNAL( doubleClicked ( TQListBoxItem *) ), this, TQ_SLOT( effectChanged()) );
237
238 new TQLabel( i18n("Speed:"), leftpart );
239
240 TQWidget* sp = new TQWidget( leftpart );
241 TQBoxLayout* speedLayout = new TQHBoxLayout( sp, KDialog::marginHint(), KDialog::spacingHint() );
242 speedLayout->setAutoAdd( true );
243
244 speedCombo = new TQComboBox( sp );
245 speedCombo->insertItem(i18n("Slow") );
246 speedCombo->insertItem(i18n("Medium") );
247 speedCombo->insertItem(i18n("Fast") );
248
249
250 speedCombo->setCurrentItem( speed );
251
252 connect( speedCombo, TQ_SIGNAL(activated(int)), this, TQ_SLOT(speedChanged(int)) );
253
254
255 TQWidget* previewgrp = new TQWidget( leftpart );
256 TQBoxLayout* previewLayout = new TQHBoxLayout( previewgrp, KDialog::marginHint(), KDialog::spacingHint() );
257 previewLayout->setAutoAdd( true );
258
259 automaticPreview = new TQCheckBox( i18n( "Automatic preview" ), previewgrp );
260 automaticPreview->setChecked( true );
261
262 TQWidget* previewspacer = new TQWidget( previewgrp );
263 previewspacer->setSizePolicy( TQSizePolicy( TQSizePolicy::Expanding,
264 TQSizePolicy::Expanding ) );
265
266 previewButton = new TQPushButton( previewgrp );
267 previewButton->setText( i18n("Preview") );
268 connect( previewButton, TQ_SIGNAL(clicked()), this, TQ_SLOT(preview()) );
269
270 TQFrame* line = new TQFrame( leftpart );
271 line->setFrameStyle( TQFrame::HLine | TQFrame::Sunken );
272
273 soundFileName = pg->getPageSoundFileName();
274 soundEffect = pg->getPageSoundEffect();
275
276 checkSoundEffect = new TQCheckBox( i18n( "Sound effect" ), leftpart );
277 checkSoundEffect->setChecked( soundEffect );
278 connect( checkSoundEffect, TQ_SIGNAL( clicked() ), this, TQ_SLOT( soundEffectChanged() ) );
279
280 TQWidget* soundgrp = new TQWidget( leftpart );
281 TQBoxLayout* soundLayout = new TQHBoxLayout( soundgrp, KDialog::marginHint(), KDialog::spacingHint() );
282 soundLayout->setAutoAdd( true );
283
284 lSoundEffect = new TQLabel( i18n( "File name:" ), soundgrp );
285 requester = new KURLRequester( soundgrp );
286 requester->setURL( soundFileName );
287 connect( requester, TQ_SIGNAL( openFileDialog( KURLRequester * ) ),
288 this, TQ_SLOT( slotRequesterClicked( KURLRequester * ) ) );
289 connect( requester, TQ_SIGNAL( textChanged( const TQString& ) ),
290 this, TQ_SLOT( slotSoundFileChanged( const TQString& ) ) );
291
292 buttonTestPlaySoundEffect = new TQPushButton( soundgrp );
293 buttonTestPlaySoundEffect->setPixmap( BarIcon("1rightarrow", TDEIcon::SizeSmall) );
294 TQToolTip::add( buttonTestPlaySoundEffect, i18n("Play") );
295
296 connect( buttonTestPlaySoundEffect, TQ_SIGNAL( clicked() ), this, TQ_SLOT( playSound() ) );
297
298 buttonTestStopSoundEffect = new TQPushButton( soundgrp );
299 buttonTestStopSoundEffect->setPixmap( BarIcon("media-playback-stop", TDEIcon::SizeSmall) );
300 TQToolTip::add( buttonTestStopSoundEffect, i18n("Stop") );
301
302 connect( buttonTestStopSoundEffect, TQ_SIGNAL( clicked() ), this, TQ_SLOT( stopSound() ) );
303
304 soundEffect = pg->getPageSoundEffect();
305 setButtonText(KDialogBase::User1,i18n( "Apply &Global" ));
306
307 slideTime = pg->getPageTimer();
308
309 new TQLabel( i18n("Automatically advance to the next slide after:"), rightpart );
310
311 timeSlider = new KIntNumInput( slideTime, rightpart );
312 timeSlider->setRange( 1, 600, 1 );
313 timeSlider->setSuffix( i18n( " seconds" ) );
314 connect( timeSlider, TQ_SIGNAL(valueChanged(int)), this, TQ_SLOT(timeChanged(int)) );
315
316 TQWidget* rspacer = new TQWidget( rightpart );
317 rspacer->setSizePolicy( TQSizePolicy( TQSizePolicy::Minimum, TQSizePolicy::Expanding ) );
318
319 TQWidget* lspacer = new TQWidget( leftpart );
320 lspacer->setMinimumSize( 10, spacingHint() );
321
322 soundEffectChanged();
323}
324
325void KPrTransEffectDia::preview()
326{
327 if( pageEffect==PEF_NONE)
328 return;
329 effectPreview->run( pageEffect, speed );
330}
331
332void KPrTransEffectDia::effectChanged()
333{
334 effectChanged( effectList->currentItem() );
335}
336
337void KPrTransEffectDia::effectChanged( int index )
338{
339 if( effectList->currentText() == i18n( "Random Transition" ) )
340 pageEffect = PEF_RANDOM;
341 else
342 pageEffect = static_cast<PageEffect>( index );
343
344 if( automaticPreview->isChecked() ) preview();
345}
346
347void KPrTransEffectDia::speedChanged( int value )
348{
349 speed = static_cast<EffectSpeed>(value);
350}
351
352void KPrTransEffectDia::timeChanged( int value )
353{
354 if( value <= 0 ) value = 1;
355 slideTime = value;
356}
357
358void KPrTransEffectDia::soundEffectChanged()
359{
360 soundEffect = checkSoundEffect->isChecked();
361
362 lSoundEffect->setEnabled( checkSoundEffect->isChecked() );
363 requester->setEnabled( checkSoundEffect->isChecked() );
364
365 if ( !requester->url().isEmpty() ) {
366 buttonTestPlaySoundEffect->setEnabled( checkSoundEffect->isChecked() );
367 buttonTestStopSoundEffect->setEnabled( checkSoundEffect->isChecked() );
368 }
369 else {
370 buttonTestPlaySoundEffect->setEnabled( false );
371 buttonTestStopSoundEffect->setEnabled( false );
372 }
373}
374
375static TQString getSoundFileFilter()
376{
377 TQStringList fileList;
378 fileList << "wav" << "au" << "mp3" << "mp1" << "mp2" << "mpg" << "dat"
379 << "mpeg" << "ogg" << "cdda" << "cda " << "vcd" << "null";
380 fileList.sort();
381
382 bool comma = false;
383 TQString full, str;
384 TQStringList::ConstIterator end( fileList.end() );
385 for ( TQStringList::ConstIterator it = fileList.begin(); it != end; ++it ) {
386 if ( comma )
387 str += '\n';
388 comma = true;
389 str += TQString( i18n( "*.%1|%2 Files" ) ).arg( *it ).arg( (*it).upper() );
390
391 full += TQString( "*.") + (*it) + ' ';
392 }
393
394 str = full + '|' + i18n( "All Supported Files" ) + '\n' + str;
395 str += "\n*|" + i18n( "All Files" );
396
397 return str;
398}
399
400void KPrTransEffectDia::slotRequesterClicked( KURLRequester * )
401{
402 TQString filter = getSoundFileFilter();
403 requester->fileDialog()->setFilter( filter );
404
405 // find the first "sound"-resource that contains files
406 TQStringList soundDirs = TDEGlobal::dirs()->resourceDirs( "sound" );
407 if ( !soundDirs.isEmpty() ) {
408 KURL soundURL;
409 TQDir dir;
410 dir.setFilter( TQDir::Files | TQDir::Readable );
411 TQStringList::ConstIterator it = soundDirs.begin();
412 while ( it != soundDirs.end() ) {
413 dir = *it;
414 if ( dir.isReadable() && dir.count() > 2 ) {
415 soundURL.setPath( *it );
416 requester->fileDialog()->setURL( soundURL );
417 break;
418 }
419 ++it;
420 }
421 }
422}
423
424void KPrTransEffectDia::slotSoundFileChanged( const TQString& text )
425{
426 soundFileName = text;
427
428 buttonTestPlaySoundEffect->setEnabled( !text.isEmpty() );
429 buttonTestStopSoundEffect->setEnabled( !text.isEmpty() );
430}
431
432void KPrTransEffectDia::playSound()
433{
434 delete soundPlayer;
435 soundPlayer = new KPrSoundPlayer( requester->url() );
436 soundPlayer->play();
437
438 buttonTestPlaySoundEffect->setEnabled( false );
439 buttonTestStopSoundEffect->setEnabled( true );
440}
441
442void KPrTransEffectDia::stopSound()
443{
444 if ( soundPlayer ) {
445 soundPlayer->stop();
446 delete soundPlayer;
447 soundPlayer = 0;
448
449 buttonTestPlaySoundEffect->setEnabled( true );
450 buttonTestStopSoundEffect->setEnabled( false );
451 }
452}
453
454void KPrTransEffectDia::slotOk()
455{
456 // TODO: only if changed. And pass flags for which settings changed
457 emit apply( false );
458}
459
460void KPrTransEffectDia::slotUser1()
461{
462 // TODO: only if changed. And pass flags for which settings changed
463 emit apply( true );
464}
465
466#include "KPrTransEffectDia.moc"