/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sdext.hxx"

#include "optimizerdialog.hxx"
#include "minimizer.hrc"
#include "helpid.hrc"

// -------------------
// - OptimizerDialog -
// -------------------
#include "pppoptimizer.hxx"
#include "graphiccollector.hxx"
#include "pagecollector.hxx"
#include <com/sun/star/presentation/XCustomPresentationSupplier.hpp>
#include <com/sun/star/drawing/XMasterPagesSupplier.hpp>
#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
#include <com/sun/star/awt/FontDescriptor.hpp>
#ifndef _COM_SUN_STAR_AWT_XFONTWEIGHT_HPP_
#include <com/sun/star/awt/FontWeight.hpp>
#endif
#include <rtl/ustrbuf.hxx>

using namespace ::com::sun::star::awt;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::script;
using namespace ::com::sun::star::drawing;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::presentation;

using ::rtl::OUString;
using ::rtl::OUStringBuffer;
// -----------------------------------------------------------------------------

void OptimizerDialog::ImplSetBold( const rtl::OUString& rControl )
{
	FontDescriptor aFontDescriptor;
	if ( getControlProperty( rControl, TKGet( TK_FontDescriptor ) ) >>= aFontDescriptor )
	{
		aFontDescriptor.Weight = FontWeight::BOLD;
		setControlProperty( rControl, TKGet( TK_FontDescriptor ), Any( aFontDescriptor ) );
	}
}

// -----------------------------------------------------------------------------

rtl::OUString OptimizerDialog::ImplInsertSeparator(
	const OUString& rControlName,
	sal_Int32 nOrientation,
	sal_Int32 nPosX,
	sal_Int32 nPosY,
	sal_Int32 nWidth,
	sal_Int32 nHeight )
{
	OUString pNames[] = {
		TKGet( TK_Height ),
		TKGet( TK_Orientation ),
		TKGet( TK_PositionX ),
		TKGet( TK_PositionY ),
		TKGet( TK_Step ),
		TKGet( TK_Width ) };

	Any	pValues[] = {
		Any( nHeight ),
		Any( nOrientation ),
		Any( nPosX ),
		Any( nPosY ),
		Any( sal_Int16( 0 ) ),
		Any( nWidth ) };

	sal_Int32 nCount = sizeof( pNames ) / sizeof( OUString );

	Sequence< rtl::OUString >	aNames( pNames, nCount );
	Sequence< Any >				aValues( pValues, nCount );

	insertControlModel( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.UnoControlFixedLineModel" ) ),
		rControlName, aNames, aValues );
	return rControlName;
}

// -----------------------------------------------------------------------------

rtl::OUString OptimizerDialog::ImplInsertButton(
	const OUString& rControlName,
	const rtl::OUString& rHelpURL,
	sal_Int32 nXPos,
	sal_Int32 nYPos,
	sal_Int32 nWidth,
	sal_Int32 nHeight,
	sal_Int16 nTabIndex,
	sal_Bool bEnabled,
	sal_Int32 nResID,
	sal_Int16 nPushButtonType )
{
	OUString pNames[] = {
		TKGet( TK_Enabled ),
		TKGet( TK_Height ),
		TKGet( TK_HelpURL ),
		TKGet( TK_Label ),
		TKGet( TK_PositionX ),
		TKGet( TK_PositionY ),
		TKGet( TK_PushButtonType ),
		TKGet( TK_Step ),
		TKGet( TK_TabIndex ),
		TKGet( TK_Width ) };

	Any	pValues[] = {
		Any( bEnabled ),
		Any( nHeight ),
		Any( rHelpURL ),
		Any( getString( nResID ) ),
		Any( nXPos ),
		Any( nYPos ),
		Any( nPushButtonType ),
		Any( (sal_Int16)0 ),
		Any( nTabIndex ),
		Any( nWidth ) };


	sal_Int32 nCount = sizeof( pNames ) / sizeof( OUString );

	Sequence< rtl::OUString >	aNames( pNames, nCount );
	Sequence< Any >				aValues( pValues, nCount );

	insertButton( rControlName, this, aNames, aValues );
	return rControlName;
}

// -----------------------------------------------------------------------------

rtl::OUString OptimizerDialog::ImplInsertFixedText(
	const rtl::OUString& rControlName,
	const OUString& rLabel,
	sal_Int32 nXPos,
	sal_Int32 nYPos,
	sal_Int32 nWidth,
	sal_Int32 nHeight,
	sal_Bool bMultiLine,
	sal_Bool bBold,
	sal_Int16 nTabIndex )
{
	OUString pNames[] = {
		TKGet( TK_Height ),
		TKGet( TK_Label ),
		TKGet( TK_MultiLine ),
		TKGet( TK_PositionX ),
		TKGet( TK_PositionY ),
		TKGet( TK_Step ),
		TKGet( TK_TabIndex ),
		TKGet( TK_Width ) };

	Any	pValues[] = {
		Any( nHeight ),
		Any( rLabel ),
		Any( bMultiLine ),
		Any( nXPos ),
		Any( nYPos ),
		Any( (sal_Int16)0 ),
		Any( nTabIndex ),
		Any( nWidth ) };

	sal_Int32 nCount = sizeof( pNames ) / sizeof( OUString );

	Sequence< rtl::OUString >	aNames( pNames, nCount );
	Sequence< Any >				aValues( pValues, nCount );

	insertFixedText( rControlName, aNames, aValues );
	if ( bBold )
		ImplSetBold( rControlName );
	return rControlName;
}

// -----------------------------------------------------------------------------

rtl::OUString OptimizerDialog::ImplInsertCheckBox(
	const OUString& rControlName,
	const OUString& rLabel,
	const rtl::OUString& rHelpURL,
	sal_Int32 nXPos,
	sal_Int32 nYPos,
	sal_Int32 nWidth,
	sal_Int32 nHeight,
	sal_Int16 nTabIndex )
{
	OUString pNames[] = {
		TKGet( TK_Enabled ),
		TKGet( TK_Height ),
		TKGet( TK_HelpURL ),
		TKGet( TK_Label ),
		TKGet( TK_PositionX ),
		TKGet( TK_PositionY ),
		TKGet( TK_Step ),
		TKGet( TK_TabIndex ),
		TKGet( TK_Width ) };

	Any	pValues[] = {
		Any( sal_True ),
		Any( nHeight ),
		Any( rHelpURL ),
		Any( rLabel ),
		Any( nXPos ),
		Any( nYPos ),
		Any( (sal_Int16)0 ),
		Any( nTabIndex ),
		Any( nWidth ) };

	sal_Int32 nCount = sizeof( pNames ) / sizeof( OUString );

	Sequence< rtl::OUString >	aNames( pNames, nCount );
	Sequence< Any >				aValues( pValues, nCount );

	Reference< XCheckBox > xCheckBox( insertCheckBox( rControlName, aNames, aValues ) );
	xCheckBox->addItemListener( this );
	return rControlName;
}

// -----------------------------------------------------------------------------

rtl::OUString OptimizerDialog::ImplInsertFormattedField(
	const OUString& rControlName,
	const rtl::OUString& rHelpURL,
	sal_Int32 nXPos,
	sal_Int32 nYPos,
	sal_Int32 nWidth,
	double fEffectiveMin,
	double fEffectiveMax,
	sal_Int16 nTabIndex )
{
	OUString pNames[] = {
		TKGet( TK_EffectiveMax ),
		TKGet( TK_EffectiveMin ),
		TKGet( TK_Enabled ),
		TKGet( TK_Height ),
		TKGet( TK_HelpURL ),
		TKGet( TK_PositionX ),
		TKGet( TK_PositionY ),
		TKGet( TK_Repeat ),
		TKGet( TK_Spin ),
		TKGet( TK_Step ),
		TKGet( TK_TabIndex ),
		TKGet( TK_Width ) };

	Any	pValues[] = {
		Any( fEffectiveMax ),
		Any( fEffectiveMin ),
		Any( sal_True ),
		Any( (sal_Int32)12 ),
		Any( rHelpURL ),
		Any( nXPos ),
		Any( nYPos ),
		Any( (sal_Bool)sal_True ),
		Any( (sal_Bool)sal_True ),
		Any( (sal_Int16)0 ),
		Any( nTabIndex ),
		Any( nWidth ) };

	sal_Int32 nCount = sizeof( pNames ) / sizeof( OUString );

	Sequence< rtl::OUString >	aNames( pNames, nCount );
	Sequence< Any >				aValues( pValues, nCount );

	Reference< XTextComponent > xTextComponent( insertFormattedField( rControlName, aNames, aValues ), UNO_QUERY_THROW );
	xTextComponent->addTextListener( this );
	Reference< XSpinField > xSpinField( xTextComponent, UNO_QUERY_THROW );
	xSpinField->addSpinListener( this );

	return rControlName;
}

// -----------------------------------------------------------------------------

rtl::OUString OptimizerDialog::ImplInsertComboBox(
	const OUString& rControlName,
	const rtl::OUString& rHelpURL,
	const sal_Bool bEnabled,
	const Sequence< OUString >& rItemList,
	sal_Int32 nXPos,
	sal_Int32 nYPos,
	sal_Int32 nWidth,
	sal_Int32 nHeight,
	sal_Int16 nTabIndex,
	bool bListen )
{
	OUString pNames[] = {
		TKGet( TK_Dropdown ),
		TKGet( TK_Enabled ),
		TKGet( TK_Height ),
		TKGet( TK_HelpURL ),
		TKGet( TK_LineCount ),
		TKGet( TK_PositionX ),
		TKGet( TK_PositionY ),
		TKGet( TK_Step ),
		TKGet( TK_StringItemList ),
		TKGet( TK_TabIndex ),
		TKGet( TK_Width ) };

	Any	pValues[] = {
		Any( sal_True ),
		Any( bEnabled ),
		Any( nHeight ),
		Any( rHelpURL ),
		Any( (sal_Int16)8),
		Any( nXPos ),
		Any( nYPos ),
		Any( (sal_Int16)0 ),
		Any( rItemList ),
		Any( nTabIndex ),
		Any( nWidth ) };

	sal_Int32 nCount = sizeof( pNames ) / sizeof( OUString );

	Sequence< rtl::OUString >	aNames( pNames, nCount );
	Sequence< Any >				aValues( pValues, nCount );

	Reference< XTextComponent > xTextComponent( insertComboBox( rControlName, aNames, aValues ), UNO_QUERY_THROW );
	if ( bListen )
		xTextComponent->addTextListener( this );
	return rControlName;
}

// -----------------------------------------------------------------------------

rtl::OUString OptimizerDialog::ImplInsertRadioButton(
	const rtl::OUString& rControlName,
	const OUString& rLabel,
	const rtl::OUString& rHelpURL,
	sal_Int32 nXPos,
	sal_Int32 nYPos,
	sal_Int32 nWidth,
	sal_Int32 nHeight,
	sal_Bool bMultiLine,
	sal_Int16 nTabIndex )
{
	OUString pNames[] = {
		TKGet( TK_Height ),
		TKGet( TK_HelpURL ),
		TKGet( TK_Label ),
		TKGet( TK_MultiLine ),
		TKGet( TK_PositionX ),
		TKGet( TK_PositionY ),
		TKGet( TK_Step ),
		TKGet( TK_TabIndex ),
		TKGet( TK_Width ) };

	Any	pValues[] = {
		Any( nHeight ),
		Any( rHelpURL ),
		Any( rLabel ),
		Any( bMultiLine ),
		Any( nXPos ),
		Any( nYPos ),
		Any( (sal_Int16)0 ),
		Any( nTabIndex ),
		Any( nWidth ) };

	sal_Int32 nCount = sizeof( pNames ) / sizeof( OUString );

	Sequence< rtl::OUString >	aNames( pNames, nCount );
	Sequence< Any >				aValues( pValues, nCount );

	Reference< XRadioButton > xRadioButton( insertRadioButton( rControlName, aNames, aValues ) );
	xRadioButton->addItemListener( this );
	return rControlName;
}

// -----------------------------------------------------------------------------

rtl::OUString OptimizerDialog::ImplInsertListBox(
	const OUString& rControlName,
	const rtl::OUString& rHelpURL,
	const sal_Bool bEnabled,
	const Sequence< OUString >& rItemList,
	sal_Int32 nXPos,
	sal_Int32 nYPos,
	sal_Int32 nWidth,
	sal_Int32 nHeight,
	sal_Int16 nTabIndex )
{
	OUString pNames[] = {
		TKGet( TK_Dropdown ),
		TKGet( TK_Enabled ),
		TKGet( TK_Height ),
		TKGet( TK_HelpURL ),
		TKGet( TK_LineCount ),
		TKGet( TK_MultiSelection ),
		TKGet( TK_PositionX ),
		TKGet( TK_PositionY ),
		TKGet( TK_Step ),
		TKGet( TK_StringItemList ),
		TKGet( TK_TabIndex ),
		TKGet( TK_Width ) };

	Any	pValues[] = {
		Any( sal_True ),
		Any( bEnabled ),
		Any( nHeight ),
		Any( rHelpURL ),
		Any( (sal_Int16)8),
		Any( sal_False ),
		Any( nXPos ),
		Any( nYPos ),
		Any( (sal_Int16)0 ),
		Any( rItemList ),
		Any( nTabIndex ),
		Any( nWidth ) };

	sal_Int32 nCount = sizeof( pNames ) / sizeof( OUString );

	Sequence< rtl::OUString >	aNames( pNames, nCount );
	Sequence< Any >				aValues( pValues, nCount );

	Reference< XListBox > xListBox( insertListBox( rControlName, aNames, aValues ) );
	xListBox->addActionListener( this );
	return rControlName;
}

// -----------------------------------------------------------------------------

void OptimizerDialog::InitNavigationBar()
{
	sal_Int32	nCancelPosX = OD_DIALOG_WIDTH - BUTTON_WIDTH - 6;
	sal_Int32	nFinishPosX = nCancelPosX - 6 - BUTTON_WIDTH;
	sal_Int32	nNextPosX = nFinishPosX - 6 - BUTTON_WIDTH;
	sal_Int32	nBackPosX = nNextPosX - 3 - BUTTON_WIDTH;

	ImplInsertSeparator( TKGet( TK_lnNavSep1 ), 0, 0, DIALOG_HEIGHT - 26, OD_DIALOG_WIDTH, 1 );
	ImplInsertSeparator( TKGet( TK_lnNavSep2 ), 1, 85, 0, 1, BUTTON_POS_Y - 6 );

	ImplInsertButton( TKGet( TK_btnNavHelp ), HID( HID_SDEXT_MINIMIZER_WIZ_PB_HELP ), 8, BUTTON_POS_Y, BUTTON_WIDTH, BUTTON_HEIGHT, mnTabIndex++, sal_True, STR_HELP, PushButtonType_HELP );
	ImplInsertButton( TKGet( TK_btnNavBack ), HID( HID_SDEXT_MINIMIZER_WIZ_PB_BACK ), nBackPosX, BUTTON_POS_Y, BUTTON_WIDTH, BUTTON_HEIGHT, mnTabIndex++, sal_False, STR_BACK, PushButtonType_STANDARD );
	ImplInsertButton( TKGet( TK_btnNavNext ), HID( HID_SDEXT_MINIMIZER_WIZ_PB_NEXT ), nNextPosX, BUTTON_POS_Y, BUTTON_WIDTH, BUTTON_HEIGHT, mnTabIndex++, sal_True, STR_NEXT, PushButtonType_STANDARD );
	ImplInsertButton( TKGet( TK_btnNavFinish ), HID( HID_SDEXT_MINIMIZER_WIZ_PB_FINISH ), nFinishPosX, BUTTON_POS_Y, BUTTON_WIDTH, BUTTON_HEIGHT, mnTabIndex++, sal_True, STR_FINISH, PushButtonType_STANDARD );
	ImplInsertButton( TKGet( TK_btnNavCancel ), HID( HID_SDEXT_MINIMIZER_WIZ_PB_CANCEL ), nCancelPosX, BUTTON_POS_Y, BUTTON_WIDTH, BUTTON_HEIGHT, mnTabIndex++, sal_True, STR_CANCEL, PushButtonType_STANDARD );

	setControlProperty( TKGet( TK_btnNavNext ), TKGet( TK_DefaultButton ), Any( sal_True ) );
}

// -----------------------------------------------------------------------------

void OptimizerDialog::UpdateControlStatesPage0()
{
	sal_uInt32 i;
	short nSelectedItem = -1;
	Sequence< OUString > aItemList;
	const std::vector< OptimizerSettings >& rList( GetOptimizerSettings() );
	if ( rList.size() > 1 )	// the first session in the list is the actual one -> skipping first one
	{
		aItemList.realloc( rList.size() - 1 );
		for ( i = 1; i < rList.size(); i++ )
		{
			aItemList[ i - 1 ] = rList[ i ].maName;
			if ( nSelectedItem < 0 )
			{
				if ( rList[ i ] == rList[ 0 ] )
					nSelectedItem = static_cast< short >( i - 1 );
			}
		}
	}
	sal_Bool bRemoveButtonEnabled = sal_False;
	Sequence< short > aSelectedItems;
	if ( nSelectedItem >= 0 )
	{
		aSelectedItems.realloc( 1 );
		aSelectedItems[ 0 ] = nSelectedItem;
		if ( nSelectedItem > 2 )	// only allowing to delete custom themes, the first can't be deleted
			bRemoveButtonEnabled = sal_True;
	}
	setControlProperty( TKGet( TK_ListBox0Pg0 ), TKGet( TK_StringItemList ), Any( aItemList ) );
	setControlProperty( TKGet( TK_ListBox0Pg0 ), TKGet( TK_SelectedItems ), Any( aSelectedItems ) );
	setControlProperty( TKGet( TK_Button0Pg0 ), TKGet( TK_Enabled ), Any( bRemoveButtonEnabled ) );
}
void OptimizerDialog::InitPage0()
{
	Sequence< OUString > aItemList;
	std::vector< rtl::OUString > aControlList;
	aControlList.push_back( ImplInsertFixedText( TKGet( TK_FixedText0Pg0 ), getString( STR_INTRODUCTION ), PAGE_POS_X, PAGE_POS_Y, PAGE_WIDTH, 8, sal_False, sal_True, mnTabIndex++ ) );
	aControlList.push_back( ImplInsertFixedText( TKGet( TK_FixedText1Pg0 ), getString( STR_INTRODUCTION_T ), PAGE_POS_X + 6, PAGE_POS_Y + 14, PAGE_WIDTH - 12, 100, sal_True, sal_False, mnTabIndex++ ) );
	aControlList.push_back( ImplInsertSeparator( TKGet( TK_Separator1Pg0 ), 0, PAGE_POS_X + 6, DIALOG_HEIGHT - 66, PAGE_WIDTH - 12, 1 ) );
	aControlList.push_back( ImplInsertFixedText( TKGet( TK_FixedText2Pg0 ), getString( STR_CHOOSE_SETTINGS ), PAGE_POS_X + 6, DIALOG_HEIGHT - 60, PAGE_WIDTH - 12, 8, sal_True, sal_False, mnTabIndex++ ) );
	aControlList.push_back( ImplInsertListBox( TKGet( TK_ListBox0Pg0 ), HID(HID_SDEXT_MINIMIZER_WIZ_STEP1_LB_SETTINGS),sal_True, aItemList, PAGE_POS_X + 6, DIALOG_HEIGHT - 48, ( OD_DIALOG_WIDTH - 50 ) - ( PAGE_POS_X + 6 ), 12, mnTabIndex++ ) );
	aControlList.push_back( ImplInsertButton( TKGet( TK_Button0Pg0 ), HID( HID_SDEXT_MINIMIZER_WIZ_STEP1_PB_DELSETTS ),OD_DIALOG_WIDTH - 46, DIALOG_HEIGHT - 49, 40, 14, mnTabIndex++, sal_True, STR_REMOVE, PushButtonType_STANDARD ) );
	maControlPages.push_back( aControlList );
	DeactivatePage( 0 );
	UpdateControlStatesPage0();
}

// -----------------------------------------------------------------------------

void OptimizerDialog::UpdateControlStatesPage1()
{
	sal_Bool bDeleteUnusedMasterPages( GetConfigProperty( TK_DeleteUnusedMasterPages, sal_False ) );
	sal_Bool bDeleteHiddenSlides( GetConfigProperty( TK_DeleteHiddenSlides, sal_False ) );
	sal_Bool bDeleteNotesPages( GetConfigProperty( TK_DeleteNotesPages, sal_False ) );

	setControlProperty( TKGet( TK_CheckBox0Pg3 ), TKGet( TK_State ), Any( (sal_Int16)bDeleteUnusedMasterPages ) );
	setControlProperty( TKGet( TK_CheckBox1Pg3 ), TKGet( TK_State ), Any( (sal_Int16)bDeleteNotesPages ) );
	setControlProperty( TKGet( TK_CheckBox2Pg3 ), TKGet( TK_State ), Any( (sal_Int16)bDeleteHiddenSlides ) );
}
void OptimizerDialog::InitPage1()
{
	Sequence< OUString > aCustomShowList;
	Reference< XModel > xModel( mxModel );
	if ( xModel.is() )
	{
		Reference< XCustomPresentationSupplier > aXCPSup( xModel, UNO_QUERY_THROW );
		Reference< XNameContainer > aXCont( aXCPSup->getCustomPresentations() );
		if ( aXCont.is() )
			aCustomShowList = aXCont->getElementNames();
	}
	std::vector< rtl::OUString > aControlList;
	aControlList.push_back( ImplInsertFixedText( TKGet( TK_FixedText0Pg3 ), getString( STR_CHOOSE_SLIDES ), PAGE_POS_X, PAGE_POS_Y, PAGE_WIDTH, 8, sal_False, sal_True, mnTabIndex++ ) );
	aControlList.push_back( ImplInsertCheckBox( TKGet( TK_CheckBox0Pg3 ), getString( STR_DELETE_MASTER_PAGES ), HID( HID_SDEXT_MINIMIZER_WIZ_STEP2_CB_MASTERPAGES ), PAGE_POS_X + 6, PAGE_POS_Y + 14, PAGE_WIDTH - 12, 8, mnTabIndex++ ) );
	aControlList.push_back( ImplInsertCheckBox( TKGet( TK_CheckBox2Pg3 ), getString( STR_DELETE_HIDDEN_SLIDES ), HID( HID_SDEXT_MINIMIZER_WIZ_STEP2_CB_HIDDENSLIDES ), PAGE_POS_X + 6, PAGE_POS_Y + 28, PAGE_WIDTH - 12, 8, mnTabIndex++ ) );
	aControlList.push_back( ImplInsertCheckBox( TKGet( TK_CheckBox3Pg3 ), getString( STR_CUSTOM_SHOW ), HID( HID_SDEXT_MINIMIZER_WIZ_STEP2_CB_CUSTOMSHOW ), PAGE_POS_X + 6, PAGE_POS_Y + 42, PAGE_WIDTH - 12, 8, mnTabIndex++ ) );
	aControlList.push_back( ImplInsertListBox( TKGet( TK_ListBox0Pg3 ), HID(HID_SDEXT_MINIMIZER_WIZ_STEP2_LB_CUSTOMSHOW),sal_True, aCustomShowList, PAGE_POS_X + 14, PAGE_POS_Y + 54, 150, 12, mnTabIndex++ ) );
	aControlList.push_back( ImplInsertCheckBox( TKGet( TK_CheckBox1Pg3 ), getString( STR_DELETE_NOTES_PAGES ), HID( HID_SDEXT_MINIMIZER_WIZ_STEP2_CB_NOTES ), PAGE_POS_X + 6, PAGE_POS_Y + 70, PAGE_WIDTH - 12, 8, mnTabIndex++ ) );
	maControlPages.push_back( aControlList );
	DeactivatePage( 1 );

	setControlProperty( TKGet( TK_CheckBox3Pg3 ), TKGet( TK_State ), Any( sal_False ) );
	setControlProperty( TKGet( TK_CheckBox3Pg3 ), TKGet( TK_Enabled ), Any( aCustomShowList.getLength() != 0 ) );
	setControlProperty( TKGet( TK_ListBox0Pg3 ), TKGet( TK_Enabled ), Any( sal_False ) );

	UpdateControlStatesPage1();
}

// -----------------------------------------------------------------------------

void OptimizerDialog::UpdateControlStatesPage2()
{
	sal_Bool bJPEGCompression( GetConfigProperty( TK_JPEGCompression, sal_False ) );
	sal_Bool bRemoveCropArea( GetConfigProperty( TK_RemoveCropArea, sal_False ) );
	sal_Bool bEmbedLinkedGraphics( GetConfigProperty( TK_EmbedLinkedGraphics, sal_True ) );
	sal_Int32 nJPEGQuality( GetConfigProperty( TK_JPEGQuality, (sal_Int32)90 ) );

	sal_Int32 nImageResolution( GetConfigProperty( TK_ImageResolution, (sal_Int32)0 ) );

	sal_Int32 nI0, nI1, nI2, nI3;
	nI0 = nI1 = nI2 = nI3 = 0;
	OUString aResolutionText;
	Sequence< OUString > aResolutionItemList( 4 );
	aResolutionItemList[ 0 ] = getString( STR_IMAGE_RESOLUTION_0 ).getToken( 1, ';', nI0 );
	aResolutionItemList[ 1 ] = getString( STR_IMAGE_RESOLUTION_1 ).getToken( 1, ';', nI1 );
	aResolutionItemList[ 2 ] = getString( STR_IMAGE_RESOLUTION_2 ).getToken( 1, ';', nI2 );
	aResolutionItemList[ 3 ] = getString( STR_IMAGE_RESOLUTION_3 ).getToken( 1, ';', nI3 );
	nI0 = nI1 = nI2 = nI3 = 0;
	if ( getString( STR_IMAGE_RESOLUTION_0 ).getToken( 0, ';', nI0 ).toInt32() == nImageResolution )
		aResolutionText = aResolutionItemList[ 0 ];
	else if ( getString( STR_IMAGE_RESOLUTION_1 ).getToken( 0, ';', nI1 ).toInt32() == nImageResolution )
		aResolutionText = aResolutionItemList[ 1 ];
	else if ( getString( STR_IMAGE_RESOLUTION_2 ).getToken( 0, ';', nI2 ).toInt32() == nImageResolution )
		aResolutionText = aResolutionItemList[ 2 ];
	else if ( getString( STR_IMAGE_RESOLUTION_3 ).getToken( 0, ';', nI3 ).toInt32() == nImageResolution )
		aResolutionText = aResolutionItemList[ 3 ];
	if ( !aResolutionText.getLength() )
		aResolutionText = OUString::valueOf( nImageResolution );

	setControlProperty( TKGet( TK_RadioButton0Pg1 ), TKGet( TK_State ), Any( (sal_Int16)( bJPEGCompression != sal_True ) ) );
	setControlProperty( TKGet( TK_RadioButton1Pg1 ), TKGet( TK_State ), Any( (sal_Int16)( bJPEGCompression != sal_False ) ) );
	setControlProperty( TKGet( TK_FixedText1Pg1 ), TKGet( TK_Enabled ), Any( bJPEGCompression ) );
	setControlProperty( TKGet( TK_FormattedField0Pg1 ), TKGet( TK_Enabled ), Any( bJPEGCompression ) );
	setControlProperty( TKGet( TK_FormattedField0Pg1 ), TKGet( TK_EffectiveValue ), Any( (double)nJPEGQuality ) );
	setControlProperty( TKGet( TK_CheckBox1Pg1 ), TKGet( TK_State ), Any( (sal_Int16)bRemoveCropArea ) );
	setControlProperty( TKGet( TK_ComboBox0Pg1 ), TKGet( TK_Text ), Any( aResolutionText ) );
	setControlProperty( TKGet( TK_CheckBox2Pg1 ), TKGet( TK_State ), Any( (sal_Int16)bEmbedLinkedGraphics ) );
}
void OptimizerDialog::InitPage2()
{
	sal_Int32 nI0, nI1, nI2, nI3;
	nI0 = nI1 = nI2 = nI3 = 0;
	Sequence< OUString > aResolutionItemList( 4 );
	aResolutionItemList[ 0 ] = getString( STR_IMAGE_RESOLUTION_0 ).getToken( 1, ';', nI0 );
	aResolutionItemList[ 1 ] = getString( STR_IMAGE_RESOLUTION_1 ).getToken( 1, ';', nI1 );
	aResolutionItemList[ 2 ] = getString( STR_IMAGE_RESOLUTION_2 ).getToken( 1, ';', nI2 );
	aResolutionItemList[ 3 ] = getString( STR_IMAGE_RESOLUTION_3 ).getToken( 1, ';', nI3 );

	std::vector< rtl::OUString > aControlList;
	aControlList.push_back( ImplInsertFixedText( TKGet( TK_FixedText0Pg1 ), getString( STR_GRAPHIC_OPTIMIZATION ), PAGE_POS_X, PAGE_POS_Y, PAGE_WIDTH, 8, sal_False, sal_True, mnTabIndex++ ) );
	aControlList.push_back( ImplInsertRadioButton( TKGet( TK_RadioButton0Pg1 ), getString( STR_LOSSLESS_COMPRESSION ), HID( HID_SDEXT_MINIMIZER_WIZ_STEP3_RB_LOSSLESS ), PAGE_POS_X + 6, PAGE_POS_Y + 14, PAGE_WIDTH - 12, 8, sal_False, mnTabIndex++ ) );
	aControlList.push_back( ImplInsertRadioButton( TKGet( TK_RadioButton1Pg1 ), getString( STR_JPEG_COMPRESSION ), HID( HID_SDEXT_MINIMIZER_WIZ_STEP3_RB_JPEG ), PAGE_POS_X + 6, PAGE_POS_Y + 28, PAGE_WIDTH - 12, 8, sal_False, mnTabIndex++ ) );
	aControlList.push_back( ImplInsertFixedText( TKGet( TK_FixedText1Pg1 ), getString( STR_QUALITY ), PAGE_POS_X + 20, PAGE_POS_Y + 40, 72, 8, sal_False, sal_False, mnTabIndex++ ) );
	aControlList.push_back( ImplInsertFormattedField( TKGet( TK_FormattedField0Pg1 ), HID( HID_SDEXT_MINIMIZER_WIZ_STEP3_MF_QUALITY ), PAGE_POS_X + 106, PAGE_POS_Y + 38, 50, 0, 100, mnTabIndex++ ) );
	aControlList.push_back( ImplInsertFixedText( TKGet( TK_FixedText2Pg1 ), getString( STR_IMAGE_RESOLUTION ), PAGE_POS_X + 6, PAGE_POS_Y + 54, 94, 8, sal_False, sal_False, mnTabIndex++ ) );
	aControlList.push_back( ImplInsertComboBox( TKGet( TK_ComboBox0Pg1 ), HID( HID_SDEXT_MINIMIZER_WIZ_STEP3_LB_DPI ), sal_True, aResolutionItemList, PAGE_POS_X + 106, PAGE_POS_Y + 52, 100, 12, mnTabIndex++ ) );
	aControlList.push_back( ImplInsertCheckBox( TKGet( TK_CheckBox1Pg1 ), getString( STR_REMOVE_CROP_AREA ), HID( HID_SDEXT_MINIMIZER_WIZ_STEP3_CB_CROP ), PAGE_POS_X + 6, PAGE_POS_Y + 68, PAGE_WIDTH - 12, 8, mnTabIndex++ ) );
	aControlList.push_back( ImplInsertCheckBox( TKGet( TK_CheckBox2Pg1 ), getString( STR_EMBED_LINKED_GRAPHICS ), HID( HID_SDEXT_MINIMIZER_WIZ_STEP3_CB_LINKS ), PAGE_POS_X + 6, PAGE_POS_Y + 82, PAGE_WIDTH - 12, 8, mnTabIndex++ ) );
	maControlPages.push_back( aControlList );
	DeactivatePage( 2 );
	UpdateControlStatesPage2();
}

// -----------------------------------------------------------------------------

void OptimizerDialog::UpdateControlStatesPage3()
{
	sal_Bool bConvertOLEObjects( GetConfigProperty( TK_OLEOptimization, sal_False ) );
	sal_Int16 nOLEOptimizationType( GetConfigProperty( TK_OLEOptimizationType, (sal_Int16)0 ) );

	setControlProperty( TKGet( TK_CheckBox0Pg2 ), TKGet( TK_State ), Any( (sal_Int16)bConvertOLEObjects ) );
	setControlProperty( TKGet( TK_RadioButton0Pg2 ), TKGet( TK_Enabled ), Any( bConvertOLEObjects ) );
	setControlProperty( TKGet( TK_RadioButton0Pg2 ), TKGet( TK_State ), Any( (sal_Int16)( nOLEOptimizationType == 0 ) ) );
	setControlProperty( TKGet( TK_RadioButton1Pg2 ), TKGet( TK_Enabled ), Any( bConvertOLEObjects ) );
	setControlProperty( TKGet( TK_RadioButton1Pg2 ), TKGet( TK_State ), Any( (sal_Int16)( nOLEOptimizationType == 1 ) ) );
}
void OptimizerDialog::InitPage3()
{
	int nOLECount = 0;
	Reference< XModel > xModel( mxModel );
	Reference< XDrawPagesSupplier > xDrawPagesSupplier( xModel, UNO_QUERY_THROW );
	Reference< XDrawPages > xDrawPages( xDrawPagesSupplier->getDrawPages(), UNO_QUERY_THROW );
	for ( sal_Int32 i = 0; i < xDrawPages->getCount(); i++ )
	{
		Reference< XShapes > xShapes( xDrawPages->getByIndex( i ), UNO_QUERY_THROW );
		for ( sal_Int32 j = 0; j < xShapes->getCount(); j++ )
		{
			const OUString sOLE2Shape( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.OLE2Shape" ) );
			Reference< XShape > xShape( xShapes->getByIndex( j ), UNO_QUERY_THROW );
			if ( xShape->getShapeType() == sOLE2Shape )
				nOLECount++;
		}
	}

	std::vector< rtl::OUString > aControlList;
	aControlList.push_back( ImplInsertFixedText( TKGet( TK_FixedText0Pg2 ), getString( STR_OLE_OPTIMIZATION ), PAGE_POS_X, PAGE_POS_Y, PAGE_WIDTH, 8, sal_False, sal_True, mnTabIndex++ ) );
	aControlList.push_back( ImplInsertCheckBox( TKGet( TK_CheckBox0Pg2 ), getString( STR_OLE_REPLACE ), HID( HID_SDEXT_MINIMIZER_WIZ_STEP4_CB_OLE ), PAGE_POS_X + 6, PAGE_POS_Y + 14, PAGE_WIDTH - 12, 8, mnTabIndex++ ) );
	aControlList.push_back( ImplInsertRadioButton( TKGet( TK_RadioButton0Pg2 ), getString( STR_ALL_OLE_OBJECTS ), HID(HID_SDEXT_MINIMIZER_WIZ_STEP4_RB_ALLOLE), PAGE_POS_X + 14, PAGE_POS_Y + 28, PAGE_WIDTH - 22, 8, sal_False, mnTabIndex++ ) );
	aControlList.push_back( ImplInsertRadioButton( TKGet( TK_RadioButton1Pg2 ), getString( STR_ALIEN_OLE_OBJECTS_ONLY ), HID(HID_SDEXT_MINIMIZER_WIZ_STEP4_RB_NOTODF),PAGE_POS_X + 14, PAGE_POS_Y + 40, PAGE_WIDTH - 22, 8, sal_False, mnTabIndex++ ) );
	aControlList.push_back( ImplInsertFixedText( TKGet( TK_FixedText1Pg2 ), nOLECount ? getString( STR_OLE_OBJECTS_DESC ) : getString( STR_NO_OLE_OBJECTS_DESC ), PAGE_POS_X + 6, PAGE_POS_Y + 64, PAGE_WIDTH - 22, 50, sal_True, sal_False, mnTabIndex++ ) );
	maControlPages.push_back( aControlList );
	DeactivatePage( 3 );
	UpdateControlStatesPage3();
}

// -----------------------------------------------------------------------------

static OUString ImpValueOfInMB( const sal_Int64& rVal, sal_Unicode nSeparator = '.' )
{
	double fVal( static_cast<double>( rVal ) );
	fVal /= ( 1 << 20 );
	fVal += 0.05;
	rtl::OUStringBuffer aVal( OUString::valueOf( fVal ) );
	sal_Int32 nX( OUString( aVal.getStr() ).indexOf( '.', 0 ) );
	if ( nX >= 0 )
	{
		aVal.setLength( nX + 2 );
		aVal.setCharAt( nX, nSeparator );
	}
	aVal.append( OUString::createFromAscii( " MB" ) );
	return aVal.makeStringAndClear();
}

void OptimizerDialog::UpdateControlStatesPage4()
{
	sal_Bool bSaveAs( GetConfigProperty( TK_SaveAs, sal_True ) );
	if ( mbIsReadonly )
	{
		setControlProperty( TKGet( TK_RadioButton0Pg4 ), TKGet( TK_State ), Any( (sal_Int16)( sal_False ) ) );
		setControlProperty( TKGet( TK_RadioButton1Pg4 ), TKGet( TK_State ), Any( (sal_Int16)( sal_True ) ) );
	}
	else
	{
		setControlProperty( TKGet( TK_RadioButton0Pg4 ), TKGet( TK_State ), Any( (sal_Int16)( bSaveAs == sal_False ) ) );
		setControlProperty( TKGet( TK_RadioButton1Pg4 ), TKGet( TK_State ), Any( (sal_Int16)( bSaveAs == sal_True ) ) );
	}
	setControlProperty( TKGet( TK_ComboBox0Pg4 ), TKGet( TK_Enabled ), Any( sal_False ) );

	sal_uInt32 w;
	Sequence< OUString > aItemList;
	const std::vector< OptimizerSettings >& rList( GetOptimizerSettings() );
	if ( rList.size() > 1 )	// the first session in the list is the actual one -> skipping first one
	{
		aItemList.realloc( rList.size() - 1 );
		for ( w = 1; w < rList.size(); w++ )
			aItemList[ w - 1 ] = rList[ w ].maName;
	}
	setControlProperty( TKGet( TK_ComboBox0Pg4 ), TKGet( TK_StringItemList ), Any( aItemList ) );

	// now check if it is sensible to enable the combo box
	sal_Bool bSaveSettingsEnabled = sal_True;
	if ( rList.size() > 1 )	// the first session in the list is the actual one -> skipping first one
	{
		for ( w = 1; w < rList.size(); w++ )
		{
			if ( rList[ w ] == rList[ 0 ] )
			{
				bSaveSettingsEnabled = sal_False;
				break;
			}
		}
	}
	sal_Int16 nInt16 = 0;
	getControlProperty( TKGet( TK_CheckBox1Pg4 ), TKGet( TK_State ) ) >>= nInt16;
	setControlProperty( TKGet( TK_CheckBox1Pg4 ), TKGet( TK_Enabled ), Any( bSaveSettingsEnabled ) );
	setControlProperty( TKGet( TK_ComboBox0Pg4 ), TKGet( TK_Enabled ), Any( bSaveSettingsEnabled && nInt16 ) );

	std::vector< OUString > aSummaryStrings;

	// taking care of deleted slides
	sal_Int32 nDeletedSlides = 0;
	rtl::OUString aCustomShowName;
	if ( getControlProperty( TKGet( TK_CheckBox3Pg3 ), TKGet( TK_State ) ) >>= nInt16 )
	{
		if ( nInt16 )
		{
			Sequence< short > aSelectedItems;
			Sequence< OUString > aStringItemList;
			Any aAny = getControlProperty( TKGet( TK_ListBox0Pg3 ), TKGet( TK_SelectedItems ) );
			if ( aAny >>= aSelectedItems )
			{
				if ( aSelectedItems.getLength() )
				{
					sal_Int16 nSelectedItem = aSelectedItems[ 0 ];
					aAny = getControlProperty( TKGet( TK_ListBox0Pg3 ), TKGet( TK_StringItemList ) );
					if ( aAny >>= aStringItemList )
					{
						if ( aStringItemList.getLength() > nSelectedItem )
							SetConfigProperty( TK_CustomShowName, Any( aStringItemList[ nSelectedItem ] ) );
					}
				}
			}
		}
	}
	if ( aCustomShowName.getLength() )
	{
		std::vector< Reference< XDrawPage > > vNonUsedPageList;
		PageCollector::CollectNonCustomShowPages( mxModel, aCustomShowName, vNonUsedPageList );
		nDeletedSlides += vNonUsedPageList.size();
	}
	if ( GetConfigProperty( TK_DeleteHiddenSlides, sal_False ) )
	{
		if ( aCustomShowName.getLength() )
		{
			std::vector< Reference< XDrawPage > > vUsedPageList;
			PageCollector::CollectCustomShowPages( mxModel, aCustomShowName, vUsedPageList );
			std::vector< Reference< XDrawPage > >::iterator aIter( vUsedPageList.begin() );
			while( aIter != vUsedPageList.end() )
			{
				Reference< XPropertySet > xPropSet( *aIter, UNO_QUERY_THROW );
				sal_Bool bVisible = sal_True;
				const OUString sVisible( RTL_CONSTASCII_USTRINGPARAM( "Visible" ) );
				if ( xPropSet->getPropertyValue( sVisible ) >>= bVisible )
				{
					if (!bVisible )
						nDeletedSlides++;
				}
				aIter++;
			}
		}
		else
		{
			Reference< XDrawPagesSupplier > xDrawPagesSupplier( mxModel, UNO_QUERY_THROW );
			Reference< XDrawPages > xDrawPages( xDrawPagesSupplier->getDrawPages(), UNO_QUERY_THROW );
			for( sal_Int32 i = 0; i < xDrawPages->getCount(); i++ )
			{
				Reference< XDrawPage > xDrawPage( xDrawPages->getByIndex( i ), UNO_QUERY_THROW );
				Reference< XPropertySet > xPropSet( xDrawPage, UNO_QUERY_THROW );

				sal_Bool bVisible = sal_True;
				const OUString sVisible( RTL_CONSTASCII_USTRINGPARAM( "Visible" ) );
				if ( xPropSet->getPropertyValue( sVisible ) >>= bVisible )
				{
					if (!bVisible )
						nDeletedSlides++;
				}
			}
		}
	}
	if ( GetConfigProperty( TK_DeleteUnusedMasterPages, sal_False ) )
	{
		std::vector< PageCollector::MasterPageEntity > aMasterPageList;
		PageCollector::CollectMasterPages( mxModel, aMasterPageList );
		Reference< XMasterPagesSupplier > xMasterPagesSupplier( mxModel, UNO_QUERY_THROW );
		Reference< XDrawPages > xMasterPages( xMasterPagesSupplier->getMasterPages(), UNO_QUERY_THROW );
		std::vector< PageCollector::MasterPageEntity >::iterator aIter( aMasterPageList.begin() );
		while( aIter != aMasterPageList.end() )
		{
			if ( !aIter->bUsed )
				nDeletedSlides++;
			aIter++;
		}
	}
	if ( nDeletedSlides > 1 )
	{
		OUString aStr( getString( STR_DELETE_SLIDES ) );
		OUString aPlaceholder( RTL_CONSTASCII_USTRINGPARAM( "%SLIDES" ) );
		sal_Int32 i = aStr.indexOf( aPlaceholder, 0 );
		if ( i >= 0 )
			aStr = aStr.replaceAt( i, aPlaceholder.getLength(), OUString::valueOf( nDeletedSlides ) );
		aSummaryStrings.push_back( aStr );
	}

// generating graphic compression info
	sal_Int32 nGraphics = 0;
	sal_Bool bJPEGCompression( GetConfigProperty( TK_JPEGCompression, sal_False ) );
	sal_Int32 nJPEGQuality( GetConfigProperty( TK_JPEGQuality, (sal_Int32)90 ) );
	sal_Int32 nImageResolution( GetConfigProperty( TK_ImageResolution, (sal_Int32)0 ) );
	GraphicSettings aGraphicSettings( bJPEGCompression, nJPEGQuality, GetConfigProperty( TK_RemoveCropArea, sal_False ),
										nImageResolution, GetConfigProperty( TK_EmbedLinkedGraphics, sal_True ) );
	GraphicCollector::CountGraphics( mxContext, mxModel, aGraphicSettings, nGraphics );
	if ( nGraphics > 1 )
	{
		OUString aStr( getString( STR_OPTIMIZE_IMAGES ) );
		OUString aImagePlaceholder( RTL_CONSTASCII_USTRINGPARAM( "%IMAGES" ) );
		OUString aQualityPlaceholder( RTL_CONSTASCII_USTRINGPARAM( "%QUALITY" ) );
		OUString aResolutionPlaceholder( RTL_CONSTASCII_USTRINGPARAM( "%RESOLUTION" ) );
		sal_Int32 i = aStr.indexOf( aImagePlaceholder, 0 );
		if ( i >= 0 )
			aStr = aStr.replaceAt( i, aImagePlaceholder.getLength(), OUString::valueOf( nGraphics ) );

		sal_Int32 j = aStr.indexOf( aQualityPlaceholder, 0 );
		if ( j >= 0 )
			aStr = aStr.replaceAt( j, aQualityPlaceholder.getLength(), OUString::valueOf( nJPEGQuality ) );

		sal_Int32 k = aStr.indexOf( aResolutionPlaceholder, 0 );
		if ( k >= 0 )
			aStr = aStr.replaceAt( k, aResolutionPlaceholder.getLength(), OUString::valueOf( nImageResolution ) );

		aSummaryStrings.push_back( aStr );
	}

	if ( GetConfigProperty( TK_OLEOptimization, sal_False ) )
	{
		sal_Int32 nOLEReplacements = 0;
		Reference< XDrawPagesSupplier > xDrawPagesSupplier( mxModel, UNO_QUERY_THROW );
		Reference< XDrawPages > xDrawPages( xDrawPagesSupplier->getDrawPages(), UNO_QUERY_THROW );
		for ( sal_Int32 i = 0; i < xDrawPages->getCount(); i++ )
		{
			Reference< XShapes > xShapes( xDrawPages->getByIndex( i ), UNO_QUERY_THROW );
			for ( sal_Int32 j = 0; j < xShapes->getCount(); j++ )
			{
				const OUString sOLE2Shape( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.OLE2Shape" ) );
				Reference< XShape > xShape( xShapes->getByIndex( j ), UNO_QUERY_THROW );
				if ( xShape->getShapeType() == sOLE2Shape )
					nOLEReplacements++;
			}
		}
		if ( nOLEReplacements > 1 )
		{
			OUString aStr( getString( STR_CREATE_REPLACEMENT ) );
			OUString aPlaceholder( RTL_CONSTASCII_USTRINGPARAM( "%OLE" ) );
			sal_Int32 i = aStr.indexOf( aPlaceholder, 0 );
			if ( i >= 0 )
				aStr = aStr.replaceAt( i, aPlaceholder.getLength(), OUString::valueOf( nOLEReplacements ) );
			aSummaryStrings.push_back( aStr );
		}
	}
	while( aSummaryStrings.size() < 3 )
		aSummaryStrings.push_back( OUString() );
	setControlProperty( TKGet( TK_FixedText4Pg4 ), TKGet( TK_Label ), Any( aSummaryStrings[ 0 ] ) );
	setControlProperty( TKGet( TK_FixedText5Pg4 ), TKGet( TK_Label ), Any( aSummaryStrings[ 1 ] ) );
	setControlProperty( TKGet( TK_FixedText6Pg4 ), TKGet( TK_Label ), Any( aSummaryStrings[ 2 ] ) );

	sal_Int64 nCurrentFileSize = 0;
	sal_Int64 nEstimatedFileSize = 0;
	Reference< XStorable > xStorable( mxModel, UNO_QUERY );
	if ( xStorable.is() && xStorable->hasLocation() )
		nCurrentFileSize = PPPOptimizer::GetFileSize( xStorable->getLocation() );

	if ( nCurrentFileSize )
	{
		double fE = static_cast< double >( nCurrentFileSize );
		if ( nImageResolution )
		{
			double v = ( static_cast< double >( nImageResolution ) + 75.0 ) / 300.0;
			if ( v < 1.0 )
				fE *= v;
		}
		if ( bJPEGCompression )
		{
			double v = 0.75 - ( ( 100.0 - static_cast< double >( nJPEGQuality ) ) / 400.0 ) ;
			fE *= v;
		}
		nEstimatedFileSize = static_cast< sal_Int64 >( fE );
	}
	sal_Unicode nSeparator = '.';
	OUString aStr( getString( STR_FILESIZESEPARATOR ) );
	if ( aStr.getLength() )
		nSeparator = aStr[ 0 ];
	setControlProperty( TKGet( TK_FixedText7Pg4 ), TKGet( TK_Label ), Any( ImpValueOfInMB( nCurrentFileSize, nSeparator ) ) );
	setControlProperty( TKGet( TK_FixedText8Pg4 ), TKGet( TK_Label ), Any( ImpValueOfInMB( nEstimatedFileSize, nSeparator ) ) );
	SetConfigProperty( TK_EstimatedFileSize, Any( nEstimatedFileSize ) );
}

void OptimizerDialog::InitPage4()
{
	{	// creating progress bar:
		OUString pNames[] = {
			TKGet( TK_Height ),
			TKGet( TK_Name ),
			TKGet( TK_PositionX ),
			TKGet( TK_PositionY ),
			TKGet( TK_ProgressValue ),
			TKGet( TK_ProgressValueMax ),
			TKGet( TK_ProgressValueMin ),
			TKGet( TK_Width ) };

		Any	pValues[] = {
			Any( (sal_Int32)12 ),
			Any( OUString( RTL_CONSTASCII_USTRINGPARAM("STR_SAVE_AS") ) ), //TODO
			Any( (sal_Int32)( PAGE_POS_X + 6 ) ),
			Any( (sal_Int32)( DIALOG_HEIGHT - 75 ) ),
			Any( (sal_Int32)( 0 ) ),
			Any( (sal_Int32)( 100 ) ),
			Any( (sal_Int32)( 0 ) ),
			Any( (sal_Int32)( PAGE_WIDTH - 12 ) ) };

		sal_Int32 nCount = sizeof( pNames ) / sizeof( OUString );

		Sequence< rtl::OUString >	aNames( pNames, nCount );
		Sequence< Any >				aValues( pValues, nCount );

		Reference< XMultiPropertySet > xMultiPropertySet( insertControlModel( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.UnoControlProgressBarModel" ) ),
			TKGet( TK_Progress ), aNames, aValues ), UNO_QUERY );
	}

	Sequence< OUString > aItemList;
	std::vector< rtl::OUString > aControlList;
	aControlList.push_back( ImplInsertFixedText( TKGet( TK_FixedText0Pg4 ), getString( STR_SUMMARY_TITLE ), PAGE_POS_X, PAGE_POS_Y, PAGE_WIDTH, 8, sal_False, sal_True, mnTabIndex++ ) );
//	aControlList.push_back( ImplInsertSeparator( TKGet( TK_Separator0Pg4 ), 0, PAGE_POS_X + 6, PAGE_POS_Y + 90, PAGE_WIDTH - 12, 1 ) );

	aControlList.push_back( ImplInsertFixedText( TKGet( TK_FixedText4Pg4 ), OUString(), PAGE_POS_X + 6, PAGE_POS_Y + 14, PAGE_WIDTH - 12, 8, sal_False, sal_False, mnTabIndex++ ) );
	aControlList.push_back( ImplInsertFixedText( TKGet( TK_FixedText5Pg4 ), OUString(), PAGE_POS_X + 6, PAGE_POS_Y + 22, PAGE_WIDTH - 12, 8, sal_False, sal_False, mnTabIndex++ ) );
	aControlList.push_back( ImplInsertFixedText( TKGet( TK_FixedText6Pg4 ), OUString(), PAGE_POS_X + 6, PAGE_POS_Y + 30, PAGE_WIDTH - 12, 8, sal_False, sal_False, mnTabIndex++ ) );

	aControlList.push_back( ImplInsertFixedText( TKGet( TK_FixedText2Pg4 ), getString( STR_CURRENT_FILESIZE ), PAGE_POS_X + 6, PAGE_POS_Y + 50, 88, 8, sal_False, sal_False, mnTabIndex++ ) );
	aControlList.push_back( ImplInsertFixedText( TKGet( TK_FixedText7Pg4 ), OUString(), PAGE_POS_X + 100, PAGE_POS_Y + 50, 30, 8, sal_False, sal_False, mnTabIndex++ ) );
	setControlProperty( TKGet( TK_FixedText7Pg4 ), TKGet( TK_Align ), Any( static_cast< short >( 2 ) ) );
	aControlList.push_back( ImplInsertFixedText( TKGet( TK_FixedText3Pg4 ), getString( STR_ESTIMATED_FILESIZE ), PAGE_POS_X + 6, PAGE_POS_Y + 58, 88, 8, sal_False, sal_False, mnTabIndex++ ) );
	aControlList.push_back( ImplInsertFixedText( TKGet( TK_FixedText8Pg4 ), OUString(), PAGE_POS_X + 100, PAGE_POS_Y + 58, 30, 8, sal_False, sal_False, mnTabIndex++ ) );
	setControlProperty( TKGet( TK_FixedText8Pg4 ), TKGet( TK_Align ), Any( static_cast< short >( 2 ) ) );

	aControlList.push_back( ImplInsertRadioButton( TKGet( TK_RadioButton0Pg4 ), getString( STR_APPLY_TO_CURRENT ), HID(HID_SDEXT_MINIMIZER_WIZ_STEP5_RB_CURDOC),PAGE_POS_X + 6, PAGE_POS_Y + 78, PAGE_WIDTH - 12, 8, sal_False, mnTabIndex++ ) );
	aControlList.push_back( ImplInsertRadioButton( TKGet( TK_RadioButton1Pg4 ), getString( STR_SAVE_AS ), HID(HID_SDEXT_MINIMIZER_WIZ_STEP5_RB_NEWDOC),PAGE_POS_X + 6, PAGE_POS_Y + 90, PAGE_WIDTH - 12, 8, sal_False, mnTabIndex++ ) );
	aControlList.push_back( ImplInsertFixedText( TKGet( TK_FixedText1Pg4 ), OUString(), PAGE_POS_X + 6, DIALOG_HEIGHT - 87, PAGE_WIDTH - 12, 8, sal_True, sal_False, mnTabIndex++ ) );
	aControlList.push_back( TKGet( TK_Progress ) );
	aControlList.push_back( ImplInsertSeparator( TKGet( TK_Separator1Pg4 ), 0, PAGE_POS_X + 6, DIALOG_HEIGHT - 58, PAGE_WIDTH - 12, 1 ) );
	aControlList.push_back( ImplInsertCheckBox( TKGet( TK_CheckBox1Pg4 ), getString( STR_SAVE_SETTINGS ), HID( HID_SDEXT_MINIMIZER_WIZ_STEP5_CB_SAVESETTINGS ), PAGE_POS_X + 6, DIALOG_HEIGHT - 47, 100, 8, mnTabIndex++ ) );
	// don't listen to this
	aControlList.push_back(
		ImplInsertComboBox(
			TKGet( TK_ComboBox0Pg4 ), HID( HID_SDEXT_MINIMIZER_WIZ_STEP5_LB_SETTINGSNAME ),sal_True, aItemList,
			PAGE_POS_X + 106, DIALOG_HEIGHT - 48, 100, 12, mnTabIndex++ ,
			false) );
	maControlPages.push_back( aControlList );
	DeactivatePage( 4 );

	// creating a default session name that hasn't been used yet
	OUString aSettingsName;
	OUString aDefault( getString( STR_MY_SETTINGS ) );
	sal_Int32 nSession = 1;
	sal_uInt32 i;
	const std::vector< OptimizerSettings >& rList( GetOptimizerSettings() );
	do
	{
		OUString aTemp( aDefault.concat( OUString::valueOf( nSession++ ) ) );
		for ( i = 1; i < rList.size(); i++ )
		{
			if ( rList[ i ].maName == aTemp )
				break;
		}
		if ( i == rList.size() )
			aSettingsName = aTemp;
	}
	while( !aSettingsName.getLength() );

	setControlProperty( TKGet( TK_ComboBox0Pg4 ), TKGet( TK_Text ), Any( aSettingsName ) );
	setControlProperty( TKGet( TK_RadioButton0Pg4 ), TKGet( TK_Enabled ), Any( !mbIsReadonly ) );
	setControlProperty( TKGet( TK_RadioButton1Pg4 ), TKGet( TK_Enabled ), Any( !mbIsReadonly ) );

	UpdateControlStatesPage4();
}

// -----------------------------------------------------------------------------
void OptimizerDialog::EnablePage( sal_Int16 nStep )
{
	std::vector< rtl::OUString >::iterator aBeg( maControlPages[ nStep ].begin() );
	std::vector< rtl::OUString >::iterator aEnd( maControlPages[ nStep ].end() );
	while( aBeg != aEnd )
		setControlProperty( *aBeg++, TKGet( TK_Enabled ), Any( sal_True ) );
}
void OptimizerDialog::DisablePage( sal_Int16 nStep )
{
	std::vector< rtl::OUString >::iterator aBeg( maControlPages[ nStep ].begin() );
	std::vector< rtl::OUString >::iterator aEnd( maControlPages[ nStep ].end() );
	while( aBeg != aEnd )
		setControlProperty( *aBeg++, TKGet( TK_Enabled ), Any( sal_False ) );
}
void OptimizerDialog::ActivatePage( sal_Int16 nStep )
{
	std::vector< rtl::OUString >::iterator aBeg( maControlPages[ nStep ].begin() );
	std::vector< rtl::OUString >::iterator aEnd( maControlPages[ nStep ].end() );
	while( aBeg != aEnd )
		setVisible( *aBeg++, sal_True );
}
void OptimizerDialog::DeactivatePage( sal_Int16 nStep )
{
	std::vector< rtl::OUString >::iterator aBeg( maControlPages[ nStep ].begin() );
	std::vector< rtl::OUString >::iterator aEnd( maControlPages[ nStep ].end() );
	while( aBeg != aEnd )
		setVisible( *aBeg++, sal_False );
}

/* vim: set noet sw=4 ts=4: */
